Seite 1 von 1

[gelöst] setCurrentWidget SLOT funktioniert nicht

Verfasst: 7. Juni 2014 20:39
von kalsan
Hallo allerseits!
Ich habe per QtCreator mit integriertem QtDesigner eine UI aufgesetzt, die ein QstackedWidget enthält. Sein Name ist stackedWidget und es enthält unter anderem die Seiten stackedBrick und stackedHome. Nun habe ich die automatisch generierte MainWindow Klasse folgendermassen angepasst (.cpp):

Code: Alles auswählen

HMainWindow::HMainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::HMainWindow)
{
    ui->setupUi(this);
    connect(ui->menuQuit,SIGNAL(triggered()), qApp, SLOT(quit()));
    connect(ui->bcHome,SIGNAL(clicked()),ui->stackedWidget,SLOT(setCurrentWidget(ui->stackedHome)));
    ui->stackedWidget->setCurrentWidget(ui->stackedBrick);
}
Das Widget springt sofort zu stackedBrick. Die letzte Zeile funktioniert folglich. Wenn ich da stackedHome statt stackedBrick reinschreibe, springt es zu stackedHome, alles in Butter soweit.
Allerdings funktioniert die zweite connect-Zeile nicht. Beim Klicken des Buttons bcHome geschieht nichts, egal ob ich stackedHome oder stackedBrick aufrufen will. Schreibe ich als SLOT hingegen hide() rein (immer noch beim stackedWidget), wird dieses korrekt versteckt, sobald der Knopf gedückt wird. Übrigens schlägt QtCreator per Autocomplete setCurrentWidget auch als SLOT vor.
Somit habe ich einen funktionierenden connect-Befehl und einen funktionierenden setCurrentWidget Befehl. Aber sobald ich setCurrentWidget als SLOT implementiere, geschieht gar nichts mehr?!
Kann mir jemand helfen?
P.S. Die zweitletzte Zeile ist von QtCreator rot unterstrichen. Es ist laut ihm eine geschlossene Klammer zu viel am Ende. Aber wenn ich die entferne, klagt der Compiler über eine Klammer zu wenig.
lg,
Kalsan

Re: setCurrentWidget SLOT funktioniert nicht

Verfasst: 8. Juni 2014 11:15
von hilefoks
Moin,

ja, das kann so leider auch nicht funktionieren.

SLOT und SIGNAL erwarten nur die Signatur einer Methode. Du kannst daher keine Membervariable als Parameter übergeben. Die Werte die der SLOT-Methode als Parameter übergeben werden, müssen von der SIGNAL Methode gesendet werden.

Also grundsätzlich müssen die Signaturen der Methoden im SLOT und im SIGNAL übereinstimmen. Sendet das SIGNAL ein int, muss der SLOT ein int Parameter übernehmen... z.B:

Code: Alles auswählen

connect( obj1, SIGNAL( clicked() ), obj2, SLOT( onClick() ) );
connect( obj1, SIGNAL( triggered(bool) ), obj2, SLOT( onTriggered(bool) ) );
connect( obj1, SIGNAL( valueChanged(int) ), obj2, SLOT( onValueChanged(int) ) );
connect( obj1, SIGNAL( positionChanged(double, double) ), obj2, SLOT( onPositionChanged(double, double) ) );
Allerdings erlaubt Qt auch, das ein SIGNAL mit einem SLOT verbunden wird, obwohl der SLOT nicht alle Parameter des SIGNAL entgegennimmt... z.B:

Code: Alles auswählen

connect( obj1, SIGNAL( triggered(bool) ), obj2, SLOT( onClicked() ) );
connect( obj1, SIGNAL( valueChanged(int) ), obj2, SLOT( onValueChanged() ) );
connect( obj1, SIGNAL( positionChanged(double, double) ), obj2, SLOT( onPositionChanged(double) ) );

Dein Problem lässt sich nun auf verschiedene Arten lösen. Eine Lösung ist, du erstellst einfach einen eigenen SLOT für diese Aufgabe und verbindest dann das clicked() Signal von bcHome mit diesem slot:

Code: Alles auswählen

void HMainWindow::selectHomeWidget() { 
    ui->stackedWidget->setCurrentWidget( ui->stackedHome ); 
}
Unter Verwendung von C++11 ("QMAKE_CXXFLAGS += -std=c++11" in deiner qmake Projektdatei) kannst du auch Lambda-Expressions einsetzen, um den Code kürzer und übersichtlicher zu halten. Dazu musst du nur deine connect-Anweisung wie folgt ändern:

Code: Alles auswählen

connect(ui->bcHome, &QPushButton::clicked, [=]() { 
    ui->stackedWidget->setCurrentWidget( ui->stackedHome ); 
} );
MfG,
Hilefoks

Re: setCurrentWidget SLOT funktioniert nicht

Verfasst: 10. Juni 2014 10:02
von kalsan
Sorry, dass ich sie so spät bemerkt habe: Ich hatte vergessen, den Thread zu abonnieren.
Herzlichen Dank für deine Antwort! Deine Erklärung trifft den Nagel auf den Kopf und hat mir sehr weitergeholfen.
Jetzt versuch ich noch, das Thema irgendwie als gelöst zu markieren ;-)