PyQT:如何显示按下按钮后经过的时间

问题描述 投票:0回答:1

在这个简单的例子中我想要:

  • 一个开始执行 2 秒工作的按钮
  • 显示工作已运行多长时间的标签

当我运行我的文件时,它工作正常,但显示:

QObject::killTimer: Timers cannot be stopped from another thread

我是 PyQT 新手,我不知道如何解决这个问题。

使用

threading.Thread
是否有意义,或者我应该使用
QThread
对于我的用例,或者一些完全不同的代码组织?

使用线程来不阻塞 GUI 是常见的还是我在重新发明轮子?

from PySide6.QtWidgets import (
    QApplication, QWidget, QVBoxLayout, QPushButton, QLabel
)
from PySide6.QtCore import QTime, QTimer
import threading
import time


class MyWindow(QWidget):
    def __init__(self):
        super().__init__()
        self.resize(200, 100)
        self.button = QPushButton('Do work', self)
        self.button.clicked.connect(self.run_work_thread)
        self.timer_label = QLabel('', self)  # hide label at the start (but save its space)
        layout = QVBoxLayout(self)
        layout.addWidget(self.button)
        layout.addWidget(self.timer_label)
        self.setLayout(layout)

    def run_work_thread(self):
        """Do work in a separate thread, not to block the GUI"""
        self.button.setEnabled(False)
        thread = threading.Thread(target=self.do_work)
        thread.start()

        self.start_time = QTime(0, 0, 0)
        self.timer = QTimer(self)
        self.timer_label.setText('Doing work for: 0 s')
        self.timer.timeout.connect(self.update_timer)
        self.timer.start(1000)  # update every 1 sec

    def do_work(self):
        time.sleep(2)  # Simulate work
        self.timer.stop()
        self.timer_label.setText('')  # clear the timer label
        self.button.setEnabled(True)

    def update_timer(self):
        """Update the timer, and its label with the elapsed time"""
        self.start_time = self.start_time.addMSecs(1000)
        self.timer_label.setText(f'Doing work for: {self.start_time.toString("s")} s')


if __name__ == '__main__':
    app = QApplication([])
    window = MyWindow()
    window.show()
    app.exec()
qt pyqt pyqt6
1个回答
0
投票

按照@musicamante的有用建议,这是我所做的解决方案:

from PySide6.QtWidgets import (
    QApplication, QWidget, QVBoxLayout, QPushButton, QLabel
)
from PySide6.QtCore import QTime, QTimer, QThread, Signal
import time


class Worker(QThread):
    finished = Signal()  # Signal to indicate the work is done

    def run(self):
        time.sleep(2)  # Simulate work
        self.finished.emit()  # Emit the finished signal


class MyWindow(QWidget):
    def __init__(self):
        super().__init__()
        self.resize(200, 100)
        self.button = QPushButton('Do work', self)
        self.button.clicked.connect(self.run_work)
        self.timer_label = QLabel('', self)
        layout = QVBoxLayout(self)
        layout.addWidget(self.button)
        layout.addWidget(self.timer_label)
        self.setLayout(layout)

        ### ADDED: ###
        self.worker = Worker()
        self.worker.finished.connect(self.on_work_finished)
        ##############

    def run_work(self):
        """Start the work and the timer"""
        self.button.setEnabled(False)
        self.start_time = QTime(0, 0, 0)
        self.timer = QTimer(self)
        self.timer_label.setText('Doing work for: 0 s')
        self.timer.timeout.connect(self.update_timer)
        self.timer.start(1000)  # update every 1 sec
        self.worker.start()

    def on_work_finished(self):
        """Stop the timer and reset the UI when work is done"""
        self.timer.stop()
        self.timer_label.setText('')
        self.button.setEnabled(True)

    def update_timer(self):
        """Update the timer and its label with the elapsed time"""
        self.start_time = self.start_time.addSecs(1)
        self.timer_label.setText(f'Doing work for: {self.start_time.toString("s")} s')

if __name__ == '__main__':
    app = QApplication([])
    window = MyWindow()
    window.show()
    app.exec()
© www.soinside.com 2019 - 2024. All rights reserved.