我正在尝试编写一个由各种窗口组成的应用程序(例如,通用消息对话框,登录对话框,主界面等),并且无法调用gtk.main_quit
函数:要么我得到关于呼叫在主循环之外的抱怨,或者根本没有调用该函数。
我是Python和GTK +的新手,但我最好的猜测是如何让它工作的是一个“根”窗口,它只是一个从未见过的占位符,但控制应用程序的GTK +循环。到目前为止,我的代码如下:
import pygtk
pygtk.require("2.0")
import gtk
class App(gtk.Window):
_exitStatus = 0
# Generic message box
def msg(self, title, text, type = gtk.MESSAGE_INFO, buttons = gtk.BUTTONS_OK):
# Must always have a button
if buttons == gtk.BUTTONS_NONE:
buttons = gtk.BUTTONS_OK
dialog = gtk.MessageDialog(None, 0, type, buttons, title)
dialog.set_title(title)
dialog.set_geometry_hints(min_width = 300)
dialog.set_resizable(False)
dialog.set_deletable(False)
dialog.set_position(gtk.WIN_POS_CENTER)
dialog.set_modal(True)
dialog.format_secondary_text(text)
response = dialog.run()
dialog.destroy()
return response
def nuke(self, widget, data):
gtk.main_quit()
exit(self._exitStatus)
def __init__(self):
super(App, self).__init__()
self.connect('destroy', self.nuke)
try:
raise Exception()
except:
self.msg('OMFG!', 'WTF just happened!?', gtk.MESSAGE_ERROR, gtk.BUTTONS_CLOSE)
self._exitStatus = 1
self.destroy()
if self.msg('OK', 'Everything worked fine') == gtk.RESPONSE_OK:
self.destroy()
# Let's go!
App()
gtk.main()
nuke
函数永远不会被调用,尽管显式调用了destroy
。
DIFF 关于@ DonQuestion的建议:
- self.destroy()
+ self.emit('destroy')
- App()
+ app = App()
这并没有解决问题...
更新已接受@ jku的回答,但也可以查看我自己的答案以获取更多信息......
答案 0 :(得分:2)
首先,代码存在一些测试问题:您从App初始化调用Gtk.main_quit():这在主循环运行之前发生,因此信号可能无效。
其次,你可能会在destroy()上收到一个警告:'destroy'处理程序只需要两个参数(self加一个)但是你的有三个......
关于控制流的评论:您不需要Window来获取信号,因为它们是GObject功能。为了满足您的测试需求,您可以编写App.test_except()函数并在对象初始化中使用glib.idle_add (self.test_except)
- 这样在主循环运行时会调用test_except()。
答案 1 :(得分:1)
我认为@jku的答案标识了我的密钥错误,因此我已将其标记为已接受,但在玩游戏时,我发现MessageDialog
不需要在GTK +循环中运行。我不知道这是否符合设计,但它确实有效!所以,我将我的通用消息对话框分解为它自己的函数,然后将主应用程序完全保存在它自己的类中,它遵循我期望的主循环:
import pygtk
pygtk.require("2.0")
import gtk
def msg(title, text, type = gtk.MESSAGE_INFO, buttons = gtk.BUTTONS_OK):
# Only allowed OK, Close, Cancel, Yes/No and OK/Cancel buttons
# Otherwise, default to just OK
if buttons not in [gtk.BUTTONS_OK, gtk.BUTTONS_CLOSE, gtk.BUTTONS_CANCEL, gtk.BUTTONS_YES_NO, gtk.BUTTONS_OK_CANCEL]:
buttons = gtk.BUTTONS_OK
dialog = gtk.MessageDialog(None, 0, type, buttons, title)
dialog.set_title(title)
dialog.set_geometry_hints(min_width = 300)
dialog.set_resizable(False)
dialog.set_deletable(False)
dialog.set_position(gtk.WIN_POS_CENTER)
dialog.set_modal(True)
dialog.format_secondary_text(text)
response = dialog.run()
dialog.destroy()
return response
class App:
def __init__(self):
# Build UI
# Connect signals
# Show whatever
def appQuit(self, widget):
gtk.main_quit()
def signalHandler(self, widget, data = None):
# Handle signal
# We can call msg here, when the main loop is running
# Load some resource
# We can call msg here, despite not having invoked the main loop
try:
# Load resource
except:
msg('OMFG!', 'WTF just happened!?', gtk.MESSAGE_ERROR, gtk.BUTTONS_CLOSE)
exit(1)
# n.b., Calls to msg work even without the following code
App()
gtk.main()
exit(0)