Qt深入浅出(十五)QTableView

谁践踏了优雅 2023-07-24 05:56 7阅读 0赞

QTableView

​ 表格视图控件QTableView,需要和QStandardItemModel, 配套使用,这套框架是基于MVC设计模式设计的,M(Model)是QStandardItemModel数据模型,不能单独显示出来。V(view)是指QTableView视图,要来显示数据模型,C(controllor)控制在Qt中被弱化,与View合并到一起。

1 QTableView简单应用

​ QStandardItmeModel表格的数据模型,那么这个模型需要填上每一行每一列的数据,就像execl表格一样。

​ widget.h

  1. #ifndef WIDGET_H
  2. #define WIDGET_H
  3. #include <QTableView>
  4. class Widget : public QTableView //继承至QTableView
  5. {
  6. Q_OBJECT
  7. public:
  8. Widget( QWidget * parent = 0);
  9. ~Widget();
  10. };
  11. #endif // WIDGET_H

​ widget.cpp

  1. #include "widget.h"
  2. #include <QStandardItemModel>
  3. #include <QDebug>
  4. Widget::Widget( QWidget * parent)
  5. : QTableView( parent)
  6. {
  7. QStandardItemModel * model = new QStandardItemModel( this);
  8. model -> setItem( 0, 0, new QStandardItem( "张三"));
  9. model -> setItem( 0, 1, new QStandardItem( "3"));
  10. model -> setItem( 0, 2, new QStandardItem( "男"));
  11. this -> setModel( model);
  12. }
  13. Widget::~Widget()
  14. {
  15. }

​ 以上代码实现了在model中添加一条数据,然后通过setModel函数设置view的数据模型为model,显示出来,如图:

20180224003905251

2 修改行列字段名

​ 修改字段名可以使用QStandardItemModel::setHeaderData,但是在这之前你需要调用QStandardItemModel::setColumnCountQStandardItemModel::setRowCount,例如:

  1. Widget::Widget( QWidget * parent)
  2. : QTableView( parent)
  3. {
  4. QStandardItemModel * model = new QStandardItemModel( this);
  5. /*设置列字段名*/
  6. model -> setColumnCount( 3);
  7. model -> setHeaderData( 0, Qt::Horizontal, "姓名");
  8. model -> setHeaderData( 1, Qt::Horizontal, "年龄");
  9. model -> setHeaderData( 2, Qt::Horizontal, "性别");
  10. /*设置行字段名*/
  11. model -> setRowCount( 3);
  12. model -> setHeaderData( 0, Qt::Vertical, "记录一");
  13. model -> setHeaderData( 1, Qt::Vertical, "记录二");
  14. model -> setHeaderData( 2, Qt::Vertical, "记录三");
  15. /*设置一条数据*/
  16. model -> setItem( 0, 0, new QStandardItem( "张三"));
  17. model -> setItem( 0, 1, new QStandardItem( "3"));
  18. model -> setItem( 0, 2, new QStandardItem( "男"));
  19. this -> setModel( model);
  20. }

3 移除数据

​ 移除数据的常用函数有:

  1. /*移除某行数据*/
  2. bool QAbstractItemModel::removeRow( int row, const QModelIndex & parent = QModelIndex())
  3. /*移除某列数据*/
  4. bool QAbstractItemModel::removeColumn( int column, const QModelIndex & parent = QModelIndex())

例如:

  1. model -> removeRow( 0); //移除第0行数据
  2. model -> removeColumn( 0); //移除第0列数据

4 插入数据

  • 插入一行数据

    void QStandardItemModel::insertRow( int row, const QList < QStandardItem *> & items)

    1. /*
    2. * row 表示从第几行插入数据
    3. * items 表示要插入的数据QStandardItem对象
    4. */
  • 例如:

    QList < QStandardItem *> list;

    1. list << new QStandardItem( "王五") << new QStandardItem( "22") << new QStandardItem( "男");
    2. model -> insertRow( 0, list); //在第0行插入一条记录

5 数据变更信号处理

​ 当QStandardModel中的数据被更改的时候,会发射出dataChanged信号:

  1. [ signal] void QAbstractItemModel::dataChanged( const QModelIndex & topLeft, const QModelIndex & bottomRight, const QVector < int > & roles = QVector < int > ());
  2. /*
  3. *topLeft bottomRight这两索引指的是表格中被更改数据的区域,如果只有一个数据被更改,那么topLeft等于bottomRight
  4. */

例如:

widget.h

  1. #ifndef WIDGET_H
  2. #define WIDGET_H
  3. #include <QTableView>
  4. class QStandardItemModel ;
  5. class Widget : public QTableView
  6. {
  7. Q_OBJECT
  8. public slots:
  9. void dataChangedSlot ( const QModelIndex & topLeft , const QModelIndex & bottomRight , const QVector < int > & roles = QVector < int > ());
  10. public:
  11. Widget( QWidget * parent = 0);
  12. QStandardItemModel * _model;
  13. ~Widget();
  14. };
  15. #endif // WIDGET_H

widget.cpp

  1. #include "widget.h"
  2. #include <QStandardItemModel>
  3. #include <QDebug>
  4. Widget::Widget( QWidget * parent)
  5. : QTableView( parent)
  6. {
  7. _model = new QStandardItemModel( this);
  8. _model -> setColumnCount( 3);
  9. _model -> setHeaderData( 0, Qt::Horizontal, "姓名");
  10. _model -> setHeaderData( 1, Qt::Horizontal, "年龄");
  11. _model -> setHeaderData( 2, Qt::Horizontal, "性别");
  12. _model -> setRowCount( 3);
  13. _model -> setHeaderData( 0, Qt::Vertical, "记录一");
  14. _model -> setHeaderData( 1, Qt::Vertical, "记录二");
  15. _model -> setHeaderData( 2, Qt::Vertical, "记录三");
  16. _model -> setItem( 0, 0, new QStandardItem( "张三"));
  17. _model -> setItem( 0, 1, new QStandardItem( "3"));
  18. _model -> setItem( 0, 2, new QStandardItem( "男"));
  19. connect( _model, SIGNAL( dataChanged( QModelIndex, QModelIndex, QVector < int >)), this, SLOT( dataChangedSlot( QModelIndex, QModelIndex, QVector < int >)));
  20. this -> setModel( _model);
  21. }
  22. void Widget::dataChangedSlot( const QModelIndex & topLeft, const QModelIndex & bottomRight, const QVector < int > & roles)
  23. {
  24. qDebug() << _model -> data( topLeft). toString() << endl;
  25. }
  26. Widget::~Widget()
  27. {
  28. }

需要知道的是函数data可以获取想要的QStandardItem对象的索引:

  1. [ pure virtual] QVariant QAbstractItemModel::data( const QModelIndex & index, int role = Qt::DisplayRole) const

返回的QVariant对象是一种泛型变量,可以转换成QString、int、double等数据类型。

6 常用函数

  1. //默认显示行头,如果你觉得不美观的话,我们可以将隐藏
  2. tableview -> verticalHeader() -> hide();
  3. //设置选中时为整行选中
  4. tableview -> setSelectionBehavior( QAbstractItemView::SelectRows);
  5. //设置表格的单元为只读属性,即不能编辑
  6. tableview -> setEditTriggers( QAbstractItemView::NoEditTriggers);
  7. //返回一个被选中的所有Item的索引,一般是去遍历这个链表进行处理
  8. [ virtual protected] QModelIndexList QTableView::selectedIndexes() const

7 QStandardItem被点选信号

​ 当QStandardItemModel中的某个QStandardItem被点选后,QStandardItemModel对象会发出一个信号:

  1. void QAbstractItemView::clicked( const QModelIndex & index);
  2. /*
  3. *返回被点选的Item的索引
  4. */

8 QItemDelegate代理

​ QTableView在处理信息显示编辑的时候比较单调,类似行编辑器,为了获得更多的灵性性,交互通过QItemDelegate执行。

​ 下面通过派生一个SpinDelegate来实现一个整数旋转框的代理器。

​ 一般我们要重写函数createEditor:

  1. [ virtual] QWidget * QItemDelegate::createEditor( QWidget * parent, const QStyleOptionViewItem & option, const QModelIndex & index) const
  2. /*
  3. *QWidget *parent一般是指哪个窗口使用了这个代理,一般用来托管内存
  4. * QStyleOptionViewItem &option 样式风格
  5. * const QModelIndex &index 需要更改的Item索引
  6. */

​ spinDelegate.h

  1. #ifndef SPINDELEGATE_H
  2. #define SPINDELEGATE_H
  3. #include <QItemDelegate>
  4. class SpinDelegate : public QItemDelegate
  5. {
  6. public:
  7. SpinDelegate( QObject * parent = Q_NULLPTR);
  8. QWidget * createEditor ( QWidget * parent , const QStyleOptionViewItem & option , const QModelIndex & index ) const;
  9. };
  10. #endif // SPINDELEGATE_H

​ spinDelegate.cpp

  1. #include "spindelegate.h"
  2. #include <QSpinBox>
  3. SpinDelegate::SpinDelegate( QObject * parent): QItemDelegate( parent)
  4. {
  5. }
  6. QWidget * SpinDelegate::createEditor( QWidget * parent
  7. , const QStyleOptionViewItem & option, const QModelIndex & index) const
  8. {
  9. if( index. column() == 1) // 返回下拉框
  10. {
  11. QSpinBox * box = new QSpinBox( parent);
  12. box -> setMinimum( 1);
  13. box -> setMaximum( 99);
  14. return box;
  15. }
  16. return QItemDelegate::createEditor( parent, option, index);
  17. }

将widget.cpp中的构造器中修改如下函数如下:

  1. Widget::Widget( QWidget * parent)
  2. : QTableView( parent)
  3. {
  4. QStandardItemModel * model = new QStandardItemModel( this);
  5. /*设置列字段名*/
  6. model -> setColumnCount( 3);
  7. model -> setHeaderData( 0, Qt::Horizontal, "姓名");
  8. model -> setHeaderData( 1, Qt::Horizontal, "年龄");
  9. model -> setHeaderData( 2, Qt::Horizontal, "性别");
  10. /*设置行字段名*/
  11. model -> setRowCount( 3);
  12. model -> setHeaderData( 0, Qt::Vertical, "记录一");
  13. model -> setHeaderData( 1, Qt::Vertical, "记录二");
  14. model -> setHeaderData( 2, Qt::Vertical, "记录三");
  15. /*设置一条数据*/
  16. model -> setItem( 0, 0, new QStandardItem( "张三"));
  17. model -> setItem( 0, 1, new QStandardItem( "3"));
  18. model -> setItem( 0, 2, new QStandardItem( "男"));
  19. this -> setModel( model);
  20. /*设置代理*/
  21. this -> setItemDelegate( new SpinDelegate( this));
  22. }

发表评论

表情:
评论列表 (有 0 条评论,7人围观)

还没有评论,来说两句吧...

相关阅读