从线程启动一个函数。 (GUI 线程和 QThread 错误)

Start a function from a thread. (GUI thread and QThread errors)

我已经使用 Python 的线程模块将例程变为 运行 子进程并等待它完成。 我使用以下行进行线程处理:

t1=Thread(target=self.routineFunction, args=(self, "file1.txt", "file2.txt", self.nextFunction)).start()

在我的函数 routineFunction(self,file1,file2,nextFunction) 中,一旦子进程完成 运行ning.

,我将下一个函数调用到 运行

在那之前一切正常。

但是如果我在下一个函数中创建新的 QObject 项,我会收到很多错误: - "QPixmap: It is not safe to use pixmaps outside the GUI thread" - "QObject::startTimer: QTimer can only be used with threads started with QThread"

我的猜测是,当我从例程中调用 nextFunction 时,它 运行 在与例程相同的线程中,因此出现错误。 有没有办法从 "main" 或 "normal" 线程中的例程调用函数?

感谢您的帮助。

一般从其他线程调用函数是可以的。但是许多 GUI 库(其中包括 QT)对此行为有一些限制。

例如,有一个名为 'GUI thread' 的指定线程,它处理所有图形内容,例如从 OS 发送消息、重绘 windows 等。您还限制使用具有此唯一线程的 GUI。因此,例如,您不应在其他线程中创建 QPixmap

QTimer 使用一些 QThread 的内部数据,所以你应该在只以 QThread 开始的线程中使用这样的计时器,而不是普通的 Python thread 模块。

回到您的问题,如果您想使用 QT,您应该使用 QThread 和 post 事件将线程生成到使用 postEvent() 方法的 GUI 线程。这将确保 QT 内部数据结构的一致性。

因此,您可以在任何 QT 线程中 运行 您的代码,但是如果您想使用 GUI(您的 QObject 使用 QPixmap,情况就是这样),您只需要在 GUI 线程中处理此类调用。

好的,所以我认为 werewindle 解决方案是可行的。不幸的是,我发现很难将我当前的脚本从 Thread 转换为 QThread(我通常是线程的新手)。

我找到了解决方法: 我没有将 nextFunction 作为参数传递,而是传递了一个 queue = Queue.Queue() 并在我的新线程中的子进程成功时使用 queue.put(True) 。没有更多的 nextFunction,我只是用 queue.get() 等待队列中的值。 通过这样做,我可以在 GUI 线程中继续。