2

我正在尝试在 Python 中的单独线程中做一些工作。我正在使用 PyQt,所以我的线程是 QThreads。

这项工作本身涉及使用 PIL 加载大图像并将图像转换为 QImage。

下面是一些在工作线程中反复加载图像的代码示例:

class testThread(QtCore.QThread):
    def run(self):
        while True:
            im = Image.open('c:\zheadline.tif')
            try:
                imgData = ImageQt.ImageQt(im)
                print (imgData.width())
            except:
                print ("Image load error")

图像非常大(16k),因此实际加载它可能需要几秒钟。但是,在此期间,GUI 变得非常迟钝,通常会冻结几百毫秒。

为什么是这样?我的机器有 16 个内核,所以没有理由为什么 1 个线程的工作会导致所有其他线程的速度变慢,对吧?

基本上我希望能够在后台加载这些大图像而不会中断用户体验。有谁知道如何将主要工作推到另一个线程而不干扰主 GUI 线程?

其他一些信息:我正在使用“thread.start()”启动 QThreads。此外,GUI 在加载期间并没有完全冻结……它只是变得非常缓慢和缓慢,间歇性地冻结。

4

2 回答 2

4

python 解释器一次只能在一个线程中运行(阅读有关 Global Interpreter Lock 的信息),因此 Image.open 和 ImageQt.ImageQt 中的一个或两个可能在 python 中做很多工作而不释放 GIL。

一种可能的解决方案是在单独的进程中加载​​图像并通过共享内存传输数据。我最近做了这样的事情:http://bazaar.launchpad.net/~luke-campagnola/pyqtgraph/dev/view/head: /widgets/RemoteGraphicsView.py。请参阅“remoteSceneChanged”方法了解如何从共享内存中重建 QImage。

于 2012-08-13T21:46:44.193 回答
0

根据“Python、线程和 Qt:繁荣!” - Teijo Holzer (Kiwi Pycon 2019) , Multithreading with Qt / qthread - Giuseppe D'Angelo和 Qt 文档,您不能从主线程外部调用以下对象:

  1. QWidget
  2. QQuickItem
  3. QPixmap
  4. 通常,所有绘图/可见/小部件事件

因此,我怀疑传递imImageQt.ImageQt(im)辅助线程会导致问题。我建议在主线程中执行此操作,然后Image.open在您的QThread.

于 2021-10-28T02:57:47.863 回答