简体   繁体   English

QML 动态组合框条目

[英]QML dynamic ComboBox Entrys

i'm trying to implement a ComboBox in QML and C++, in which i can dynamically change the content of my ComboBox.我正在尝试用 QML 和 C++ 实现一个 ComboBox,在其中我可以动态更改 ComboBox 的内容。 I'm providing a QStringList as ComboBox-Model and want to insert/remove an entry from the ComboBox with two buttons.我提供了一个 QStringList 作为 ComboBox-Model 并且想要从带有两个按钮的 ComboBox 中插入/删除一个条目。

I can display the QStringList in my ComboBox, but when i click on the Add-Button for example, my QStringList gets updated in my class, but somehow the View does not update the ComboBox entrys.我可以在我的 ComboBox 中显示 QStringList,但是例如,当我单击 Add-Button 时,我的 QStringList 在我的班级中得到更新,但不知何故视图没有更新 ComboBox 条目。 What should i do, to tell the View that my ComboBox-Model has updated?我应该怎么做,告诉 View 我的 ComboBox-Model 已经更新?

This is my code:这是我的代码:

comboboxmodel.h组合框模型.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

comboboxmodel.cpp组合框模型.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);
    }
}

main.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(); }

main.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)
    } }

So i finnaly figured out how to do this kind of stuff.所以我最终想出了如何做这种事情。

In main.qml it should be:在 main.qml 中它应该是:

model: comboModel.comboList

instead of:代替:

model: myModel

Now i can add/remove items from my list and they are displayed correctly.现在我可以从我的列表中添加/删除项目并且它们正确显示。

Thanks for your hint BaCaRoZzo.感谢您的提示 BaCaRoZzo。

Can somebody change this subject to "Solved"?有人可以将此主题更改为“已解决”吗?

The example has helped me a lot, thank you!这个例子对我帮助很大,谢谢! Here's a slightly modified version as a finished working example:这是一个稍微修改过的版本,作为一个完成的工作示例:

comboboxmodel.h组合框模型.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

comboboxmodel.cpp组合框模型.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);
    }
}

main.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();
}

main.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)
    } }

pro-file轮廓

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM