import sys from threading import Thread from time import sleep from PyQt5 import QtCore, QtWidgets from PyQt5.QtCore import pyqtSlot from PyQt5.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QLabel class Ui_MainWindow(object): def setupUi(self, MainWindow): MainWindow.setObjectName("MainWindow") MainWindow.resize(445, 333) self.centralwidget = QtWidgets.QWidget(MainWindow) self.centralwidget.setObjectName("centralwidget") self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.centralwidget) self.verticalLayout_2.setObjectName("verticalLayout_2") self.verticalLayout = QtWidgets.QVBoxLayout() self.verticalLayout.setObjectName("verticalLayout") self.scrollArea = QtWidgets.QScrollArea(self.centralwidget) self.scrollArea.setWidgetResizable(False) self.scrollArea.setAlignment(QtCore.Qt.AlignLeading | QtCore.Qt.AlignLeft | QtCore.Qt.AlignTop) self.scrollArea.setObjectName("scrollArea") self.scrollAreaWidgetContents = QtWidgets.QWidget() self.scrollAreaWidgetContents.setGeometry(QtCore.QRect(0, 0, 423, 256)) self.scrollAreaWidgetContents.setObjectName("scrollAreaWidgetContents") self.scrollArea.setWidget(self.scrollAreaWidgetContents) self.verticalLayout.addWidget(self.scrollArea) self.verticalLayout_2.addLayout(self.verticalLayout) self.pushButton = QtWidgets.QPushButton(self.centralwidget) self.pushButton.setObjectName("pushButton") self.verticalLayout_2.addWidget(self.pushButton) self.lineEdit = QtWidgets.QLineEdit(self.centralwidget) self.lineEdit.setObjectName("lineEdit") self.verticalLayout_2.addWidget(self.lineEdit) MainWindow.setCentralWidget(self.centralwidget) self.retranslateUi(MainWindow) self.pushButton.clicked.connect(MainWindow.start_thread) self.lineEdit.returnPressed.connect(MainWindow.send_message) QtCore.QMetaObject.connectSlotsByName(MainWindow) def retranslateUi(self, MainWindow): _translate = QtCore.QCoreApplication.translate MainWindow.setWindowTitle(_translate("MainWindow", "Test")) self.pushButton.setText(_translate("MainWindow", "start thread")) class Test(QMainWindow, Ui_MainWindow): def __init__(self, parent=None): super().__init__(parent) self.setupUi(self) layout = QVBoxLayout() layout.addStretch(1) self.scrollAreaWidgetContents.setLayout(layout) @pyqtSlot() def start_thread(self): start(self.incoming_message, err_callback) @pyqtSlot() def send_message(self): self.write_message(self.lineEdit.text(), "lightblue") self.lineEdit.setText("") def write_message(self, message, color): print(f"received {message}") label = QLabel(self.scrollAreaWidgetContents) label.setText(message) label.setStyleSheet(f"background-color:{color}") self.scrollAreaWidgetContents.layout().addWidget(label) def incoming_message(self, message): print(f"passed {message}") self.write_message(message, "khaki") def start(msg_callback, error_callback): Thread(target=listen, args=(msg_callback, error_callback), daemon=True).start() def listen(msg_callback, error_callback): while True: try: sleep(5.0) print("Ping !") msg_callback("Ping !") except: error_callback("error") def err_callback(message): print(message) if __name__ == '__main__': app = QApplication(sys.argv) test = Test() test.show() app.exec_()