2010-01-12 17 views
14

Sono nuovo a QT. Capisco che puoi forzare un aggiornamento del display, ma ho tirato fuori tutti i miei capelli cercando di capire come. Ecco cosa sto cercando in particolare di fare.QT Ridisegna/ridisegna/aggiorna/fa qualcosa

Premere un pulsante (evento segnale onClick), che esegue il codice che modifica un'immagine (QLabel) sul display, attende l'input, quindi procede modificando una nuova immagine (QLabel diversa). Ho provato tutto e il display non si aggiorna fino a quando il codice evento del segnale onclick è completo. Al momento, non sto aspettando l'input dell'utente, sto usando usleep (~ 500 ms) a scopo di test.

Da quello che ho letto, QT è event driven, ovvero sto praticamente creando una serie di eventi, che vengono messi in una coda, ed eseguiti quando l'evento (onclick signal) ritorna al (loop principale)/(gestore di eventi). Non voglio aspettare fino al completamento della funzione, renderà la programmazione estremamente dolorosa se devo eseguire questa routine interamente basata sugli eventi.

Come è possibile forzare l'aggiornamento della pixmap QLabel. Ho provato di tutto. Di seguito è riportato tutto il codice che ho provato nel mio gestore di eventi di segnale onClick. (UpButton è il nome del QLabel che è un pixmap)

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

Come potete vedere, sto solo le riprese al buio, a questo punto. Ho provato a guardare il codice di esempio e fare tutti i miei compiti, ma sono perso. Apprezzare qualsiasi aiuto, consiglio e/o codice di esempio.

+2

Nei sistemi GUI basati su eventi, in genere non si "aspetta l'input" nei callback. Lo stato di attesa dell'input significa solo che sei nel ciclo degli eventi. Quindi sono confuso perché staresti usando il sonno per qualsiasi cosa - che routine stavi pensando di chiamare quando * avevi * intenzione di trattare con l'input dell'utente? Non preoccuparti che gli eventi siano dolorosi ... i segnali e le slot non mordono (di solito). – HostileFork

risposta

7

Non si dovrebbe essere in attesa di input nel gestore eventi. È necessario ripensare la logica del programma per utilizzare gli eventi nel modo in cui erano previsti. Tutte le chiamate update() e repaint() nel codice non sono necessarie se si ritorna al ciclo degli eventi.

19

Stavo usando il sonno per emulare una breve quantità di tempo che il computer stava aspettando che succedesse qualcosa.

Come ho affermato nella mia domanda, non volevo utilizzare gli eventi perché è un sacco di lavoro non necessario per realizzare qualcosa in modo estremamente semplice.

Inoltre, l '"evento" che deve aver luogo affinché il programma continui, è un evento USB. Dal momento che sto usando un dispositivo di classe HID, non c'è modo di impostare un evento che si verifichi senza un ciclo di attesa. Le classi HID USB non consentono di impostare gli interrupt, il sistema operativo richiede il dispositivo.

Sono riuscito a far funzionare quanto sopra. Ho attraversato il debugger e ho notato che il display si aggiornava prima della funzione sleep. Eseguendo il programma in modo indipendente, ho ottenuto risultati casuali con il display che si aggiornava l'1% delle volte. Mi sono liberato della funzione sleep e ho aggiunto un altro codice nella sua posizione per emulare un ritardo, e andava bene.

Proprio per la conoscenza di tutti, questo è possibile, non è vietato, ed è facile da fare con il seguente:

qApp->processEvents(); 

QAPP è una variabile esterna globale nell'intestazione QApplication.

Poiché questo evento USB sta rendendo difficile il mio flusso, sono incappato nella classe QWaitCondition. Stavo per iniziare un processo in attesa dell'evento USB. Aspetterei fino a quando il processo non rilascerà la condizione di attesa affinché la mia routine continui.

Ma se qualcuno pensa che questa sia una cattiva idea, per favore, parla. Apprezzo molto il tuo feedback PiedPiper e Ostile Fork.

Grazie.

2

Se ho capito correttamente, si dispone di uno slot e in questo slot, si aggiorna l'immagine mostrata in una QLabel. Ma vuoi che questa modifica venga visualizzata prima che lo slot termini.

In tal caso, emettere un evento update() e chiamare qApp-> processEvents(). Questo metodo elabora gli eventi che sono in attesa nella coda degli eventi e quindi restituisce, quindi questo potrebbe essere ciò che si sta cercando.

PS: un aggiornamento() potrebbe non essere affatto necessario, non sono sicuro.

2

Ho notato che quando si dispone di più widget a più livelli o di widget all'interno dei widget è utile chiamare gli eventi repaint().

Per esempio

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

Questo è di gran lunga più facile poi spingendo fuori alcun trattamento ad un altro thread, o la creazione di gestori di eventi aggiuntivi.