2016-09-04 4 views
2

Innerhalb eines Steckplatzes überprüfe ich die QObject::sender(), aber jetzt möchte ich diesen Steckplatz direkt als Funktion aufrufen.Qt: Wie man weiß, ob Slot von Signal-Slot-Mechanismus aufgerufen wurde, indem das Signal wie eine Funktion aufgerufen

Kann ich wissen, wie dieser Steckplatz innerhalb des Steckplatzes aufgerufen wurde? Entweder per Signal-Slot-Mechanismus oder einfach durch Aufruf des Slots als Funktion?

+1

Setzen Sie den Code in eine andere Funktion, die eine 'Bool vonSignal' hat, und nennen Sie diese andere Funktion von Ihrem Slot mit' true' und rufen Sie sie direkt mit 'false' an anderer Stelle auf. –

+1

@ JohannesSchaub-litb Das wäre eine bessere Antwort, denke ich, besser als die jetzigen. – hyde

Antwort

1

Sie können die sender() in beiden Fällen überprüfen. Im Falle, dass der Slot über einen Signal/Slot-Mechanismus aufgerufen wird, gibt der Sender einen Zeiger zurück, während er, wenn er als Methode aufgerufen wird, einen Nullzeiger zurückgibt.

Einfaches Beispiel:

class Test : public QObject 
{ 
    Q_OBJECT 
signals: 
    void signal(); 

public slots: 
    void slot() { qDebug() << sender(); } 
}; 

Und die Verwendung:

int main(int argc, char *argv[]) 
{ 
    QApplication a(argc, argv); 

    Test test; 
    Test test2; 

    QObject::connect(&test, &Test::signal, &test2, &Test::slot); 

    test.signal(); //slot is caled by signal 
    test2.slot(); //slot is called as method directly 

    return a.exec(); 
} 

Und die Ausgabe:

Test (0xa8e8aff5b0)

QObject (0x0)

+0

Absender ist nicht null, wenn es als Methode aufgerufen wird – kakush

+0

Es ist sogar in der Dokumentation angegeben: "Gibt einen Zeiger auf das Objekt zurück, das das Signal gesendet hat, wenn es in einem durch ein Signal aktivierten Slot aufgerufen wird; andernfalls gibt es 0 zurück ist nur während der Ausführung des Steckplatzes gültig, der diese Funktion vom Threadkontext dieses Objekts aufruft. " http://doc.qt.io/qt-5/qobject.html#sender – Resurrection

+2

Das "wenn in einem Slot aufgerufen" bedeutet hier vermutlich "wenn während der Aktivierung eines Slots aufgerufen". Das heißt, wenn er den Slot direkt "als eine Funktion" aufruft, aber von einem anderen Slot, der durch ein Signal aufgerufen wird, wird der direkt angerufene Slot einen Rückgabewert ungleich Null beobachten. Aber das ist nicht das, wonach er gesucht hat. Und es macht Ihre Lösung fehlerhaft, wenn nicht ungültig. –

3
  1. einen Standardparameter zu Ihrem Slot hinzufügen:

    public slots: 
        void slot(bool calledBySignal = true); 
    
  2. den Parameter auf false gesetzt, wenn der Schlitz Aufruf direkt:

    void MyClass::method() 
    { 
        [...] 
        slot(false); 
        [...] 
    } 
    
  3. Lassen Sie die connect() Anrufe, wie sie sind; Fügen Sie keinen Bool-Parameter zu den Signalen hinzu, noch ändern Sie SLOT(slot()) zu SLOT(slot(bool)).

Nachteil: Es ist leicht zu vergessen, den Parameter zu setzen.

Wenn Ihr Steckplatz nicht öffentlich sein muss, weil connect() nur innerhalb der Klasse behandelt wird, sollten Sie ihn privat machen und eine Wrapper-Methode hinzufügen, die stattdessen aufgerufen werden soll, aber trotzdem benötigt wird etwas Disziplin beim Anrufen von innerhalb der Klasse. Der Vorschlag von Johannes würde diese Probleme lösen.

Verwandte Themen