【问题标题】:Get Size of ApplicationWindow in C++在 C++ 中获取应用程序窗口的大小
【发布时间】:2018-07-07 12:24:06
【问题描述】:

如何在 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 内容的大小(减去工具栏、菜单栏等),但我该如何访问呢?

尝试使用property 方法访问window_object 上的window 属性会返回一个空指针。

【问题讨论】:

  • 什么是window_object
  • @eyllanesc,一个从我的代码中复制和粘贴的神器。我更新了 sn-p 以使其更具代表性。

标签: c++ qt qml qt5 applicationwindow


【解决方案1】:

一种可能的解决方案是使用QQmlProperty获取QQuickItem,然后连接信号heightChangedwidthChanged,这些信号只通知属性已更改但不指示值,所以您必须使用方法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;
};

ma​​in.cpp

...
GameObject my_obj_here;

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

ma​​in.qml

ApplicationWindow{


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

【讨论】:

  • 有什么理由使用 qvariant_cast 而不是使用QVariant::value 方法?我觉得value 方法更具可读性,但我想知道这是否是因为我只是不习惯投射,并且想获得外部意见。
  • @BenHoff 他们是等价的,这是一个品味问题:)
猜你喜欢
  • 2021-09-14
  • 1970-01-01
  • 2012-01-26
  • 1970-01-01
  • 2011-10-03
  • 2011-06-13
  • 1970-01-01
  • 2012-11-19
  • 1970-01-01
相关资源
最近更新 更多