问题描述
这是我的此处未回答的问题.与下面的代码完全一样,它会因段错误而崩溃(将其复制/粘贴到您的系统中并运行它).当我从一个或两个信号构造函数调用中删除 type=QtCore.Qt.DirectConnection
时(因此使用 QtCore.Qt.AutoConnection
代替),一切都按照它应该的方式运行:出现一个小部件,显示五个进度条在无限循环中填满然后清空.
This is a follow-up to my unanswered question here. The code, exactly as it is below crashes with a segfault (copy/paste it into your system and run it). When I remove type=QtCore.Qt.DirectConnection
from one or both of the signal constructor calls (thereby using QtCore.Qt.AutoConnection
instead), everything runs the way it should: A widget appears, showing five progress bars filling up then emptying in an endless loop.
from PySide import QtCore, QtGui
import time
class Worker(QtCore.QThread):
sig_worker_update_progress = QtCore.Signal(int, int)
def __init__(self, thread_id, *args, **kwargs):
super(Worker, self).__init__(*args, **kwargs)
self.thread_id = thread_id
self.stop_requested = False
def slot_interrupt(self):
self.stop_requested = True
def run(self):
progress = 0
while(True):
self.sig_worker_update_progress.emit(self.thread_id, progress % 100)
progress += 1
if self.stop_requested:
break
else:
time.sleep(0.1)
class Controller(QtCore.QObject):
sig_controller_update_progress = QtCore.Signal(int, int)
def __init__(self, num_workers, *args, **kwargs):
super(Controller, self).__init__(*args, **kwargs)
self.workers = []
for i in range(num_workers):
self.workers.append(Worker(i))
self.workers[i].sig_worker_update_progress.connect(
self.slot_worker_update_progress,
type=QtCore.Qt.DirectConnection)
for worker in self.workers:
worker.start()
def slot_worker_update_progress(self, thread_id, progress):
# Do
# Stuff
self.sig_controller_update_progress.emit(thread_id, progress)
class Monitor(QtGui.QWidget):
def __init__(self, num_workers, *args, **kwargs):
super(Monitor, self).__init__(*args, **kwargs)
main_layout = QtGui.QVBoxLayout()
self.setLayout(main_layout)
self.progress_bars = []
for _ in range(num_workers):
progress_bar = QtGui.QProgressBar()
main_layout.addWidget(progress_bar)
self.progress_bars.append(progress_bar)
self.controller = Controller(num_workers)
self.controller.sig_controller_update_progress.connect(
self.slot_controller_update_progress,
type=QtCore.Qt.DirectConnection)
def slot_controller_update_progress(self, thread_id, progress):
self.progress_bars[thread_id].setValue(progress)
if __name__ == "__main__":
app = QtGui.QApplication([])
monitor = Monitor(5)
monitor.show()
app.exec_()
为什么使用两个嵌套的 DirectConnection
信号会导致段错误?如果 Qt 不希望您这样做,为什么没有给出更多信息错误?
Why does using two nested DirectConnection
signals cause a segfault? If Qt does not want you to do that, why isn't a more informative error given?
我使用的是 PySide v1.2.2,它封装了 Qt 4.8 框架.
I am using PySide v1.2.2 which wraps the Qt 4.8 framework.
推荐答案
我找到了一个令人满意的解释 这里.显然,发出 DirectConnection
类型的信号相当于直接函数调用.因此,当两个信号都是 DirectConnect
时,GUI 毕竟是在 Worker
线程上更新的.正如我在其他问题中所提到的,线程不允许改变GUI.问题不在于嵌套 DirectConnection
本身.
I found a satisfying explanation here. Apparently, emitting a signal of type DirectConnection
is equivalent to a direct function call. So the GUI is after all updated on a Worker
thread when both signals are DirectConnect
-ed. As mentioned on my other question, threads are not allowed to change the GUI. The issue is NOT with nesting DirectConnection
s per se.
这篇关于嵌套 DirectConnection 信号导致段错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!