我有一个PyQt应用程序,它通过回调从外部源接收信息,这些回调是从不受我控制且不是QThread
的线程调用的。在没有轮询的情况下,将这些信息传递给主线程的正确方法是什么?特别是,我想发出一个Qt信号,这样我就可以在新数据到达时唤醒主线程(或另一个QThread
)。
答案 0 :(得分:1)
信号的默认连接类型为Qt.AutoConnection,文档描述如下:
如果信号是从与接收不同的线程发出的 对象,信号排队,表现为Qt :: QueuedConnection。 否则,直接调用插槽,表现为 Qt的:: DirectConnection。连接类型是在确定时确定的 发出信号。
因此,在发出信号之前,Qt只需比较发送方和接收方的当前线程关联性,然后再决定是否对其进行排队。 如何最初启动底层线程无关紧要。
这是一个使用python工作线程的简单演示:
$ python test.py
show: [MainThread]
start: [MainThread]
work: [Worker]
callback: 0 [Worker]
received: 0 [MainThread]
still active...
callback: 1 [Worker]
received: 1 [MainThread]
still active...
callback: 2 [Worker]
received: 2 [MainThread]
still active...
callback: 3 [Worker]
received: 3 [MainThread]
callback: 4 [Worker]
received: 4 [MainThread]
典型输出:
-- Sample data
-- including an id for use as a tie-breaker for a unique pk/clustered index on c1 & c2
DECLARE @tbl TABLE
(id int identity not null, c1 char(1), c2 tinyint, primary key (c1,c2,id));
INSERT @tbl VALUES ('a', 2), ('b', 1), ('a', 1), ('b', 3), ('a', 2);
-- Solution
SELECT c1, MaxOccurs = MAX(c)
FROM
(
SELECT c1, c2, c = COUNT(1)
FROM @tbl
GROUP BY c1, c2
) x
GROUP BY c1;
答案 1 :(得分:0)
如果您只是轮询外部设备或库,我会像处理它一样处理它。创建一个处理回调的单独工作线程,并向主GUI线程发出信号。
class Worker(QObject):
data_ready = pyqtSignal(object, object)
def callback(self, *args, **kwargs):
self.data_ready.emit(args, kwargs)
class Window(...)
def __init__(self):
...
self.worker = Worker(self)
# Connect worker callback function to your external library
library.register_callback(self.worker.callback) #??
...
# Mover worker to thread and connect signal
self.thread = QThread(self)
self.worker.data_ready.connect(self.handle_data)
self.worker.moveToThread(self.thread)
self.thread.start()
@pyqtSlot(object, object)
def handle_data(self, args, kwargs):
# do something with data