pyqt5 gui在while循环中冻结
pyqt5 gui freezing in while loop
我正在编写 python gui 应用程序来处理图像并从串行端口发送图像颜色并显示结果,但不幸的是我的 gui 冻结了。我尝试使用 QApllication.processEvents 并且它有效,但我的程序速度很慢,速度对我来说非常重要,每一秒一次迭代都应该完成。
这是我的代码:
while self.knot <= knotter_width:
color_to_send = []
for i in range(1, number_of_knotter + 1):
color_to_send.append(self.baft["knotters"][i][self.lay][self.knot])
# send color numbers
# receive color feedback
self.knot = self.knot + 1
if self.knot > knotter_width:
break
self.config_write()
self.knotters_status() # gui update function
QCoreApplication.processEvents()
和knotters_status函数:
def knotters_status(self):
try:
for i in range(number_of_knotter):
self.knotters_status_dict[i].deleteLater()
except:
pass
try:
self.baft
except:
self.status.setAlignment(Qt.Alignment(132))
status_gui_font_error = QFont("Arial", 43)
status_gui_font_error.setBold(True)
self.status.setFont(status_gui_font_error)
self.status.setText("فایل بافت لود نشده است!")
return
self.knotters_status_dict = {}
# size calculation:
width_geo_start_point = 50
width_step = int((self.status_width - 50)/number_of_knotter)
self.each_knotters_sector_unit_height = int(self.status_height / 7)
knotters_status_font_size = int(self.each_knotters_sector_unit_height / 1.5)
knotters_status_font = QFont("Arial", knotters_status_font_size)
knotters_status_font.setBold(True)
for i in range(number_of_knotter):
self.knotters_status_dict[i] = QLabel(self.status)
self.knotters_status_dict[i].setGeometry((width_geo_start_point + width_step * (number_of_knotter - i - 1)),
0,
width_step,
self.status_height)
self.knotters_status_dict[i].setStyleSheet("border: 1px solid black;"
"background-color: whitesmoke")
self.knotters_status_dict[i].setAlignment(Qt.Alignment(36))
self.knotters_status_dict[i].setFont(knotters_status_font)
color_number = self.baft["knotters"][i + 1][self.lay][self.knot] + 1
self.knotters_status_dict[i].setText("بافنده {}\nلای {}\nگره {}\nرنگ {}".format(i,
self.lay,
self.knot,
color_number))
colors_width = width_step // 4
y = self.each_knotters_sector_unit_height * 4 + self.each_knotters_sector_unit_height // 3
colors = {}
if self.lay != 1 and self.lay != self.baft["height"]:
if self.knot != 1 and self.knot != knotter_width:
for j in range(2):
colors[j] = {}
x = colors_width // 4
for k in range(1,-2,-1):
target_lay = self.lay - j
target_knot = self.knot + k
colors[j][k] = QLabel(self.knotters_status_dict[i])
colors[j][k].setGeometry(x,
y,
colors_width,
self.each_knotters_sector_unit_height)
color_rgb = self.baft["color table"][self.baft["knotters"][i+1][target_lay][target_knot]+1]
colors[j][k].setStyleSheet("border: 1px solid black;"
"border-radius: 10px;"
"background-color: rgb({}, {}, {});".format \
(color_rgb[0],
color_rgb[1],
color_rgb[2]))
colors[j][k].show()
x = x + colors_width + colors_width // 4
y = y + int(self.each_knotters_sector_unit_height * 4 / 3)
elif self.knot == 1:
pass
elif self.knot == knotter_width:
pass
elif self.lay == 1:
pass
elif self.lay == self.baft["height"]:
pass
self.knotters_status_dict[i].show()
经过我的研究,我发现了这个但也不起作用:
class Worker(QObject):
progress = pyqtSignal(int)
gui_update = pyqtSignal()
finish = pyqtSignal(bool)
ex = pyqtSignal()
@pyqtSlot(int, int, dict)
def run(self, knot, lay, baft):
# send finish order
# recieve finish feedback
while knot <= knotter_width:
color_to_send = []
for i in range(1, number_of_knotter + 1):
color_to_send.append(baft["knotters"][i][lay][knot])
# send color numbers
# receive color feedback
if knot < knotter_width:
knot = knot + 1
else:
break
self.progress.emit(knot)
self.gui_update.emit()
self.finish.emit(True)
# send finish order
#reveive finish feedback
self.ex.emit()
并设置线程:
self.thrd = QThread()
self.worker = Worker()
self.worker.moveToThread(self.thrd)
self.thrd.started.connect(lambda: self.worker.run(self.knot, self.lay, self.baft))
self.worker.progress.connect(self.progress)
self.worker.gui_update.connect(self.knotters_status)
self.worker.finish.connect(self.finished)
self.worker.ex.connect(self.thrd.quit)
self.worker.ex.connect(self.worker.deleteLater)
self.thrd.finished.connect(self.thrd.deleteLater)
self.thrd.start()
经过几天的研究,我找到了这个解决方案:
首先,您必须编写 class 并从 QThread class 继承,然后使用信号和槽重新实现 运行 方法,然后您从 class 创建对象,紧接着你应该调用 processEvents() 方法来引用你的 QApplication 对象。在这种情况下,它不会导致速度变慢,而且它非常适合 mopre 细节你可以参考我的另一个问题和答案,你可以点击
我正在编写 python gui 应用程序来处理图像并从串行端口发送图像颜色并显示结果,但不幸的是我的 gui 冻结了。我尝试使用 QApllication.processEvents 并且它有效,但我的程序速度很慢,速度对我来说非常重要,每一秒一次迭代都应该完成。 这是我的代码:
while self.knot <= knotter_width:
color_to_send = []
for i in range(1, number_of_knotter + 1):
color_to_send.append(self.baft["knotters"][i][self.lay][self.knot])
# send color numbers
# receive color feedback
self.knot = self.knot + 1
if self.knot > knotter_width:
break
self.config_write()
self.knotters_status() # gui update function
QCoreApplication.processEvents()
和knotters_status函数:
def knotters_status(self):
try:
for i in range(number_of_knotter):
self.knotters_status_dict[i].deleteLater()
except:
pass
try:
self.baft
except:
self.status.setAlignment(Qt.Alignment(132))
status_gui_font_error = QFont("Arial", 43)
status_gui_font_error.setBold(True)
self.status.setFont(status_gui_font_error)
self.status.setText("فایل بافت لود نشده است!")
return
self.knotters_status_dict = {}
# size calculation:
width_geo_start_point = 50
width_step = int((self.status_width - 50)/number_of_knotter)
self.each_knotters_sector_unit_height = int(self.status_height / 7)
knotters_status_font_size = int(self.each_knotters_sector_unit_height / 1.5)
knotters_status_font = QFont("Arial", knotters_status_font_size)
knotters_status_font.setBold(True)
for i in range(number_of_knotter):
self.knotters_status_dict[i] = QLabel(self.status)
self.knotters_status_dict[i].setGeometry((width_geo_start_point + width_step * (number_of_knotter - i - 1)),
0,
width_step,
self.status_height)
self.knotters_status_dict[i].setStyleSheet("border: 1px solid black;"
"background-color: whitesmoke")
self.knotters_status_dict[i].setAlignment(Qt.Alignment(36))
self.knotters_status_dict[i].setFont(knotters_status_font)
color_number = self.baft["knotters"][i + 1][self.lay][self.knot] + 1
self.knotters_status_dict[i].setText("بافنده {}\nلای {}\nگره {}\nرنگ {}".format(i,
self.lay,
self.knot,
color_number))
colors_width = width_step // 4
y = self.each_knotters_sector_unit_height * 4 + self.each_knotters_sector_unit_height // 3
colors = {}
if self.lay != 1 and self.lay != self.baft["height"]:
if self.knot != 1 and self.knot != knotter_width:
for j in range(2):
colors[j] = {}
x = colors_width // 4
for k in range(1,-2,-1):
target_lay = self.lay - j
target_knot = self.knot + k
colors[j][k] = QLabel(self.knotters_status_dict[i])
colors[j][k].setGeometry(x,
y,
colors_width,
self.each_knotters_sector_unit_height)
color_rgb = self.baft["color table"][self.baft["knotters"][i+1][target_lay][target_knot]+1]
colors[j][k].setStyleSheet("border: 1px solid black;"
"border-radius: 10px;"
"background-color: rgb({}, {}, {});".format \
(color_rgb[0],
color_rgb[1],
color_rgb[2]))
colors[j][k].show()
x = x + colors_width + colors_width // 4
y = y + int(self.each_knotters_sector_unit_height * 4 / 3)
elif self.knot == 1:
pass
elif self.knot == knotter_width:
pass
elif self.lay == 1:
pass
elif self.lay == self.baft["height"]:
pass
self.knotters_status_dict[i].show()
经过我的研究,我发现了这个但也不起作用:
class Worker(QObject):
progress = pyqtSignal(int)
gui_update = pyqtSignal()
finish = pyqtSignal(bool)
ex = pyqtSignal()
@pyqtSlot(int, int, dict)
def run(self, knot, lay, baft):
# send finish order
# recieve finish feedback
while knot <= knotter_width:
color_to_send = []
for i in range(1, number_of_knotter + 1):
color_to_send.append(baft["knotters"][i][lay][knot])
# send color numbers
# receive color feedback
if knot < knotter_width:
knot = knot + 1
else:
break
self.progress.emit(knot)
self.gui_update.emit()
self.finish.emit(True)
# send finish order
#reveive finish feedback
self.ex.emit()
并设置线程:
self.thrd = QThread()
self.worker = Worker()
self.worker.moveToThread(self.thrd)
self.thrd.started.connect(lambda: self.worker.run(self.knot, self.lay, self.baft))
self.worker.progress.connect(self.progress)
self.worker.gui_update.connect(self.knotters_status)
self.worker.finish.connect(self.finished)
self.worker.ex.connect(self.thrd.quit)
self.worker.ex.connect(self.worker.deleteLater)
self.thrd.finished.connect(self.thrd.deleteLater)
self.thrd.start()
经过几天的研究,我找到了这个解决方案:
首先,您必须编写 class 并从 QThread class 继承,然后使用信号和槽重新实现 运行 方法,然后您从 class 创建对象,紧接着你应该调用 processEvents() 方法来引用你的 QApplication 对象。在这种情况下,它不会导致速度变慢,而且它非常适合 mopre 细节你可以参考我的另一个问题和答案,你可以点击