Qt Quick-如何仅从c++代码与qml属性交互

Qt Quick - How to interact with a qml property exclusively from the c++ code

本文关键字:qml 属性 交互 代码 c++ Quick- 何仅 Qt      更新时间:2023-10-16

在用Visual Studio 2019编写的Qt5项目中,我必须与c++类中的几个qml属性进行非常密切的通信。更确切地说,我需要能够从我的c++类更改qml窗口的x、y、宽度和高度属性,当这些属性更改时,我还需要收到通知,当然还需要知道新的值。

通过在qml端编写部分代码,我可以找到以下解决方案:

qml文件:

...
ApplicationWindow
{
id: mainWindow
...
onXChanged: {if (mfMainFormHelper) mfMainFormHelper.onFormXChanged(mainWindow.x);}
onYChanged: {if (mfMainFormHelper) mfMainFormHelper.onFormYChanged(mainWindow.y);}
onWidthChanged: {if (mfMainFormHelper) mfMainFormHelper.onFormWidthChanged(mainWindow.width);}
onHeightChanged: {if (mfMainFormHelper) mfMainFormHelper.onFormHeightChanged(mainWindow.height);}
Connections
{
target: mfMainFormHelper
onDoChangeX:
{
mainWindow.x = value;
}
onDoChangeY:
{
mainWindow.y = value;
}
onDoChangeWidth:
{
mainWindow.width = value;
}
onDoChangeHeight:
{
mainWindow.height = value;
}
}
...

WQtMainFormHelper.h

class WQtMainFormHelper : public QObject
{
Q_OBJECT
Q_SIGNALS:
void doChangeX(int value);
void doChangeY(int value);
void doChangeWidth(int value);
void doChangeHeight(int value);
...
public:
...
virtual Q_INVOKABLE void onFormXChanged(int value);
virtual Q_INVOKABLE void onFormYChanged(int value);
virtual Q_INVOKABLE void onFormWidthChanged(int value);
virtual Q_INVOKABLE void onFormHeightChanged(int value);
...

main.cpp

...
WQtMainFormHelper mainFormHelper;
m_pQTEngine->rootContext()->setContextProperty("mfMainFormHelper", &mainFormHelper);
...

这个解决方案运行得很好,但被我的老板拒绝了,因为他要求所有这部分代码都只能在c++端编写。

因此,我的问题是:如何实现与上述完全相同的功能,但在我的c++类中编写所有代码,而在qml端没有ANY行代码?

尝试替换Q_SIGNAL&Q_INVOKABLE与Q_PROPERTIES&实现所有时隙/信号。在UI中,对所有4个属性使用mainWindow中的属性绑定,如"x:mfMainFormHelper.x"。

不要使用签名运算符,它会破坏属性绑定(即通知停止对该属性的工作(

我终于可以通过以下方式解决我的问题:

  1. 我创建了一个继承自QObject的类
  2. 在加载qml之后,我从QQmlApplicationEngine获得了作为QWindow对象的qml窗口指针
  3. 我使用connect((函数连接我需要的信号,如下例所示:connect(pQtWindow, &QWindow::widthChanged, this, &WQtFormHelper::onFormWidthChanged);
  4. 我使用Qt代理读取和写入我的窗口属性,如以下示例所示:int value = QQmlProperty(pQtWindow, "width").read().value<int>();

    QQmlProperty(pQtWindow, "width").write(1000);

    (注意pQtWindow->setProperty("width", 1000);也起作用(