【问题标题】:Creating custom QAbstractItemModel from comma seperated text file从逗号分隔的文本文件创建自定义 QAbstractItemModel
【发布时间】:2018-05-14 04:39:30
【问题描述】:

我有这个问题,我的 Qtableview 在插入 100.000 行并特别使用多选后变得非常缓慢。

所以经过一些研究后,我决定使用我自己的模型,该模型继承自 QAbstractItemModel。但问题是我不知道如何使用它,因为文本文件可以更改。外汇。我可以加载一个包含 5 列和 50.000 行的文件,一段时间后它可以有 15 列和 10.000 行。 数据不需要更改,因此它只是只读的。 谁能帮我解决这个问题?

我的“空”自定义模型在这里

#include "customabstractmodel.h"

CustomAbstractModel::CustomAbstractModel(QObject *parent)
    : QAbstractItemModel(parent)
{
}

QVariant CustomAbstractModel::headerData(int section, Qt::Orientation orientation, int role) const
{
    // FIXME: Implement me!
}

bool CustomAbstractModel::setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, int role)
{
    if (value != headerData(section, orientation, role)) {
        // FIXME: Implement me!
        emit headerDataChanged(orientation, section, section);
        return true;
    }
    return false;
}

QModelIndex CustomAbstractModel::index(int row, int column, const QModelIndex &parent) const
{
    // FIXME: Implement me!
}

QModelIndex CustomAbstractModel::parent(const QModelIndex &index) const
{
    // FIXME: Implement me!
}

int CustomAbstractModel::rowCount(const QModelIndex &parent) const
{
    if (!parent.isValid())
        return 0;

    // FIXME: Implement me!
}

int CustomAbstractModel::columnCount(const QModelIndex &parent) const
{
    if (!parent.isValid())
        return 0;

    // FIXME: Implement me!
}

QVariant CustomAbstractModel::data(const QModelIndex &index, int role) const
{
    if (!index.isValid())
        return QVariant();

    // FIXME: Implement me!
    return QVariant();
}

bool CustomAbstractModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
    if (data(index, role) != value) {
        // FIXME: Implement me!
        emit dataChanged(index, index, QVector<int>() << role);
        return true;
    }
    return false;
}

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

    return Qt::ItemIsEditable; // FIXME: Implement me!
}

bool CustomAbstractModel::insertRows(int row, int count, const QModelIndex &parent)
{
    beginInsertRows(parent, row, row + count - 1);
    // FIXME: Implement me!
    endInsertRows();
}

bool CustomAbstractModel::insertColumns(int column, int count, const QModelIndex &parent)
{
    beginInsertColumns(parent, column, column + count - 1);
    // FIXME: Implement me!
    endInsertColumns();
}

bool CustomAbstractModel::removeRows(int row, int count, const QModelIndex &parent)
{
    beginRemoveRows(parent, row, row + count - 1);
    // FIXME: Implement me!
    endRemoveRows();
}

bool CustomAbstractModel::removeColumns(int column, int count, const QModelIndex &parent)
{
    beginRemoveColumns(parent, column, column + count - 1);
    // FIXME: Implement me!
    endRemoveColumns();
}

编辑 #1 Csv 数据(非真实信息,随机)

姓名、电话、电子邮件、地址、城市、邮编 Chavez, Lisandra F.,1-498-913-8181,ac.fermentum.vel@semperrutrumFusce.org,Ap #123-1044 Sed Rd.,Drayton Valley,21833 Humphrey, Briar W.,1-583-466-4027,Morbi.accumsan.laoreet@Loremipsumdolor.net,Ap #642-6497 Id Rd.,Lochgilphead,16394 Benson, Tasha H.,1-898-918-7872,consequat@enimEtiam.ca,P.O. 197 号信箱,4720 Ipsum。圣,德福,56688 Emerson, Susan P.,1-190-818-1919,dignissim@liberoatauctor.ca,P.O. Box 482, 7813 多洛尔。大道,圣安东尼奥,M8C 7F6 Dunn, Alexander U.,1-222-379-2231,libero.Donec.consectetuer@nonegestasa.ca,803-958 Lectus Rd.,Raleigh,74078

【问题讨论】:

  • 因为你需要一个表(没有层次结构)你应该使用QAbstractTableModel,其中index()等功能已经实现,并且必须只实现rowCount()columnCount(),和data()
  • 所以简而言之,您想显示一个由 CSV 数据源支持的表格,但数据可以更改?如果您想在表格视图中反映更改的文件,或者您只想显示一次并手动刷新(使用按钮或其他东西),那会非常复杂?
  • 您以哪种形式获取数据?请举个例子。
  • @vahancho 好的,我可以去。但同样,我的数据是什么,除了 QString,我的意思是我应该在那里实现什么?编辑:我阅读了文件,并用逗号分隔它们。目前我使用 QStandartitemmodel,我将 QStandartitem 添加到其中
  • 同样在 CSV 文件中,您通常无法直接跳转到特定行,如果您想从文件中流式传输数据,则必须在正确完成后才能实现。我猜从头开始读取文件并跳过行可能但不是那么干净,如果它不是很大,你应该将整个数据读入内存,但只显示你需要的表视图。

标签: qt model-view-controller qtableview qabstractitemmodel


【解决方案1】:

假设我们将整个文件读入内存,我将通过以下方式实现模型(QAbstractTableModel 的子类):

CustomAbstractModel::CustomAbstractModel(const QString &filePath,
                                         QObject *parent)
    :
        QAbstractTableModel(parent)
{
    // Parse the file and store its data in an internal data structure
    QFile file(filePath);
    if (file.open(QIODevice::ReadOnly))
    {
        QTextStream in(&file);
        while (!in.atEnd())
        {
            // Assuming that m_data is a std::vector<QString>
            m_data.emplace_back(in.readLine());
        }
    }    
}

QVariant CustomAbstractModel::headerData(int section,
                                         Qt::Orientation orientation,
                                         int role) const
{
    if (orientation == Qt::Horizontal && role == Qt::DisplayRole &&
        !m_data.empty())
    {
        // Read the column names from the first line        
        const QString &firstLine = m_data.front();
        QStringList headers = firstLine.split(',');
        return headers.at(section);
    }    
}

int CustomAbstractModel::rowCount(const QModelIndex &parent) const
{
    if (!m_data.empty())
    {
        return m_data.size() - 1; // First line is the column names data
    }
    return 0;
}

int CustomAbstractModel::columnCount(const QModelIndex &parent) const
{
    if(!m_data.empty())
    {
        const QString &firstLine = m_data.front();
        return firstLine.count(",") + 1;
    }
    return 0;    
}

QVariant CustomAbstractModel::data(const QModelIndex &index, int role) const
{
    if (m_data.empty() && role == Qt::DisplayRole)
    {
        // First line is the header data.
        const QString &line = m_data[index.row() + 1];
        QStringList columnData = firstLine.split(',');
        return columnData.at(index.column());
    }
    return QVariant();    
}

【讨论】:

  • 谢谢。我只是试图在 tableView 中加载模型,但是当我设置模型时它崩溃了。 /* ui->tableView->setModel(model); */
  • 你必须调试它。很遗憾,我不能为你做这件事。
  • 我希望我能解决它,谢谢你的帮助!
猜你喜欢
  • 1970-01-01
  • 2017-02-09
  • 1970-01-01
  • 1970-01-01
  • 2017-06-13
  • 2014-12-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多