QML 动态组合框条目

QML dynamic ComboBox Entrys

本文关键字:组合 动态 QML      更新时间:2023-10-16

我正在尝试在QML和C++中实现一个ComboBox,我可以在其中动态更改ComboBox的内容。我提供了一个QStringList作为组合框模型,并希望使用两个按钮从组合框中插入/删除条目。

我可以在我的组合框中显示 QStringList,但是当我单击添加按钮时,我的 QStringList 在我的类中更新,但不知何故视图不会更新组合框条目。我应该怎么做才能告诉视图我的组合框模型已更新?

这是我的代码:

组合框模型.h

#ifndef COMBOBOXMODEL_H
#define COMBOBOXMODEL_H
#include <QObject>
#include <QStringList>
class ComboBoxModel : public QObject
{
    Q_OBJECT
    Q_PROPERTY(QStringList comboList READ comboList WRITE setComboList NOTIFY comboListChanged)
    Q_PROPERTY(int count READ count WRITE setCount NOTIFY countChanged)
public:
    ComboBoxModel(QObject *parent = 0);
    ComboBoxModel(const QStringList &list,int count, QObject *parent = 0);
    const QStringList comboList();
    void setComboList(const QStringList &comboList);
    int count();
    void setCount(int cnt);
    Q_INVOKABLE void addElement(const QString &element);
    Q_INVOKABLE void removeElement(int index);
signals:
    void comboListChanged();
    void countChanged();
public slots:

private:
    QStringList m_comboList;
    int         m_count;
};
#endif // COMBOBOXMODEL_H

组合框模型.cpp

#include "comboboxmodel.h"
#include "qdebug.h"
ComboBoxModel::ComboBoxModel(QObject *parent) :
    QObject(parent)
{
}
ComboBoxModel::ComboBoxModel(const QStringList &list, int count, QObject *parent) :
    QObject(parent), m_comboList(list), m_count(count)
{
}
const QStringList ComboBoxModel::comboList()
{
    return m_comboList;
}
void ComboBoxModel::setComboList(const QStringList &comboList)
{
    if (m_comboList != comboList)
    {
        m_comboList = comboList;
        emit comboListChanged();
    }
}
int ComboBoxModel::count()
{
    return m_count;
}
void ComboBoxModel::setCount(int cnt)
{
    if (cnt != m_count)
    {
        m_count = cnt;
        emit countChanged();
    }
}
void ComboBoxModel::addElement(const QString &element)
{
    m_comboList.append(element);
    emit comboListChanged();
    setCount(m_comboList.count());
    emit countChanged();
    for (int i = 0; i<m_count; i++)
    {
        qDebug() << m_comboList.at(i);
    }
}
void ComboBoxModel::removeElement(int index)
{
    if (index < m_comboList.count())
    {
        m_comboList.removeAt(index);
        emit comboListChanged();
        setCount(m_comboList.count());
        emit countChanged();
    }
    for (int i = 0; i<m_count; i++)
    {
        qDebug() << m_comboList.at(i);
    }
}

主.cpp

#include <QApplication>
#include <QQmlApplicationEngine>
#include <qqmlengine.h>
#include <qqmlcontext.h>
#include <qqml.h>
#include <QStringList>
#include "comboboxmodel.h"
int main(int argc, char *argv[]) {
    QApplication app(argc, argv);

    QQmlApplicationEngine engine;
    ComboBoxModel combo;
    QStringList tmp;
    tmp << "1" << "2" << "3" << "4" << "5" << "6" << "7";
    combo.setComboList(tmp);
    QQmlContext *ownContext = engine.rootContext();
    ownContext->setContextProperty("myModel", QVariant::fromValue(combo.comboList()));
    QQmlContext *classContext = engine.rootContext();
    classContext->setContextProperty("comboModel", &combo);
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
    return app.exec(); }

主.qml

import QtQuick 2.3 import QtQuick.Controls 1.2
ApplicationWindow {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")
    menuBar: MenuBar {
        Menu {
            title: qsTr("File")
            MenuItem {
                text: qsTr("&Open")
                onTriggered: console.log("Open action triggered");
            }
            MenuItem {
                text: qsTr("Exit")
                onTriggered: Qt.quit();
            }
        }
    }
    Text {
        text: qsTr("Hello World")
        anchors.centerIn: parent
    }
    ComboBox {
        id: comboBox1
        x: 258
        y: 54
        model: myModel
        editable: true
        onAccepted: {
             if (editableCombo.find(currentText) === -1) {
                 model.append({text: editText})
                 currentIndex = editableCombo.find(editText)
             }
         }
    }
    Button {
        id: button1
        x: 280
        y: 139
        text: qsTr("Remove Item")
        onClicked: comboModel.removeElement(comboBox1.currentIndex)
    }
    Rectangle{
        x: 281
        y: 316
        width: 80
        height: 20
        color: "white"
        TextEdit {
            id: textEdit1
            width: 80
            height: 20
            text: qsTr("Text Edit")
            font.pixelSize: 12
        }
    }
    Button {
        id: button2
        x: 280
        y: 388
        text: qsTr("Add Item")
        onClicked: comboModel.addElement(textEdit1.text)
    } }

所以我最终想出了如何做这种事情。

在main.qml中,它应该是:

model: comboModel.comboList

而不是:

model: myModel

现在我可以在列表中添加/删除项目,并且它们会正确显示。

感谢您的提示 BaCaRoZzo。

有人可以将此主题更改为"已解决"吗?

这个例子对我帮助很大,谢谢!这是一个稍微修改的版本作为完成的工作示例:

组合框模型.h

#ifndef COMBOBOXMODEL_H
#define COMBOBOXMODEL_H
#include <QObject>
#include <QStringList>
class ComboBoxModel : public QObject
{
    Q_OBJECT
    Q_PROPERTY(QStringList comboList READ comboList WRITE setComboList NOTIFY comboListChanged)
    Q_PROPERTY(int count READ count WRITE setCount NOTIFY countChanged)
    Q_PROPERTY(int currentIndex READ currentIndex WRITE setcurrentIndex NOTIFY currentIndexChanged)
public:
    ComboBoxModel(QObject *parent = 0);
    ComboBoxModel(const QStringList &list,int count, QObject *parent = 0);
    const QStringList comboList();
    void setComboList(const QStringList &comboList);
    int count();
    void setCount(int cnt);
    int currentIndex();
    void setcurrentIndex(int index);
    Q_INVOKABLE void addElement(const QString &element);
    Q_INVOKABLE void removeElement(int index);
signals:
    void comboListChanged();
    void countChanged();
    void currentIndexChanged();
public slots:

private:
    QStringList m_comboList;
    int         m_count;
    int         m_currentIndex;
};
#endif // COMBOBOXMODEL_H

组合框模型.cpp

#include "comboboxmodel.h"
#include "qdebug.h"
ComboBoxModel::ComboBoxModel(QObject *parent) :
    QObject(parent)
{
}
ComboBoxModel::ComboBoxModel(const QStringList &list, int count, QObject *parent) :
    QObject(parent), m_comboList(list), m_count(count)
{
}
const QStringList ComboBoxModel::comboList()
{
    return m_comboList;
}
void ComboBoxModel::setComboList(const QStringList &comboList)
{
    if (m_comboList != comboList)
    {
        m_comboList = comboList;
        emit comboListChanged();
    }
}
int ComboBoxModel::count()
{
    return m_count;
}
void ComboBoxModel::setCount(int cnt)
{
    if (cnt != m_count)
    {
        m_count = cnt;
        emit countChanged();
    }
}
int ComboBoxModel::currentIndex()
{
    return m_currentIndex;
}
void ComboBoxModel::setcurrentIndex(int index)
{
    if (index != m_currentIndex)
    {
        m_currentIndex = index;
        qDebug()<<"current index is"<<index;
        emit currentIndexChanged();
    }
}
void ComboBoxModel::addElement(const QString &element)
{
    m_comboList.append(element);
    emit comboListChanged();
    setCount(m_comboList.count());
    emit countChanged();
    for (int i = 0; i<m_count; i++)
    {
        qDebug() << m_comboList.at(i);
    }
}
void ComboBoxModel::removeElement(int index)
{
    if (index < m_comboList.count())
    {
        m_comboList.removeAt(index);
        emit comboListChanged();
        setCount(m_comboList.count());
        emit countChanged();
    }
    for (int i = 0; i<m_count; i++)
    {
        qDebug() << m_comboList.at(i);
    }
}

主.cpp

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include <QStringList>
#include "comboboxmodel.h"
int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
    QGuiApplication app(argc, argv);
    QQmlApplicationEngine engine;
    ComboBoxModel combo;
    QStringList tmp;
    tmp << "1" << "2" << "3" << "4" << "5" << "6" << "7";
    combo.setComboList(tmp);
    QQmlContext *ownContext = engine.rootContext();
    ownContext->setContextProperty("myModel", QVariant::fromValue(combo.comboList()));
    QQmlContext *classContext = engine.rootContext();
    classContext->setContextProperty("comboModel", &combo);
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
    if (engine.rootObjects().isEmpty())
        return -1;
    return app.exec();
}

主.qml

import QtQuick 2.3
import QtQuick.Controls 2.2
ApplicationWindow {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")
    Text {
        text: qsTr("Hello World")
        anchors.centerIn: parent
    }
    ComboBox {
        id: comboBox1
        x: 258
        y: 54
        model: comboModel.comboList
        onActivated: {
            console.log("combomodel activated" + comboBox1.currentIndex)
            comboModel.currentIndex = comboBox1.currentIndex
         }
    }
    Button {
        id: button1
        x: 280
        y: 139
        text: qsTr("Remove Item")
        onClicked: comboModel.removeElement(comboBox1.currentIndex)
    }
    Rectangle{
        x: 281
        y: 316
        width: 80
        height: 20
        color: "white"
        TextEdit {
            id: textEdit1
            width: 80
            height: 20
            text: qsTr("Text Edit")
            font.pixelSize: 12
        }
    }
    Button {
        id: button2
        x: 280
        y: 388
        text: qsTr("Add Item")
        onClicked: comboModel.addElement(textEdit1.text)
    } }

亲文件

QT += quick
CONFIG += c++11
DEFINES += QT_DEPRECATED_WARNINGS
SOURCES += main.cpp 
    comboboxmodel.cpp
RESOURCES += qml.qrc
QML_IMPORT_PATH =
QML_DESIGNER_IMPORT_PATH =
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
HEADERS += 
    comboboxmodel.h