从cpp中的随机函数到qml

时间:2019-07-18 06:53:29

标签: c++ qt qml

我有一个类,我可以从构造函数中获取数据以在qml中的T​​ableView中显示它,但是问题是当我想从该类的另一个函数中显示数据时。例如:

main.cpp

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQuickView>
#include <QQmlContext>
#include "myclass.h"

int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);
    QQmlApplicationEngine engine;
    MyModel *myTable=new MyModel;
    engine.rootContext()->setContextProperty("myTable", myTable);
    const QUrl url(QStringLiteral("qrc:/main.qml"));
    QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
                     &app, [url](QObject *obj, const QUrl &objUrl) {
        if (!obj && url == objUrl)
            QCoreApplication::exit(-1);
    }, Qt::QueuedConnection);
    engine.load(url);

    return app.exec();

}

MyModel.h

struct Info
{
    QString name;
    QString address;
    QString values;
    QString salary;
};

class MyModel : public QAbstractTableModel
{
    Q_OBJECT

public:
    MyModel(QObject *parent=nullptr);
.
////some variables declared////
.
Q_INVOKABLE int rowCount(const QModelIndex &parent = QModelIndex()) const override;
Q_INVOKABLE int columnCount(const QModelIndex &parent = QModelIndex()) const override;
Q_INVOKABLE QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const override;
Q_INVOKABLE QHash<int,QByteArray> roleNames() const override;
private:
    QList<Votes> m_model;

MyModel.cpp

MyModel::MyModel(QObject *parent)
    : QAbstractTableModel{parent}
{
    m_model.append({"name1","add1","value1","salary1"});
    m_model.append({"name2", "add2","value2","salary2"});
    m_model.append({"name3","add3","value3","salary3"});
} ////I can see this in TableView

void MyModel::mapTable(QVector<QStringList> mapGroup)
{
    for(int i=0;i<mapGroup.count();i++)
    {
        m_model.append ({mapGroup[i][0], mapGroup[i][1], mapGroup[i][2], mapGroup[i][3});
    }
} ////I cannot see this in TableView

...

MyModel.qml

import QtQuick 2.0
import QtQuick.Controls 1.4 as CI

CI.TableView
{
    model: myTable

CI.TableViewColumn
{
    role: "name"
    title:"Name"
    width: 100
}
CI.TableViewColumn
{
    role: "add"
    title:"Address"
    width: 100
}
CI.TableViewColumn
{
    role: "value"
    title:"Value"
    width: 100
}
CI.TableViewColumn
{
    role: "salary"
    title:"Salary"
    width: 100
}
}

Dialog.qml

...
Rectangle
    {
        id: tableRec
        width: parent.width/1.5
        height: parent.height/2

        MyModel
        {
            id: infoTable
            width: tableRec.width
            height: tableRec.height
            anchors.fill: parent

            rowDelegate: Rectangle
            {
                id: rowTable
                height: 15

                SystemPalette
                {
                    id: myPalette
                    colorGroup: SystemPalette.Active
                }
                color:
                {
                    var baseColor = styleData.alternate?myPalette.alternateBase:myPalette.base
                    return styleData.selected?myPalette.highlight:baseColor
                }
            }

            itemDelegate: Item
            {
                Text
                {
//                    anchors.centerIn: parent
                    anchors.verticalCenter: parent.verticalCenter
                    text: styleData.value
                    font.pixelSize: Math.round(infoTable.height)/16
                }
            }
        }

如何将数据从mapTable函数传递到TableView?我知道这与QAbstractTableModel有关,但我无法使其正常工作。

1 个答案:

答案 0 :(得分:0)

基于内部数据模型创建自定义模型时,必须通知视图已插入/删除的行。

模型不知道何时更改其内部模型。这就是为什么您必须在beginInsertRows方法中使用endInsertRowmapTable的原因。

一个简单的例子:

class MyModel: public QAbstractListModel
{
    Q_OBJECT
public:
    MyModel(QObject* parent=nullptr): QAbstractListModel (parent)
    {
        innerModel.append("Bob");
        innerModel.append("Patrick");
        innerModel.append("Alice");
    }
    Q_INVOKABLE int rowCount(const QModelIndex &parent = QModelIndex()) const override
    {
        if (parent.isValid())
            return 0;
        return innerModel.size();
    }
    Q_INVOKABLE int columnCount(const QModelIndex &parent = QModelIndex()) const override
    {
        if (parent.isValid())
            return 0;
        return 2;
    }
    Q_INVOKABLE QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const override
    {
        qDebug() << index << role;
        switch (role)
        {
            case Qt::DisplayRole:
            case Qt::UserRole + 1:
                return innerModel.at(index.row());
            case Qt::UserRole + 2:
                return QString::number(index.row() + 1);
        }
        return QVariant();
    }

    Q_INVOKABLE QHash<int,QByteArray> roleNames() const override
    {
        QHash<int,QByteArray> roles;
        roles.insert(Qt::UserRole + 1, "name");
        roles.insert(Qt::UserRole + 2, "index");
        return roles;
    }

    Q_INVOKABLE void add(QString const& name)
    {
        beginInsertRows(QModelIndex(), rowCount(), rowCount());
        innerModel.append(name);
        endInsertRows();
    }
    private:
        QList<QString> innerModel;
};
Item {
    anchors.fill: parent
        TextEdit {
            width: 100
            id: name
            anchors.left: parent.left
            anchors.top: parent.top
        }
        Button {
            text: "save"
            onClicked: theModel.add(name.text)
            anchors.left: name.right
            anchors.top: parent.top
        }
    ListView {
        anchors.left: parent.left
        anchors.right: parent.right
        anchors.bottom: parent.bottom
        anchors.top: name.bottom
        model: theModel
        delegate: Text {
            text: name
        }
    }
}

如果您在方法beginInsertRows(QModelIndex(), rowCount(), rowCount());中注释endInsertRowsadd,则将无法看到列表中的新行,因为模型无法知道内部模型何时更改