2012-05-08 11 views
2

私は読んだことのあるシリアルターミナルプログラム(ハイパーターミナル、TeraTermなど)のようにQTextEdit Boxを使って(とりわけ)PyQtアプリケーションを構築しようとしています。 PySerialのページからいくつかの例があります。私は受信データスレッドを正しく動作させることができたと思いますが、可能な限り効率的ではないかもしれません。PyQtを使ってスレッドを持つ端末

私の問題は、QTextEditボックスで最後に入力した文字をどのようにしてシリアル接続から送り出すのですか? QTextEditが発行するtextChangedシグナルを使用しようとしましたが、入力したすべてのものが送信され、それが受信します。メインのGUIクラスでeventFilterを設定しようとしましたが、別のファイルのシリアル関数に渡す方法を理解できません。私はeventFilterから放出されたシグナルを聞く別のスレッドを持っていますか?それ、どうやったら出来るの?これを行うよりエレガントな方法はありますか?

私はちょうどこれを克服することができたと確信して、ソリューションは簡単ですが、私はそれとやや苦労しています。適切なコードスニペット(完全なコードセットではありません)を添付して、誰かが私を正しい方向に向けることができます。誰かが、私がやっているスレッディングがより効率的なやり方でやり遂げられると思っているなら、それを私にも伝えてください!

誰もが提供できるお手伝いをありがとう!

メインファイル:

import sys 
from PyQt4 import QtGui 
from MainGUI import TestGUI 
from SerialClasses import * 
from SerialMiniterm import * 

class StartMainWindow(QtGui.QMainWindow):  
    def __init__(self, parent=None): 
     super(StartMainWindow, self).__init__(parent) 
     self.ui = TestGUI() 
     self.ui.setupUi(self)  
     self.ui.serialTextEditBox.installEventFilter(self) 

    def eventFilter(self, source, event): 
     if (event.type() == QtCore.QEvent.KeyPress and source is self.ui.serialTextEditBox): 
      # print some debug statements to console 
      if (event.key() == QtCore.Qt.Key_Tab): 
       print ('Tab pressed') 
      print ('key pressed: %s' % event.text()) 
      print ('code pressed: %d' % event.key()) 
      # do i emit a signal here? how do i catch it in thread? 
      self.emit(QtCore.SIGNAL('transmitSerialData(QString)'), event.key()) 
      return True 
     return QtGui.QTextEdit.eventFilter(self, source, event) 

    def serialConnectCallback(self): 
     self.miniterm = SerialMiniterm(self.ui, self.SerialSettings) 
     self.miniterm.start() 
     temp = self.SerialSettings.Port + 1 
     self.ui.serialLabel.setText("<font color = green>Serial Terminal Connected on COM%d" % temp) 

if __name__ == "__main__": 
    app = QtGui.QApplication(sys.argv) 
    app.setStyle("Cleanlooks") 
    myapp = StartMainWindow() 
    myapp.show() 
    sys.exit(app.exec_()) 

がSerialMiniterm.py:

import serial 
from PyQt4 import QtGui, QtCore 

def character(b): 
    return b 

class SerialMiniterm(object): 
    def __init__(self, ui, SerialSettings): 
     self.SerialSettings = SerialSettings 
     self.ui = ui 
     self.serial = serial.Serial(self.SerialSettings.Port, self.SerialSettings.BaudRate, parity=self.SerialSettings.Parity, rtscts=self.SerialSettings.RTS_CTS, xonxoff=self.SerialSettings.Xon_Xoff, timeout=1) 
     self.repr_mode = self.SerialSettings.RxMode 
     self.convert_outgoing = self.SerialSettings.NewlineMode 
     self.newline = NEWLINE_CONVERISON_MAP[self.convert_outgoing] 
     self.dtr_state = True 
     self.rts_state = True 
     self.break_state = False 

    def _start_reader(self): 
     """Start reader thread""" 
     self._reader_alive = True 
     self.receiver_thread = ReaderThread(self.alive, self._reader_alive, self.repr_mode, self.convert_outgoing, self.serial) 
     self.receiver_thread.connect(self.receiver_thread, QtCore.SIGNAL("updateSerialTextBox(QString)"), self.updateTextBox) 
     self.receiver_thread.start() 

    def _stop_reader(self): 
     """Stop reader thread only, wait for clean exit of thread""" 
     self._reader_alive = False 
     self.receiver_thread.join() 

    def updateTextBox(self, q): 
     self.ui.serialTextEditBox.insertPlainText(q) 
     self.ui.serialTextEditBox.moveCursor(QtGui.QTextCursor.End) 
     #print "got here with value %s..." % q 

    def start(self): 
     self.alive = True 
     self._start_reader() 
     # how do i handle transmitter thread? 

    def stop(self): 
     self.alive = False 

    def join(self, transmit_only=False): 
     self.transmitter_thread.join() 
     if not transmit_only: 
      self.receiver_thread.join() 

class ReaderThread(QtCore.QThread):  
    def __init__(self, alive, _reader_alive, repr_mode, convert_outgoing, serial, parent=None): 
     QtCore.QThread.__init__(self, parent) 
     self.alive = alive 
     self._reader_alive = _reader_alive 
     self.repr_mode = repr_mode 
     self.convert_outgoing = convert_outgoing 
     self.serial = serial 

    def __del__(self): 
     self.wait() 

    def run(self): 
     """loop and copy serial->console""" 
     while self.alive and self._reader_alive: 
      data = self.serial.read(self.serial.inWaiting()) 
      if data:       #check if not timeout 
       q = data 
       self.emit(QtCore.SIGNAL('updateSerialTextBox(QString)'), q) 

答えて

1

このような何か?

from PyQt4 import QtCore, QtGui 
app = QtGui.QApplication([]) 

class Terminal(QtGui.QPlainTextEdit): 
    def keyPressEvent(self, event): 
     print event.text() 
     return QtGui.QPlainTextEdit.keyPressEvent(self, event) 

term = Terminal() 
term.show() 
関連する問題