首页 文章

QML绑定整数属性 - c中的更改未发送到QML

提问于
浏览
0

我是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中的属性将终止所有声明性绑定,但我不明白为什么会发生这种情况,特别是当它适用于'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();
}

2 回答

  • 0

    让我们分步进行:

    1)您创建组合框对象并将其属性(索引和模型)绑定到类的属性

    2)你调用modifyValues和a)更改列表,这会触发模型更改b)更改索引,这会触发......什么都没有

    问题出在步骤2a . ComboBox里面有以下代码:

    onModelChanged: {
        ...
        popup.__selectedIndex = 0
    }
    

    此调用会破坏您对索引的绑定,因此当您转到步骤2b时,绑定将不再存在 .

    这里是您的问题的解决方案,您应该在模型更改后更新绑定:

    onModelChanged: {
         currentIndex = Qt.binding( function(){return testClassInstance.testIndex} )
    }
    
  • 2

    作为快速回复,您可以使用Connections

    ComboBox {
           id: myCombo
           model: testClassInstance.test_list
           visible: true
           onCurrentIndexChanged: {
               testClassInstance.test_index = myCombo.currentIndex
           }
           Connections {
               target: testClassInstance
               onNotification: myCombo.currentIndex = test_index;
           }
       }
    

相关问题