Home > Software design >  Update a label while inside a loop. PyQT
Update a label while inside a loop. PyQT

Time:04-06

So I have a TCP server, which just echo's back whatever I send to it. And I have a GUI client which sends the stuff. But since I have to maintain the connection I can't seem to get the label I want to change once in a certain amount of time, I was trying to use signals but I seem to be doing something terribly wrong since the application freezes as soon as I connect to the server on button click. Here's what I got so far. Also, eventually I need to get 2 servers to echo to the client the information, and I guess that will pose even more of a problem and I will have to use multithreading.

from PyQt5 import QtWidgets, QtCore
from PyQt5.QtWidgets import *
import sys
import socket
import time

class MyClient(QMainWindow):
    updateText = QtCore.pyqtSignal(str)

    def __init__(self):
        super(MyClient, self).__init__()
        self.setGeometry(200, 200, 300, 300)
        self.setWindowTitle("Krs")
        self.initSocket()
        self.initUI()

    def initSocket(self):
        self.ClientSocket = socket.socket()
        self.s1 = ['127.0.0.1', 1233]

    def initUI(self):
        self.label = QLabel(self)
        self.label.setText("nuthin")
        self.label.move(50,50)
        self.updateText.connect(self.label.setText)

        self.b1 = QtWidgets.QPushButton(self)
        self.b1.setText("S1")
        self.b1.clicked.connect(lambda: self.conntoS(self.s1))

    def conntoS(self, addrs):
        self.ClientSocket.connect((addrs[0], addrs[1]))
        while True:
            time.sleep(1)
            self.ClientSocket.send(str.encode("Anything"))
            Response = self.ClientSocket.recv(1024)
            self.upd(Response.decode('utf-8'))

    @QtCore.pyqtSlot()
    def upd(self, txt):
        self.updateText.emit(txt)


def window():

    app = QApplication(sys.argv)
    win = MyClient()
    win.show()
    sys.exit(app.exec_())

window()

CodePudding user response:

You should not run while True loop with time.sleep() inside gui thread, because it freezes the eventloop: while it run, widgets have no chance to recieve any events, and no chance to handle them - no repaints, no signals can be emited, no handlers invoked. All long operations should be performed outside of the gui thread.

You need to create worker, move your blocking function to it and run it separate QThread, or in your case you can use QTcpSocket asyncronous signal-slot api.

Example of the right way to use QThread in PyQt?

Python QTcpSocket and QTcpServer receiving message

  • Related