首页 > 解决方案 > 在 C++ 中获取应用程序窗口的大小

问题描述

你如何在 C++ 中获得 QML ApplicationWindow 的大小?

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();

我意识到我也没有获得 ApplicationWindow 内容的大小(减去工具栏、菜单栏等),但是我如何访问它呢?

尝试使用该方法访问该window属性会返回一个空指针。window_objectproperty

标签: c++qtqmlqt5applicationwindow

解决方案


一种可能的解决方案是使用QQmlProperty获取QQuickItem,然后与信号heightChanged和连接widthChanged,这些信号仅通知属性已更改但不指示值,因此您必须使用方法height()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());
    });
}

另一种解决方案是在QML侧面进行连接,为此您必须创建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;
};

主文件

...
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
    }
    ...

推荐阅读