[英]Using a QThread in PyQT for serial communication (w. pyserial)
在 GUI 編程方面,我幾乎是初學者。 我將 QT 與 python 綁定(PyQT4)結合使用。
我正在嘗試做的事情:
QThread
以讀取和寫入串行端口。QThread
發出新的串行數據。 並通過信號從QThread
接收串行數據。 我基於此代碼 ( Link ) 開始了我自己的測試實現。 在此之前,我閱讀了有關QThread
的基礎知識,並試圖了解它們的用途。 下面的測試代碼是我想出來的。 對不起,我盡量保持最小,但它仍然是 75 行代碼:
from PyQt4 import QtCore, QtGui
import time
import sys
class SerialData(QtCore.QObject):
def __init__(self, message):
super(SerialData, self).__init__()
self.__m = message
def getMsg(self):
return self.__m
class SerialCon(QtCore.QObject):
finished = QtCore.pyqtSignal()
received = QtCore.pyqtSignal(SerialData)
def init(self):
super(SerialCon, self).__init__()
# TODO setup serial connection:
# setting up a timer to check periodically for new received serial data
self.timer = QtCore.QTimer()
self.timer.setInterval(400)
self.timer.timeout.connect(self.readData)
self.timer.start(200)
# self.finished.emit()
def readData(self):
self.received.emit(SerialData("New serial data!"))
print "-> serial.readLine() ..."
@QtCore.pyqtSlot(SerialData)
def writeData(self, data):
print "-> serial.write(), ", data.getMsg()
class MyGui(QtGui.QWidget):
serialWrite = QtCore.pyqtSignal(SerialData)
def __init__(self):
super(MyGui, self).__init__()
self.initUI()
def initUI(self):
bSend = QtGui.QPushButton("Send",self)
bSend.clicked.connect(self.sendData)
self.show()
@QtCore.pyqtSlot(SerialData)
def updateData(self, data):
print "Gui:", data.getMsg()
def sendData(self, pressed):
data = SerialData("Send me!")
self.serialWrite.emit(data)
def usingMoveToThread():
app = QtGui.QApplication(sys.argv)
guui = MyGui()
thread = QtCore.QThread()
serialc = SerialCon()
serialc.moveToThread(thread)
# connecting signals to slots
serialc.finished.connect(thread.quit)
guui.serialWrite.connect(serialc.writeData)
serialc.received.connect(guui.updateData)
thread.started.connect(serialc.init)
thread.finished.connect(app.exit)
thread.start()
sys.exit(app.exec_())
if __name__ == "__main__":
usingMoveToThread()
我的問題:
在測試代碼中,從SerialCon
對象(已移動到QThread
)發出的信號似乎沒有被相應的插槽接收(在MyGui
, updateData
)
運行的測試代碼遲早會導致Segmentation fault (core dumped)
。 這讓我相信我錯過了一些重要的部分。
什么可能導致這種情況?
也許我采取了完全錯誤的方法? - 所以如果你有更好的想法如何實現這一點,我會很感激聽到它!
非常感謝!
起初我只關注新方式,從 QT4 ( Link ) 起應該如何使用QThreads
,通過創建一個QObject
,然后調用moveToThread()
,就像在我的第一個代碼示例中一樣(至少我是這樣理解的) )。 但是我就是想不通,為什么我不能將信號從QThread
傳遞到主應用程序。
由於我真的需要快速解決我的問題,我拼命嘗試各種事情。 這是第二個代碼,它似乎按我想要的方式工作:
from PyQt4 import QtCore, QtGui
import time
import sys
import math
class SerialCon(QtCore.QThread):
received = QtCore.pyqtSignal(object)
def __init__(self, parent=None):
QtCore.QThread.__init__(self)
# specify thread context for signals and slots:
# test: comment following line, and run again
self.moveToThread(self)
# timer:
self.timer = QtCore.QTimer()
self.timer.moveToThread(self)
self.timer.setInterval(800)
self.timer.timeout.connect(self.readData)
def run(self):
self.timer.start()
#start eventloop
self.exec_()
def readData(self):
# keeping the thread busy
# figure out if the GUI remains responsive (should be running on a different thread)
result = []
for i in range(1,1000000):
result.append(math.pow(i,0.2)*math.pow(i,0.1)*math.pow(i,0.3))
#
self.received.emit("New serial data!")
@QtCore.pyqtSlot(object)
def writeData(self, data):
#print(self.currentThreadId())
print(data)
class MyGui(QtGui.QWidget):
serialWrite = QtCore.pyqtSignal(object)
def __init__(self, app, parent=None):
self.app = app
super(MyGui, self).__init__(parent)
self.initUI()
def initUI(self):
self.bSend = QtGui.QPushButton("Send",self)
self.bSend.clicked.connect(self.sendData)
self.show()
def closeEvent(self, event):
print("Close.")
self.serialc.quit();
@QtCore.pyqtSlot(object)
def updateData(self, data):
print(data)
def sendData(self, pressed):
self.serialWrite.emit("Send Me! Please?")
def usingMoveToThread(self):
self.serialc = SerialCon()
# binding signals:
self.serialc.received.connect(self.updateData)
self.serialWrite.connect(self.serialc.writeData)
# start thread
self.serialc.start()
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
guui = MyGui(app)
guui.usingMoveToThread()
sys.exit(app.exec_())
我現在認為這是一種解決方法,但它並沒有真正回答我的問題。 另外,正如之前鏈接的 QT 博客條目中提到的,這並不是使用QThread
真正預期方式。 所以我仍然想知道如何讓我的問題中的第一個代碼按預期工作。 如果您對我的第一個代碼有什么問題有一些想法,請告訴我!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.