Home > database >  pyqt5 gui freezing in while loop
pyqt5 gui freezing in while loop

Time:01-08

i'm writing python gui application that process a image and send image color from serial port and show the results but unfortunately my gui freeze. i try using QApllication.processEvents and it is work but my program speed slow and speed is so important to me and every one second one iteration should be complete. Here is my code:

        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()

and knotters_status function:

    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()

After i research i found this but not working too:

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()

and this setting up the thread:

    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()

CodePudding user response:

After somedays of research i found this solution: At first you have to write class and inherit from QThread class and then reimplement run method with signals and slots then after that you have create object from that class and just after that you should call processEvents() method referring to your QApplication object. In this situation it doesn't cause slowing down and it's work perfectly for mopre detail you can refer to my another question and answer which you can click Here

  •  Tags:  
  • Related