【发布时间】:2022-01-08 00:36:35
【问题描述】:
我正在编写处理图像并从串行端口发送图像颜色并显示结果的 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()
【问题讨论】:
-
当循环阻塞时。如果您需要繁重的处理,则必须使用 QThread,并使用信号与主应用程序通信(并且 only 与它们通信,因为您可以 NEVER 从外部线程访问、创建和修改小部件)。
-
你能帮我吗,因为我不知道该怎么做,谢谢@musicamante
-
对 pyqt 和 QThread 进行一些研究,因为关于该主题的帖子和资源确实有数百个。
-
我做到了,但不幸的是我无法更新 gui @musicamante
-
@musicamante 我研究并发现了一些好东西,我将我的新代码添加到我的 qs 但不能再次工作你能看看并告诉我我哪里错了
标签: python qt user-interface pyqt pyqt5