qt - QTQuick design: how to have a global class available from both C++ and QML? -


i'm converting project made borland c++builder. there have class manages messages , electronic device. class (call msgmanager) encapsulate both serial port , tcpsocket, provides unified method , events no matter kind of connection used long properties, , handle whole protocol checks.

i want class "global": each of other classes have pointer msgmanager, qml pages needs use methods , properties. thing qml pages not use various "events" (like datareceived events or error timouts etc)

1) bad design qt applications? seems old habits sometime wrong in new enviroment...

2)if no (or @ least not bad) how can obtain this? tried using qmlregistertype<cmessagemanager>("phase.messagemanager", 1, 0, "messagemanager"); in main.cpp , then

messagemanager { id: msgman; }

in mainform.qml i'm not able "point" class c++... , i'm not able view class qml when create in c++

thanks.

-edit- adding code , asking clarification:

@leemes: detailed (but noob-friendly :) ) answer.

i still have troubles.... previous working code (even before trying adding new class):

#include <qtgui/qguiapplication> #include <qqmlapplicationengine> #include <qtqml> #include <qtquick/qquickview>   // necessario per qquickwindow  #include "ui_updater.h"  int main(int argc, char *argv[]) {     qguiapplication app(argc, argv);     qmlregistertype<ui_updater>("phase.ui_updater", 1, 0, "ui_updater");     qqmlapplicationengine engine(qurl("qrc:/qml/mainform.qml"));     qobject *toplevel = engine.rootobjects().value(0);     qquickwindow *window = qobject_cast<qquickwindow *>(toplevel);     if ( !window ) {         qwarning("error: root item has window.");         return -1;     }     window->show();     return app.exec(); } 

i tried changes:

#include <qtgui/qguiapplication> #include <qqmlapplicationengine> #include <qtqml> #include <qtquick/qquickview>   // necessario per qquickwindow  #include "ui_updater.h"  int main(int argc, char *argv[]) {     qguiapplication app(argc, argv);      // --- changes try setcontextproperty solution -------------------------     //qmlregistertype<ui_updater>("phase.ui_updater", 1, 0, "ui_updater");     //qqmlapplicationengine engine(qurl("qrc:/qml/mainform.qml"));      ui_updater*         ui_up;     ui_up = new ui_updater();      qqmlapplicationengine engine;     engine.rootcontext()->setcontextproperty("ui_updater",ui_up);     engine.setbaseurl(qurl("qrc:/qml/mainform.qml"));     //-------------------------------------------------------------------------      qobject *toplevel = engine.rootobjects().value(0);     qquickwindow *window = qobject_cast<qquickwindow *>(toplevel);     if ( !window ) {         qwarning("error: root item has window.");         return -1;     }     window->show();     return app.exec(); } 

but debugger breaks somewhere in disassembler window "segmentation fault" error. see don't have qquickview (or qtquickapplicationviewer) object mentioned, , can't recall why ended code have (but way found make work :( )

so, me tiny bit again?

first of all, type want export qml world needs accessible qt meta object system in order invoke functions of in qml. requires type inherit qobject , functions slots (or "invokable methods" correct). can add "properties" in classes (to use properties of object in expression), see q_property macro.

creating instance in c++ , exporting address qml common way give qml document ability invoke c++ methods "globally". there lot of use cases in want that, you're on right path there.

if want export type c++ qml want instanciate there, type registration, in code snippet. that's not want, since want create instance in c++ , give pointer qml.

if want export instance of type c++ qml, context properties:

msgmanager *instance = ...; view->rootcontext()->setcontextproperty("msgman", instance); 

where view qquickview (or qtquickapplicationviewer). please note context property has set before setting qml file name in order available beginning.

see also: embedding c++ objects qml context properties


if don't use qquickview want instantiate window (or applicationwindow) within qml, typically use qqmlengine directly. code loading qml file after setting root context property this:

// qml engine: qqmlengine qml; qml.rootcontext()->setcontextproperty("msgman", instance);  // <-- property  // load main window (in example qml/main.qml): qqmlcomponent windowcomponent(&qml, qurl::fromlocalfile("qml/main.qml")); if (windowcomponent.iserror()) {     (auto error : windowcomponent.errors())         qdebug() << error;     return 1;  // exit main function }  // error checking , casting object window qobject *object = windowcomponent.create(); if (!object)     qfatal("failed create instance of main.qml!"); qquickwindow *window = qobject_cast<qquickwindow*>(object); if (!window)     qfatal("top-level item in main.qml not derived qquickwindow!");  // show window window->show(); 

note instance never mentioned in qml other accessing (you don't have code such messagemanager { id: msgman; } in qml file). use name msgman as if there code that. also, instance available in sub-documents include (aka "components").

example: want have status display manager. should display property "ready" made available in class, reporting if device ready communication. declared property q_property macro , want access in qml:

msgmanagerstatus.qml:

import qtquick 2.0  text {     text: msgman.ready ? "device ready." : "device not ready."     color: msgman.ready ? "black" : "red" } 

one last thing mention: if qml document instantiates custom c++ types (custom visual items, c++ models, helper classes, ...), can't access context properties during construction of classes qml components. after finishing construction, class have access qml context in living. there several workarounds that, none of perfect. guess topic beyond question. keep in mind instances of custom c++ types living in qml can access qml context properties after finishing construction.


Comments

Popular posts from this blog

windows - Single EXE to Install Python Standalone Executable for Easy Distribution -

c# - Access objects in UserControl from MainWindow in WPF -

javascript - How to name a jQuery function to make a browser's back button work? -