2012-03-25 8 views
12

Um Signale mit Steckplätzen zu verbinden, müssen die Parameter des Signals, soweit ich weiß, mit den Parametern des Steckplatzes übereinstimmen. So zum Beispiel:Signale an Steckplätze mit konstanten Werten anschließen

connect(dockWidget->titleBarWidget(), SIGNAL(closeButtonClicked()), ui->sideControls, SLOT(closeDockWidget())); 

Aber was, wenn ich ein Signal Anruf eines Schlitz haben will, die eine unterschiedliche Anzahl von Parametern, aber immer einen konstanten Wert in den Schlitz passieren. Zum Beispiel mit dem oben Stück Code:

connect(dockWidget->titleBarWidget(), SIGNAL(closeButtonClicked()), ui->sideControls, SLOT(setDockWidget(false))); 

Oder in anderen Worten, wenn die Taste gedrückt wird, ruft es die setDockWidget() Funktion mit dem falschen Parameter. Ist das möglich?

Antwort

8

Nein, das ist nicht möglich. Sie dürfen nur Slots mit weniger oder gleicher Argumentanzahl als im entsprechenden Signal verbinden. (siehe documentation)

Sie müssen Proxy-Steckplatz erstellen, die gewünschte aufgerufen wird.

+1

Diese Antwort ist nicht mehr wirklich gültig, da die Qt5-Syntax in C++ 11 es sehr einfach macht, ein Lambda für diesen Zweck zu verwenden. –

+1

@ André, auf der anderen Seite, können Sie einfach 'Proxy-Steckplatz erstellen, die gewünschte 'anrufen wird jetzt an Ort und Stelle – Lol4t0

+1

Sicher, Sie können. Aber ein zusätzlicher Steckplatz bedeutet mehr Dinge in Ihrem Header, die Sie nicht benötigen, indem Sie externen Anrufen ausgesetzt werden (ja, auch wenn ein privater Steckplatz von außen angerufen werden kann) und Ihren Code über mehrere Standorte verteilt. Möglicherweise benötigen Sie sogar zusätzliche Membervariablen, die Werte enthalten, die Sie übergeben möchten. Dadurch wird zusätzlicher Status in Ihrer Klasse eingeführt. Die Lambda-Lösung ist so viel eleganter, dass sie die Einführung eines Proxy-Slots als eine Lösung IMO disqualifiziert. –

6

In gewisser Weise, ja, können Sie. Aber es ist nicht sehr mächtig: einfach erklären die setDockWidget auf diese Weise:

[virtual] void setDockWidget(bool state=false) ; 

und erklären die Verbindung auf diese Weise:

connect(emitter, SIGNAL(closeButtonClicked()), receiver, SLOT(setDockWidget())); 

setDockWidget ohne Argumente aufgerufen nehmen die Standardeinstellungen.

8

Sie können Lambda mit gewünschten Anruf mit Konstante Argument verwenden. Beispiel:

connect(obj, &ObjType::signalName, [this]() { desiredCall(constantArgument); }); 

Mehr über neue Verbindungs ​​Syntax: https://wiki.qt.io/New_Signal_Slot_Syntax.

+0

In Ihrem Fall ist es möglich, konstante Argumente mit Variablen zu mischen? –

+0

@AlekseyKontsevich: Wenn ich Sie richtig verstehe, wollen Sie auch eine Variable vom Signal zum Slot übergeben? Sicher kannst du. Machen Sie es zum Argument für das Lambda und verwenden Sie dieses Argument im Funktionsaufruf. Ich empfehle jedoch, dass Sie das Argument context auch mit dem Wert 'this' verwenden. Auf diese Weise können Sie sicher sein, dass die Verbindung zerstört wird, wenn das Empfangsobjekt zerstört wird. Andernfalls kann es zu einem nicht definierten Verhalten kommen. –