Qt 实战(10)模型视图 | 10.6、自定义 QTableView

文章目录

  • 一、自定义QTableView
    • 1、自定义模型
    • 2、自定义代理
    • 3、示例

一、自定义QTableView

1、自定义模型

模型中存储表格要显示的数据,要自定义一个QAbstractTableModel,需要从该类派生一个新的类,并在其中实现一些关键的方法。这些方法定义了模型如何与表格视图交互,包括数据的获取、行列的数量、数据项的修改等。如下:

// MyModel.h
#include <QAbstractTableModel>

class MyModel : public QAbstractTableModel
{
    Q_OBJECT

public:
    explicit MyModel(QObject *parent = nullptr);
    ~MyModel();

public:
    // 必须要实现的基类虚函数
    int rowCount(const QModelIndex &parent = QModelIndex()) const override;
    int columnCount(const QModelIndex &parent = QModelIndex()) const override;
    QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;

    // 选择实现的虚函数
    bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;
    Qt::ItemFlags flags(const QModelIndex &index) const override;
    QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;

private:
    // 自定义方法
    void InitData();

private:
    QVector<QString> m_headers;
    QVector<QVector<QString>> m_data;
};

2、自定义代理

如果需要自定义单元格的渲染或编辑方式,可以创建一个自定义的代理类。委托类通常继承自QStyledItemDelegateQItemDelegate。当单击单元格时,代理控件会显示出来,编辑结束就会被隐藏起来,如果希望在编辑结束不要隐藏,必须要继承并重写QStyledItemDelegatepaint函数,相当于在单元格上完全自绘图形(当然QT也提供了一些辅助类,帮你快速画出一些常见控件)。

场景:代理提供QSpinBox控件,当编辑结束,希望单元格会显示进度条。

  • 创建代理
// MyScoreDelegate.cpp
void MyScoreDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    int progress = index.data().toInt();

    QStyleOptionProgressBar progressBarOption;
    progressBarOption.initFrom(option.widget);
    progressBarOption.progress = progress;
    progressBarOption.text = QString::number(progress) + "/100";
    progressBarOption.textAlignment = Qt::AlignHCenter;
    progressBarOption.rect = option.rect;
    progressBarOption.minimum = 0;
    progressBarOption.maximum = 100;
    progressBarOption.textVisible = true;

    QApplication::style()->drawControl(QStyle::CE_ProgressBar,
        &progressBarOption, painter);
}
  • 设置代理
void MyWidget::InitDelegate()
{
    MyLineEditDelegate *pLineEditDelaget = new MyLineEditDelegate();
    MySexComboxDelegate *pSexDelegate = new MySexComboxDelegate();
    MyScoreDelegate *pScoreDelegate = new MyScoreDelegate();

    ui.m_pTableView->setItemDelegate(pLineEditDelaget);
    ui.m_pTableView->setItemDelegateForColumn(eSexIndex, pSexDelegate);
    ui.m_pTableView->setItemDelegateForColumn(eScoreIndex, pScoreDelegate);
}

3、示例

下面是运行效果,源码参考附件

在这里插入图片描述

上一篇:【Linux网络】UdpSocket


下一篇:保研考研机试攻略:python笔记(2)