使用QThread进行PyQt4多线程编程

0 投票
2 回答
1751 浏览
提问于 2025-04-16 15:45

当在 QThread 中调用 xml.etree.ElementTree.fromstring() 函数时,会出现一个无尽的阻塞情况。此外,像 multiprocessing.Process() 这样的许多其他调用也会导致 QThread 被阻塞。需要特别说明的是,这种阻塞是纯粹的,没有任何异常或中断。

以下是代码(稍微编辑过,但原理和源代码相同):

from PyQt4.QtGui import *
from Ui_mainwindow import Ui_MainWindow
import sys
import xml.etree

class Bruton(QThread):
    def __init__(self, mw):
        super(Bruton, self).__init__(mw) 
        self.mw = mw

    def run(self):
        print("This message I see.")
        tree = xml.etree.ElementTree.fromstring("<element>text</element>")
        print("But this one never.")

class MainWindow(QMainWindow):
    def __init__(self):
        QMainWindow.__init__(self)
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.init_bruton()

    # When the form is shown...
    def showEvent(self, arg1):
        self.bruton.start()

    def init_bruton(self):
        self.bruton = Bruton(self)

app = QApplication(sys.argv)
mw = MainWindow()
mw.show()
sys.exit(app.exec_())

2 个回答

2

这个代码本身其实是不能运行的,不过只要稍微改动一下,就能正常运行并且效果很好。下面是修改后的代码:

from PyQt4.QtGui import *
from PyQt4.QtCore import *
import sys
import xml.etree.ElementTree

class Bruton(QThread):
    def __init__(self, mw):
        super(Bruton, self).__init__(mw)
        self.mw = mw

    def run(self):
        print("This message I see.")
        tree = xml.etree.ElementTree.fromstring("<element>text</element>")
        print("But this one never.")

class MainWindow(QMainWindow):
    def __init__(self):
        QMainWindow.__init__(self)
        self.init_bruton()

    # When the form is shown...
    def showEvent(self, arg1):
        self.bruton.start()

    def init_bruton(self):
        self.bruton = Bruton(self)

app = QApplication(sys.argv)
mw = MainWindow()
mw.show()
sys.exit(app.exec_())

这是运行后的输出结果:

$ python test.py 
This message I see.
But this one never.

这个是在Python 2.6.6和PyQt4 4.8.3的环境下,在Debian Unstable系统上测试的。

你能在你的环境中试试看我修改后的例子能不能运行吗?如果可以的话,你就离解决你真正的代码问题更近一步了。=)

0

我这里展示的代码是简化过的(源代码分成了两个文件,还有一个叫做 __ini__.py 的文件)。我发现,主模块必须是启动 QApplication 的那个模块。所以我在我的程序的主模块 __init__.py 中添加了 app.exec_()

撰写回答