Seite 1 von 1

Interface mit Signal und Slot

Verfasst: 17. Dezember 2010 17:21
von anno1988
Hallo zusammen,

ist es möglich in Qt ein Interface für ein eigenes Plugin mit Signals und Slots zu programmieren?


Wenn ja, könnte das so gehen?

Code: Alles auswählen


#include <QObject>

class TestInterface : QObject {

	Q_OBJECT

	public:
		virtual void setTestValue(int value) = 0;

	signals:
		void Signal1(QString moduleid, QString data);

	public slots:
		virtual void Slot1(QString moduleid, QString data) = 0;
		virtual void Slot2(QString moduleid, QFile *file) = 0;

};

Q_DECLARE_INTERFACE(TestInterface "org.qt.TestInterface");


Verfasst: 17. Dezember 2010 17:43
von franzf
Ja, das geht. Du musst nur sicher stellen, dass auch der gemocte Header verfügbar ist. Also entweder in jedem Plugin mitkompilieren+linken, oder gleich in eine eigene lib packen, die mitgelinkt wird. Vllt. hast du in deinem Projekt sowieso schon eine extra lib (die jedes Plugin mitlinkt), dann packst du das einfach da mit rein.

Verfasst: 17. Dezember 2010 20:58
von anno1988
aber führt das nicht zu problemen, wenn ich bereits in der Klasse in er das Interface eingebunden wird bereits eine QObject-Klasse vererbt habe?

denn da bekomme ich folgende Meldung vom compiler:

Code: Alles auswählen

QObject’ is an ambiguous base of

Verfasst: 17. Dezember 2010 21:33
von Christian81
Wenn das Interface schon von QObject abgeleitet wird - warum dann nochmal von QObject ableiten?

Verfasst: 17. Dezember 2010 21:37
von anno1988
ja, das hatte ich mir auch shcon gedacht. wenn ich aber die Vererbung vom QObject in meinem Plugin raus nehme, bekomme ich diese Meldung:

Code: Alles auswählen

QObject’ is an inaccessible base of MyPlugin.
Obwohl ich die Klasse vom Interface vererbt habe.

Verfasst: 17. Dezember 2010 21:46
von Christian81
Wie wärs mit C++ Grundlagen?

Code: Alles auswählen

class TestInterface : QObject
QObject wird private vererbt...

Verfasst: 17. Dezember 2010 22:07
von anno1988
:oops: stimmt, da hätte ich auch selbst drauf kommen müssen. thx. das habe ich da ganz übersehen.

Verfasst: 18. Dezember 2010 21:21
von Giesbert
aber ob das zu 100% funktioniert? wenn du 2 ableitungen von der selben Klasse hast, kann es schon zu problemen kommen, gerade bei QObject, wo ja einiges an Code mit eingezogen wird: Stichwort: Meta Object Code.

Dann hast du 2 x die Meta info. Wenn jetzt jemand ein signal / einen slot von dir verwenden möchte, geht das connectr statement an deine meta info. ubnd die geht an die der basisklasse, aber welcher der 2??? üblicherweise die der ersten....

Wen du also multiple inheritance hast und deine klasse von QObject und von interfaces ableiten willst, hast du in den interfaces wohl eher keine signals/slots, fürchte ich.

Verfasst: 19. Dezember 2010 09:11
von padreigh
http://doc.qt.nokia.com/latest/plugins- ... plications
Making an application extensible through plugins involves the following steps:

1. Define a set of interfaces (classes with only pure virtual functions) used to talk to the plugins.
Ich würde mal vermuten das diese Bedingung wegfällt sobald du von QObject erbst da dieses garantiert nicht pure virutal ist...

Verfasst: 19. Dezember 2010 10:47
von franzf
Giesbert hat geschrieben:aber ob das zu 100% funktioniert? wenn du 2 ableitungen von der selben Klasse hast, kann es schon zu problemen kommen, gerade bei QObject, wo ja einiges an Code mit eingezogen wird: Stichwort: Meta Object Code.
2x von QObject (Interface + konkretes Plugin) ist eh nicht nötig. Wenn das Plugin selber nicht zusätzlich von QObject sondern z.B. von QWidget ableitet, hast du natürlich ein Problem!

Das mit dem pure-virtual-Interface macht schon irgendwo Sinn.
Um das Problem mit SIGNALS/SLOTS im Interface zu umgehen, hast du mehrere Möglichkeiten.
1) Das Signal/Slot-System in Qt läuft über Strings, bei falschen Namen beim connect gibt es zur Laufzeit eine Meldung (hat sicher jeder schonmal gesehen). In der eigenen Doku angeben "wenn dies und das funktionieren soll, bitte SIGNAL soundso und SLOT soundso im Plugin implementieren" - fertig. Schon ist das Interface pure virtual und kein QObject mehr.

2) Dem Interface eine Methode "bool connectToActionXYZ(const QObject*) const =0;" geben, die implementiert werden MUSS. In dieser Methode kann dann das konkrete Plugin connecten was es will.

1 ist bequem schränkt aber bei der Namensgebung ein, 2 hebt diesen Nachteil auf, zwingt aber den Benutzer eine eigene Methode zu implementieren nur für die connects.

Ich selber hatte schonmal ein System mit Interface-Klassen von QObject abgeleitet am Laufen, das war aber mehr auf Unerfahrenheit als auf absolute Notwendigkeit zurückzuführen. Es hat funktioniert (Lösung war diejenige mit eigener Lib, wo das das Interface-MOC-Zeugs drin gesteckt hatte).
Ich würde heute eher Lösung 1) fahren.