【发布时间】:2016-02-26 01:41:28
【问题描述】:
我是 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
}
}
}
}
testClass.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
main.cpp
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();
}
【问题讨论】:
标签: c++ qml qt5 qtquick2 qtquickcontrols