PYQT5张标签使用循环文本

发布于 2025-02-09 23:18:11 字数 1045 浏览 0 评论 0 原文

代码从错误中很干净,但是运行程序何时会冻结 该程序使用按钮的倒计时开始倒计时 下面的图片设置了布局 在此处输入图像说明

probelm正在使用循环来更改标签文本,并使程序变得冻结

from time import sleep
import PyQt5.QtWidgets as Qtw


class MainWindow(Qtw.QWidget):

    def __init__(self):
        super().__init__()

        self.setLayout(Qtw.QVBoxLayout())
        
        pushButton = Qtw.QPushButton("start",clicked = lambda: setting_label())
        self.layout().addWidget(pushButton)


        my_label = Qtw.QLabel("00:00:00")
        self.layout().addWidget(my_label)
        

        self.show()
        def setting_label():
            t = 1200
            while t:
            
                h  = t // 3600
                m  = t // 60
                s  = t % 60
                timer = "{:02d}:{:02d}:{:02d}".format(h,m,s)
                my_label.setText(timer)
                sleep(1)
                t -= 1


   

app = Qtw.QApplication([])
window = MainWindow()
    
app.exec_()

code it's clean from bugs but when is running program will freezing
the program its countdown using button to start the countdown
the picture below discripe the layout
enter image description here

the probelm is im using loop to changing label text and that make program freezed

from time import sleep
import PyQt5.QtWidgets as Qtw


class MainWindow(Qtw.QWidget):

    def __init__(self):
        super().__init__()

        self.setLayout(Qtw.QVBoxLayout())
        
        pushButton = Qtw.QPushButton("start",clicked = lambda: setting_label())
        self.layout().addWidget(pushButton)


        my_label = Qtw.QLabel("00:00:00")
        self.layout().addWidget(my_label)
        

        self.show()
        def setting_label():
            t = 1200
            while t:
            
                h  = t // 3600
                m  = t // 60
                s  = t % 60
                timer = "{:02d}:{:02d}:{:02d}".format(h,m,s)
                my_label.setText(timer)
                sleep(1)
                t -= 1


   

app = Qtw.QApplication([])
window = MainWindow()
    
app.exec_()

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

扎心 2025-02-16 23:18:11

代码写在OP中的方式,它并没有真正被卡住或冻结。但是,显示显示未能更新。您可以通过尝试强迫QT使用 app.processevents()来更新GUI来解决此问题。将其放入 setter_label 函数之后:

self.my_label.setText(timer)
app.processEvents()

使用 app.processevents()的首选方式

通常会灰心。制作倒数计时器的另一种方法是使用a qtimer 。设置所有信号和插槽时,还有更多的开销。但这可能非常强大。这是一个例子

from time import sleep
import PyQt5.QtWidgets as Qtw
from PyQt5.QtCore import QTimer

class MainWindow(Qtw.QWidget):

    def __init__(self):
        super().__init__()

        self.setLayout(Qtw.QVBoxLayout())

        pushButton = Qtw.QPushButton("start",clicked = self.start_countdown)
        self.layout().addWidget(pushButton)

        self.my_label = Qtw.QLabel("00:00:00")
        self.layout().addWidget(self.my_label)

        self.timer = QTimer()        # create a new QTimer instance
        self.timer.setInterval(1000) # make it fire every 1000 msec
        self.t = 1200
        self.timer.timeout.connect(self.setting_label) # connect the timeout signal to self.setting_label

        self.show()

    def start_countdown(self):
        self.t = 1200
        self.timer.start()

    def setting_label(self):

        if self.t == 0:
            self.timer.stop()
            print('timer stopped')

        h  = self.t // 3600
        m  = self.t // 60
        s  = self.t % 60
        timer = "{:02d}:{:02d}:{:02d}".format(h,m,s)
        self.my_label.setText(timer)
        self.t -= 1

app = Qtw.QApplication([])
window = MainWindow()

app.exec_()

The way the code is written in the OP, it doesn't really get stuck or frozen. But rather, the display fails to update. You can get around this by trying to force Qt to update the GUI with app.processEvents(). Put it in your setting_label function after the setText():

self.my_label.setText(timer)
app.processEvents()

The Preferred Way

Using app.processEvents() a lot is usually discouraged. Another way to make a countdown timer is to use a QTimer. There is a little more overhead in setting up all of the signals and slots. But it can be very powerful. Here is an example

from time import sleep
import PyQt5.QtWidgets as Qtw
from PyQt5.QtCore import QTimer

class MainWindow(Qtw.QWidget):

    def __init__(self):
        super().__init__()

        self.setLayout(Qtw.QVBoxLayout())

        pushButton = Qtw.QPushButton("start",clicked = self.start_countdown)
        self.layout().addWidget(pushButton)

        self.my_label = Qtw.QLabel("00:00:00")
        self.layout().addWidget(self.my_label)

        self.timer = QTimer()        # create a new QTimer instance
        self.timer.setInterval(1000) # make it fire every 1000 msec
        self.t = 1200
        self.timer.timeout.connect(self.setting_label) # connect the timeout signal to self.setting_label

        self.show()

    def start_countdown(self):
        self.t = 1200
        self.timer.start()

    def setting_label(self):

        if self.t == 0:
            self.timer.stop()
            print('timer stopped')

        h  = self.t // 3600
        m  = self.t // 60
        s  = self.t % 60
        timer = "{:02d}:{:02d}:{:02d}".format(h,m,s)
        self.my_label.setText(timer)
        self.t -= 1

app = Qtw.QApplication([])
window = MainWindow()

app.exec_()
最初的梦 2025-02-16 23:18:11

编辑:此解决方案适用于OP,但其他人指出,使用螺纹进行此操作可能会导致意外行为,崩溃等。因此,最好使用其他方法进行此操作(例如:

答案接收输入)。您可以通过将函数移动到这样的线程来解决此问题:

import threading
from time import sleep

import PyQt5.QtWidgets as Qtw


class MainWindow(Qtw.QWidget):
    def __init__(self):
        super().__init__()

        self.setLayout(Qtw.QVBoxLayout())

        def setting_label():
            t = 1200
            while t:
                h  = t // 3600
                m  = t // 60
                s  = t % 60
                timer = "{:02d}:{:02d}:{:02d}".format(h,m,s)
                my_label.setText(timer)
                sleep(1)
                t -= 1
        
        pushButton = Qtw.QPushButton(
            "start",
            clicked=lambda: thread.Thread(target=setting_label).start()
        )
        self.layout().addWidget(pushButton)

        my_label = Qtw.QLabel("00:00:00")
        self.layout().addWidget(my_label)

        self.show()


app = Qtw.QApplication([])
window = MainWindow()
    
app.exec_()

Edit: This solution works for the OP, but others have pointed out that doing this using threading can cause unexpected behavior, crashes, etc. so it's better to do this using other methods (for example: this answer)

The interface freezes because the while loop you use to change the label blocks the event loop of the app (i.e. receiving inputs). You can fix this by moving the function to a thread like this:

import threading
from time import sleep

import PyQt5.QtWidgets as Qtw


class MainWindow(Qtw.QWidget):
    def __init__(self):
        super().__init__()

        self.setLayout(Qtw.QVBoxLayout())

        def setting_label():
            t = 1200
            while t:
                h  = t // 3600
                m  = t // 60
                s  = t % 60
                timer = "{:02d}:{:02d}:{:02d}".format(h,m,s)
                my_label.setText(timer)
                sleep(1)
                t -= 1
        
        pushButton = Qtw.QPushButton(
            "start",
            clicked=lambda: thread.Thread(target=setting_label).start()
        )
        self.layout().addWidget(pushButton)

        my_label = Qtw.QLabel("00:00:00")
        self.layout().addWidget(my_label)

        self.show()


app = Qtw.QApplication([])
window = MainWindow()
    
app.exec_()
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文