QAbstractTableMode



看了别人的内容,把原来的实现细节写了出来,并增加了许多说明性的语句和调试信息,讲解如何自定义一个抽象表格模型和使用,熟悉内部的实现流程。

代码如下,运行在centos qt环境下。

效果如下:

#ifndef TABLEMODEL_H
#define TABLEMODEL_H
#include <QString>
#include <QAbstractTableModel>
#include <QList>
struct FileRecord
{
   bool bChecked;
   QString strFilePath;
};

class TableModel : public QAbstractTableModel
{
    Q_OBJECT
public:
    explicit TableModel(QObject *parent = 0);
    ~TableModel();
    Qt::ItemFlags flags(const QModelIndex &index) const;
    QVariant headerData(int section, Qt::Orientation orientation, int role) const;
    QVariant data(const QModelIndex &index, int role) const;
    bool setData(const QModelIndex &index, const QVariant &value, int role);
    int columnCount(const QModelIndex &parent) const;
    int rowCount(const QModelIndex &parent) const;
    void updateData(QList<FileRecord> recordList);

signals:

public slots:
private:
    QList<FileRecord> m_recordList;
  

};

#endif // TABLEMODEL_H




#include "tablemodel.h"
#include <QColor>
#include <QDebug>
#define CHECK_BOX_COLUMN 0
#define File_PATH_COLUMN 1
TableModel::TableModel(QObject *parent)
    : QAbstractTableModel(parent)
{
 
}

TableModel::~TableModel()
{

}

// 更新表格数据
void TableModel::updateData(QList<FileRecord> recordList)
{
    m_recordList = recordList;

    beginResetModel();//开始重置模型,相当于刷新功能,从模型中从新获取数据
    endResetModel();//完成上面的过程,一般用在模型中开始的时候没有数据,然后需要重新刷新设置的模型,从中读取数据,在这个案例中,没有这两句话,是不能显示数据的。
}

// 行数
int TableModel::rowCount(const QModelIndex &parent) const
{
    return m_recordList.count();
}

// 列数
int TableModel::columnCount(const QModelIndex &parent) const
{
    return 2;
}

// 设置表格项数据,设置数据显示中的数据,一种是界面设置,一种是代码设置
bool TableModel::setData(const QModelIndex &index, const QVariant &value, int role)//value数据可以从界面获取。
{
    if (!index.isValid())
    {

        return false;
        qDebug()<<"index is valid";
    }

    int nColumn = index.column();
    FileRecord record = m_recordList.at(index.row());
    switch (role)
    {
//    case Qt::DisplayRole:  //显示模式不能对数据进行更改
//    {
//        if (nColumn == File_PATH_COLUMN)
//        {
//            record.strFilePath = value.toString();
//            qDebug()<<"value.toString():"<<value.toString();

//            m_recordList.replace(index.row(), record);
//            emit dataChanged(index, index);
//            return true;
//        }
//    }
    case Qt::EditRole:  //编写模式,可以对数据进行更改
    {
        if (nColumn == File_PATH_COLUMN)
        {
        record.strFilePath = value.toString();
        qDebug()<<"value.toString():"<<value.toString();
        qDebug()<<"***************************";

        m_recordList.replace(index.row(), record);
        emit dataChanged(index, index);
        return true;
        }
    }
    case Qt::CheckStateRole: //根据状态修改数据库中的数据
    {
        if (nColumn == CHECK_BOX_COLUMN)
        {
            record.bChecked = (value.toInt() == Qt::Checked);
            qDebug()<<"value.toInt():"<<value.toInt();
            m_recordList.replace(index.row(), record);
            emit dataChanged(index, index);
            return true;
        }
    }
    default:
        return false;
    }
    return false;
}

// 表格项数据的获取:动态的从数据结构中获取数据,并将数据显示出来。
QVariant TableModel::data(const QModelIndex &index, int role) const
{
    //i++;
    if (!index.isValid())
    {
        qDebug()<<"index is not valid";
        return QVariant();
    }

    int nRow = index.row();
    int nColumn = index.column();
    FileRecord record = m_recordList.at(nRow);
    qDebug()<<record.bChecked;
    qDebug()<<record.strFilePath;
    //每个角色都是对应所有列的。
    switch (role)
    {
    case Qt::TextColorRole:
    {

        qDebug()<<"Qt::TextColorRole"<<i;

        return QColor(Qt::green);
    }
    case Qt::TextAlignmentRole:
    {
        qDebug()<<"Qt::TextAlignmentRole";
        return QVariant(Qt::AlignLeft | Qt::AlignVCenter);
    }
    case Qt::DisplayRole://直接把数据显示出来。
    {
        qDebug()<<"Qt::DisplayRole";
        if (nColumn == File_PATH_COLUMN)
            return record.strFilePath;//根据记录中的数据显示在图表中。
        return "";
    }
    case Qt::EditRole: //只有选中的时候且双击才会显示出来。
    {
        qDebug()<<"Qt::EditRole";
        if (nColumn == File_PATH_COLUMN)
            return record.strFilePath;
        return "";
    }
    case Qt::CheckStateRole: //这一行语句在第一列显示方格
    {
        qDebug()<<"Qt::CheckStateRole";
        if (nColumn == CHECK_BOX_COLUMN)
            return record.bChecked ? Qt::Checked : Qt::Unchecked;

    }
    default:
    {
        qDebug()<<"default";
        return QVariant();
    }
    }

    return QVariant();
}

// 表头数据,表头数据没有从数据结构中获取,而是写死的。
QVariant TableModel::headerData(int section, Qt::Orientation orientation, int role) const
{
    switch (role)
    {
    case Qt::TextAlignmentRole:
        return QVariant(Qt::AlignLeft | Qt::AlignVCenter);
    case Qt::DisplayRole:
    {
        if (orientation == Qt::Horizontal)
        {
            if (section == CHECK_BOX_COLUMN)
                return QStringLiteral("状态");

            if (section == File_PATH_COLUMN)
                return QStringLiteral("文件路径");
        }
    }
    default:
        return QVariant();
    }

    return QVariant();
}

// 表格可选中、可复选
Qt::ItemFlags TableModel::flags(const QModelIndex &index) const
{
    if (!index.isValid())
        return QAbstractItemModel::flags(index);

    Qt::ItemFlags flags = Qt::ItemIsEnabled | Qt::ItemIsSelectable;//ItemIsEnabled,表明这一项可以使用,ItemIsSelectable 表明这一项可以选中。

//    flags |= Qt::ItemIsUserCheckable|Qt::ItemIsEditable;
   // Qt::ItemFlags tempFlag =Qt::ItemIsSelectable;
   // return tempFlag;
   if (index.column() == CHECK_BOX_COLUMN)//增加第一列的控制选项。
     flags |= Qt::ItemIsUserCheckable|Qt::ItemIsEditable;
    return flags;

}



#include "dialog.h"
#include <QApplication>
#include "tablemodel.h"
#include <QTableView>
#include <QHeaderView>
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
//    Dialog w;
//    w.show();


    QTableView *pTableView = new QTableView;
    TableModel *pModel = new TableModel;
   // pModel->setHeaderData(1,Qt::Vertical,Qt::DisplayRole);

    // 设置单行选中、最后一列拉伸、表头不高亮、无边框等
    pTableView->setSelectionBehavior(QAbstractItemView::SelectRows);
    pTableView->horizontalHeader()->setStretchLastSection(true);
    pTableView->horizontalHeader()->setHighlightSections(false);//当选中表中数据时,表头是否会高亮,显示已经选中状态。
    pTableView->verticalHeader()->setVisible(true);
    pTableView->setShowGrid(true); //是否显示网格线
    //pTableView->setFrameShape(QFrame::NoFrame);
    pTableView->setSelectionMode(QAbstractItemView::SingleSelection);
    pTableView->setModel(pModel);

    // 加载数据、更新界面
    QList<FileRecord> recordList;
    for (int i = 0; i < 5; ++i)
    {
        FileRecord record;
        record.bChecked = false;
        record.strFilePath = QString("E:/Qt/image_%1.png").arg(i + 1);
        recordList.append(record);
    }
    pModel->updateData(recordList);

    pTableView->show();
    return a.exec();
}


  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值