哪些 GUI 框架最适合多线程 Python 程序?

发布于 2024-10-15 03:29:39 字数 319 浏览 2 评论 0原文

我正在编写一个带有 GUI 的多线程 Python 程序,其中有几个模块可以通过更改文本和背景颜色来“触摸”GUI。我目前正在使用 PyGTK,发现 GUI 有时会“无提示”崩溃(没有错误消息;程序只是终止),有时会遇到分段错误。

这个网站指出 GTK 并不是完全线程-安全,而且 PyGTK 多线程编程很棘手。是否有更好的 Python GUI 框架用于多线程程序且不太可能产生问题?

I am writing a multi-threaded Python program with a GUI, with several modules that "touch" the GUI by changing text and background colors. I am currently using PyGTK and am finding that the GUI sometimes crashes "silently" (no error messages; the program just terminates), and sometimes encounters segmentation faults.

This site notes that GTK is not completely thread-safe, and that PyGTK multi-threaded programming is tricky. Are there better Python GUI frameworks for multi-threaded programs that are less likely to produce problems?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

━╋う一瞬間旳綻放 2024-10-22 03:29:39

哦,我绝对推荐 PyQt4。起初,我没有明白这些 SIGNALEMIT 的废话,但现在我已经用它编写了一个程序,QThread模块非常有用。

至于稳定性,我从来没有遇到过崩溃。即使当我调试半功能代码时,QT 也没有任何问题。每当我单击带有无效信号槽的按钮时,它都会向控制台窗口抛出错误。

另一方面,GTK 只是“偶尔爆发一次,没有任何错误”。只是您极具描述性和友好的分段错误。这是我觉得使用 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()

Ohh, I definitely recommend PyQt4. At first, I didn't get all this SIGNAL and EMIT nonsense, but now that I've made a program with it, the QThread module is amazingly useful.

As for stability, I have never had a crash, ever. Even while I was debugging half-functional code, QT didn't have any problems. It just threw an error to the console window whenever I clicked a button with an invalid signal slot.

GTK, on the other hand, just 'sploded once in a while with no errors whatsoever. Just your extremely descriptive and friendly Segmentation Fault. That was one of the reasons I find PyQt a joy to work with. When you get an error, you actually know what's wrong.

I'm pretty sure it's personal preference after that, but one more plus is native-looking GUIs on Mac, Linux, and Windows. GTK+ on Windows (don't get me wrong. I use Ubuntu) just has this X-org feel to it, which disturbs me.

Good luck!


Just to make PyQt a bit more attractive, here's an excerpt from my book binding application (it's a bit messy):

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()
凉城凉梦凉人心 2024-10-22 03:29:39

如果您要从线程更新 GUI,您可能需要使用 gobject.idle_add() 以便稍后在循环中调用 GUI 更新函数,大多数 GUI 框架(如 Qt)要求您添加一个稍后在主循环空闲时调用的回调。 GTK 还支持通过使用 gtk.gdk.lock 上下文管理器或调用 gtk.gdk.threads_enter 和 gtk.gdk.threads_leave 从线程调用 GUI 函数/code> 围绕你的 GUI 调用。

所以你要么这样做:

gobject.idle_add(lambda: window.whatever(arg1, arg2))

要么你这样做:

with gtk.gdk.lock:
    window.whatever(arg1, arg2)

If you are updating the GUI from a thread, you might want to use gobject.idle_add() so that the GUI update function is called later in the loop, most GUI frameworks (like Qt) require you to add a callback that will be called later when the mainloop is idle. GTK also supports calling the GUI functions from threads by using the gtk.gdk.lock context manager or calling gtk.gdk.threads_enter and gtk.gdk.threads_leave around your GUI calls.

So you either do:

gobject.idle_add(lambda: window.whatever(arg1, arg2))

Or you do:

with gtk.gdk.lock:
    window.whatever(arg1, arg2)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文