Como posso criar uma caixa de mensagem simples em Python?

119

Estou procurando o mesmo efeito alert()do JavaScript.

Escrevi um intérprete simples baseado na web esta tarde usando Twisted.web. Basicamente, você envia um bloco de código Python por meio de um formulário, e o cliente vem e o pega e executa. Eu quero ser capaz de fazer uma mensagem pop-up simples, sem ter que reescrever um monte de código clichê wxPython ou TkInter todas as vezes (já que o código é enviado por meio de um formulário e depois desaparece).

Eu tentei tkMessageBox:

import tkMessageBox
tkMessageBox.showinfo(title="Greetings", message="Hello World!")

mas isso abre outra janela em segundo plano com um ícone tk. Eu não quero isso. Eu estava procurando algum código wxPython simples, mas sempre exigia configurar uma classe e inserir um loop de aplicativo, etc. Não existe uma maneira simples e fácil de criar uma caixa de mensagem em Python?

Carson Myers
fonte

Respostas:

257

Você pode usar uma importação e um código de linha única como este:

import ctypes  # An included library with Python install.   
ctypes.windll.user32.MessageBoxW(0, "Your text", "Your title", 1)

Ou defina uma função (Mbox) assim:

import ctypes  # An included library with Python install.
def Mbox(title, text, style):
    return ctypes.windll.user32.MessageBoxW(0, text, title, style)
Mbox('Your title', 'Your text', 1)

Observe que os estilos são os seguintes:

##  Styles:
##  0 : OK
##  1 : OK | Cancel
##  2 : Abort | Retry | Ignore
##  3 : Yes | No | Cancel
##  4 : Yes | No
##  5 : Retry | No 
##  6 : Cancel | Try Again | Continue

Diverta-se!

Nota: editado para usar em MessageBoxWvez deMessageBoxA

user2140260
fonte
2
Exatamente o que eu estava procurando. O OP também pelo que parece. Deve ser marcada como a resposta!
CodeMonkey
3
Meh. Talvez eu tenha falado muito cedo. Estou recebendo apenas um único caractere para título e mensagem. Estranho ...
CodeMonkey
18
Tive que usar MessageBoxW em vez de MessageBoxA.
CodeMonkey de
9
@CodeMonkey em python 3, use MessageBoxW em vez de MessageBoxA
Oliver Ni
2
Observação: meu pop-up não estava em inglês e pode ser corrigido lendo a resposta do
Ari
50

Você já olhou para easygui ?

import easygui

easygui.msgbox("This is a message!", title="simple gui")
Ryan Ginstrom
fonte
7
isso não é tkinter, não é fornecido por padrão, estranho, quem está interessado em introduzir uma funcionalidade tão simples para trazer dependências desnecessárias?
Tebe
7
Na verdade gekannt, easygui é um invólucro em torno do tkinter. Sim, é uma dependência extra, mas é um único arquivo python. Alguns desenvolvedores podem pensar que a dependência vale a pena para implementar uma GUI extremamente simples.
Ryan Ginstrom
22

Além disso, você pode posicionar a outra janela antes de retirá-la para que posicione sua mensagem

#!/usr/bin/env python

from Tkinter import *
import tkMessageBox

window = Tk()
window.wm_withdraw()

#message at x:200,y:200
window.geometry("1x1+200+200")#remember its .geometry("WidthxHeight(+or-)X(+or-)Y")
tkMessageBox.showerror(title="error",message="Error Message",parent=window)

#centre screen message
window.geometry("1x1+"+str(window.winfo_screenwidth()/2)+"+"+str(window.winfo_screenheight()/2))
tkMessageBox.showinfo(title="Greetings", message="Hello World!")
Lewis Cowles
fonte
3
Existe algum método, para que não seja necessário pressionar o botão ok no tkMessageBox e processar automaticamente?
varsha_holla
@varsha_holla Não é assim que a caixa de mensagens funciona. Você pode querer criar uma janela padrão com um cronômetro.
Kelly Elton
19

O código que você apresentou está bom! Você só precisa criar explicitamente a "outra janela em segundo plano" e ocultá-la, com este código:

import Tkinter
window = Tkinter.Tk()
window.wm_withdraw()

Bem antes de sua caixa de mensagens.

Jotaf
fonte
4
Tive que adicionar "window.destroy ()" ao final para fazer com que ele fechasse corretamente.
kuzzooroo
11

O módulo PyMsgBox faz exatamente isso. Possui funções de caixa de mensagem que seguem as convenções de nomenclatura do JavaScript: alert (), confirm (), prompt () e senha () (que é prompt (), mas usa * quando você digita). Essas chamadas de função são bloqueadas até que o usuário clique no botão OK / Cancelar. É um módulo Python puro de plataforma cruzada sem dependências.

Instale com: pip install PyMsgBox

Uso de amostra:

import pymsgbox
pymsgbox.alert('This is an alert!', 'Title')
response = pymsgbox.prompt('What is your name?')

Documentação completa em http://pymsgbox.readthedocs.org/en/latest/

Al Sweigart
fonte
estranho. você escreve que ele não tem dependências, mas quando tento usá-lo, ele imprimeAssertionError: Tkinter is required for pymsgbox
merda
Devo mudar isso: pymsgbox não tem dependências fora da biblioteca padrão, da qual tkinter faz parte. Qual versão do Python e qual sistema operacional você está usando?
Al Sweigart
Desculpe, sou novato em Python, pensei que todas as libs Python são instaladas por meio pip, mas na verdade parte das libs são instaladas de outra maneira - usando o gerenciador de pacotes do sistema. Então instalei python-tkusando meu gerenciador de pacotes. Estou usando Python 2.7 no Debian.
shitpoet de
offtopic: mas a caixa de mensagem criada por PyMsgBox / Tk parece muito feia no meu Debian
shitpoet
10

No Windows, você pode usar ctypes com a biblioteca user32 :

from ctypes import c_int, WINFUNCTYPE, windll
from ctypes.wintypes import HWND, LPCSTR, UINT
prototype = WINFUNCTYPE(c_int, HWND, LPCSTR, LPCSTR, UINT)
paramflags = (1, "hwnd", 0), (1, "text", "Hi"), (1, "caption", None), (1, "flags", 0)
MessageBox = prototype(("MessageBoxA", windll.user32), paramflags)

MessageBox()
MessageBox(text="Spam, spam, spam")
MessageBox(flags=2, text="foo bar")
VOCÊS
fonte
9

No Mac, a biblioteca padrão do python tem um módulo chamado EasyDialogs. Também existe uma versão do Windows (baseada em ctypes) em http://www.averdevelopment.com/python/EasyDialogs.html

Se é importante para você: ele usa diálogos nativos e não depende do Tkinter como o já mencionado easygui, mas pode não ter tantos recursos.

Steven
fonte
7
import ctypes
ctypes.windll.user32.MessageBoxW(0, "Your text", "Your title", 1)

O último número (aqui 1) pode ser alterado para alterar o estilo da janela (não apenas botões!):

## Button styles:
# 0 : OK
# 1 : OK | Cancel
# 2 : Abort | Retry | Ignore
# 3 : Yes | No | Cancel
# 4 : Yes | No
# 5 : Retry | No 
# 6 : Cancel | Try Again | Continue

## To also change icon, add these values to previous number
# 16 Stop-sign icon
# 32 Question-mark icon
# 48 Exclamation-point icon
# 64 Information-sign icon consisting of an 'i' in a circle

Por exemplo,

ctypes.windll.user32.MessageBoxW(0, "That's an error", "Warning!", 16)

vai dar isso :

insira a descrição da imagem aqui

Arkelis
fonte
1

Usar

from tkinter.messagebox import *
Message([master], title="[title]", message="[message]")

A janela mestre deve ser criada antes. Isso é para Python 3. Isso não é para wxPython, mas para tkinter.

HD1920
fonte
Veja meu comentário sobre "import *" na resposta de Robert.
Jürgen A. Erhard,
1
import sys
from tkinter import *
def mhello():
    pass
    return

mGui = Tk()
ment = StringVar()

mGui.geometry('450x450+500+300')
mGui.title('My youtube Tkinter')

mlabel = Label(mGui,text ='my label').pack()

mbutton = Button(mGui,text ='ok',command = mhello,fg = 'red',bg='blue').pack()

mEntry = entry().pack 
Robert
fonte
Além disso, por favor, pelo amor de todos os que são PEP8 e pítônicos, desistam de "importar *". Está ruim, ok?
Jürgen A. Erhard,
1

Além disso, você pode posicionar a outra janela antes de retirá-la para que posicione sua mensagem

from tkinter import *
import tkinter.messagebox

window = Tk()
window.wm_withdraw()

# message at x:200,y:200
window.geometry("1x1+200+200")  # remember its.geometry("WidthxHeight(+or-)X(+or-)Y")
tkinter.messagebox.showerror(title="error", message="Error Message", parent=window)

# center screen message
window.geometry(f"1x1+{round(window.winfo_screenwidth() / 2)}+{round(window.winfo_screenheight() / 2)}")
tkinter.messagebox.showinfo(title="Greetings", message="Hello World!")

Observação: esta é a resposta de Lewis Cowles apenas para Python 3ified, uma vez que tkinter mudou desde python 2. Se você deseja que seu código seja compatível com backwords, faça algo assim:

try:
    import tkinter
    import tkinter.messagebox
except ModuleNotFoundError:
    import Tkinter as tkinter
    import tkMessageBox as tkinter.messagebox
Hexiro
fonte
0

Não é o melhor, aqui está minha caixa de mensagem básica usando apenas tkinter.

#Python 3.4
from    tkinter import  messagebox  as  msg;
import  tkinter as      tk;

def MsgBox(title, text, style):
    box = [
        msg.showinfo,       msg.showwarning,    msg.showerror,
        msg.askquestion,    msg.askyesno,       msg.askokcancel,        msg.askretrycancel,
];

tk.Tk().withdraw(); #Hide Main Window.

if style in range(7):
    return box[style](title, text);

if __name__ == '__main__':

Return = MsgBox(#Use Like This.
    'Basic Error Exemple',

    ''.join( [
        'The Basic Error Exemple a problem with test',                      '\n',
        'and is unable to continue. The application must close.',           '\n\n',
        'Error code Test',                                                  '\n',
        'Would you like visit http://wwww.basic-error-exemple.com/ for',    '\n',
        'help?',
    ] ),

    2,
);

print( Return );

"""
Style   |   Type        |   Button      |   Return
------------------------------------------------------
0           Info            Ok              'ok'
1           Warning         Ok              'ok'
2           Error           Ok              'ok'
3           Question        Yes/No          'yes'/'no'
4           YesNo           Yes/No          True/False
5           OkCancel        Ok/Cancel       True/False
6           RetryCancal     Retry/Cancel    True/False
"""
Creuil
fonte
A formatação de importação é completamente maluca. Você é um antigo programador COBOL ou FORTRAN, por acaso? ;-)
Jürgen A. Erhard
0

confira meu módulo python: pip install quickgui (requer wxPython, mas não requer conhecimento de wxPython) https://pypi.python.org/pypi/quickgui

Pode criar qualquer número de entradas, (proporção, caixa de seleção, caixa de entrada), organizá-los automaticamente em um único gui.

Jerry T
fonte
0

Uma versão recente da caixa de mensagem é o módulo prompt_box. Possui dois pacotes: alerta e mensagem. A mensagem oferece maior controle sobre a caixa, mas leva mais tempo para digitar.

Exemplo de código de alerta:

import prompt_box

prompt_box.alert('Hello') #This will output a dialog box with title Neutrino and the 
#text you inputted. The buttons will be Yes, No and Cancel

Exemplo de código de mensagem:

import prompt_box

prompt_box.message('Hello', 'Neutrino', 'You pressed yes', 'You pressed no', 'You 
pressed cancel') #The first two are text and title, and the other three are what is 
#printed when you press a certain button
Samuel Crawford
fonte
0

Módulo ctype com threading

Eu estava usando a caixa de mensagens tkinter, mas meu código travaria. Eu não queria descobrir por que, então, usei o módulo ctypes .

por exemplo:

import ctypes
ctypes.windll.user32.MessageBoxW(0, "Your text", "Your title", 1)

eu peguei aquele código de Arkelis


Eu gostei de não travar o código, então trabalhei nisso e adicionei um threading para que o código depois fosse executado.

exemplo para o meu código

import ctypes
import threading


def MessageboxThread(buttonstyle, title, text, icon):
    threading.Thread(
        target=lambda: ctypes.windll.user32.MessageBoxW(buttonstyle, text, title, icon)
    ).start()

messagebox(0, "Your title", "Your text", 1)

para estilos de botão e números de ícone:

## Button styles:
# 0 : OK
# 1 : OK | Cancel
# 2 : Abort | Retry | Ignore
# 3 : Yes | No | Cancel
# 4 : Yes | No
# 5 : Retry | No
# 6 : Cancel | Try Again | Continue

## To also change icon, add these values to previous number
# 16 Stop-sign icon
# 32 Question-mark icon
# 48 Exclamation-point icon
# 64 Information-sign icon consisting of an 'i' in a circle
Trabalhadores Esmeralda
fonte
0

Você pode usar pyautoguiou pymsgbox:

import pyautogui
pyautogui.alert("This is a message box",title="Hello World")

Usar pymsgboxé o mesmo que usar pyautogui:

import pymsgbox
pymsgbox.alert("This is a message box",title="Hello World")
Algum cara
fonte