5

GUIプログラミングに関しては、私はほとんど初心者です。QT を Python バインディング (PyQT4) と組み合わせて使用​​しています。

私がやろうとしていること:

  • QThreadpyserialを使用してシリアルポートから読み書きするように設定します。
  • メイン アプリケーションは、実行中の へのシグナルを介して新しいシリアル データを送信できる必要がありますQThread。信号でからシリアル データを受信し QThreadます。

このコード ( Link )に基づいて、独自のテスト実装を開始しました。これに先立って、s の基本を読み、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が、対応するスロット ( MyGuiupdateData)で受信されないようです。

  • 遅かれ早かれ、実行中のテスト コードは常にSegmentation fault (core dumped). これは、私がいくつかの重要なビットを逃したと信じさせます.

何が原因でしょうか?

多分私は完全に間違ったアプローチを取っていますか?- それで、これを達成するためのより良いアイデアがあれば、それについて聞いてとても感謝しています!

どうもありがとう!

4

1 に答える 1

1

最初は、最初のコードサンプルとほとんど同じように、 を作成してから を呼び出すことによってQThreads、 QT4 ( Link ) 以降の使用方法にのみ焦点を当てていました(少なくともそれが私が理解した方法です)。しかし、なぜメインアプリケーションに信号を渡すことができなかったのか、私にはわかりませんでした 。QObjectmoveToThread()QThread

問題を早急に解決する必要があったため、必死にさまざまなことを試しました。これは私が望んでいたように動作するように見えるいくつかの2番目のコードです:

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. そのため、質問の最初のコードを期待どおりに機能させる方法をまだ考えています。私の最初のコードの何が問題なのかについて何か考えがあれば、私に知らせてください!

于 2013-08-23T12:01:45.520 に答える