如果应用程序注意到任何事件,PyQt5 应用程序在操作期间不会响应

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

我创建了一个简单的应用程序来复制这个问题。 基本上,如果您单击离开或单击应用程序(复制由应用程序处理的事件),则会将其设置到队列中并停止更新。这还会提示“未响应”通知。无论出于何种原因,我刚刚输入的代码在第六次迭代之前都不会出现此问题。

我对线程进行了一些研究,但似乎没有任何帮助。也许我错过了一些东西。

以下是代码的工作原理。您所需要做的就是单击运行按钮。这应该会提示应用程序每 1 秒用新的增量数值更新右侧的所有 5 个编辑框。该应用程序还会在右侧的文本字段中提醒用户。

我主要好奇的是:有没有办法创建一个线程来对所有事件进行排队,这样它们就不会影响应用程序更新用户内部发生的情况?或者有没有办法一起禁用所有事件,以确保操作期间发生的唯一事情是更新用户有关应用程序内的事件。

这是代码:

QApp.py

import sys
import time
from PyQt5.QtWidgets import QApplication, QMainWindow, QWidget, QVBoxLayout, QHBoxLayout, QTextEdit, QPushButton, QLineEdit


class MyApp(QMainWindow):
    def __init__(self):
        super().__init__()

        self.initUI()

    def initUI(self):
        self.setWindowTitle('Increment App')
        self.setGeometry(100, 100, 600, 300)

        central_widget = QWidget(self)
        self.setCentralWidget(central_widget)

        # Layouts
        main_layout = QHBoxLayout(central_widget)
        input_layout = QVBoxLayout()
        output_layout = QVBoxLayout()
        text_layout = QVBoxLayout()

        main_layout.addLayout(input_layout)
        main_layout.addLayout(output_layout)
        main_layout.addLayout(text_layout)

        # Input Edit Fields
        self.input_fields = []
        for i in range(5):
            input_field = QLineEdit(self)
            input_field.setText("0")
            input_layout.addWidget(input_field)
            self.input_fields.append(input_field)

        # Output Edit Fields
        self.output_fields = []
        for i in range(5):
            output_field = QLineEdit(self)
            output_field.setReadOnly(True)
            output_layout.addWidget(output_field)
            self.output_fields.append(output_field)

        # Text Box
        self.text_box = QTextEdit(self)
        text_layout.addWidget(self.text_box)

        # Run Button
        self.run_button = QPushButton('Run', self)
        self.run_button.clicked.connect(self.run_button_clicked)
        text_layout.addWidget(self.run_button)

    def run_button_clicked(self):
        try:
            # Get the current values from input fields
            input_values = [int(input_field.text()) for input_field in self.input_fields]

            while input_values[0] < 101:
                # Increment each value and update the output fields
                for i in range(5):
                    input_values[i] += 1
                    self.output_fields[i].setText(str(input_values[i]))

                # Update the text box
                self.text_box.append("Updated values in output fields.")

                self.run_button.setEnabled(False)

                self.repaint()
                time.sleep(1)

            self.text_box.append("All values have reached 100.")

        except ValueError:
            self.text_box.append("Invalid input. Please enter valid integers.")


def main():
    app = QApplication(sys.argv)
    window = MyApp()
    window.show()
    sys.exit(app.exec_())


if __name__ == '__main__':
    main()

请参阅附图,了解应用程序见证事件后的样子。

我尝试过使用这个问题中推荐的内容:Background thread with QThread in PyQt

但是即使使用线程我仍然没有运气。

pyqt5 qthread
1个回答
0
投票

好吧,我找到了问题的答案。如果您想摆脱这个问题,只需使用以下代码:

import sys

from PyQt5.QtCore import QThread, pyqtSignal
from PyQt5.QtWidgets import QApplication, QMainWindow, QWidget, QVBoxLayout, QHBoxLayout, QTextEdit, QPushButton, \
    QLineEdit


class UpdateThread(QThread):
    update_signal = pyqtSignal(list)

    def __init__(self, input_values=None, output_fields=None, text_box=None):
        super().__init__()
        self.input_values = input_values
        self.output_fields = output_fields
        self.text_box = text_box

    def run(self):

        try:
            while self.input_values[0] < 101:
                # Increment each value and update the output fields
                for i in range(5):
                    self.input_values[i] += 1
                    self.output_fields[i].setText(str(self.input_values[i]))

                # Update the text box
                self.text_box.append("Updated values in output fields.")

                self.msleep(1000)  # Sleep for 1 second

            self.text_box.append("All values have reached 100.")

        except ValueError:
            self.text_box.append("Invalid input. Please enter valid integers.")


class MyApp(QMainWindow):
    def __init__(self):
        super().__init__()

        self.initUI()

    def initUI(self):
        self.setWindowTitle('Increment App')
        self.setGeometry(100, 100, 600, 300)

        central_widget = QWidget(self)
        self.setCentralWidget(central_widget)

        # Layouts
        main_layout = QHBoxLayout(central_widget)
        input_layout = QVBoxLayout()
        output_layout = QVBoxLayout()
        text_layout = QVBoxLayout()

        main_layout.addLayout(input_layout)
        main_layout.addLayout(output_layout)
        main_layout.addLayout(text_layout)

        # Input Edit Fields
        self.input_fields = []
        for i in range(5):
            input_field = QLineEdit(self)
            input_field.setText("0")
            input_layout.addWidget(input_field)
            self.input_fields.append(input_field)

        # Output Edit Fields
        self.output_fields = []
        for i in range(5):
            output_field = QLineEdit(self)
            output_field.setReadOnly(True)
            output_layout.addWidget(output_field)
            self.output_fields.append(output_field)

        # Text Box
        self.text_box = QTextEdit(self)
        text_layout.addWidget(self.text_box)

        # Run Button
        self.run_button = QPushButton('Run', self)
        self.run_button.clicked.connect(self.run_button_clicked)
        text_layout.addWidget(self.run_button)

        # Initialize the thread for updates
        self.update_thread = UpdateThread(self.input_fields, self.output_fields, self.text_box)
        self.update_thread.update_signal.connect(self.update_thread.run)

    def run_button_clicked(self):
        try:
            # Get the current values from input fields
            input_values = [int(input_field.text()) for input_field in self.input_fields]

            # Start the update thread
            self.update_thread.input_values = input_values
            self.run_button.setEnabled(False)
            self.update_thread.start()

            # Disable the "Run" button
            self.run_button.setEnabled(True)

        except ValueError:
            self.text_box.append("Invalid input. Please enter valid integers.")

def main():
    app = QApplication(sys.argv)
    window = MyApp()
    window.show()
    sys.exit(app.exec_())


if __name__ == '__main__':
    main()

在这种情况下,通过添加 Qthread 类,然后调用它并运行其中的代码,您可以毫无问题地移动和更新应用程序。修复方法是使用 self.msleep(1000) 而不是 time.sleep(1)。

© www.soinside.com 2019 - 2024. All rights reserved.