Python中最简单的跨平台弹出图形对话框的方法是什么?

41
我希望以最简单的方式在Python脚本中弹出简单对话框。理想情况下,解决方案应该:
  • 适用于Windows、OS X、Gnome和KDE
  • 在任何操作系统上看起来像本地对话框
  • 需要最少的代码
弹出一个简单的标准对话框只需要很少的代码。基本上你只需要说"弹出一个带有这个文本的标准对话框"或者"弹出一个带有问题x的对话框,并将响应反馈到变量y中"。
这是为了简单的脚本,否则它们将在命令行上运行。我不想知道GUI框架或者设置代码,比如“启动一个GUI线程,注册一个事件处理程序,配置一些窗口属性,运行一个循环”等等。我不想设置一个窗口或者关闭窗口之后。我给它要放在窗口、按钮和/或复选框中的文本,它返回用户点击的内容。其他所有事情都应该自动处理。例如:
message_box('File conversion complete')

对于带有“确定”按钮的标准对话框,或者

balloon_tip('File conversion complete')

用于系统托盘弹出气泡,或者

format = button_box('Which file format do you want?', 'JPG', 'PNG')

当他们按下两个按钮中的一个时,format 就等于 'JPG',或者

response = text_query('What would you like to name the file?')

当用户在框中输入并按下“确定”后,response现在等于'bananas.txt'。不需要其他代码,也不需要丑陋的命令行提示。我列出了Zenity和EasyGUI作为示例回答,因为它们与我想要的类似,但并不完美。[此前在Python论坛上提问]

更多的重复问题(实际上比Greg Hewgill的还要准确): https://dev59.com/wEXRa4cB1Zd3GeqPtqt0 https://dev59.com/zHNA5IYBdhLWcg3wNa6T - John Y
对于大多数人而言,“跨平台”这个问题已被包含在标准 Python 中的 Tkinter 解决掉了。 (Tk 和 Python 都是跨平台的)。因此,如果你需要原生的外观和感受,这就是你需要强调的重点。从你现在的表达来看,它似乎只是一个很好的东西,除非人们花时间阅读你在 Python 论坛的版本。 - John Y
1
我想了解您的软件打包要求有多少。您是否希望能够将.py文件发送给他人,而他们的Python安装将自动弹出对话框? - jmucchiello
查看网址 https://pythonprogramming.net/tkinter-popup-message-window/ - Seeni Vasan
类似于https://dev59.com/-XRB5IYBdhLWcg3wxZ1K的跨平台GUI工具包,用于部署Python应用程序。 - Rajnish
显示剩余6条评论
11个回答

23

EasyGUI是一个单文件,提供了一种简单的方式来处理Tkinter对话框,但它们仍然是难看的非本地Tkinter对话框。

from easygui import msgbox
msgbox('Stuff')

Ubuntu下的Tkinter很丑 Windows 7下的Tkinter很丑

可以使用以下命令轻松安装:

$ sudo pip3 install --upgrade easygui

有一个GitHub存储库文档非常整洁。

以前还有一个叫做EasyGuiTtk的分支,但不幸的是它已经不可用了。

输入图像描述


2
Tk不需要丑陋,至少从Python 2.7开始就不需要了...这包括ttk:http://code.google.com/p/python-ttk/wiki/Screenshots - Sridhar Ratnakumar
1
请注意,github.com/Who8MyLunch/EasyGuiTtk已经不存在。 - Sam
@Sam 是的,我刚刚注意到了。作者仍然存在,并且有一个电子邮件地址,而且我可能在我的另一台计算机上有一份副本。 - endolith
1
@Sam 实际上我猜我在三月份写了他,但没有回应。o_O - endolith
1
@Nayan,EasyGuiTtk似乎已经消失了。 - endolith
显示剩余5条评论

17

Zenity可在Linux和Windows下运行,并可以直接从Python调用:

import os
os.system('zenity --info --text="Stuff"')

使用--warning而不是--info会弹出警告对话框而不是信息框。其他选项可以在此找到:https://help.gnome.org/users/zenity/stable/

需要捕获问题框的返回值以进行操作,这更复杂,您必须了解与子进程通信等内容。

它还可以与PyZenity前端一起使用,这使得捕获返回值变得简单:

from PyZenity import InfoMessage
InfoMessage('Stuff')

我已经在Ubuntu和Windows XP中测试了PyZenity,并且在两个系统中都能正常工作。

Zenity在Gnome中看起来很好 出人意料的是,Zenity在KDE中也很好看 在Windows中,Zenity有错误的GTK主题

我读到Zenity只支持GTK+,但我在Gnome和KDE中尝试过,看起来在两者上都很本地化。尽管如此,移植到Windows中看起来并不本地化,因为它使用了错误的GTK主题?

还有其他类似KDialogXdialog的程序,可以与类似的Python前端进行接口,以检查并查看可用的可执行文件,以便自动处理一切?(也有一个用于KDialog的Ruby前端。)

我不知道PyZenity在OS X下是否可用。


1
很遗憾,PyZenity的维护工作在2011年左右停止了,并且它的主页也已经无法访问了-请点击http://web.archive.org/web/20110814174311/http://www.brianramos.com/?page_id=110 查看原始内容。 - phlummox
1
PyZenity 仍然在Pypi上(https://pypi.org/project/PyZenity/),但正如上面所提到的,似乎没有维护。可能的替代品似乎是https://pypi.org/project/Zenity/和https://pypi.org/project/python-zenity/。 - phlummox

13

TkInter通常随Python一起提供。

# File: hello1.py

from Tkinter import *

root = Tk()

w = Label(root, text="Hello, world!")
w.pack()

root.mainloop()
如果您想要更本地化的外观,您需要安装类似wxPython的东西。

11

PyMsgBox模块几乎完全实现了这一功能。它使用内置的tkinter模块来提供消息框函数,这些函数遵循JavaScript的命名约定:alert()、confirm()、prompt()和password()(它是prompt(),但在你输入时使用*)。这些函数调用会阻塞,直到用户点击OK/Cancel按钮。这是一个跨平台的、纯Python的模块,没有依赖。

原生外观的消息框将在未来版本中提供。

安装方法:pip install PyMsgBox

示例用法:

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

完整文档请参阅http://pymsgbox.readthedocs.org/en/latest/


10

在endolith的tkMessageBox答案基础上进行扩展,解决了背景窗口为空的问题...

下面的代码弹出窗口时不会显示背景窗口。

import Tkinter, tkMessageBox
root = Tkinter.Tk()
root.withdraw()
tkMessageBox.showinfo("my dialog title", "my dialog message")

这是我从这篇文章最底下找到的一条有用的评论,感谢Jason(评论者)和effbot.org。


6

wxPython是最好的Python GUI库(在我看来),并且使用本地小部件。

import wx
app = wx.PySimpleApp()
dialog = wx.MessageDialog(None, 'wxPython is awesome!', 'Dialog Box', wx.OK|wx.ICON_INFORMATION)
dialog.ShowModal()
dialog.Destroy()
app.MainLoop()

1
这并不太糟糕。但我不明白为什么它不只是一个一行代码的事情。导入wx wx.OpenADialogBox('一些文本') - endolith
1
因为大多数使用GUI的人希望不只是一个弹出窗口,你算是个特例。 - jmucchiello
6
如果有这样的对话框可用,我认为会有很多人在他们的剧本中使用它们。 - endolith

6

@ endolith, 关于Windows下的Zenity。

你好,

我重新打包了“Windows下的Zenity”,并包含了正确的GTK主题文件。现在它看起来更好了。 :) 现在可以下载了: http://www.placella.com/software/zenity/

截图:

alt text
(来源: placella.com)

祝好,Rouslan


如果不难的话,那应该默认就是那样的! :) 这个主题适用于任何版本的Windows还是只有XP? - endolith
嗨,我已经纠正了这个问题,并编辑了上面的帖子以反映这些更改。 哦,我不确定Vista或W7,也许其他人会发表反馈... 大家都享受吧!祝平安,Rouslan - Roccivic

5
另一种可能性是tkMessageBox模块,它显然内置于标准库中,并且跨平台,尽管这比其他方法更丑陋:
import tkMessageBox
tkMessageBox.showinfo('Title','Stuff') 

Tkinter is super ugly


2

pyglet是另一种选择,尽管它可能不是最简单的。话虽如此,它是跨平台的,并且只依赖于Python,因此没有外部依赖。仅凭这个事实就足以理由使用它而不是其他工具。

此外,它可以很容易地处理多媒体,非常方便,如果您想显示图像或视频等内容。

下面的示例来自文档...

#!/usr/bin/python
import pyglet
window = pyglet.window.Window()
label = pyglet.text.Label('Hello, world',
                      font_name='Times New Roman',
                      font_size=36,
                      x=window.width/2, y=window.height/2,
                      anchor_x='center', anchor_y='center')

@window.event
def on_draw():
    window.clear()
    label.draw()

pyglet.app.run()

有没有办法使用Pyglet创建消息框(或任何类型的对话框窗口)? - memyself

0

由于这里的任何方法都对我无效,我自己想出了一个解决方案。一个简单的函数可以解决这个问题:

import tkinter as tk
from tkinter import messagebox

def message(message: str):
    root = tk.Tk()
    root.withdraw()
    root.after(1000, root.destroy)
    messagebox.showinfo("", message)
    root.mainloop()

你仍然启动一个临时循环,但是不需要像按钮之类的东西来触发对话框,而是只需传递一个函数以在短暂延迟后执行。这确保了循环开始。这样,当你单击它时,你的框实际上会关闭,并且也会摆脱根。它有效地暂停了你的脚本,直到框被关闭。这种方法看起来很原生(至少在我的 Mac 上)。

编辑: 如果你还需要选择文件,则此方法似乎存在问题。如果在它们之间切换,则会在内部出现问题,因此我最终使用了 Tkinter 来弹出文件选择器,并使用特定于平台的方法来处理此类消息:

def message(message: str):
    if is_macOS():
        os.system(
            f"""osascript -e 'Tell application "System Events" to display dialog "{message}" buttons {{"Continue"}}'""")
    if is_windows():
        os.system(
            f"""PowerShell -Command "Add-Type -AssemblyName PresentationFramework;[System.Windows.MessageBox]::Show('{message}')" """
        )

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接