我是QtQuick控件的新手,我想創建一個簡單的GUI,並遇到以下問題,將某些C++變量綁定到qml小部件屬性: 下面簡單的例子,我有一個單獨的組合框,我想分配一個項目列表,並且能夠設置從應用程序的C++端選擇哪個項目。QML綁定整型屬性 - C++中的更改未發送到QML
對於test_list/model對,一切正如我所料,但對於test_index/currentIndex它不是。在test_index被設置爲2並且調用通知之後,沒有任何事情發生 - 我期望應該調用READ方法(getIndex),但它不是(它是針對test_list的)。由於onCurrentIndexChanged,更改GUI的索引工作,即從qml發送到C++端,但它不會以其他方式工作。因此,在調用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: 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();
}
哦......這實際上是有道理的。我不得不說,即使我自己意識到這一點,我不認爲我會弄清楚我必須使用'Qt.binding(...)'語法而不是像'currentIndex: test_index',這看起來很不直觀,我沒有看到在我遇到的任何教程中使用過...儘管如此,非常感謝您的解釋和解決方案。 – tomj
無論何時您編寫信號處理程序代碼,它都是javascript,並且簡單分配不會作爲綁定工作,因此您必須顯式創建綁定。 –