Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

QWidget Application w/QML and Registered Types

Tags:

c++

qt

qml

qt5.5

I have a QWidget application that makes use of QML. I have a class that I'm using to expose some of our organizations utility functions.

I have boiled the problem down to the following code (I'll explain my problem below the code):

First, here is the main.cpp file (I've excluded most of the includes for brevity):

#include "main.h"

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    MainWindow window;
    window.show();

    return app.exec();
}

Here is the included main.h:

class MyUtils : public QObject
{
    Q_OBJECT

public:
    MyUtils(QObject* parent = nullptr)
        : QObject(parent)
    {
    }

    virtual ~MyUtils() = default;

    Q_INVOKABLE QString doSomething()
    {
        return QString("I did something!");
    }

    static QObject* MyUtilsProvider(QQmlEngine *engine, QJSEngine *scriptEngine)
    {
        Q_UNUSED(engine)
        Q_UNUSED(scriptEngine)

        qDebug() << "MyUtils Invoked!";
        return new MyUtils();
    }
};

class MyView : public QQuickWidget
{
    Q_OBJECT

public:
    MyView(QWidget* parent = nullptr)
        : QQuickWidget(parent)
    {
        setResizeMode(QQuickWidget::SizeRootObjectToView);
        setSource(QUrl("qrc:/main.qml"));
    }

    virtual ~MyView() = default;
};


class MainWindow : public QMainWindow
{
    Q_OBJECT

    QTabWidget   _tabView;

public:
    MainWindow(QWidget * parent = 0)
        : QMainWindow(parent)
    {
        qmlRegisterSingletonType<MyUtils>("MyUtilities", 1, 0, "myutils", &MyUtils::MyUtilsProvider);
        setCentralWidget(&_tabView);
        _tabView.addTab(new MyView(), "Tab 1");
    }
};

And last, here is my QML file:

import QtQuick 2.1
import MyUtilities 1.0

Rectangle
{
    Text
    {
        text: myutils.doSomething()
        anchors.centerIn: parent
    }
}

What I am trying to do is register the MyUtils class as a singleton that I can then include in my QML and use. The problem is that when I run this, I get the following message from the Application's output:

QML debugging is enabled. Only use this in a safe environment.

Qml debugging is enabled. Only use this in a safe environment!

qrc:/main.qml:8: ReferenceError: myutils is not defined

I have tried putting qmlRegisterSingletonType in main(), before the instantiation of the QApplication object (and in various other places for giggles) but so far I have not been able to get this to work.

I have noticed that if I put a breakpoint or qDebug() message in the MyUtils::MyUtilsProvider method, it never gets called. This leads me to think that maybe my MyView class is using a different QQmlEngine object than the one in which the qmlRegisterSingletonType is registering the singleton with. But if that's the case, then I don't know how to get that engine to then pass to the MyView constructor.

Can someone please tell me what I am doing wrong and how I can get this to work?

Thank you!

like image 808
Addy Avatar asked Mar 22 '26 06:03

Addy


1 Answers

QML component names must begin with capital letters:

qmlRegisterSingletonType<MyUtils>("MyUtilities", 1, 0, "Myutils",
                                  &MyUtils::MyUtilsProvider);

and thus

text: Myutils.doSomething()
like image 56
Kuba hasn't forgotten Monica Avatar answered Mar 24 '26 18:03

Kuba hasn't forgotten Monica