pythonpyqtqlabel

python Qlabel text is not updated as I expect


I have a question about Qlabel. Following is the example of code. While opertaiong the program, I want to show message that the system is operating. But somehow Qlabel message was not updated as I expected. “self.text_label.setText('reading file ......') “ area of following code. (this is not shown as expected)

And at the end Qlabel text was updated. “self.text_label.setText('opertaion finish') “ area
(this is shown as expected)

If there is any mistake or missing information, please advise.

import  os , sys, time
from PyQt5 import QtWidgets
from PyQt5.QtWidgets import (QMainWindow, QVBoxLayout,QHBoxLayout,
     QApplication,QPushButton,QWidget,QRadioButton,QLabel,QTextEdit)  
class Main(QMainWindow):
    def __init__(self):
        super().__init__()

        #overall layout
        layout = QVBoxLayout()
                
        # Pushbutton for excution         
        bt_layout = QtWidgets.QGridLayout()
        bt_layout.setContentsMargins(0,0,0,20)
        start_bt = QPushButton("start")
        start_bt.setStyleSheet("background-color:lightblue")        
        bt_layout.addWidget(start_bt)
        start_bt.clicked.connect(self.start)
        layout.addLayout(bt_layout)
 
        text_layout = QHBoxLayout()
        self.text_label = QLabel()
        self.text_label.setText('before operation') 
        text_layout.addWidget(self.text_label)                    
        layout.addLayout(text_layout)

        #overall layout        
        self.container = QWidget()
        self.container.setLayout(layout)
        self.setCentralWidget(self.container)               
        self.setGeometry(500, 100, 330, 200)
        self.show()
    
    def start(self):
        self.text_label.setText('reading file ......')   
        time.sleep(5)
            
        self.text_label.setText('opertaion finish')   
        self.text_label.setStyleSheet("background-color:#00FF00 ")        
        
# call the main() function.
if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = Main()
    sys.exit(app.exec_())

Solution

  • If all you want is to for the label to update in real time then you can use QTimer and it's singleShot class method to trigger the update once the pre-set amount of time has completely elapsed.

    For example you can call the QTimer.singleShot in your start method just after setting the label text to "reading file.......", and set the callback to another method that performs the rest of the label updates after 5 seconds.

    ...
    from PyQt5 import QtCore
    ...
    
    ...
    ...
    
        def start(self):
            self.text_label.setText('reading file ......')
            QtCore.QTimer().singleShot(5000, self.updateLabel)
    
        def updateLabel(self):
            self.text_label.setText('operation finish')
            self.text_label.setStyleSheet("background-color:#00FF00 ")
    
    

    This won't be of much help though if you actually are going to be opening a file that takes 5 seconds to read. If this is the case then you will likely want to perform that operation in a different thread and then pass the read data from the thread once it has finished reading it by connecting to a signal that sends the read data when it emits.

    For example:

    
    class ReadThread(QThread):
        fileRead = Signal(str)
    
        def __init__(self, filename):
            super().__init__()
            self.filename = filename
    
        def run(self):
            with open(self.filename) as file:
                data = file.read()
            self.fileRead.emit(data)
            
    
    class Main(QMainWindow):
        def __init__(self):
            super().__init__()
            ...
            ...
    
        def updateLabel(self, data):
            ... do something with data
            self.text_label.setText('operation finish')
            self.text_label.setStyleSheet("background-color:#00FF00 ")
    
    
        def start(self):
            self.text_label.setText('reading file ......')
            self.thread = ReadThread(filename)
            self.thread.fileRead.connect(self.updateLabel)
            self.thread.finished.connect(self.thread.deleteLater())
            self.thread.start()