PyQT5 Progress Bar 出现卡死

在 PyQT5 中,存在 Progress Bar 这个控件,它的作用是显示当前任务的百分比。

对于这样一个控件,最合适的使用场景就是拿来当计时器,或者下载进度条之类。

有两种典型的 Progress Bar 卡死原因:

1. 没有为 Progress Bar 开辟线程

2. 没有将对 Progress Bar 的操作移到主线程进行

 

1. 没有为 Progress Bar 开辟线程

以用作计时器为例,需要为 Progress Bar 的任务开一个线程,以避免在计时期间,界面无法进行任何操作。如果在主界面里计时10s,那么在这10s内,界面就会处在类似于锁定的状态,只有当10s计时结束,才能进行别的操作。

如下面这段代码所示,通过操作线程 t 的 pause, resume,来实现对 countDownSingal 的操作,而不是直接把 countDownSingal 放在主线程中操作。

    def init_thread(self):
        self.t = threading.Thread(target=self.countDownSingal)
        self.__flag = threading.Event()
        self.__flag.set()
        self.__running = threading.Event()
        self.__running.set()
        self.t.setDaemon(True)
        self.t.start()
        self.pause()

    def countDownSingal(self):
        ......
        pass

 

2. 没有将对 Progress Bar 的操作移到主线程进行

就算开了线程,依然会存在这个问题。当我们在线程中改变 Progress Bar 的值,会发现依然会卡死。这是由于要对界面进行的操作,必须在主线程中完成。那么在支线程中想要对界面操作,就需要发出信号,并由主线程接收信号,再去做修改。

通过自定义一个信号,例如叫 _time_signal,并将它与最终主线程上的界面操作方法 changeTimeBar connect 起来,在支线程中发射信号,由主线程接收信号,并对 Progress Bar 进行操作,可以完成避免卡死的问题。

    _time_signal = QtCore.pyqtSignal()

    def signal(self, Form):
        self._time_signal.connect(self.changeTimeBar)

    def countDownSingal(self):
        while self.__running.isSet():
            self.__flag.wait()        
            while (self.count_down):
                self.__flag.wait()
                self._time_signal.emit()
                self.count_down -= 1
                time.sleep(1)

    def changeTimeBar(self):
        ......
        pass

 

你可能感兴趣的:(pyqt,python)