Ich entwickle eine wissenschaftliche Datenerfassungsanwendung mit Qt. Da ich kein Experte für Qt bin, möchte ich von der Community einige Ratschläge zu folgendem Problem erhalten:
Die Anwendung unterstützt mehrere Hardware-Erfassungsschnittstellen, aber ich würde gerne eine gemeinsame API zusätzlich zu diesen Schnittstellen bereitstellen. Jede Schnittstelle hat einen Beispieldatentyp und eine Einheit für ihre Daten. Also repräsentiere ich einen Vektor von Proben von jedem Gerät als std::vector
von Boost.Units-Mengen (d. H.% Co_de%). Ich würde gerne eine Multicast-Architektur verwenden, bei der jede Datenquelle neu empfangene Daten an 1 oder mehrere interessierte Parteien sendet. Der Signal / Slot-Mechanismus von Qt passt zu diesem Stil. Daher möchte ich, dass jede Datenquelle ein Signal wie
für die Einheit und den probe_typ, die für dieses Gerät geeignet sind. Da templated std::vector<boost::units::quantity<unit,sample_type> >
subclasses vom Metaobjekt-Compiler nicht unterstützt werden, scheint es keine Möglichkeit zu geben, eine (templated) Basisklasse für alle Datenquellen zu haben, die das QObject
Signal definiert. Mit anderen Worten, das folgende funktioniert nicht :
Die beste Option, die ich mir ausgedacht habe, ist ein zweischichtiger Ansatz:
%Vor% Das Signal samplesAcquired
gibt jetzt einen Zeitstempel und eine Anzahl von Beispielen für die Erfassung an, und Clients müssen die samplesAcquired
API verwenden, um diese Beispiele abzurufen. Natürlich müssen Datenquellen sowohl DataSource als auch IAcquiredSamples
ableiten.
Der Nachteil dieses Ansatzes scheint ein Verlust der Einfachheit in der API zu sein ... es wäre viel schöner, wenn Clients die erfassten Samples in den Slot bekommen könnten. Die Möglichkeit, die in der Warteschlange stehenden Verbindungen von Qt zu verwenden, würde auch Threading-Probleme erleichtern, anstatt sie in der Methode IAcquiredSamples
innerhalb jeder Unterklasse verwalten zu müssen.
Eine andere Möglichkeit ist die Verwendung eines acquiredData
-Arguments. Dies bringt notwendigerweise die Unterklasse dazu, ihren speziellen Abtastvektortyp mit QVariant
/ Q_REGISTER_METATYPE
zu registrieren. Nicht wirklich eine große Sache. Clients der Basisklasse haben jedoch keine Möglichkeit zu wissen, welchen Typ der qRegisterMetaType
-Werttyp hat, es sei denn, eine Tag-Struktur wird auch mit dem Signal übergeben. Ich betrachte diese Lösung als mindestens so verschachtelt wie die obige, da sie Clients der abstrakten Basisklassen-API zwingt, sich mit einigen der gröberen Aspekte des Systemtyps zu befassen.
Gibt es also eine Möglichkeit, den templated Signalparameter zu erreichen? Gibt es eine bessere Architektur als die, die ich vorgeschlagen habe?
Es gibt QVariant-Typ - Sie können Ihren benutzerdefinierten Untertyp darauf erstellen und benutze es als Parameter (wenn ich dein Recht verstehe und das ist, was du willst) in Signalen von Ссылка
Eine Vereinfachung Ihres zweischichtigen Ansatzes wäre, die QObject
-Klasse als eine nicht-gestützte Basis für die Klassenvorlage, d. h. etwas wie
Beachten Sie, dass der Nachteil dieses Ansatzes darin besteht, dass Sie in Qt's Metaobjektsystem keine Informationen darüber finden können, da Sie das Makro Q_OBJECT
in der Klassenvorlage nicht verwenden können.
Qt mag keine Klassenvorlagen, die von QObject erben. Wenn Sie die Laufzeit-Introspektion von QObject nicht benötigen, sollten Sie Boost.Signals verwenden statt dessen, das dieses Problem nicht hat.
Die Einführung der Boost.Signals-Bibliothek in ein Qt-Projekt kann jedoch ein wenig schwierig sein. In Boost.Signals ist signals
ein Namespace, während Qt #define
s signal
bis protected
ist. Sie sollten sicherstellen, dass Ihr Qt-Projekt mit QT_NO_KEYWORDS
definiert ( CONFIG += no_keywords
in qmake) kompiliert, bevor Sie Boost.Signals einführen.
Sie können tatsächlich Qt-Klassen mit Templates verwenden, mit kleinen Änderungen an Ihrem Code.
Das Problem mit Qt-Klassen und Templates ist das Moc-Tool, das die Meta-Objektinformationen generiert, es hat überhaupt keine Kenntnisse über Templates, aber der generierte Code muss nicht von Moc kommen.
Sie können Verdigris verwenden, um Ihre C ++ / QObject-Klasse zu erstellen, die wird Arbeiten Sie mit Vorlagen ohne Probleme und umgehen Sie den Moc-Schritt für solchen Code.
Tags und Links c++ qt4 templates signals-slots