SRC*_*SRC 4 python qt multithreading pyside progress-bar
这可能是一个很长的帖子,所以,提前感谢与我在一起直到最后.这是问题,(我认为这是一个相当基本的问题,只是我对PiSide和Qt缺乏经验使我更难.)我有一个主窗口,其中包含一个菜单项,假设为"Process".代码如下 -
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)
.
Run Code Online (Sandbox Code Playgroud)
这里self.myappobj指的是我创建的app类,它充当我的应用程序的主要逻辑控制器.代码 -
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()
Run Code Online (Sandbox Code Playgroud)
所以,我很容易看到我在这里要做的是创建一个主窗口.添加一个名为"Process"的菜单,单击该菜单会触发app类中的回调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
Run Code Online (Sandbox Code Playgroud)
根据我的理解,这应该在与主线程不同的线程中更新状态栏附带的进度条.这将允许用户自由地与GUI交互.
现在,如果我尝试冲洗这个,一切都很好,直到我点击Process菜单.然后,进度条会缓和但不会更新,并且控制台已满且出错 -
0 QPixmap:在GUI线程外使用pixmaps是不安全的
QPixmap:在GUI线程之外使用pixmaps是不安全的
QPixmap:在GUI线程之外使用pixmaps是不安全的
QPixmap:在GUI线程之外使用pixmaps是不安全的
0
1
QPixmap:在GUI线程之外使用pixmaps是不安全的
QPixmap:在GUI线程之外使用pixmaps是不安全的
QPixmap:在GUI线程之外使用pixmaps是不安全的
QPixmap:在GUI线程之外使用pixmaps是不安全的
[xcb]出队时队列中的未知请求
[xcb]这很可能是一个多线程客户端,而且还没有调用XInitThreads
[xcb]中止,对不起.
python:../../ src/xcb_io.c:178:dequeue_pending_request:断言`!xcb_xlib_unknown_req_in_deq'失败.
中止(核心倾倒)
我非常需要任何帮助.我无法找出和/或指出错误的原始原因并修复相同的问题.
问题在于如何将信号连接到插槽:
QtCore.QObject.connect(self.processThread, QtCore.SIGNAL("progress(int)"),self.progressBar, QtCore.SLOT("setValue(int)"), QtCore.Qt.DirectConnection)
Run Code Online (Sandbox Code Playgroud)
在这里,您明确强制执行DirectConnection.这是错的!它使得槽在调用者的线程中被处理.这意味着progressBar的GUI更新发生在进程线程中,而不是发生在GUI线程中.但是,只允许在GUI线程中绘图.
将信号从一个线程连接到另一个线程的插槽是完全正常的.但是,您需要AutoConnection(默认情况下,将识别线程并使用QueuedConnection)或QueuedConnection.
这行应该解决你的问题:
QtCore.QObject.connect(self.processThread, QtCore.SIGNAL("progress(int)"),self.progressBar, QtCore.SLOT("setValue(int)"), QtCore.Qt.QueuedConnection)
Run Code Online (Sandbox Code Playgroud)
请参见http://doc.qt.io/archives/qt-4.7/qt.html#ConnectionType-enum.
| 归档时间: |
|
| 查看次数: |
5179 次 |
| 最近记录: |