计算值并在GUI Python中更新此值,而不会阻塞我的GUI

时间:2019-11-13 09:10:46

标签: python pyqt pthreads

我有一个简单的应用程序,一个标签和2个按钮(开始增量,停止增量),用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_())

1 个答案:

答案 0 :(得分:1)

也许我来晚了,您却想出了解决该问题的方法,但是对于那些有同样问题的人:

您不能为此目的在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_())