python

2017-02-16 54 views
0

運行時進度狀態(如狀態欄)我正在嘗試爲我的Pyqt5 Python代碼創建簡單的進度狀態標籤,並在函數執行一堆東西的循環的每次迭代後更新它。我想要更新的標籤是「status_label_counter」。下面的代碼只顯示了創建標籤的部分以及我想要使用我提到的功能的確切位置。python

#initialisation code, etc... 

    self.status_label_counter = QLabel() 
    self.status_label_from = QLabel(' from: ') 
    self.status_label_total = QLabel() 
    status_hbox = QHBoxLayout() 
    status_hbox.addStretch() 
    status_hbox.addWidget(self.status_label_counter) 
    status_hbox.addWidget(self.status_label_from) 
    status_hbox.addWidget(self.status_label_total) 
    status_hbox.addStretch() 

    #bunch of other code... 

    def create_ics(self): 
     counter = 0 
     self.status_label_total.setText(str(len(self.groups))) 
     for group in self.groups: 
      #does a bunch of stuff inside 
      group_manager.create_calendar_for(self.rows, group, self.term) 
      counter += 1 
      #for console output 
      print('iteration: ', counter) 
      #trying to update status counter 
      self.status_label_counter.setText(str(counter)) 

問題是,當循環完成嵌套函數時,我只看到兩個標籤的更新。當我點擊一個按鈕,要求「create_ics」功能窗口變爲非活動狀態約5秒時,我會看到控制檯上的日誌與迭代次數,但沒有任何反應。

+0

嘗試QApplication.processEvents()循環 – eyllanesc

+0

裏面我也建議使用的QThread – eyllanesc

回答

1

視圖(Qt)被鎖定在您的主線程中,從來沒有機會處理其事件循環,從而重繪自己。如果你真的想這樣做,這樣一來,叫:

self.status_label_counter.repaint() 

在設置文本(如果你有一些複雜的佈局測量呼叫QApplication.processEvents()代替)。

但是,更好的選擇是在獨立的線程中運行你的create_ics()函數,讓主線程處理視圖和Qt的事件處理。您可以通過標準Python的threading模塊或使用Qt自己的QThread:https://nikolak.com/pyqt-threading-tutorial/來完成。

+0

我用QApplication.processEvents(),和它的工作,但處理的時間幾乎翻了一倍,我看到它在這個特殊的情況下工作因爲這只是幾秒鐘的事情,但我也會嘗試穿線,因爲如果物品的數量不是現在的〜200,而是〜5000,那實際上很重要。謝謝! –

+0

處理時間當然會增加 - 即使您不需要它,您也可以在每次調用時初始化Qt的事件循環檢查,這就是爲什麼線程是有用的 - Qt的事件循環有其自己的時間表,並且會定期更新,但在你的情況下它會卡在你的循環中。當你將處理分離到另一個線程時,不會阻塞Qt進行更新。你可以加快你的處理過程,而不需要線程處理,只要在Qt處理事件時添加一個條件,例如''if not counter%1000:QApplication.processEvents()' – zwer