我创建了一个简单的应用程序来复制这个问题。 基本上,如果您单击离开或单击应用程序(复制由应用程序处理的事件),则会将其设置到队列中并停止更新。这还会提示“未响应”通知。无论出于何种原因,我刚刚输入的代码在第六次迭代之前都不会出现此问题。
我对线程进行了一些研究,但似乎没有任何帮助。也许我错过了一些东西。
以下是代码的工作原理。您所需要做的就是单击运行按钮。这应该会提示应用程序每 1 秒用新的增量数值更新右侧的所有 5 个编辑框。该应用程序还会在右侧的文本字段中提醒用户。
我主要好奇的是:有没有办法创建一个线程来对所有事件进行排队,这样它们就不会影响应用程序更新用户内部发生的情况?或者有没有办法一起禁用所有事件,以确保操作期间发生的唯一事情是更新用户有关应用程序内的事件。
这是代码:
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
但是即使使用线程我仍然没有运气。
好吧,我找到了问题的答案。如果您想摆脱这个问题,只需使用以下代码:
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)。