将QStandardItemModel从C ++传递到QtQuick / QML TableView并显示它

时间:2014-09-17 11:21:17

标签: c++ qt tableview qml qtquick2

我目前正在尝试将QStandardItemModel传递给QtQuick TableView,然后显示它。这基本上是我的代码(只是一个简化的摘录,所以我希望我没有在这里添加任何额外的错误。)

C ++ / Qt部分:

foo.cpp

[...]

QStandardItemModel *Foo::getModel()
{
    QStandardItemModel *model = new QStandardItemModel(this);
    QList<QStandardItem*> standardItemList;

    QList<QString> data;
    data.append("Cat");
    data.append("Dog");
    data.append("Mouse");

    foreach (QString cell, comInputData->getHeadings()) {
        QStandardItem *item = new QStandardItem(cell);
        standardItemList.append(item);
    }

    // we only add one row here for now; more will come later
    model->appendRow(standardItemList);
    standardItemList.clear();
    return model;
}

[...]

main.cpp

Foo f;
QQmlApplicationEngine engine;
engine.rootContext()->setContextProperty("myModel", f.getModel());
engine.load(QUrl(QStringLiteral("qrc:///InputView.qml")));

QtQuick / QML部分:

InputView.qml

TableView {
    id: monitorInputVectorsTable
    [... positioning and sizing ...] 
    model: myModel
}

我想,我仍然缺少QML部分的一些重要部分,是吗?我找到了一些内联模型定义的例子:

ListModel {
    id: libraryModel
    ListElement{ title: "A Masterpiece" ; author: "Gabriel" }
    ListElement{ title: "Brilliance"    ; author: "Jens" }
}

...以这种方式显示(以下内容添加在TableView项目中):

TableViewColumn{ role: "title"  ; title: "Title" ; width: 100 }
TableViewColumn{ role: "author" ; title: "Author" ; width: 200 }

我的猜测:我也需要添加这样的一行。但是,我无法弄清楚从C ++ QStandardItemModel获取角色的位置?是否有必要设定一个角色?至少QWidgets的例子是&#34; classic&#34; QTreeView只需设置模型,一切都很好......

2 个答案:

答案 0 :(得分:3)

您可以继承QStandardItemModel并重新实施roleNames()来定义您想要的角色名称:

#include <QStandardItemModel>

class MyModel : public QStandardItemModel
{

public:

    enum Role {
        role1=Qt::UserRole,
        role2,
        role3
    };


    explicit MyModel(QObject * parent = 0): QStandardItemModel(parent)
    {
    }
    explicit MyModel( int rows, int columns, QObject * parent = 0 ): QStandardItemModel(rows, columns, parent)
    {
    }

    QHash<int, QByteArray> roleNames() const
    {
         QHash<int, QByteArray> roles;
         roles[role1] = "one";
         roles[role2] = "two";
         roles[role3] = "three";

         return roles;
    }
};

添加项目后,您可以将数据设置为模型,如:

model->setData(model->index(0,0), "Data 1", MyModel::role1);
model->setData(model->index(0,1), "Data 2", MyModel::role2);
model->setData(model->index(0,2), "Data 3", MyModel::role3);

现在在qml中,您可以通过角色名称访问不同的列:

TableView {

    TableViewColumn {title: "1"; role: "one"; width: 70 }
    TableViewColumn {title: "2"; role: "two"; width: 70   }
    TableViewColumn {title: "3"; role: "three"; width: 70 }

    model: myModel

}

答案 1 :(得分:0)

在Nejats答案中向模型添加数据在我的案例中不起作用(Qt 5.5)。必须按如下方式添加数据:

QStandardItem* it = new QStandardItem();
it->setData("data 1", MyModel::role1);
it->setData("data 2", MyModel::role2);
it->setData("data 3", MyModel::role3);
model->appendRow(it);

Nejat的答案的完整示例如下(此处也可以使用https://github.com/psimona/QStandardItemModel_Example

main.cpp

#include <QApplication>
#include <QQmlApplicationEngine>
#include <QtQml>

// QStandardItemModel derived class
#include <QStandardItemModel>
class MyModel : public QStandardItemModel {

public:
    enum Role {
        role1=Qt::UserRole,
        role2,
        role3
    };

    explicit MyModel(QObject * parent = 0): QStandardItemModel(parent){}
    explicit MyModel( int rows, int columns, QObject * parent = 0 )
        : QStandardItemModel(rows, columns, parent){}

    QHash<int, QByteArray> roleNames() const{
         QHash<int, QByteArray> roles;
         roles[role1] = "one";
         roles[role2] = "two";
         roles[role3] = "three";
         return roles;
    }
};


// Main
int main(int argc, char *argv[])
{
    QApplication app(argc, argv);


    MyModel* model = new MyModel;


    QStandardItem* it = new QStandardItem();
    it->setData("data 1", MyModel::role1);
    it->setData("data 2", MyModel::role2);
    it->setData("data 3", MyModel::role3);
    model->appendRow(it);

    it = new QStandardItem();
    it->setData("more data 1", MyModel::role1);
    it->setData("more data 2", MyModel::role2);
    it->setData("more data 3", MyModel::role3);
    model->appendRow(it);

    QQmlApplicationEngine engine;
    // register cpp model with QML engine
    engine.rootContext()->setContextProperty("myModel", model);

    // Load qml file in QML engine
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));

    return app.exec();
}

main.qml

import QtQuick 2.4
import QtQuick.Controls 1.3
import QtQuick.Window 2.2
import QtQuick.Dialogs 1.2

ApplicationWindow {
    title: qsTr("Hello World")
    width: 640
    height: 480
    visible: true

    TableView {

        anchors.fill: parent

        TableViewColumn {title: "1"; role: "one"; width: 150 }
        TableViewColumn {title: "2"; role: "two"; width: 150   }
        TableViewColumn {title: "3"; role: "three"; width: 150 }

        model: myModel

    }
}