C++/QML交互式组合框实现

C++ / QML interactive combo box implementation

本文关键字:实现 组合 交互式 QML C++      更新时间:2023-10-16

我有两个组合框,第二个的数据由第一个的数据决定。第二个组合框中的字符串数从 2 到 4 不等。如果我:

  1. 在第一个组合框中选择一个新字符串,然后
  2. 选择最后一个选项 在第二个组合框中,其列表比上一个列表长 那个盒子,

第二个组合框中的当前字符串将保留并覆盖正确的文本

例如,如果我在第一个组合框中选择 Scubapro(第二个框中有 4 个选项)并在第二个组合框中选择 Smart(第 4 个选项),然后再次选择第一个组合框中的任何其他选项(第二个框中<4 个选项),则第二个组合框中的条目仍然是"智能",这是不合适的。但是,正确的列表将加载到第二个组合框中。对基础字符串列表的检查还表明它包含正确的数据。问题似乎是第二个组合框的视觉更新。该算法的核心来自 Stackoverflow,是组合框 1 中的文本每次更改时调用的生成器。人们可以做些什么来纠正这种情况?

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQuickWindow>
#include <QQuickView>
#include <QQuickItem>
#include <QStringListModel>
#include <QQmlContext>
#include <QDebug>
QStringList dat1, dat2, dat3;
QStringList vendorList;
class Generator : public QObject
    Q_OBJECT
    QStringListModel * m_model;
public:
    Generator(QStringListModel * model) : m_model(model) {}
    Q_INVOKABLE void generate(const QVariant & val) {
        m_model->removeRows(0,m_model->rowCount()); // This has no effect
        if (QString::compare(val.toString(),   QString::fromStdString("Mares"), Qt::CaseInsensitive) == 0) {
            m_model->setStringList(dat1);
        }
        else {
            if (QString::compare(val.toString(),     QString::fromStdString("ScubaPro"), Qt::CaseInsensitive) == 0) {
                m_model->setStringList(dat2);
            }
            else
                m_model->setStringList(dat3);
        }
};

int main(int argc, char *argv[])
{
    QStringListModel model1, model2;
    generator(&model2);
    dat1 << "Puck" << "Nemo" << "Matrix";
    dat2 << "Aladin" << "Meridian" << "Galilio" << "Smart";
    dat3 << "D4" << "D6";
    vendorList << "Mares" << "Scubapro" << "Suunto" << "Shearwater";
    model1.setStringList(vendorList);
    QGuiApplication app(argc, argv);
    QQuickView view;
    QQmlContext *ctxt = view.rootContext(); 
    ctxt->setContextProperty("model1", &model1);
    ctxt->setContextProperty("model2", &model2);
    ctxt->setContextProperty("generator", &generator);
    view.setSource(QUrl("qrc:main.qml"));
    view.show();
    return app.exec();
}
#include "main.moc"

这是QML:

import QtQuick 2.0
import QtQuick.Controls 1.0
Rectangle {
width: 400; height: 300
    Text { text: "Vendor";  }
    Text {
        x: 200
        text: "Product"; }
    ComboBox {
        id: box2
        objectName: "productBox"
        x:200; y:25; width: 180
        model: model2
        textRole: "display"
    }
    ComboBox {
        y:25; width: 180
        id: box1
        model: model1
        textRole: "display"
        onCurrentTextChanged:  {
            generator.generate(currentText)
        }
    }
}

任何评论都非常感谢。

ComboBox项不会对在后台对模型执行的更改做出反应。

有几种解决方案可以解决它。

一种可能的方法是在信号处理程序的末尾使用以下语句将模型重新分配给自身:

model = model;

从文档中:

初始化后更改模型会将当前索引重置为 0。

否则,您可以将currentIndex显式设置为首选值,或者更好的是,设置为 -1
实际上,从文档中我们可以:

将 currentIndex 设置为 -1 将重置所选内容并清除文本标签。