【问题标题】:How can I access QAbstractTableModel Data from QML Repeater如何从 QML Repeater 访问 QAbstractTableModel 数据
【发布时间】:2018-03-24 05:42:35
【问题描述】:

几天来,我一直在苦苦寻找如何在 QML 窗口中显示一些非常简单的数据。我意识到有很多方法可以完成这项任务,在这种情况下,我更愿意了解如何使用 QAbstractTableModel。

我有一行数据,每行包含两个项目,一个名称和一个值(名称/值或键/值对)。我对 QAbstractTableModel 进行了子类化,以将此数据传递给 QML。这是我到目前为止的代码;它主要基于可以在此处找到的教程(也很旧):https://doc.qt.io/archives/4.6/itemviews-addressbook.html

databridge.h

#include <QObject>
#include <QAbstractTableModel>
#include <QPair>

class DataBridge : public QAbstractTableModel
{
    Q_OBJECT
public:
    explicit DataBridge();
    explicit DataBridge(QList<QPair<QString, QString>> listOfPairs);

    int rowCount(const QModelIndex &parent) const;
    int columnCount(const QModelIndex &parent) const;
    QVariant data(const QModelIndex &index, int role) const;
    bool setData(const QModelIndex &index, const QVariant &value, int role);
    QVariant headerData(int section, Qt::Orientation orientation, int role) const;
    bool insertRows(int row, int count, const QModelIndex &parent);
    bool removeRows(int row, int count, const QModelIndex &parent);
    Qt::ItemFlags flags(const QModelIndex &index) const;
    QList<QPair<QString, QString>> getList();

signals:

public slots:

private:
    QList<QPair<QString, QString>> m_listOfPairs;

};

#endif // DATABRIDGE_H

databridge.cpp

#include "databridge.h"

DataBridge::DataBridge()
{}
DataBridge::DataBridge(QList<QPair<QString, QString> > listOfPairs)
{  m_listOfPairs = listOfPairs; }

int DataBridge::rowCount(const QModelIndex &parent) const
{
    Q_UNUSED(parent);
    return m_listOfPairs.size();
}

int DataBridge::columnCount(const QModelIndex &parent) const
{
    Q_UNUSED(parent);
    //Number of columns is always 2 in this kata
    return 2;
}

QVariant DataBridge::data(const QModelIndex &index, int role) const
{
    if(!index.isValid())
        return QVariant();
    if(index.row() >= m_listOfPairs.size() || index.row() < 0)
        return QVariant();
    if(role == Qt::DisplayRole)
    {
        QPair<QString, QString> pair = m_listOfPairs.at(index.row());
        if(index.column() == 0)
            return pair.first;
        else
            return pair.second;
    }
    return QVariant();
}

bool DataBridge::setData(const QModelIndex &index, const QVariant &value, int role)
{
    //TODO
    return QVariant();
}

QVariant DataBridge::headerData(int section, Qt::Orientation orientation, int role) const
{
    //TODO
    return QVariant();
}

bool DataBridge::insertRows(int row, int count, const QModelIndex &parent)
{
    //TODO
    return true;
}

bool DataBridge::removeRows(int row, int count, const QModelIndex &parent)
{
    //TODO
    return true;
}

Qt::ItemFlags DataBridge::flags(const QModelIndex &index) const
{
    if(!index.isValid())
        return Qt::ItemIsEnabled;

    return QAbstractTableModel::flags(index) | Qt::ItemIsEditable;
}

QList<QPair<QString, QString> > DataBridge::getList()
{
    return m_listOfPairs;
}

main.cpp

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include <QPair>
#include "databridge.h"

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
    QGuiApplication app(argc, argv);

    QQmlApplicationEngine engine;

    QList<QPair<QString, QString>> inserter;
    inserter.append(QPair<QString, QString>("0", "zero"));
    inserter.append(QPair<QString, QString>("1", "one"));
    inserter.append(QPair<QString, QString>("2", "two"));
    inserter.append(QPair<QString, QString>("3", "three"));
    inserter.append(QPair<QString, QString>("4", "four"));

    DataBridge * bridge = new DataBridge(inserter);
    engine.rootContext()->setContextProperty("bridge", bridge);

    engine.load(QUrl(QLatin1String("qrc:/main.qml")));
    if (engine.rootObjects().isEmpty())
        return -1;

    return app.exec();
}

main.qml

import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.3

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

    Component{
        id: myComponent
        Row{
            id: thisRow
            Text{
                text: bridge.data(index, 0)
            }
            Text{
                text: "\t.\t.\t.\t"
            }
            Text{
                text: bridge.data(index, 0)
            }
        }
    }

    Column{
        id: thisColumn
        anchors.horizontalCenter: parent.horizontalCenter
        Repeater{
            id: myRepeater
            delegate: myComponent
            model: bridge
        }
    }

    Component.onCompleted: {
        console.log("DEBUG main.qml");
    }
}

请忽略databridge.cpp中带有TODO的函数。为简洁起见,我没有包括尸体。

我面临的第一个问题是,当我在main.qml中的repeater调用bridge.data(index, 0)时,在data函数的第一个if语句(if(! index.isValid())。我不知道为什么会这样。我可以看到的第二个问题,虽然我还没有走到那一步,如果我正在调用第 0 列或第 1 列?它稍后会在函数中检查这一点,并返回与请求的列相关的对。我猜在 myComponent 中,我需要更具体的东西来从任何列请求数据,但我不确定是什么那会是什么?

对此的任何帮助将不胜感激。提前谢谢!

QModelIndex Documentation

Another link to the example referenced at the top

QAbstractTableModel Documentation

Qt Role Enum Documentation

【问题讨论】:

    标签: c++ qt qml


    【解决方案1】:

    我能够找到解决方案,但我不确定它是否正确。我已经向 databridge 类添加了一个函数,该函数从 QML 获取整数输入,找到相应的 QModelIndex,并以这种方式从模型中提取数据。代码是这样的:

    来自 databridge.cpp

    QString DataBridge::getThisItem(int index, int column)
    {
        QModelIndex currentIndex = QAbstractTableModel::index(index, column);
        QString retVal = data(currentIndex, 0).toString();
        return retVal;
    }
    

    相应的 QML 中继器更改

    Component{
        id: myComponent
        Row{
            id: thisRow
            Text{
                text: bridge.getThisItem(index, 0)
            }
            Text{
                text: "\t.\t.\t.\t"
            }
            Text{
                text: bridge.getThisItem(index, 1)
            }
        }
    }
    

    这会产生所需的输出,即:

    我很想知道这是否是一个好的实现,或者是否有更好的方法来做到这一点。再次感谢!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-23
      • 2011-11-23
      • 1970-01-01
      • 2016-03-14
      相关资源
      最近更新 更多