起初我只集中於新路,如何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
並不是真正的預期方式。 所以我仍然想知道如何讓我的問題中的第一個代碼按預期工作。 如果您對我的第一個代碼有什麼問題有一些想法,請讓我知道!
當我用構造函數參數'self'調用SerialData(QObject)的Parent構造函數時,Segmentation Fault似乎消失了 - 至少現在我不能重現它。 我仍然不明白的是,爲什麼插槽'updateData'似乎永遠不會收到信號。 – 0laf
如果我在'usingMoveToThread()'的'thread.start()'之前調用'serialc.readData()',那麼發出的信號到達'updateData'槽。另外,我得到一個警告:_不能創建一個父母的孩子,這是在不同的線程。 - - 這是有道理的。至少該信號似乎在線程啓動之前工作。 但是我仍然必須弄清楚它爲什麼不起作用:( – 0laf
這裏給大家看看這個問題的一些建議:儘可能遠離Python中的'QThread',它充滿了bug,完全沒用,因爲Python的GIL,我使用它在C++和Python中,並且我必須說,在Python中它是大量的問題,並且在我沒有問題的情況下一次都沒有工作過,在C++中,它是好的和可靠的。你需要真正的多線程,使用'multiprocessing''' QThread'可能聽起來很誘人,因爲通過信號和插槽可以輕鬆共享數據,但它不能很好地工作,並隨機崩潰你的程序。 –