0

In my script, I send data by serial connection. Whenever something is executed in my script, there is a timestamp displayed in the console. When I start to send the data it should say "Send data..."

and when it is finished

"Data sent..."

My script takes the timestamp from the beginning. But unfortunately, it is only output at the end together with Data sent... That means "Send Data..." and "Data sent..." appear at the same time by the end of sending process.

Now to my question: Why is the timestamp, which is printed BEFORE the start of the serial communication, only printed afterward?

Below is a mini example with GUI. I work with PyQt5.

Script:

#SCRIPT
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QApplication
from PyQt5.QtCore import Qt
import sys
import GUI
import datetime
import serial

ser = serial.Serial(
        port='/dev/serial0',
        baudrate = 57600,
        timeout=1
        )
        
class my_class(QtWidgets.QMainWindow, GUI.Ui_MainWindow):
    def __init__(self, parent=None):
        super(my_class, self).__init__(parent)
        self.setupUi(self)
        self.pushButton.clicked.connect(self.push_button_pressed)

    def push_button_pressed(self):
        self.sendData()
        
    def sendData(self):
        self.Console.append(str(datetime.datetime.now()) + " Send Data...")
        data_to_send = []
        for i in range(10000):
            data_to_send.append(i)
        print(data_to_send)
        ser.write(str(data_to_send).encode('utf-8'))
        self.Console.append(str(datetime.datetime.now()) + " Data sent...")


def main():
    app = QApplication(sys.argv)
    form = my_class()
    form.show()
    app.exec_()
    
    
if __name__ == '__main__':
    main()

GUI:

from PyQt5 import QtCore, QtGui, QtWidgets


class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(238, 191)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.pushButton = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton.setGeometry(QtCore.QRect(80, 120, 91, 30))
        self.pushButton.setObjectName("pushButton")
        self.Console = QtWidgets.QTextEdit(self.centralwidget)
        self.Console.setGeometry(QtCore.QRect(10, 10, 221, 101))
        self.Console.setObjectName("Console")
        MainWindow.setCentralWidget(self.centralwidget)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.pushButton.setText(_translate("MainWindow", "PushButton"))
Gert Arnold
  • 105,341
  • 31
  • 202
  • 291
AndrewFFL
  • 37
  • 5
  • 1
    I don't know Qt very thoroughly but it runs an event loop in the main and usually the repaint is handled by this loop but the repaint can't be done while the main thread is blocked by the execution of `sendData`. – Michael Butscher Apr 29 '23 at 10:18
  • [Use PyQt's QThread to Prevent Freezing GUIs](https://realpython.com/python-pyqt-qthread/). – ekhumoro Apr 29 '23 at 11:01

1 Answers1

0

It's because sendData() is executed in the main GUI thread. While the function is running the GUI isn't being updated. You should setup sendData() in a QThread and send the output via signals to the console.

mahkitah
  • 562
  • 1
  • 6
  • 19