计算一个值并在 GUI python 中更新它,而不会阻止我的 gui

Calculate a value and update this in a GUI python, without block my gui

我有一个简单的应用程序,一个标签和两个按钮(开始增量,停止增量),用pyqt5 编写。

当我按下开始按钮想在 ui 中查看时,值会实时更新并且可以在停止按钮上访问。

现在,当我按下开始按钮时,在 UI 中看不到更新,当我尝试按下停止按钮时,接收不到响应。

一个解决方案可能是线程,但我不明白工作线程在 Python

中是如何工作的
import sys
import time
from PyQt5 import QtWidgets, Qt
from PyQt5.QtWidgets import QMainWindow, QApplication, QPushButton, QLineEdit
from PyQt5.QtCore import *
from PyQt5.QtGui import *


class MainWindow(QMainWindow):
    running = True
    value = 1

def __init__(self):
    QMainWindow.__init__(self)
    self.setMinimumSize(QSize(600, 500))
    self.setMaximumSize(QSize(600, 500))
    self.setWindowTitle("Demo app")
    QApplication.setStyle("fusion")
    self.move(1000, 200)

    self.button_start = QPushButton('Start', self)
    self.button_start.setFixedHeight(40)
    self.button_start.setFixedWidth(170)
    self.button_start.move(10, 215)
    self.button_start.clicked.connect(self.start_function)
    self.update()

    self.button_stop = QPushButton('Stop', self)
    self.button_stop.setFixedHeight(40)
    self.button_stop.setFixedWidth(170)
    self.button_stop.move(200, 215)
    self.button_stop.setDisabled(True)
    self.button_stop.clicked.connect(self.stop_function)
    self.update()

    self.label = QLineEdit(self)
    self.label.move(10, 170)
    self.label.resize(170, 40)
    self.label.setEnabled(False)
    self.label.setAlignment(Qt.AlignCenter)
    self.label.setStyleSheet("color: red;")
    self.update()

def start_function(self):
    self.button_start.setDisabled(True)
    self.button_stop.setDisabled(False)
    while self.running is True:
        self.value += 1
        self.label.setText(str(self.value))
        print("Value: ", self.value)
        time.sleep(1)

def stop_function(self):
    self.running = False


if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    mainWin = MainWindow()
    mainWin.show()
    mainWin.update()
    sys.exit(app.exec_())

也许我来晚了,你自己想出了如何解决这个问题,但对于那些有同样问题的人:

您不能为此目的在 GUI 线程中设置循环,它会阻止 GUI 线程执行任何操作。相反,您可以使用 QTimer 在稍后的时间点将某些内容安排到 运行。您可以使用它来实现类似秒表的功能。

这是一个最小的功能示例:

import sys
import time
from PyQt5 import QtWidgets, Qt
from PyQt5.QtWidgets import QMainWindow, QApplication, QPushButton, QLineEdit
from PyQt5.QtCore import *
from PyQt5.QtGui import *


class MainWindow(QMainWindow):
    value = 0

    def __init__(self):
        QMainWindow.__init__(self)
        self.setMinimumSize(QSize(600, 500))
        self.setMaximumSize(QSize(600, 500))
        self.setWindowTitle("Demo app")
        QApplication.setStyle("fusion")
        self.move(1000, 200)

        self.button_start = QPushButton('Start', self)
        self.button_start.setFixedHeight(40)
        self.button_start.setFixedWidth(170)
        self.button_start.move(10, 215)
        self.button_start.clicked.connect(self.start_function)
        self.update()

        self.button_stop = QPushButton('Stop', self)
        self.button_stop.setFixedHeight(40)
        self.button_stop.setFixedWidth(170)
        self.button_stop.move(200, 215)
        self.button_stop.setDisabled(True)
        self.button_stop.clicked.connect(self.stop_function)
        self.update()

        self.label = QLineEdit(self)
        self.label.move(10, 170)
        self.label.resize(170, 40)
        self.label.setEnabled(False)
        self.label.setAlignment(Qt.AlignCenter)
        self.label.setStyleSheet("color: red;")
        self.label.setText(str(self.value))
        self.update()

        self.workTimer = QTimer()
        self.workTimer.setInterval(1000)
        self.workTimer.timeout.connect(self.increase_value)

    def start_function(self):
        self.workTimer.start()

        self.button_start.setDisabled(True)
        self.button_stop.setDisabled(False)

    def stop_function(self):
        self.workTimer.stop()

        self.button_start.setDisabled(False)
        self.button_stop.setDisabled(True)

    def increase_value(self):
        self.value += 1
        self.label.setText(str(self.value))


if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    mainWin = MainWindow()
    mainWin.show()
    mainWin.update()
    sys.exit(app.exec_())