在用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"。
不要使用签名运算符,它会破坏属性绑定(即通知停止对该属性的工作(
我终于可以通过以下方式解决我的问题:
- 我创建了一个继承自
QObject
的类 - 在加载qml之后,我从
QQmlApplicationEngine
获得了作为QWindow
对象的qml窗口指针 - 我使用connect((函数连接我需要的信号,如下例所示:
connect(pQtWindow, &QWindow::widthChanged, this, &WQtFormHelper::onFormWidthChanged);
-
我使用Qt代理读取和写入我的窗口属性,如以下示例所示:
int value = QQmlProperty(pQtWindow, "width").read().value<int>();
QQmlProperty(pQtWindow, "width").write(1000);
(注意
pQtWindow->setProperty("width", 1000);
也起作用(