引言
- 先上效果图:
最近想要实现上图所示的一个数据展示列表,最先使用的QTreeWidget组件进行展示,但是遇到了当数据量过大(10000以上),第一次点击TabPage加载数据时,总是有很卡顿的感觉,得隔一段时间才能加载显示出数据。汗!偷懒偷不成了,效果自己都不能忍,更何况别人。因此使用了Model/View框架,自己实现了数据项和数据模型,最后效果还算满意。
需求是这样的,当点击表头时,可以全部选中或者全部不选中视图中的数据,而点击数据时,表头能展示选中状态的三态效果。配合键盘的Ctrl和Shift键,实现区域选中,多块选中(效果图见文章最后)
实现
一、 子类化QAbstractItemModel,自定义QTreeView的数据模型
QAbstractItemModel类是虚基类,子类化该类,得需要实现所有的纯虚函数才能实例化自定义的数据模型类。
virtual int rowCount(const QModelIndex & parent = QModelIndex()) const;
virtual int columnCount(const QModelIndex & parent = QModelIndex()) const;
virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
virtual bool setData(const QModelIndex & index, const QVariant & value, int role = Qt::EditRole);//设置数据
virtual Qt::ItemFlags flags(const QModelIndex & index) const;//返回Item项的可选,可用户点击等标识
virtual QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const;//返回每个数据项的index
virtual QModelIndex parent(const QModelIndex &index) const;//本需求树只有一层,parent返回NULL
virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;//返回相应role的表头数据
以上函数是为了实现本需求,必须实现的方法。可以说是自定义QTreeView模型的核心。
- 自定义Model头文件
#ifndef TREEVIEWMODEL_H
#define TREEVIEWMODEL_H
#include <QAbstractItemModel>
struct FlashIndexData{
FlashIndexData():is_be_checked(false){
}
bool is_be_checked;
quint32 unix_time;
quint16 addr;
};
class TreeViewModel:public QAbstractItemModel
{
Q_OBJECT
public:
explicit TreeViewModel(QObject *parent=NULL);
void setFlashData(QList<FlashIndexData> &flash_data);
void clear();
void getSelectedFlashData(QMap<quint32,quint16> &selected_list);
virtual int rowCount(const QModelIndex & parent = QModelIndex()) const;
virtual int columnCount(const QModelIndex & parent = QModelIndex()) const;
virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
virtual bool setData(const QModelIndex & index, const QVariant & value, int role = Qt::EditRole);
virtual Qt::ItemFlags flags(const QModelIndex & index) const;
virtual QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const;
virtual QModelIndex parent(const QModelIndex &index) const;
virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
signals:
void stateChanged(Qt::CheckState state);
private slots:
void slot_stateChanged(Qt::CheckState state);
private:
QList<FlashIndexData> m_flash_index; //flash 索引
void onStateChanged();
enum{
CHECK_BOX_COLUMN = 0,
UNIX_TIME_COLUMN,