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、自定义代理
如果需要自定义单元格的渲染或编辑方式,可以创建一个自定义的代理类。委托类通常继承自
QStyledItemDelegate
或QItemDelegate
。当单击单元格时,代理控件会显示出来,编辑结束就会被隐藏起来,如果希望在编辑结束不要隐藏,必须要继承并重写QStyledItemDelegate
的paint
函数,相当于在单元格上完全自绘图形(当然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、示例
下面是运行效果,源码参考附件