QPixmap 在 GUI 线程之外不安全

QPixmap not safe outside GUI thread

我的程序有主 GUI 线程来处理用户界面。

在不冻结主 GUI 的情况下启动另一个线程来处理繁重的工作(循环、计算等)。

从我的 "calculations thread" 我正在使用另一个模块 draw_plots,它只绘制和保存多种绘图。

import draw_plots as plots
    class calculatorThread(QtCore.QThread):
        signal1 = QtCore.pyqtSignal(int, int)
        signal2 = QtCore.pyqtSignal(int,int) 
        signal3 = QtCore.pyqtSignal(int) 

        def __init__(self,input_file_txt, parameter_file_txt):
            QtCore.QThread.__init__(self)
            #and etc etc

在这个线程的某个时刻,我正在调用:

plots.stacked_barplot(*arguments)

一切正常,但是,我多次在屏幕上收到消息:

QPixmap: It is not safe to use pixmaps outside the GUI thread

想知道我做错了什么以及如何避免此消息。

那么,您从计算器线程发出绘图命令,该命令又使用 QPixmap 绘制绘图 - 全部来自您的计算器线程。

理想情况下,您不应该从计算器线程中提取,而是例如发出您已准备好绘图的信号 - 并在主线程中进行绘图。也许沿着以下几行:

class calculatorThread(QtCore.QThread):
    plot_emit = QtCore.pyqtSignal()

    def run(self):
        self.plot_args = your_calculation()
        self.plot_ready.emit()

在外面,将 plot_ready 信号连接到您的绘图命令:

calculator.plot_emit.connect(lambda x: 
                             plots.stacked_barplot(*calculator.plot_args))

如果计算是在单独的线程中完成的,您应该使用 QImage。您还可以安全地访问 QImage.bits() 并直接对像素数据进行图像处理(快很多)。

正如警告明确指出的那样,QPixmap 对象只能在 GUI 线程中使用。如果您确实需要 QPixmap,您可以将计算出的 QImage 转换为 QPixmap(但例如,您可以直接在 QPainter 上绘制 QImage)。