PyGTK窗口在我的PyGTK应用程序中,我要求用户找到一个文件,以便可以对其执行操作。应用程序询问用户该文件,并将该文件名传递给必要的方法。不幸的是,当在该对话框上调用gtk.dispose()
方法时,它只是在那里挂起,直到调用完成文件IO的方法。我甚至尝试将文件操作放在另一个线程中,但没有任何效果。PyGTK窗口不告诉
我缩进的目的是让程序显示一个对话框给用户,通知他们他们选择进行操作的文件正在发生。在当前的实施中,在处置gtk.FileChooserDialog
之后对话出现。
下面是我的代码:
def performFileManipulation(self, widget, data=None):
# Create the file chooser dialog:
dialog = gtk.FileChooserDialog("Open..", None, gtk.FILE_CHOOSER_ACTION_OPEN, (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OPEN, gtk.RESPONSE_OK))
dialog.set_default_response(gtk.RESPONSE_OK)
# Display the file selector and obtain the response back
response = dialog.run()
# If the user selected a file, then get the filename:
if response == gtk.RESPONSE_OK:
dataLocation = dialog.get_filename()
# If the file was not chosen, then just close the window:
else:
print "Closed, no files selected" # Just for now
########## Problem Area ##########
# The dialog is told to get destroyed, however, it hangs here in an
# unresponsive state until the the file-manipulations performed in a new thread
# below are completed. Then, the status dialog (declared below) is displayed.
dialog.destroy() # Close the dialog.
## Show a dialog informing the user that the file manipulation is taking place:
statusDialog = gtk.Dialog("Performing File Operations...", parent=None, flags=0, buttons=None)
statusLabel = gtk.Label("Performing File Operations.\nPlease wait...")
statusLabel.set_justify(gtk.JUSTIFY_CENTER)
statusLabel.show()
statusDialog.vbox.pack_start(statusLabel, True, True, 0)
statusDialog.set_default_size(350, 150)
statusDialog.show()
# Create the thread to perform the file conversion:
errorBucket = Queue.Queue() # Make a bucket to catch all errors that may occur:
theFileOperationThread = doStuffToTheFile(dataLocation, errorBucket) # Declare the thread object.
## Perform the file operations:
theFileOperationThread.start() # Begin the thread
# Check on the thread. See if it's still running:
while True:
theFileOperationThread.join(0.1)
if theFileOperationThread.isAlive():
continue
else:
break
# Check if there was an error in the bucket:
try:
errorFound = errorBucket.get(False)
# If no errors were found, then the copy was successful!
except Queue.Empty:
pass
# There was an error in the bucket! Alert the user
else:
print errorFound
statusDialog.destroy()
请注意,此代码尚未完成,例如,它并没有正确处理用户不选择一个文件,并取消该操作。
编辑:经过进一步调查,似乎是PyGTK的线程问题。问题发生在while True
循环中。我用time.sleep(15)
替换了该代码,并且类似地,文件选择对话框将暂停。这是非常奇怪的行为,并且所有内容都应该在不同的线程中运行。我想现在的问题是要找出如何将文件选择对话框放在它自己的线程中。
只要有机会,我会尽快解决。 – Phanto 2010-07-08 19:52:47
我正在使用'gobject.timeout_add()'方法的混合,以及ptomato建议删除线程的方法。这使得弹出显示。但是,当只使用一个简单的回调函数时,我怎么知道'doFileStuff()'方法处理完成? 'gobject.timeout_add()'方法返回一个事件源的整数ID。 'gobject.signal_query()'方法会这样做吗? – Phanto 2010-07-09 13:10:50
我认为是这样的:http://pygtk.org/pygtk2reference/gobject-functions.html#function-gobject--signal-query2表示元组将包含'信号回调函数返回的GType。如果回调尚未完成,我认为它将返回无(或GType等效)。 – 2010-07-09 13:56:21