Search code examples
c++qtqmlqt5applicationwindow

Get Size of ApplicationWindow in C++


How do you get the size of the QML ApplicationWindow in C++?

QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));

if (engine.rootObjects().isEmpty())
    return -1;

QObject *application_object = engine.rootObjects().first();

// Throws ApplicationWindow_QMLTYPE_11::height(int), no such signal
QObject::connect(application_object, SIGNAL(height(int)), &my_obj_here, SLOT(set_game_height(int)));
QObject::connect(application_object, SIGNAL(width(int)), &my_obj_here, SLOT(set_game_width(int)));

return app.exec();

I realize that I'm also not getting the size of the contents of the ApplicationWindow (minus the toolbar, menubar etc), but how do I get access to that?

Trying to access the window property on the window_object using the property method returns a null pointer.


Solution

  • One possible solution is to use QQmlProperty to obtain the QQuickItem, then connect with the signals heightChanged and widthChanged, these signals only notify that the property has changed but it does not indicate the value, so you must use the method height() and width().

    QObject *topLevel = engine.rootObjects().first();
    QQuickItem *contentItem =qvariant_cast<QQuickItem *>(QQmlProperty::read(topLevel, "contentItem"));
    if(contentItem){
        QObject::connect(contentItem, &QQuickItem::heightChanged,
                         [&my_obj_here, contentItem](){
            my_obj_here.set_game_height(contentItem->height());
        });
        QObject::connect(contentItem, &QQuickItem::widthChanged, 
                         [&my_obj_here, contentItem](){
            my_obj_here.set_game_width(contentItem->width());
        });
    }
    

    Another solution is to make the connection on the QML side, for this you must create the q-property:

    class GameObject: public QObject{
        Q_OBJECT
        Q_PROPERTY(int game_width READ game_width WRITE set_game_width NOTIFY game_widthChanged)
        Q_PROPERTY(int game_height READ game_height WRITE set_game_height NOTIFY game_heightChanged)
    public:
        using QObject::QObject;
        int game_width() const{
            return m_width;
        }
        void set_game_width(int width){
    
            if(width == m_width)
                return;
            m_width = width;
            emit game_widthChanged();
        }
        int game_height() const{
            return m_height;
        }
        void set_game_height(int height){
            if(height == m_height)
                return;
            m_height = height;
            emit game_heightChanged();
        }
    signals:
        void game_widthChanged();
        void game_heightChanged();
    private:
        int m_width;
        int m_height;
    };
    

    main.cpp

    ...
    GameObject my_obj_here;
    
    QQmlApplicationEngine engine;
    engine.rootContext()->setContextProperty("my_obj_here", &my_obj_here);
    ...
    

    main.qml

    ApplicationWindow{
    
    
        Connections{
            target: contentItem
            onHeightChanged:
                my_obj_here.game_height = height
            onWidthChanged:
                my_obj_here.game_width = width
        }
        ...