PyQt - создайте QLabels во время выполнения и измените текст впоследствии - PullRequest
0 голосов
/ 27 мая 2018

Я хочу динамически создавать QLabels во время выполнения и впоследствии изменять текст.Я сделал это так:

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

1 Ответ

0 голосов
/ 27 мая 2018

Я улучшил ваш код в следующих аспектах:

  • Если в вашем макете есть столбец, нет необходимости использовать QGridLayout, просто QVBoxLayout.

  • Наличие метода read_hosts() для каждого класса является пустой тратой, поэтому я создал уникальную функцию.

  • self.item является атрибутомкласс, который постоянно перезаписывается, поэтому создавать его нет необходимости.

  • 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_())
...