Ein ziemlich häufiges Problem bei der Arbeit mit Signalen mit Slots in Qt5 ist nach meinen Beobachtungen von Fragen im Forum die Verbindung von Slots innerhalb der Syntax mit Zeigern auf Signale, die eine Signaturüberladung haben. Gleiches gilt für überlastete Slots.
Nehmen wir eine Testklasse mit überlasteten Signalen.
#include <QObject> class TestClass : public QObject { Q_OBJECT public: explicit TestClass(QObject *parent = nullptr); signals: void testSignal(int arg1); void testSignal(int arg1, int arg2); };
Hier ist ein Signal mit Signaturüberlastung. Dieses Signal wird auch mit Slots verbunden, die in der Widget -Klasse deklariert sind und die ebenfalls eine Signaturüberladung haben.
#include <QWidget> #include "testclass.h" namespace Ui { class Widget; } class Widget : public QWidget { Q_OBJECT public: explicit Widget(QWidget *parent = 0); ~Widget(); private slots: void onTestSlot(int arg1); void onTestSlot(int arg1, int arg2); private: Ui::Widget *ui; TestClass* m_testClass; };
Wie in Qt4
Im Rahmen von Qt4 wurde alles ganz einfach gelöst, indem in den Makros SIGNAL und SLOT. die Signatur des Signals und der Slot angegeben wurden.**
connect(m_testClass, SIGNAL(testSignal(int,int)), this, SLOT(onTestSlot(int,int))); connect(m_testClass, SIGNAL(testSignal(int)), this, SLOT(onTestSlot(int)));
Wie es in Qt5 wurde
Aber in Qt5 gibt es beim Schreiben in die neue Signal- und Slot-Syntax einige Probleme. Da es erforderlich ist, static_cast -Methodensignaturen auszuführen.
connect(m_testClass, static_cast<void(TestClass::*)(int)>(&TestClass::testSignal), this, static_cast<void(Widget::*)(int)>(&Widget::onTestSlot)); connect(m_testClass, static_cast<void(TestClass::*)(int, int)>(&TestClass::testSignal), this, static_cast<void(Widget::*)(int, int)>(&Widget::onTestSlot));
Übrigens erlaubt die neue Syntax auch, Signale mit kleineren Signaturen an Slots zu binden, wie es in Qt4 der Fall war.
connect(m_testClass, static_cast<void(TestClass::*)(int, int)>(&TestClass::testSignal), this, static_cast<void(Widget::*)(int)>(&Widget::onTestSlot));
Vorteile der neuen Syntax
Und jetzt der Stolperstein. Warum die neue Signal- und Slot-Syntax verwenden? Diese Frage höre ich immer noch ab und zu. Vor allem, wenn die Leute so schreckliche Kasten von Unterschriften sehen.
Hier sind also die potenziellen Vorteile:
- Die Fähigkeit, Fehler in der Verbindung von Signalen und Slots in der Kompilierungsphase und nicht zur Laufzeit zu verfolgen
- Reduzieren der Kosten für die Kompilierzeit durch Eliminieren von Makros aus dem Code
- Die Fähigkeit, Lambda-Funktionen zu verbinden, das ist ein ziemlich wichtiges Brötchen
- Wir schützen uns vor Fehlern, wenn wir versuchen, uns von außen mit einem privaten Slot zu verbinden. Ja!! Ja!! Die Makros SIGNAL und SLOT ignorieren Methodenzugriffsebenen und verletzen OOP.
Im Allgemeinen reicht mir das schon, aber dir?
Отличная необходимая статья.