Я новичок в элементах управления QtQuick, я хотел бы создать простой графический интерфейс, и я столкнулся со следующей проблемой при привязке определенных переменных c ++ к свойствам виджетов qml:
В приведенном ниже упрощенном примере у меня есть один комбинированный список, для которого я хотел бы назначить список элементов, а также иметь возможность установить, какой элемент выбирается в пределах стороны c ++ приложения.
Для пары test_list / model все работает именно так, как я и ожидал, но для test_index / currentIndex это не так. После того, как test_index установлен в 2 и вызвано уведомление, ничего не происходит — я ожидаю, что метод READ (getIndex) должен быть вызван, но это не так (это только для test_list). Изменение индекса из графического интерфейса работает, то есть значение отправляется из qml на сторону c ++ из-за onCurrentIndexChanged, но не работает наоборот. Таким образом, после вызова modifyValues () в выпадающем списке есть четыре элемента — 0, 1, 2, 3 — но currentIndex по-прежнему равен 0, поэтому выбран элемент «0» (между тем, test_index равен 2).
Странно то, что getIndex вызывается при первом создании виджета. Я прочитал, что изменение свойства в qml прекратит все декларативные привязки, но я не понимаю, почему это должно происходить здесь, особенно когда это работает для свойства ‘model’ (или другого, который я пробовал, например, 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: 480Rectangle {
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();
}
Давайте разберемся в шагах:
1) Вы создаете комбинированный объект и привязываете его свойства (индекс и модель) к свойствам класса
2) Вы вызываете modifyValues и
а) список изменений, это вызывает изменение модели
б) изменить индекс, это вызывает … ничего
Проблема в шаге 2а. Внутри ComboBox есть следующий код:
onModelChanged: {
...
popup.__selectedIndex = 0
}
Этот вызов нарушает вашу привязку к индексу, поэтому при переходе к шагу 2b привязка больше не существует.
И вот решение вашей проблемы, вы должны обновить привязку после изменения модели:
onModelChanged: {
currentIndex = Qt.binding( function(){return testClassInstance.testIndex} )
}
В качестве быстрого ответа вы можете использовать Connections
,
ComboBox {
id: myCombo
model: testClassInstance.test_list
visible: true
onCurrentIndexChanged: {
testClassInstance.test_index = myCombo.currentIndex
}
Connections {
target: testClassInstance
onNotification: myCombo.currentIndex = test_index;
}
}