为什么 PyQt 在没有信息的情况下崩溃?(退出代码 0xC0000409)



我正在尝试使用 PyQt 开发软件,但我经常在没有调试信息的情况下卡在软件崩溃上(只有退出代码0xC0000409)。我正在使用QThread,我写了一个这样的系统:

class serialThreadC(QThread):
    updateOutBox = QtCore.pyqtSignal(str)
    updateStatus = QtCore.pyqtSignal(int)
    def __init__(self):
        super(serialThreadC, self).__init__()
        self.ser = False
        self.state = 0
        self.serialEnabled = False
    def run(self):
        while True:
            if self.state == -3 or self.state == -2:
                if self.SerialEnabled:
                    self.updatePB(20)
            elif self.state == 0:
                if self.serialEnabled:
                    self.updatePB(20)
    def ConnDisconn(self):
        self.serialEnabled = not self.serialEnabled
    def updatePB(self, stat):
        self.state = stat
        self.updateStatus.emit(self.state)
serialThread = serialThreadC()
serialThread.start()
## sw is a QDialog already loaded
serialThread.updateOutBox.connect(sw.updateOutBox)
serialThread.updateStatus.connect(sw.updateStatus)
sw.PB_ConnDisconn.clicked.connect(serialThread.ConnDisconn)

我在run()ConnDisconn()中读/写serialEnabled时崩溃。我知道 PyQt 不是线程安全的,并且错误地处理变量会导致我的类型崩溃,但我无法理解我的代码出了什么问题。我的想法(可能是错误的)是所有serialThread方法都在同一线程上执行,即使它们连接到 gui(主线程)。这有错吗?同样,我从serialThread发出事件并将它们连接到GUI,但这从来没有给我带来问题。

你能看到我犯的错误吗?如果没有其他信息,有没有办法调试代码?(我使用 PyCharm 2017.1.3)。

PyQt 是线程安全的,与 Qt 的线程安全程度相同。Qt文档会告诉你他们的API的哪些部分是保证的,以及在什么情况下。

跨线程信号是线程安全的,因此在示例中调用 updatePB 方法是可以的。你的ConnDisconn方法不是线程安全的,但这与 PyQt 或 Qt 无关 - 这只是你如何编写它的结果。serialEnabled属性可以由两个线程同时读取/写入,因此行为是严格未定义的。编写此内容的线程安全方法是使用互斥锁,如下所示:

class serialThreadC(QThread):
    updateOutBox = QtCore.pyqtSignal(str)
    updateStatus = QtCore.pyqtSignal(int)
    def __init__(self):
        super(serialThreadC, self).__init__()
        self.ser = False
        self.state = 0
        self._mutex = QMutex()
        self.serialEnabled = False   
    def ConnDisconn(self):
        self._mutex.lock()
        self.serialEnabled = not self.serialEnabled
        self._mutex.unlock()
    def run(self):
        while True:
            if self.state == -3 or self.state == -2:
                self._mutex.lock()
                if self.serialEnabled:
                    self.updatePB(20)
                self._mutex.unlock()
            elif self.state == 0:
                self._mutex.lock()
                if self.serialEnabled:
                    self.updatePB(20)
                self._mutex.unlock()

(注意:如果您使用的是任何类型的 IDE 或调试器,并且遇到意外错误或崩溃,则诊断问题的第一步应始终是在标准控制台中测试代码。通常,IDE 或调试器本身可能是问题的原因,或者可能屏蔽来自 Python 或底层库(如 Qt)的错误消息。

我将所有浮点变量设置为 int 值,它有效

以前

<小时 />
var1 = 10.0
var2 = 26.0

<小时 />
var1 = 10
var2 = 26

最新更新