Message Dialog from outside the main gui thread

python blue and yellow logoIf you’ve ever wanted to show a dialog from a gtk app, but needed wanted to do it from outside the main thread, you quickly run into problems. Spawning things in gobject idle loops is usually fine for getting gui updates to happen in the main thread, but running a full blown dialog is not one of these easy feats.

So here’s a simple standalone program that fetches the dialog’s title and message before displaying it. You can also specify an image file path and icon size to override the default message info dialog icon.

From your worker thread, launch it using subprocess, system, or whatever you want, and immediately write the fields to it’s standard input. To simulate the usual dialog.run followed by dialog.destroy blocking behavior where you’re waiting for the user to close the dialog, just wait for the process to complete, die, or check its pid if you really don’t trust your io pipes. The side bonus is it’s not blocking if you just spawn it asynchronously and you will know the cleanup is handled since the dialog is not a part of your calling process other than the handle you create for spawning it.

import gtk
import sys

# read stdin lines for data
title = sys.stdin.readline().strip() # Dialog Title
msg = sys.stdin.readline().strip()  # Dialog Label
img = sys.stdin.readline().strip() # Dialog Image Filename
size = int(sys.stdin.readline().strip()) # Desired image pixel size

# create dialog
dialog = gtk.MessageDialog(None, gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_INFO, gtk.BUTTONS_OK, msg)
dialog.set_title(title)
dialog.set_keep_above(True)

# override default dialog icon
try:
    pixbuf = gtk.gdk.pixbuf_new_from_file_at_size(img, size, size)
    image = gtk.Image()
    image.set_from_pixbuf(pixbuf)
    image.show()
    dialog.set_image(image)
except:
    pass

# run
response = dialog.run()
sys.exit(0)

Dirty hack or part of the ingenious gtk masterplan?

Leave a Reply

Your email address will not be published. Required fields are marked *