从 C++ 更新 QML Window 属性标志

Posted

技术标签:

【中文标题】从 C++ 更新 QML Window 属性标志【英文标题】:Update QML Window property flags from C++ 【发布时间】:2021-08-25 20:40:03 【问题描述】:

我有一个基本的 qml 应用程序 QWindow,它已经定义了属性 flags。我想从main.cpp 更改/更新属性flags,使其不是无框的。我知道我可以直接在 QML 中完成,但我想动态更改它而不重新编译。我找到了许多示例,但没有一个示例显示使用 QQmlApplicationEngine::load() 方法后如何执行此操作。我在下面发布了我的代码,我可以看到当前标志十进制值2048 或十六进制值0x800。根据documentation,0x800 的十六进制值指的是当前设置的Qt::FramelessWindowHint。我尝试修改flags 属性,但窗口没有更新。

// Main.qml
import QtQuick 2.9
import QtQuick.Window 2.2

Window 
  id: window
  objectName: "window"
  ...
  flags: Qt.FramelessWindowHint

  ...

// main.cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QWindow>

int main(int argc, char *argv[])

    QGuiApplication app(argc, argv);

    QQmlApplicationEngine engine;
    engine.addImportPath("qrc:/");
    QObject::connect(&engine, &QQmlApplicationEngine::quit, &app,
                     &QGuiApplication::quit);

    const QUrl url(QStringLiteral("qrc:/Main.qml"));
    QObject::connect(
                &engine, &QQmlApplicationEngine::objectCreated, &app,
                [url](QObject *obj, const QUrl &objUrl) 
        if (!obj && url == objUrl) QCoreApplication::exit(-1);
        QVariant obj2 = obj->property("flags");
        if (obj2.isValid()) 
            Qt::WindowFlags flags = qvariant_cast<Qt::WindowFlags>(obj2);
            flags &= ~Qt::FramelessWindowHint;
            auto *tmp = dynamic_cast<QWindow*>(obj);
            tmp->setFlags(flags);
            tmp->show();
        
    ,
    Qt::QueuedConnection);
    engine.load(url);

    return app.exec();

【问题讨论】:

您的代码实际上对我来说很好。我在 Linux 上使用 Qt 5.15.0。 为什么要创建 obj2?您可以轻松地从 c++ 中设置属性。 @JarMan 嗯。我在 Qt 5.15.2 MSVC 2019 64 位。它绝对行不通。我什至尝试过obj-&gt;setProperty("flags", 0); 将标志清零,但也不起作用。 好的,当我想覆盖 Qt.FramelessWindowHint 标志时,看起来我必须使用 obj-&gt;setProperty("flags", Qt::Window); 【参考方案1】:

你有 obj,如果你想改变 main.qml,你可以很容易地向它添加属性:

obj-&gt;setProperty("flags", Qt::FramelessWindowHint);

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QWindow>

int  main(int argc, char *argv[])

    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

    QGuiApplication        app(argc, argv);
    QQmlApplicationEngine  engine;
    const QUrl             url(QStringLiteral("qrc:/main.qml"));
    QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
                     &app, [url](QObject *obj, const QUrl &objUrl)
    
        if (!obj && (url == objUrl))
        
          QCoreApplication::exit(-1);
        

        obj->setProperty("flags", Qt::FramelessWindowHint);
    , Qt::QueuedConnection);

    engine.load(url);

    return app.exec();

已编辑:

【讨论】:

qml Window 中的标志设置为 Qt.FramelessWindowHint 我想像您显示的那样在连接 lambda 中覆盖它,但使用 obj-&gt;setProperty("flags", 0); 但它似乎不适用于 Qt 5.15.2 MSVC 2019 64 位。 它适用于我,我在 ubuntu 中使用 Qt 5.14.0,首先,使用 MinGW .@slayer 尝试它 @slayer ,我编辑并向您展示了我的屏幕和代码,我尝试了您所说的 这就是我最初尝试的方法,但它不适用于 0 作为值。看起来(也许对于 Windows)我必须使用obj-&gt;setProperty("flags", Qt::Window);。现在它按预期工作。 看documentation,好像Qt::Widget设置为0x000000Widgets of this type are child widgets if they have a parent, and **independent windows** if they have no parent.

以上是关于从 C++ 更新 QML Window 属性标志的主要内容,如果未能解决你的问题,请参考以下文章

从高度动态的 C++ 数据模型更新 QML:计时器与属性绑定

QML 对象不更新显示

从 C++ 更改 QML Listview 委托

如何从 C++ 中检索 QML 属性的值?

Qml/QtQuick2 中的 QSignalBlocker?

从宿主语言更新 QML 属性需要啥?