2013-08-22 51 views
4

當談到GUI編程時,我幾乎是一個初學者。 我使用QT與python綁定(PyQT4)結合使用。在PyQT中使用QThread進行串行通信(w。pyserial)

我所試圖做的事:

  • 建立一個QThread從&寫有 pyserial讀串行端口。
  • 主應用程序應該能夠通過 信號發送新的串行數據到正在運行的QThread。並用信號從 QThread接收串行數據。

我開始基於此代碼(Link)自己的測試實現。 在此之前,我閱讀了有關QThread的基本知識,並嘗試瞭解它們是如何使用的。 下面的測試代碼就是我想到的。我對不起,我試圖保持它minmal, 但它仍然是75行的代碼:

​​

我的問題:

  • 在測試代碼從SerialCon物體發出的信號(其中 已被移至QThread)似乎沒有被 對應的槽接收(在MyGui,updateData中)

  • 運行測試代碼遲早會導致Segmentation fault (core dumped)。這讓我相信我錯過了一些重要的比特。

這是什麼原因造成的?

也許我採取了一個完全錯誤的方法? - 所以如果你有一個更好的想法如何實現這一點,我會非常感激聽到它!

非常感謝!

+0

當我用構造函數參數'self'調用SerialData(QObject)的Parent構造函數時,Segmentation Fault似乎消失了 - 至少現在我不能重現它。 我仍然不明白的是,爲什麼插槽'updateData'似乎永遠不會收到信號。 – 0laf

+0

如果我在'usingMoveToThread()'的'thread.start()'之前調用'serialc.readData()',那麼發出的信號到達'updateData'槽。另外,我得到一個警告:_不能創建一個父母的孩子,這是在不同的線程。 - - 這是有道理的。至少該信號似乎在線程啓動之前工作。 但是我仍然必須弄清楚它爲什麼不起作用:( – 0laf

+1

這裏給大家看看這個問題的一些建議:儘可能遠離Python中的'QThread',它充滿了bug,完全沒用,因爲Python的GIL,我使用它在C++和Python中,並且我必須說,在Python中它是大量的問題,並且在我沒有問題的情況下一次都沒有工作過,在C++中,它是好的和可靠的。你需要真正的多線程,使用'multiprocessing''' QThread'可能聽起來很誘人,因爲通過信號和插槽可以輕鬆共享數據,但它不能很好地工作,並隨機崩潰你的程序。 –

回答

0

起初我只集中於新路,如何QThreads應該因爲QT4 (Link), 通過創建一個QObject,然後調用moveToThread(),很像我的第一個代碼示例中(至少使用這就是我如何理解它)。 但是我只是想不通,爲什麼我無法將信號從 QThread傳遞到主應用程序。

由於我真的需要一個快速解決我的問題,我拼命嘗試varius的東西。 下面是一些第二個代碼,這似乎工作,我想要的方式:

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並不是真正的預期方式。 所以我仍然想知道如何讓我的問題中的第一個代碼按預期工作。 如果您對我的第一個代碼有什麼問題有一些想法,請讓我知道!

相關問題