2010-01-12 62 views
14

我是QT的新手。我知道你可以強制顯示刷新,但是我已經把所有的頭髮都試圖弄清楚了。這是我特別想要做的。QT重繪/重繪/更新/做點什麼

我按下一個按鈕(onClick信號事件),該按鈕運行在顯示器上更改圖像(QLabel)的代碼,等待輸入,然後通過更改新圖像(不同的QLabel)繼續進行。我試過了所有的東西,直到onclick信號事件代碼完成後,顯示纔會刷新。現在,我不等待用戶輸入,我正在使用usleep(〜500 ms)進行測試。我從中讀到,QT是事件驅動的,意思是我基​​本上創建了一堆事件,將其放入隊列中,並在(onClick信號事件)返回到(主循環)/(事件處理程序)。我不想等到函數完成後,如果我必須完全基於事件完成這個例程,那麼編程就會非常痛苦。

如何強制刷新QLabel像素圖。我已經嘗試了一切。以下是我在我的onClick信號事件處理程序中嘗試過的所有代碼。 (upButton是這是一個像素圖的QLabel的名稱)

update(); 
repaint(); 
ui->upButton->setUpdatesEnabled(TRUE); 
update(); 
repaint(); 
QPaintEvent paintevent(ui->upButton->childrenRegion()); 
QPaintEvent * test = &paintevent; 
paintEvent(test); 
this->changeEvent(test); 
ui->upButton->update(); 
ui->upButton->repaint(); 
ui->upButton->repaint(ui->upButton->childrenRegion()); 
repaint(); 
QApplication::sendPostedEvents(); 
this->parentWidget()->update(); 
usleep(100000); 

正如你所看到的,我只是在黑暗中在這一點上拍攝。我試圖看看示例代碼,完成我的所有功課,但我迷路了。欣賞任何幫助,建議和/或示例代碼。

+2

在事件驅動的GUI系統中,您通常不會在回調中「等待輸入」。等待輸入的狀態意味着你處於事件循環中。所以我很困惑,爲什麼你會用什麼東西來休眠 - 你打算什麼時候打電話來處理用戶輸入?不要擔心事件是痛苦的......信號和插槽不會咬(通常)。 – HostileFork 2010-01-12 22:55:14

回答

7

您不應該等待事件處理程序中的輸入。您需要重新思考程序的邏輯以便按照預期方式使用事件。如果您返回到事件循環,則代碼中的所有update()和repaint()調用都是不必要的。

19

我正在使用睡眠來模擬計算機等待發生事件的一小段時間。

正如我在我的問題中指出的那樣,我不想使用事件,因爲完成某些事情非常簡單,這是一大堆不必要的工作。

另外,需要爲程序繼續執行的'事件'是USB事件。由於我使用的是HID類設備,因此無法在沒有等待循環的情況下設置事件發生。 USB HID類不允許設置中斷,操作系統聲稱該設備。

我設法讓上面的工作。我走過調試器,發現顯示器會在睡眠功能之前刷新。獨立運行該程序,隨機結果顯示刷新率爲1%。我擺脫了睡眠功能,並在其中添加了一些其他代碼來模擬延遲,並且沒有問題。

只是每個人的知識,這是可能的,它不禁止的,而且很容易與以下的事情:

qApp->processEvents(); 

qApp是在QApplication的頭一個全球性的外部變量。

因爲這個USB事件讓我的流程變得棘手,我偶然發現了QWaitCondition類。我正要開始一個等待USB事件的進程。我會等到該過程釋放等待條件以繼續我的例程。

但如果有人認爲這是一個壞主意,請說出來。我真的很感激你的反饋PiedPiper和敵對叉。

謝謝。

2

如果我理解正確,您有一個插槽,並在此插槽中,您更新QLabel中顯示的圖像。但您希望在插槽完成之前顯示此更改。

如果是這樣,請發出update()事件,然後調用qApp-> processEvents()。這個方法處理在事件隊列中等待的事件,然後返回,因此這可能就是你所追求的。 PS:更新()可能根本不需要,我不確定。

2

我注意到有時當你有多個分層的小部件或小部件內部的小部件時,它有助於調用他們的repaint()事件。

例如

this->repaint(); 
this->parentWidget()->repaint(); 
this->parentWidget()->parentWidget()->repaint(); 

這是容易得多然後任何處理壓出到另一個線程,或創建附加的事件處理程序。