Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Qt for Python
  4. PyQt5 front-end and python back-end
Forum Updated to NodeBB v4.3 + New Features

PyQt5 front-end and python back-end

Scheduled Pinned Locked Moved Unsolved Qt for Python
qt for pythonpython
4 Posts 2 Posters 1.7k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • Q Offline
    Q Offline
    QtFranchise
    wrote on last edited by
    #1

    Hi I just created a simple Serial Terminal App. Its UI is designed using Qt Designer and imported in the project using UIC module. Just wanted to know that the way I used PyQt5 with Python is he correct one any comments and input are welcome. Since Qt uses signals and slots for communication used QThread subclass that will generate necessary signal which is captured by the Event Loop and since I did not find a way to send back response (like button press, text change etc) used class instance and passed that to the respective member for further processing.

    It is working well for now. But, I need someone to look into the code and provide inputs on the same.

    main.py

    from PyQt5 import QtWidgets
    from gui import UI
    import sys
    
    
    if __name__ == '__main__':
        app = QtWidgets.QApplication(sys.argv)
        window = UI()
        window.show()
        sys.exit(app.exec_())
    

    serial_control.py

    from PyQt5.QtCore import QThread
    from PyQt5 import QtCore
    import serial
    import serial.tools.list_ports
    import time
    
    
    class SerialControl(QThread):
        status = QtCore.pyqtSignal(bool)
        received = QtCore.pyqtSignal(str)
    
        def __init__(self):
            super().__init__()
            self.VID = 0x2341
            self.PID = 0x3d
            self.serial = None
            self.input = ""
            self.output = ""
            self.connected = False
    
        def find_port(self):
            for port in serial.tools.list_ports.comports():
                if (port.vid == self.VID) and (port.pid == self.PID):
                    print("Port: ", port.device)
                    return port.device
            return None
    
        def run(self):
            while True:
                if not self.connected:
                    port = self.find_port()
                    if port:
                        try:
                            self.serial = serial.Serial(port, 115200, timeout=0.25)
                            if self.serial:
                                self.connected = True
                                print("Connected")
                                self.status.emit(True)
                        except serial.SerialException:
                            pass
                elif self.connected:
                    try:
                        if not self.serial.is_open:
                            self.serial.open()
                    except AttributeError:
                        pass
    
                    try:
                        if self.serial.in_waiting:
                            self.input = self.serial.readline().decode("utf-8")
                            print("Received: ", self.input)
                            self.received.emit(self.input)
                        elif self.output:
                            time.sleep(0.25)
                            self.serial.write(self.output.encode())
                            print("Sent: ", self.output)
                            self.output = ""
                    except OSError:
                        print("Disconnected")
                        self.connected = False
                        self.status.emit(False)
    
                time.sleep(0.25)
    
    

    gui.py

    from PyQt5 import QtWidgets, uic
    from serial_control import SerialControl
    
    
    class UI(QtWidgets.QMainWindow):
        def __init__(self):
            super(UI, self).__init__()
            self.terminal = SerialControl()
            self.setup_ui()
    
        def setup_ui(self):
            uic.loadUi('ui.ui', self)
            self.btn_send.clicked.connect(self.send)
            self.start_terminal()
    
        def start_terminal(self):
            self.terminal.status.connect(self.control_button)
            self.terminal.received.connect(self.receive)
            self.terminal.start()
    
        def control_button(self, state):
            self.btn_send.setEnabled(state)
    
        def send(self):
            self.terminal.output = self.lineEdit.text()
            self.lineEdit.setText('')
    
        def receive(self, msg):
            self.textEdit.setText(msg)
    
    

    ui.ui

    <?xml version="1.0" encoding="UTF-8"?>
    <ui version="4.0">
     <class>MainWindow</class>
     <widget class="QMainWindow" name="MainWindow">
      <property name="geometry">
       <rect>
        <x>0</x>
        <y>0</y>
        <width>715</width>
        <height>510</height>
       </rect>
      </property>
      <property name="windowTitle">
       <string>Serial Terminal</string>
      </property>
      <widget class="QWidget" name="centralwidget">
       <layout class="QVBoxLayout" name="verticalLayout_3">
        <item>
         <layout class="QVBoxLayout" name="verticalLayout" stretch="1,0,5">
          <item>
           <widget class="QWidget" name="horizontalWidget" native="true">
            <property name="sizePolicy">
             <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
              <horstretch>0</horstretch>
              <verstretch>0</verstretch>
             </sizepolicy>
            </property>
            <layout class="QHBoxLayout" name="horizontalLayout" stretch="1,0,0">
             <property name="spacing">
              <number>6</number>
             </property>
             <property name="leftMargin">
              <number>5</number>
             </property>
             <property name="topMargin">
              <number>5</number>
             </property>
             <property name="rightMargin">
              <number>5</number>
             </property>
             <property name="bottomMargin">
              <number>5</number>
             </property>
             <item>
              <widget class="QLineEdit" name="lineEdit"/>
             </item>
             <item>
              <spacer name="horizontalSpacer">
               <property name="orientation">
                <enum>Qt::Horizontal</enum>
               </property>
               <property name="sizeHint" stdset="0">
                <size>
                 <width>40</width>
                 <height>20</height>
                </size>
               </property>
              </spacer>
             </item>
             <item>
              <widget class="QPushButton" name="btn_send">
               <property name="enabled">
                <bool>false</bool>
               </property>
               <property name="text">
                <string>Send</string>
               </property>
              </widget>
             </item>
            </layout>
           </widget>
          </item>
          <item>
           <spacer name="verticalSpacer">
            <property name="orientation">
             <enum>Qt::Vertical</enum>
            </property>
            <property name="sizeType">
             <enum>QSizePolicy::Fixed</enum>
            </property>
            <property name="sizeHint" stdset="0">
             <size>
              <width>20</width>
              <height>10</height>
             </size>
            </property>
           </spacer>
          </item>
          <item>
           <widget class="QGroupBox" name="groupBox">
            <property name="title">
             <string>Received</string>
            </property>
            <layout class="QVBoxLayout" name="verticalLayout_2">
             <property name="spacing">
              <number>0</number>
             </property>
             <property name="leftMargin">
              <number>0</number>
             </property>
             <property name="topMargin">
              <number>0</number>
             </property>
             <property name="rightMargin">
              <number>0</number>
             </property>
             <property name="bottomMargin">
              <number>0</number>
             </property>
             <item>
              <widget class="QTextEdit" name="textEdit"/>
             </item>
            </layout>
           </widget>
          </item>
         </layout>
        </item>
       </layout>
      </widget>
      <widget class="QStatusBar" name="statusbar"/>
     </widget>
     <resources/>
     <connections/>
    </ui>
    
    1 Reply Last reply
    0
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Hi,

      Before analyzing your code deeper, why not use Qt's QSerialPort class that is asynchronous rather than adding threading to the mix ?

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      Q 1 Reply Last reply
      1
      • SGaistS SGaist

        Hi,

        Before analyzing your code deeper, why not use Qt's QSerialPort class that is asynchronous rather than adding threading to the mix ?

        Q Offline
        Q Offline
        QtFranchise
        wrote on last edited by
        #3

        @SGaist Yes that may be a choice. But I preferred pyserial because it did my work easy. Will consider QSerialPort when working next time. Any other inputs please.

        1 Reply Last reply
        0
        • SGaistS Offline
          SGaistS Offline
          SGaist
          Lifetime Qt Champion
          wrote on last edited by
          #4

          You should:

          • provide a clean way to quit your thread
          • use a cleaner setup/tear down for the opening and closing of your device
          • why all these sleep call ?

          Interested in AI ? www.idiap.ch
          Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

          1 Reply Last reply
          0

          • Login

          • Login or register to search.
          • First post
            Last post
          0
          • Categories
          • Recent
          • Tags
          • Popular
          • Users
          • Groups
          • Search
          • Get Qt Extensions
          • Unsolved