在不同的线程PySide和QProgressBar更新(PySide and QProgressBa

2019-06-27 09:58发布

这可能是一个有点长职务,因此,在此先感谢和我在一起,直到结束。 这里的问题是,(我想一个相当基本的一个,只是我经验不足与PiSide和Qt使其更难为我)。我有一个菜单项主窗口,假设“过程”。 代码如下 -

from PySide import QtCore, QtGui

class Ui_MainWindow(object):

      def setupUi(self, MainWindow, AppObj):
            .
            .
            self.statusbar = QtGui.QStatusBar(MainWindow)
            self.statusbar.setObjectName("statusbar")
            MainWindow.setStatusBar(self.statusbar)
            .
            .
            .
           self.actionProcess = QtGui.QAction(MainWindow)
           self.actionProcess.setObjectName("actionProcess")
           self.actionProcess.triggered.connect(self.myappObj.menuActionProcess) 
           .

这里self.myappobj指我已经创建了一个应用程序类,用作用于我的应用程序的主要逻辑控制器。 代码 -

from PySide import QtCore, QtGui
from MainWindow import Ui_MainWindow

class App(QtGui.QDialog):
      def __init__(self, parent=None):
          self.__mainWindow = QtGui.QMainWindow()
          self.__mainWindowDesignContext = Ui_MainWindow()
          self.__mainWindowDesignContext.setupUi(self.__mainWindow, self)
          self.__mainWindow.show()
      def menuActionProcess(self):
          self.processThread = BatchProcesser()
          self.progressBar = QtGui.QProgressBar()
          statusBar.addWidget(self.progressBar)
          self.progressBar.show()
          self.progressBar.setMinimum(0)
          self.progressBar.setMaximum(100)
          QtCore.QObject.connect(self.processThread, QtCore.SIGNAL("progress(int)"),self.progressBar, QtCore.SLOT("setValue(int)"), QtCore.Qt.DirectConnection)
          if not self.processThread.isRunning():
              self.processThread.exiting = False
              self.processThread.start()

因此,很容易看到什么,我想在这里做的是创建一个主窗口。 添加有所谓的“过程”菜单,点击其中将引发应用程序类,在这里我想提出一个进度条,并与我的主窗口的状态栏将其附着回调menuActionProcess方法(实际的代码有许多其他的事情,我给这里重新排列为伪例如必要的部分),最后在上面的代码中提到的BatchProcesser类,我这样做 -

from PySide.QtGui import *
from PySide.QtCore import *

class BatchProcesser(QThread):
     __errorHappened = False
     def __init__(self, parent=None):
         QThread.__init__(self, parent)
         self.exiting = False
     def run(self):
         for a in range(101):
            print a
            QThread.msleep(100)
            self.emit(SIGNAL("progress(int)"), a)
            print a

在我的理解这应该更新附着在状态栏在不同的线程比主线程的进度条。 这将允许用户与GUI自由互动。

现在,如果我尝试凛这一点,一切都很好,直到我打的过程菜单。 然后,进度条姑息,但不更新和控制台是完全错误 -

0 QPixmap的:它是不是安全使用GUI线程之外像素图

QPixmap的:它是不是安全使用GUI线程之外的像素图

QPixmap的:它是不是安全使用GUI线程之外的像素图

QPixmap的:它是不是安全使用GUI线程之外的像素图

0

1

QPixmap的:它是不是安全使用GUI线程之外的像素图

QPixmap的:它是不是安全使用GUI线程之外的像素图

QPixmap的:它是不是安全使用GUI线程之外的像素图

QPixmap的:它是不是安全使用GUI线程之外的像素图

在队列[XCB]未知请求而离队

[XCB]这很可能是一个多线程的客户端和XInitThreads没有被调用

[XCB]中止,抱歉。

蟒蛇:../../src/xcb_io.c:178:dequeue_pending_request:断言`xcb_xlib_unknown_req_in_deq失败。

中止(核心转储)

任何帮助是非常需要我。 我无法找出和/ OT点错误的最初原因和修复相同。

Answer 1:

问题在于你如何连接信号到槽:

      QtCore.QObject.connect(self.processThread, QtCore.SIGNAL("progress(int)"),self.progressBar, QtCore.SLOT("setValue(int)"), QtCore.Qt.DirectConnection)

在这里,你明确的强制执行DirectConnection。 这是不对的! 它使槽在调用者的线程处理。 这意味着,进度条的GUI更新发生在进程中的线程,而不是在GUI线程。 然而,绘图只允许在GUI线程。

它是完全正常的信号从一个线程连接到从另一个槽。 但是,你需要或者AutoConnection (默认,这将承认线程和使用QueuedConnection )或QueuedConnection

此行应该解决您的问题:

      QtCore.QObject.connect(self.processThread, QtCore.SIGNAL("progress(int)"),self.progressBar, QtCore.SLOT("setValue(int)"), QtCore.Qt.QueuedConnection)

见http://doc.qt.io/archives/qt-4.7/qt.html#ConnectionType-enum 。



文章来源: PySide and QProgressBar update in a different thread