What's the simplest cross-platform way to pop up graphical dialogs in Python?
Asked Answered
S

11

41

I want the simplest possible way to pop up simple dialogs in Python scripts. Ideally, the solution would:

  • Work on Windows, OS X, Gnome, KDE
  • Look like a native dialog on any OS
  • Require minimal code

To pop up a simple standard dialog should require only minimal code. Essentially you're just saying "Pop up a standard dialog with this text", or "Pop up a dialog with question x and feed response into variable y".

This is for simple scripts that would otherwise run on the command line. I don't want to know about GUI frameworks or have to set up code that says "start a GUI thread, register an event handler, configure some window properties, run a loop", etc. I don't want to have to set up a window or close the window afterward. I give it the text to put in the window and/or buttons and/or checkboxes, it returns what the user clicked on. Everything else should be taken care of automatically. For example:

message_box('File conversion complete')

for a standard dialog box with an "Ok" button, or

balloon_tip('File conversion complete')

for a system tray popup balloon, or

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

and they press one of the two buttons, and then format equals 'JPG', or

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

and after they type in the box and press Ok, response now equals 'bananas.txt'. No other code required. No ugly command line prompts for the poor user.

I've listed Zenity and EasyGUI as example answers, since they're similar to what I want, but not perfect.

[Previously asked on Python Forum]

Shoal answered 28/10, 2009 at 3:20 Comment(11)
Further duplicates (actually more precisely duplicates than Greg Hewgill's): https://mcmap.net/q/358029/-message-box-in-python https://mcmap.net/q/358030/-how-to-create-a-message-box-with-tkinterBanlieue
Hmm... following the link to the python-forum.org question, the point of the question changes drastically to what is shown here on SO. On SO, the title and the text strongly suggest that the top priority is simple dialogs. But on python-forum.org, it becomes clear that the priority is native look-and-feel, and that Tkinter is NOT an option. That really changes everything, because Tk-based solutions are the most obvious simple ones.Banlieue
They're both first priority. :)Shoal
Two of those duplicates don't mention cross-platform, and the other is for an entire GUI toolkit, which I'm trying to avoid.Shoal
To most people, "cross-platform" will be taken care of by the fact that Tkinter is included in standard Python. (Tk and Python are both already cross-platform.) Therefore, if you need native look-and-feel, that is the thing you need to stress. As you have expressed it now, it looks like a nice-to-have unless people take the time to read your python-forum version.Banlieue
If your programs works from the command line, why can't you just let the user type there?Crematorium
"Works from the command line"?Shoal
I want to know how minimal your packaging requirements are. Do you expect to be able to mail your .py file to someone and their install of Python will somehow pop up a dialog?Messapian
I don't personally have any packaging requirements. I wish something like this were built into the standard library, though.Shoal
To see the url pythonprogramming.net/tkinter-popup-message-windowChemoprophylaxis
Similar #520515Chrystel
S
23

EasyGUI is a single file, and provides a simple way to work with Tkinter dialogs, but they're still ugly non-native Tkinter dialogs.

from easygui import msgbox
msgbox('Stuff')

Tkinter is ugly on Ubuntu TKinter is ugly on Windows 7

It can easily be installed using:

$ sudo pip3 install --upgrade easygui

There is a GitHub repository and documentation is very neat.

Previously, there was also a fork called EasyGuiTtk, which unfortunately is no longer available.

enter image description here

Shoal answered 28/10, 2009 at 3:25 Comment(9)
Tk need not be ugly, not since Python 2.7 anyway ... which includes ttk: code.google.com/p/python-ttk/wiki/ScreenshotsFeld
But how difficult is it to make it non-ugly in a cross-platform way?Shoal
@SridharRatnakumar: Can the non-ugliness be built into things like PyZenity or EasyGUI?Shoal
@SridharRatnakumar: Oh look, it may already exist: github.com/Who8MyLunch/EasyGuiTtkShoal
Note that github.com/Who8MyLunch/EasyGuiTtk is gone.Stine
@Stine Yeah I just noticed that. The author still exists, though, and has an email address, and I might have a copy on my other computer anyway.Shoal
@Stine Actually I guess I wrote him in March and no response. o_OShoal
@Nayan EasyGuiTtk seems to be gone, though.Shoal
@Shoal True.Culver
S
17

Zenity works under Linux and Windows, and can be called from Python directly:

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

Using --warning instead of --info gives a warning dialog box instead of an info box. Other options can be found here: https://help.gnome.org/users/zenity/stable/

The return values from question boxes need to be captured for acting on, though, which is more complex, and you have to learn about communicating with subprocesses, etc.

It can also be used with the PyZenity front-end, which makes capturing return values simple:

from PyZenity import InfoMessage
InfoMessage('Stuff')

I have tested PyZenity in both Ubuntu and Windows XP, and it works in both.

Zenity looks pretty good in Gnome Zenity looks good in KDE, too, suprisingly Zenity in Windows has the wrong GTK theme

I read that Zenity is GTK+ only, but I tried it in Gnome and KDE and it looks native in both. The port to Windows does not look native, though, because it uses the wrong GTK theme?

There are also other programs like KDialog and Xdialog that might be interfaced to a similar Python frontend that could check and see what executables are available so that it automatically takes care of everything? (There's a Ruby frontend for KDialog, too.)

I don't know if PyZenity works under OS X, either.

Shoal answered 28/10, 2009 at 3:26 Comment(3)
Maintenance of PyZenity unfortunately seems to have stopped around 2011 and its homepage is no longer up - see web.archive.org/web/20110814174311/http://www.brianramos.com/… to view the original content.Weintraub
PyZenity is still on Pypi (pypi.org/project/PyZenity), but as noted above, seems unmaintained. Possibly replacements seem to be pypi.org/project/Zenity and pypi.org/project/python-zenity.Weintraub
ans=os.popen(<zenity stuff>).read() to read an answer from Zenity.Anderson
T
13

TkInter is usually supplied with Python

# File: hello1.py

from Tkinter import *

root = Tk()

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

root.mainloop()

If you want something more native looking, you'll have to install something like wxpython

Tuberculate answered 28/10, 2009 at 3:24 Comment(0)
H
11

The PyMsgBox module does almost exactly this. It uses the built-in tkinter module for its message box functions that follow the naming conventions of JavaScript: alert(), confirm(), prompt() and password() (which is prompt() but uses * when you type). These function calls block until the user clicks an OK/Cancel button. It's a cross-platform, pure Python module with no dependencies.

Native look-and-feel message boxes will be available in a future version.

Install with: pip install PyMsgBox

Sample usage:

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

Full documentation at http://pymsgbox.readthedocs.org/en/latest/

Hipparchus answered 4/9, 2014 at 0:24 Comment(0)
S
10

To extend on endolith's tkMessageBox answer with the ugly empty window in the background...

The code below pops up the box without the background window.

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

This is lifted directly from a useful comment I found at the bottom of this article. Thanks to Jason (the commenter) and effbot.org.

Spain answered 20/2, 2011 at 21:3 Comment(0)
T
6

@ endolith, re: zenity for Windows.

Hi,

I repackaged "Zenity for Windows" and included the correct GTK-theme file. It looks much better now. :) It is now available for download: http://www.placella.com/software/zenity/

Screenshot:

alt text
(source: placella.com)

Peace, Rouslan

Transude answered 2/11, 2009 at 21:49 Comment(2)
If it's not difficult, then it should be that way by default! :) Does that theme work on any version of Windows or just XP?Shoal
Hi, I corrected this issue and edited the above post to reflect such changes. Oh, and I'm not sure about Vista or W7, maybe someone else will post feedback... Enjoy, everyone! Peace, RouslanTransude
C
6

wxPython is the best Python GUI library (IMO) and uses native widgets.

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()
Center answered 5/11, 2009 at 14:36 Comment(3)
That's not too terrible. I don't understand why it's not just a one-liner, though. import wx wx.OpenADialogBox('Some text')Shoal
Because most people using a GUI want more than just a single popup. You are an edge case.Messapian
I think there are a lot of people who would use dialogs like this in their scripts if they were available.Shoal
S
5

Another possibility is the tkMessageBox module, which is apparently built into the standard library and is cross-platform, though this is even more ugly than the rest:

import tkMessageBox
tkMessageBox.showinfo('Title','Stuff') 

Tkinter is super ugly

Shoal answered 31/10, 2009 at 0:38 Comment(0)
P
2

pyglet is another alternative, though it may not be the simplest. that being said, it's cross-platform and only depends on python, so there's no external dependencies. that fact alone can be reason enough to use it over others.

and all it can handle multimedia pretty easily as well, pretty handy if you want to display an image or video or something.

the example below is from the documentation...

#!/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()
Prom answered 28/10, 2009 at 16:48 Comment(1)
is there a way to create messageboxes with pyglet (or dialog windows of any kind)?Galloot
S
0

Since nothing here worked for me I figured something out myself. Easy function to solve the problem:

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()

You still start a temporary loop but instead of having some button or something like that to trigger your dialog you just pass a function to be executed after a small delay. That makes sure that the loop starts. That way your box actually closes when you click on it and it also gets rid of the root. It effectively pauses your script until the box is closed. Has the nice positive of looking native (at least on my mac).

Edit: This seems to have problems if you need to also select files. Something blows up internally if alternate between them so I ended up using Tkinter to bring up file selectors and a platform specific approach for messages such as this:

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}')" """
        )
Slider answered 19/5, 2023 at 20:33 Comment(0)
C
-3

This is not possible. If you want simple then you have to use Tkinter because that is what is included. If Tkinter is not good enough then you will have to choose and package a GUI for each platform separately.

I suggest that you do use Tkinter and wrap the parts that you need in a class that will be even simpler to use.

Chalky answered 5/11, 2009 at 14:47 Comment(1)
This isn't quite true. Python can, for example, use the built-in ctypes module to call ctypes.windll.user32.MessageBoxW() and make the Windows native message box appear. However, you are right in that this would also require adding different code for every operating system.Hipparchus

© 2022 - 2024 — McMap. All rights reserved.