使用 PyQt 和信号在 qt5serialport.dll 中获取段错误
Posted
技术标签:
【中文标题】使用 PyQt 和信号在 qt5serialport.dll 中获取段错误【英文标题】:Getting segfault in qt5serialport.dll with PyQt and signals 【发布时间】:2013-12-06 09:18:28 【问题描述】:我目前正在努力解决在 Windows XP SP3、Python 3.3.3 和 PyQt5 5.1.1 中使用 QSerialPort 并发出信号时遇到的奇怪段错误。
我真的很想知道这是否也发生在带有 C++ 的纯 Qt 中,但是我的 C++ 很糟糕,而且我没有设置正在运行的工具链。
最小的示例代码(抱歉,无法简化更多):
#!/usr/bin/python
import sys
from PyQt5.QtWidgets import QWidget, QApplication, QPushButton
from PyQt5.QtCore import QObject, pyqtSlot, QIODevice, pyqtSignal
from PyQt5.QtSerialPort import QSerialPort
PORT = 'COM59'
class DVIFlasher(QObject):
ser = None
flash_done = pyqtSignal(int, int)
def __init__(self):
super(DVIFlasher, self).__init__()
self.ser = QSerialPort(PORT)
self.ser.readyRead.connect(self.read)
def flash(self):
print(self.ser.open(QIODevice.ReadWrite))
self.ser.setBaudRate(115200)
def read(self):
print("Got data")
self.ser.close()
self.flash_done.emit(0, 0)
class Widget(QWidget):
def __init__(self):
super(Widget, self).__init__()
self.btn = QPushButton("Start", self)
self.flasher = DVIFlasher()
self.btn.clicked.connect(self.flasher.flash)
self.resize(self.btn.sizeHint())
if __name__ == '__main__':
app = QApplication(sys.argv)
win = Widget()
win.show()
sys.exit(app.exec_())
当我运行它并通过串行端口接收一个字节时,我在 qt5serialport.dll 中得到一个“访问冲突”(又名 segfault)。有时在第一次单击“开始”时会发生这种情况,有时会在第二次单击“开始”后发生。
到目前为止我观察到的一些事情:
信号需要有一个 bool/int 作为第一个参数,以及其他一些参数——否则它似乎不会触发。
当我发出信号之前端口已关闭(self.ser.close()
),它似乎没有触发。
在 Linux(Archlinux、Python 3.3.2、PyQt 5.1.1)上我无法重现此问题,但在第二次启动后,我总是收到 QSocketNotifier: Invalid socket specified
。
什么给了?难道我做错了什么?或者这是某个地方的 [Py]Qt 中的错误?
【问题讨论】:
不知道您是否解决了这个问题?如果没有,您能否提供包含调试符号的崩溃回溯? @LaszloPapp 我在发出信号后通过ser.close()
解决了这个问题。这里有人提到它可能是一个特定的 Qt 错误(而且看起来非常相似),但他的评论现在已经消失了......我不知道如何安装带有调试符号的 Qt/PyQt 并在 Windows 下获得跟踪,但我怀疑这不会太容易......
【参考方案1】:
你面对的是this bug。这是一个相对古老的问题并且众所周知。如果幸运的话,它可以在 5.2.1 中修复。您在 readyRead
信号处理程序中不调用 ser.close()
的解决方法看起来很合理。
希望,这会有所帮助。
【讨论】:
我确实在我的信号处理程序中调用ser.close()
,就在最后,这似乎有效。
@TheCompiler:请不要那样做。它目前具有未定义的行为,主要被识别为崩溃。
你说得对,经过一些重构,我现在得到“... .exe funktioniert nicht mehr”(字面意思是“不再工作”,但不确定英文信息是什么)。但是当我在插槽中设置一个标志并使用我的 MainWindow 中的 QTimer 关闭串行端口时,会发生同样的事情!目前没有时间收集更多信息,但会在假期后尝试。
@TheCompiler:好的,好好休息。
没关系——它确实与 MainWindow 中的 QTimer 一起工作,我只是忘了实际从插槽中删除 ser.close()
。以上是关于使用 PyQt 和信号在 qt5serialport.dll 中获取段错误的主要内容,如果未能解决你的问题,请参考以下文章