我正在编写一个带有GUI的多线程Python程序,其中有几个模块通过更改文本和背景颜色来“触摸”GUI。我目前正在使用PyGTK,并且发现GUI有时会“无声地”崩溃(没有错误消息;程序刚刚终止),有时会遇到分段错误。
This site注意到GTK不是完全线程安全的,并且PyGTK多线程编程很棘手。是否有更好的Python GUI框架用于不太可能产生问题的多线程程序?
答案 0 :(得分:4)
哦,我绝对推荐PyQt4。起初,我没有得到所有这些SIGNAL
和EMIT
废话,但现在我已经用它制作了一个程序,QThread
模块非常有用。
至于稳定性,我从来没有遇到过崩溃。即使在我调试半功能代码时,QT也没有任何问题。只要我点击一个信号槽无效的按钮,它就会向控制台窗口抛出一个错误。
另一方面,GTK只是偶尔发布一次,没有任何错误。只是你的描述性和友好Segmentation Fault
。这是我发现PyQt工作愉快的原因之一。当你收到错误时,你实际上知道什么是错的。
之后我很确定这是个人偏好,但在Mac,Linux和Windows上还有一个原生外观的GUI。 Windows上的GTK +(不要误解我。我使用的是Ubuntu)只是有这种X-org的感觉,这让我感到不安。
祝你好运!只是为了让PyQt更具吸引力,这里是我的书籍装订应用程序的摘录(它有点乱):
class Binder(QtCore.QThread):
'''
Class for binding the actual book
'''
def __init__(self, parent = None):
super(Binder, self).__init__(parent)
def initialize(self, pages, options, outfile):
self.pages = pages
self.options = options
self.outFile = outfile
self.book = organizer.Book()
self.enc = Encoder(self.options)
self.ocr = ocr.OCR(self.options)
self.connect(self.enc, QtCore.SIGNAL('updateProgress(int, int)'), self.updateProgress)
def updateProgress(self, percent, item):
self.emit(QtCore.SIGNAL('updateProgress(int, QString)'), int(percent), 'Binding the book...')
self.emit(QtCore.SIGNAL('updateBackground(int, QColor)'), int(item), QtGui.QColor(170, 255, 170, 120))
if int(percent) == 100:
time.sleep(0.5)
self.emit(QtCore.SIGNAL('finishedBinding'))
def run(self):
self.die = False
for page in self.pages:
self.add_file(page, 'page')
if not self.die:
self.analyze()
if not self.die:
self.book.get_dpi()
if self.options['ocr'] and not self.die:
self.get_ocr()
if not self.die:
self.enc.initialize(self.book, self.outFile)
self.enc.start()
答案 1 :(得分:0)
如果要从线程更新GUI,可能需要使用gobject.idle_add()
以便稍后在循环中调用GUI更新函数,大多数GUI框架(如Qt)都要求您添加回调将在主循环空闲时调用。 GTK还支持使用gtk.gdk.lock
上下文管理器或在GUI调用周围调用gtk.gdk.threads_enter
和gtk.gdk.threads_leave
来从线程调用GUI函数。
所以你要么:
gobject.idle_add(lambda: window.whatever(arg1, arg2))
或者你这样做:
with gtk.gdk.lock:
window.whatever(arg1, arg2)