2016-08-03 4 views
1

Ich muss eine einfache GUI erstellen, die Bilder anzeigt, die Bilder in diesem Beispiel können sich ändern und die GUI muss ihren Inhalt aktualisieren.Aktualisierung von Qt Images funktioniert erst, wenn exec aufgerufen wird

Ich schrieb die folgende Update-Funktion in meiner Widget-Klasse:

void myClass::updatePic() { 
    QPixmap pix("./pic.png"); 
    int width = ui->picLabel->width(); 
    int height = ui->picLabel->height(); 
    ui->picLabel->setPixmap(pix.scaled(width,height,Qt::KeepAspectRatio));} 

Ich versuche es auf folgende Weise zu verwenden:

int main(int argc, char *argv[]) { 
QApplication a(argc, argv); 
myClass w; 
w.show(); 

sleep(3); 
w.updatePic(); 

sleep(3); 
w.updatePic(); 

sleep(3); 
return a.exec();} 

Aber das Fenster öffnet gerade und zeigt nicht die Bilder bis wir zur a.exec() Zeile gelangen und dann das letzte Bild öffnet. Was mache ich falsch?


EDIT:

Klärung der Auslöser für die Bilder ändert von einem externen Programm kommt (genauer gesagt, wird die GUI ein Knoten in ros, und wird von einem anderen Knoten ausgelöst werden). Gibt es eine Möglichkeit, einen Knopf nicht über ein externes Programm von der GUI zu drücken? Der Timer wird funktionieren, aber ich mag diese "busy wait" -Stil-Lösungen nicht.

Danke für die Vorschläge bisher

Antwort

2

exec führt die Ereignisschleife QT, welche Widgets Rendering umfasst.

So bewegen Sie Ihren updatePic Anruf in Ihr Widget und aktiviert, indem zum Beispiel einer Taste oder in dem Show-Event auch

+0

Der Auslöser stammt von einem externen Programm, die QT-GUI zeigt nur die Ergebnisse an und hat keine Schaltflächen. – user44874

0

Die Funktion exec das Kind-Widgets macht. exec() blockiert den Anwendungsfluss, während show() dies nicht tut. Exec wird also hauptsächlich für modale Dialoge verwendet.

Ich empfehle, es in Ihrem benutzerdefinierten witget zu aktualisieren, indem Sie einen Aktualisierungstimer verwenden. Verwenden Sie ein QTimer das Bild alle 3 Sekunden aktualisiert:

QTimer* timer = new QTimer(this); 
timer->setInterval(3000); 
connect(timer, SINGAL(timeout()), this, SLOT(updatPicture())); 

Aktualisieren Sie Ihr Bild in Ihrem benutzerdefinierten Slot:

MainWindow::updatePicture() { 
    updatePic() 
} 

Wenn Sie wollen, können Sie eine Lambda-Funktion verwenden:

connect(timer, &QTimer::timeout, this, [&w]() { 
    updatePic() 
}); 
+0

Hier ist eine Rede über 'QApplication :: exec ', die in fast jeder GUI-Anwendung notwendig ist. Was meintest du mit modalen Dialogen? – ilotXXI

1

Zuerst erfahren Sie mehr über Event-Loop. Insbesondere müssen Sie wissen, dass alle Ereignisse wie paintEvent oder resizeEvent in der Regel bei entsprechenden Ereignishandles aufgerufen werden. Der Ereignishandle wird normalerweise von der Ereignisschleife aufgerufen, d. H. Innerhalb der exec Funktion.

Lassen Sie uns Antworten von @MohaBou und @RvdK vereinen. Sie müssen Timer-Aufnahmen nach dem exec Anruf behandeln. Verwenden Sie dazu QObject::timerEvent.

myClass::myClass() 
{ 
    <...> 

    // This two variables are members of myClass. 
    _timerId = startTimer(3000); 
    _updatesCount = 0; 
} 

myClass::~myClass() 
{ 
    <...> 

    // For any case. As far as I remember, otherwise the late event 
    // may be handled after the destructor. Maybe it is false, do 
    // not remember... 
    if (_timerId >= 0) { 
     killTimer(_timerId); 
     _timerId = - 1; 
    } 
} 

myClass::timerEvent(QTimerEvent *event) 
{ 
    if (event->timerId() == _timerId) { 
     if (_updatesCount < 2) { 
      updatePic(); 
      ++_updatesCount; 
     } else { 
      killTimer(_timerId); 
      _timerId = - 1; 
     } 
    } 
} 

Die startTimer Methode fügt hier besonders Timer-Ereignis auf das Ereignis Abfrage alle 3 Sekunden. Wie alle Ereignisse kann es nur behandelt werden, wenn die Ereignisschleife die Kontrolle übernimmt und alle früheren Ereignisse behandelt werden. Aus diesem Grund können Sie eine Dauer haben, wenn viele "schwere" Ereignisse behandelt werden.

EDIT: Entschuldigung, ich habe @MohaBou beim ersten Lesen nicht verstanden.Seine Antwort mit expliziten QTimer ist auch gut genug (aber ich verstehe immer noch nicht einen Teil über Modalität).

Verwandte Themen