我对这个网站很陌生,所以我希望在提出要求时遵守所有规则。关于问题:
我正在使用Glade构建GTK + / Python3程序。当用户单击“读取文件”按钮时,将调用某些耗时的函数。这是一个给你一个想法的片段:
def onReadFile(self, widget, data=None):
### I want the statusbar (had the same problem with a progressbar)
### to push() and display at this point
self.statusbar.push(self.contextID, "Reading file...")
### Unfortunately, my program waits for all this to finish
### before displaying the statusbar.push() far too late
text = back.readFile(self.inFile)
splitText = back.textSplit(text)
choppedArray = back.wordChop(splitText)
back.wordCount(choppedArray, self.currDict)
currSortedArray = back.wordOrder(self.currDict)
handles.printResults(currSortedArray, "resCurrGrid", self.builder)
主要的想法是,事情并没有按照我期望的顺序发生,而且我不知道为什么(事情仍然没有发生错误)。我四处阅读(here和there并认为线程可能是我的问题,但我不确定,因为我没有发现任何人提出的问题与我的问题太相似。
为什么statusbar.push()
等到最后才能显示其消息?
我已尝试按照线程示例here对其进行排序,但我无法适应'那课对我基于班级的课程的布局。
这就是它的样子(为了简洁和相关性而剪裁):
from gi.repository import Gtk, GLib, GObject
import threading
import back
import handles
class Application:
def __init__(self):
# I build from glade
self.builder = Gtk.Builder()
...
# I want this window to show later
self.progWindow = self.builder.get_object("progWindow")
self.window = self.builder.get_object("mainWindow")
self.window.show()
# I believe this code should go here in the __init__, though
# I'm quite possibly wrong
thread = threading.Thread(target=self.onReadFile)
thread.daemon = True
thread.start()
...
def upProgress(self):
self.progWindow.show()
return False
def onReadFile(self, widget, data=None):
# Following the example I linked to, this to my understanding
# should show the progWindow by asking the main Gtk thread
# to execute it
GLib.idle_add(self.upProgress)
# Time-consuming operations
text = back.readFile(self.inFile)
splitText = back.textSplit(text)
...
if __name__ == "__main__":
GObject.threads_init()
main = Application()
Gtk.main()
我threading.Thread(target=self.onReadFile)
时遇到以下错误,但它最接近'工作'我明白了:
Exception in thread Thread-1:
Traceback (most recent call last):
File "/usr/lib/python3.2/threading.py", line 740, in _bootstrap_inner
self.run()
File "/usr/lib/python3.2/threading.py", line 693, in run
self._target(*self._args, **self._kwargs)
TypeError: onReadFile() takes at least 2 arguments (1 given)
我唯一的想法是:
如果你可以提供帮助,那很棒,如果你能做到,但可以提出一个很棒的教程。我的头发不能拉扯。
如果我要发布一个完整的工作示例,请告诉我。
答案 0 :(得分:2)
因为GTK +重绘是从运行回调的同一执行线程发生的。因此,如果您在需要重绘的回调中执行某些操作,那么在回调退出之后实际上不会发生这种情况。
解决方案是通过使用线程或使用异步I / O来解除长时间运行的操作。
如果您使用线程,请记住只有一个线程可以执行GTK +调用。
您也可以通过使用类似from this answer之类的内容让GTK +处理来自回调内的待处理事件来手动解决此问题:
while Gtk.events_pending(): Gtk.main_iteration()