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

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章