在循环内更新标签。 PyQT

Update a label while inside a loop. PyQT

所以我有一个 TCP 服务器,无论我发送给它什么,它都会回显。我有一个 GUI 客户端可以发送这些东西。但是由于我必须保持连接,我似乎无法在一定时间内获得我想要更改一次的标签,我试图使用信号但我似乎做错了一些事情,因为应用程序很快就会冻结当我点击按钮连接到服务器时。这是我到目前为止得到的。此外,最终我需要让 2 个服务器向客户端回显信息,我想这会带来更多问题,我将不得不使用多线程。

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()

你不应该 运行 while True 在 gui 线程中使用 time.sleep() 循环,因为它冻结了事件循环:当它 运行 时,小部件没有机会接收任何事件,并且没有机会处理它们 - 没有重绘,没有信号可以发出,没有处理程序被调用。所有长操作都应该在 gui 线程之外执行。

您需要创建 worker,将阻塞函数移至它并 运行 将其分开 QThread,或者在您的情况下,您可以使用 QTcpSocket 异步 signal-slot api.

Example of the right way to use QThread in PyQt?

Python QTcpSocket and QTcpServer receiving message