PyQt - 在运行时创建 QLabel 并在之后更改文本

PyQt - Create QLabels at runtime and change text afterwards

我想在运行时动态创建 QLabel,然后更改文本。 我是这样做的:

def __init__(self, *args, **kwargs):
    QWidget.__init__(self, *args, **kwargs)
    self.counter = 0
    self.items = self.read_hosts()
    self.layout = QGridLayout()
    for item in self.items:
        self.item = QLabel(item, self)

        self.item.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        self.item.setAlignment(Qt.AlignCenter)
        self.item.setStyleSheet("QLabel {background-color: green;}")
        self.layout.addWidget(self.item,self.counter, 0)
        self.counter += 1
    self.setLayout(self.layout)
    self.startWorker()
    self.show()

def change_txt(self, lb, i):
     self.item.setText("{}".format(i))

这行不通。 我明白为什么它只会改变最后一个标签的文本。我在分配期间做错了什么。

如何完全可变地创建所有标签并随后更改文本?

我正在使用:

PyQT5 在 Windows 10

谢谢!

这是我的全部代码:

import sys
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
import os

class Worker(QObject):
    update = pyqtSignal(str,int)
    exception = pyqtSignal(str)

    def read_hosts(self):
        #try:
            file = open("hosts.ini", "r") 
            return file.readlines() 
        #except Exception as ex:
            #self.exception.emit(str(ex))

    def check_ping(self):
        #try:
            hosts = self.read_hosts()
            while True:
                for host in hosts:
                    print(host)
                    params = " -l 1000"
                    response = os.system("ping  " + host + params)
                    print("weiter")
                    self.update.emit(host, response)

        #except Exception as ex:
            #self.exception.emit(str(ex))

class Window(QWidget):
    def __init__(self, *args, **kwargs):
        QWidget.__init__(self, *args, **kwargs)

        self.counter = 0
        self.items = self.read_hosts()
        self.layout = QGridLayout()
        for item in self.items:
            self.item = QLabel(item, self)
            self.item.setObjectName("label" + str(self.counter))
            print("label" + str(self.counter))
            self.item.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
            self.item.setAlignment(Qt.AlignCenter)
            self.item.setStyleSheet("QLabel {background-color: green;}")
            self.layout.addWidget(self.item,self.counter, 0)
            self.counter += 1
        self.setLayout(self.layout)
        self.startWorker()
        self.show()

    def startWorker(self):
        self.thread = QThread() 
        self.obj = Worker()  
        self.thread = QThread() 
        self.obj.moveToThread(self.thread)
        self.obj.update.connect(self.onUpdate)
        self.obj.exception.connect(self.onException)
        self.thread.started.connect(self.obj.check_ping)
        self.thread.start()

    def read_hosts(self):
        #try:
            file = open("hosts.ini", "r") 
            return file.readlines() 
        #except Exception as ex:
            #self.exception.emit(str(ex))

    def onException(self, msg):
        QMessageBox.warning(self, "Eine Exception im Worker wurde geworfen: ", msg)

    def onUpdate(self, lb, i):
        label = lb
        self.label0.setText("{}".format(i))


app = QApplication(sys.argv)
win = Window()
sys.exit(app.exec_())

hosts.ini:

192.168.1.1
192.168.1.2
192.168.1.30

我在以下几个方面改进了您的代码:

  • 如果您的布局有一个列,则不必使用 QGridLayout,只需 QVBoxLayout

  • 每个 class 都有一个 read_hosts() 方法是一种浪费,所以我创建了一个独特的函数。

  • self.item 是不断被覆盖的 class 的属性,因此没有必要创建它们。

  • objectName应该是主机名,也就是IP,因为那是线程拥有的信息。

  • 要通过 objectName 查找标签,您可以使用 findChild()


import sys
import os

from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *

def read_hosts():
    file = open("hosts.ini", "r") 
    return file.readlines() 

class Worker(QObject):
    update = pyqtSignal(str, int)
    exception = pyqtSignal(str)

    def check_ping(self):
        hosts = read_hosts()
        while True:
            for host in hosts:
                params = "-l 1000"
                response = os.system("ping  {} {}".format(host, params))
                print("weiter")
                self.update.emit(host, response)

class Window(QWidget):
    def __init__(self, *args, **kwargs):
        QWidget.__init__(self, *args, **kwargs)
        self.layout = QVBoxLayout(self)

        hosts = read_hosts()
        for host in hosts:
            label = QLabel(host)
            label.setObjectName(host)
            label.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
            label.setAlignment(Qt.AlignCenter)
            label.setStyleSheet("QLabel {background-color: green;}")
            self.layout.addWidget(label)
        self.startWorker()

    def startWorker(self):
        self.thread = QThread() 
        self.obj = Worker()  
        self.thread = QThread() 
        self.obj.moveToThread(self.thread)
        self.obj.update.connect(self.onUpdate)
        self.obj.exception.connect(self.onException)
        self.thread.started.connect(self.obj.check_ping)
        self.thread.start()

    def onException(self, msg):
        QMessageBox.warning(self, "Eine Exception im Worker wurde geworfen: ", msg)

    def onUpdate(self, host, value):
        label = self.findChild(QLabel, host)
        label.setText("{}".format(value))

if __name__ == '__main__':
    app = QApplication(sys.argv)
    win = Window()
    win.show()
    sys.exit(app.exec_())