我是 QtQuick 控件的新手,我想创建一个简单的 GUI,并且在将某些 c++ 变量绑定到 qml 小部件属性时遇到了以下问题:在下面的简化示例中,我有一个我想为其分配的组合框项目列表,还可以设置从应用程序的 c++ 端选择的项目。
对于 test_list/model 对,一切都按照我的预期工作,但对于 test_index/currentIndex 则不是。在 test_index 设置为 2 并调用通知后,什么也没有发生 - 我希望应该调用 READ 方法(getIndex),但它不是(虽然它是用于 test_list)。从 GUI 更改索引是可行的,即由于 onCurrentIndexChanged 将值从 qml 发送到 c++ 端,但反之则不起作用。所以调用 modifyValues() 后,组合框中有四个项目 - 0、1、2、3 - 但 currentIndex 仍然为 0,因此选择了“0”项目(同时,test_index 等于 2)。
奇怪的是 getIndex 确实在第一次创建小部件时被调用。我已经读过更改 qml 中的属性将终止所有声明性绑定,但我不明白为什么会在这里发生这种情况,尤其是当它适用于“模型”属性(或我尝试过的其他属性,例如 currentText)时。尽管如此,我也尝试将myCombo.currentIndex = testClassInstance.test_index
onCurrentIndexChanged 放入,但这无济于事(而且它似乎不正确......)。
我的问题: currentIndex 属性有什么特别之处吗?如何在不借助 qml 中显式定义信号连接的情况下实现我想要的(我认为这基本上就是 Q_PROPERTY 宏的用途)?我想我可以想出一些解决方法来实现我的目标,所以这不是我在这里寻找的——相反,如果有人可以向我解释为什么这种特殊方法没有按我期望的方式工作,我更愿意。
main.qml
import QtQuick 2.4
import QtQuick.Controls 1.3
import QtQuick.Dialogs 1.2
ApplicationWindow {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
MainForm {
objectName: "mainForm"
anchors.fill: parent
}
}
MainForm.qml
import QtQuick 2.4
import QtQuick.Controls 1.3
import QtQuick.Layouts 1.1
Item {
width: 640
height: 480
Rectangle {
anchors.centerIn: parent
ComboBox {
id: myCombo
model: testClassInstance.test_list
currentIndex: testClassInstance.test_index
visible: true
onCurrentIndexChanged: {
testClassInstance.test_index = myCombo.currentIndex
}
}
}
}
测试类.h
#ifndef TESTCLASS_H
#define TESTCLASS_H
#include <QObject>
class testClass : public QObject
{
Q_OBJECT
Q_PROPERTY(int test_index READ getIndex WRITE setIndex NOTIFY notification)
Q_PROPERTY(QStringList test_list READ getList WRITE setList NOTIFY notification)
public:
testClass(QObject *parent) : QObject(parent) {}
~testClass() {}
void modifyValues()
{
test_list << "1" << "2" << "3";
notification();
test_index = 2;
notification();
}
int getIndex() { return test_index; }
QStringList getList() { return test_list; }
void setIndex(int val) { test_index = val; }
void setList(QStringList val) { test_list = val; }
signals:
void notification();
private:
int test_index = 0;
QStringList test_list = QStringList("0");
};
#endif
主文件
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QQmlApplicationEngine engine;
testClass test(&engine);
engine.rootContext()->setContextProperty("testClassInstance", &test);
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
test.modifyValues();
return app.exec();
}