User Tools

Site Tools


id_qml_module_dev

This is an old revision of the document!


QML Module Concept

Unser Tool ist frontendseitig modular aufgebaut (verschiedene Viewer). Jedes Modul löst ein Visualisierungs oder Analyseproblem odr ermöglicht die Bearbeitung von Datenmanipulationen etc. Solche Module sind beispielsweise der “TableViewer”, der “PlotViewer”, etc. Dadurch ist es möglich unterschiedliche Modulkombinationen dem Kunden anbieten zu können.

  Hinweis2: Ein beispielhaftes Modul ist mit "ModuleExamplicTemplate" im Source zu finden. Es dient als
  Vorlage um sich zu orientieren, wenn man eigene Module entwickeln möchte.

Die Module werden QML seitig (also seitig der UI) über eine jeweils seperate QML je Modul gepflegt und in die main.qml eingebunden. Beispielsweise enthält die QML_For_Module_TableViewer.qml die UI-Komponenten der für das TableViewer Modul. Auch jedes neue Modul benötig eine entsprechende eigene QML, welche als Namenskonvention wie folgt zu benennen ist QML_For_Module_<Name des Moduls>.qml .

In der main.qml sind lediglich die QML-Dateien der Module einzubinden. UI-Code für ein bestimmtes Modul, gehört nicht in die main.qml, sondern immer in die QML des entsprechenden Moduls.



Beteiligte Klassen und QML-Files

Um dieses Modul Konzept zu ermöglichen, bedarf es einem deizitierten Zusammenspiel aus C++ Klassen und QML-Dateien, welche folgend erläutert werden. Nehmen wir dafür an, wir möchten ein Module <module> erstellen und dem Tool hinzufügen. Da Klassen immer auch header Dateien benötigen, lasse ich in der Beschreibung im Folgenden header Dateien einfach weg, da es klar ist, das diese auch zu implementieren sind. Beteiligte Klassen und QML-Files für unser <module>-Beispiel wären dann:

IUI/sources

  • IsModule.cpp
  • ContainerUI.cpp
  • <module>.cpp
  • GuiState.cpp

resources

  • QML_For_<module>.qml
  • qml.rc
  • main.qml

Die Klassen/QML welche <module> beinhalten, sind neu zu erstellen und implementieren die Funktionalität unseres Modules. Alle anderen genannten Daten sind bereits vorhanden, und von diesen wird im Weiteren entweder einfach abgeleitet, oder es gibt notwendige Anpassungen in diesen Dateien, wie folgt detailiert erläutert



Detailierte Beschreibung des Zusammenspiels zuvor genannter Daten um ein neues Modul dem Tool hinzuzufügen

* IsModule.cpp ist ein abstraktes Interface von welchem abgeleitet wird um ein Modul als solches zu kennzeichnen.

Es enthält die Methode "updateModule()", welche jedes Modul das von IsModule abgeleitet wird, zu
implementieren hat. Diese Methode wird im späteren in einem Modul immer dann aufgerufen, wenn der
Zustand eines Moduls aktualisiert werden muss, z.B. wenn ein Datensatz geladen wird. 
  • ContainerUI.cpp ist eine Klasse welche verwendet wird um alle Module zu managen, und zu verwalten (auch die internationalisierung der Sprachen und das Laden von Daten ist hier implmentiert.)
 Es enthält die Klassen-Methode "void registryModule(IsModule *pointer_on_an_Is_Module_Object)", welche
 verwendet wird um eine Klasse welche von "IsModule" abgeleitet wurde, tool-weit als eine Modul zu registrieren.
 Zudem gib es hier eine Liste als Klassen-Member mit Zeigern auf alle registrierten Module des Tools,
 "ContainerUI::mIsRegistryAsAModuleListVector".
 
 

* <module>.cpp implementiert das neue Modul, beispielsweise als QQuickPaintedItem oder Ähnliches.

Dabei ist <module>.cpp von der Klasse "IsModule.cpp" abzuleiten, nur adurch wird es als Modul im Rahmen
unseres Modulkonzeptes nutzbar. In dem Konstruktor von <module>.cpp is das Modul nun noch zu
registrieren durch den aufruf von "ContainerUI::registryModule(this)". Dadurch wird das Modul in der
Modulliste von ContainerUI per Zeiger hinterlegt. Zudem muss das Modul im Konstructor noch benannt werden,
durch this->mStringTypeName="Module Viewer >";.  Nun ist noch die geerbte Mehtode "updateModule()"
zu implementieren.

* GuiState.cpp verwaltet den Zustand des Tools.

 Hier ist das neue Modul für die Nutzung in qml bekannt zumachen, innerhalb der exec()-Methode.
 Dafür füg man dort hinzu:
 qmlRegisterType<module>("mpv.module", 1, 0, "module");
 
 

* QML_For_<module>.qml ist als neue qml für das neue Modul anzulegen, dort wo auch die main.qml liegt.

In dieser QML werden alle relevanten UI Funktionen implementiert. das neue Modul wird in seiner
QML bekannt gemacht durch "import mpv.<module> 1.0".

Nach dem initialen "Item{" oder ähnliches
ist zwingend das folgende in die qml zu schreiben:

 property int thisIntQML_Modules_Visible_Variable : 0
 property int thisIntQML_Module_Index_Variable : -1
      Connections {
          target: appWindow
          onSQML_Modules_Visible_Changed_Signal: {
              if(thisIntQML_Modules_Visible_Variable==thisIntQML_Module_Index_Variable){
                  visible = true;
              }
              else{visible = false;}
          }
      } 
 Dadurch wird das Modul mit dem Reiter-Button system verbunden, welches einen button erzeugt um das Modul
 sichtbar werden zu lassen im Tool.
 Zudem muss das modul min einmal in seiner qml instanziiert werden  z.B. durch "<module>{}" damit einmal der
 Konstruktor aufgerufen wird und das Modul so registriert ist.

* qml.rc führt alle Resourcen des tools auf. Hier muss die qml-Datei des Moduls hinzugefügt werden damit

  sie im weiteren dem Tool zur Nutzung bekannt ist, durch hinzufügen von:  <file><module>.qml</file>

* main.qml erstellt alle Module, so dass sie zur Laufzeit nutzbar sind. Hier ist hinzuzufügen:

  
  QML_For_Module_<module>{
      id: qmlModule<module>Viewer
      z: 200
      visible: false;
      thisIntQML_Modules_Visible_Variable : intQML_Modules_Visible_Variable
      thisIntQML_Module_Index_Variable : containerUI.getModuleIndex("Module Viewer >");
  }
  Dadurch wird das Modul zur Laufzeit erstellt und kann im Tool genutzt werden. Bitte darauf achten das
  der String "Module Viewer >" exakt der gleiche ist, wie er im Konstructor von <module>.cpp bei
  this->mStringTypeName  genannt wurde (sonst funktioniert es nicht).
  Nun ist das Modul angemeldet, eingebunden und kann genutzt werden. Wann immer Module aktualisiert werden
  müssen, kann an jeder beliebigen Stelle im qml einfach "containerUI.updateAllModules();" aufgerufen werden,
  wodurch für jedes registrierte Modul seine jeweils eigene "updateModule()" Methode aufgerufen wird.
  
  Hier erschließt sich auch der Sinn des Modulkonzeptes: durch einfaches ein und auskommentieren der
  Module in der main.qml können unterschiedliche Modulkonfigurationen, also verschiedene Toolversionen,
  erzeugt werden; und so wird ein kundenspezifisches Pricing ermöglicht. 


  Hinweis: Hin und wieder kann es notwendig sein von qml Objkten bestimmte Eigenschaften aud dem c++ code selbst
  heraus zu setzen, anstatt über die qml Files selbser. Dafür gib es GuiState die Klassenfunktion
  "Object Object= static QObject * m_getQMLObjectAsQObject(QString QML_Object_String);" welche das
  QObject aus dem qml zurückgibt, das als Objektname 'objectName: "QML_Object_String" ' besitzt.
  Die Eigenschaften können dann leicht wie folgt gesetzt werden:
  
  if(QML_Object) {
      QML_Object->setProperty("visible", true);
      QML_Object->setProperty("enabled", true);
  }
  Hinweis2: Ein beispielhaftes Modul ist mit "ModuleExamplicTemplate" im Source zu finden. Es dient als
  Vorlage um sich zu orientieren, wenn man eigene Module entwickeln möchte.
id_qml_module_dev.1516510988.txt.gz · Last modified: 2018/01/21 06:03 by 178.0.146.219