pyGTK -- how to wait for modal dialog?
Mitch Chapman
chapman at bioreason.com
Thu Oct 12 12:31:56 EDT 2000
Steffen Ries wrote:
> ...
> I came up with a similar solution, but I can't say whether *that* one
> is recommended:
> [...sample code omitted...]
Your solution is similar to the one recommended in Havoc
Pennington's "Gtk+/GNOME Application Development", so it must
be good :)
See section 7.2, pp. 129-131, for the related discussion.
Havoc notes that there's a potential for race conditions.
I assume most of these arise from the fact that you can close
a dialog by clicking on one of the dialog buttons, and also by
using the window manager to close the window.
Havoc's book is available online. Here's the relevant URL:
http://developer.gnome.org/doc/GGAD/sec-modaldialogs.html
Your solution is also similar to the one in use at Bioreason,
as discussed in (self-serving plug) the April, 2000, issue of
Dr. Dobb's. Sample code is available here:
http://www.ddj.com/ftp/2000/2000_04/pygtk.zip/
(Sample code is also attached, so why am I telling you this? =8)
--
Mitch Chapman
chapman at bioreason.com
-------------- next part --------------
#!/usr/bin/env python
"""ModalDialog.py:
This module provides pygtk ModalDialogs."""
import gtk
class ModalDialog(gtk.GtkDialog):
"""This class extends GtkDialog to give it modal behavior."""
def __init__(self, master=None):
"""Initialize a new instance."""
gtk.GtkDialog.__init__(self)
self.master = master
self.set_modal(gtk.TRUE)
if self.master:
self.set_transient_for(self.master)
# Capture attempts to delete/destroy self. It's hard to reuse
# a dialog when Gtk+ has destroyed its components.
self.connect("delete_event", self.deleteEH)
def runModal(self):
"""Display the dialog and start a modal event loop."""
self.show()
# Invoke a nested Gtk+ event loop.
gtk.mainloop()
def endModal(self, *args):
"""Terminate the modal event loop and dismiss the dialog."""
self.hide()
gtk.mainquit()
def deleteEH(self, *args):
"""Event handler invoked when the dialog is deleted."""
self.endModal()
# The return value tells Gtk+ that the delete event has
# been processed. Without a return value of true, Gtk+
# will provide the default deletion behavior: it will destroy
# self's visuals.
return gtk.TRUE
def main():
"""Module mainline (for standalone execution)"""
class Test:
"""Tests the behavior of class ModalDialog."""
def __init__(self):
import AppWindow
win = self.window = AppWindow.AppWindow(title="ModalDialog Demo")
win.show()
box = gtk.GtkVBox()
win.add(box)
box.show()
btn = gtk.GtkButton("Go Modal...")
btn.connect("clicked", self.goModalCB)
box.pack_start(btn, expand=gtk.FALSE, fill=gtk.FALSE)
btn.show()
btn = gtk.GtkButton("Quit")
btn.connect("clicked", gtk.mainquit)
box.pack_start(btn, expand=gtk.FALSE, fill=gtk.FALSE)
btn.show()
self.dlg = self.buildDialog()
def buildDialog(self):
"""Build a sample modal dialog."""
result = ModalDialog(master=self.window)
result.set_position(gtk.WIN_POS_MOUSE)
result.set_title("The Spanish Inquisition")
# Add some content.
# A GtkDialog provides two pre-built containers:
# vbox is where all of the "custom" controls, e.g.
# entry fields and comboboxes, belong.
# action_area appears at the bottom of the dialog, and
# is a good place for the dialog buttons.
label = gtk.GtkLabel("NOOoobody expects\n\n"
"the Spanish Inquisition!")
result.vbox.pack_start(label, padding=5)
label.show()
closeBtn = gtk.GtkButton("Close")
closeBtn.connect("clicked", result.endModal)
result.action_area.pack_start(closeBtn)
closeBtn.show()
return result
def goModalCB(self, *args):
"""Callback invoked when the 'Go Modal...' button is clicked."""
self.dlg.runModal()
test = Test()
gtk.mainloop()
if __name__ == "__main__":
main()
More information about the Python-list
mailing list