zoukankan      html  css  js  c++  java
  • Qt深入浅出(十五)QTableView

    转载:吓人的猿

    TableView

    表格视图控件QTableView,需要和QStandardItemModel, 配套使用,这套框架是基于MVC设计模式设计的,M(Model)是QStandardItemModel数据模型,

    不能单独显示出来。V(view)是指QTableView视图,要来显示数据模型,C(controllor)控制在Qt中被弱化,与View合并到一起。

    1 QTableView简单应用

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

    widget.h

    #ifndef WIDGET_H
    #define WIDGET_H​
    
    #include <QTableView>
    class Widget : public QTableView //继承至QTableView
    {
        Q_OBJECT
    public:
        Widget(QWidget *parent = 0);
        ~Widget();
    };
    #endif // WIDGET_H

    widget.cpp

    #include "widget.h"
    #include <QStandardItemModel>
    #include <QDebug>
    Widget::Widget(QWidget *parent)
        : QTableView(parent)
    {
       QStandardItemModel* model = new QStandardItemModel(this);
       model->setItem(0, 0, new QStandardItem("张三"));
       model->setItem(0, 1, new QStandardItem("3"));
       model->setItem(0, 2, new QStandardItem(""));
       this->setModel(model);
    }
    
    Widget::~Widget()
    {
    
    }

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

    2 修改行列字段名

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

    Widget::Widget(QWidget *parent)
        : QTableView(parent)
    {
       QStandardItemModel* model = new QStandardItemModel(this);
       /*设置列字段名*/
       model->setColumnCount(3);
       model->setHeaderData(0,Qt::Horizontal, "姓名");
       model->setHeaderData(1,Qt::Horizontal, "年龄");
       model->setHeaderData(2,Qt::Horizontal, "性别");
       /*设置行字段名*/
       model->setRowCount(3);
       model->setHeaderData(0,Qt::Vertical, "记录一");
       model->setHeaderData(1,Qt::Vertical, "记录二");
       model->setHeaderData(2,Qt::Vertical, "记录三");
    
       /*设置一条数据*/
       model->setItem(0, 0, new QStandardItem("张三"));
       model->setItem(0, 1, new QStandardItem("3"));
       model->setItem(0, 2, new QStandardItem(""));
       this->setModel(model);
    }

    把1中的构造函数换为以上代码,运行即可得出下图:

    3 移除数据

    移除数据的常用函数有:

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

    例如:

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

    4 插入数据

    插入一行数据:

    void QStandardItemModel::insertRow(int row, const QList<QStandardItem *> &items)
    /*
    * row 表示从第几行插入数据
    * items 表示要插入的数据QStandardItem对象
    */

    例如:

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

    5 数据变更信号处理

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

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

    例如:

    widget.h

    #ifndef WIDGET_H
    #define WIDGET_H​
    #include <QTableView>
    class QStandardItemModel;
    class Widget : public QTableView
    {
        Q_OBJECT
    public slots:
        void dataChangedSlot(const QModelIndex &topLeft, const QModelIndex &bottomRight,
                             const QVector<int> &roles = QVector<int> ());
    public:
        Widget(QWidget *parent = 0);
        QStandardItemModel* model;
        ~Widget();
    };
    #endif // WIDGET_H

    widget.cpp

    #include "widget.h"
    #include <QStandardItemModel>
    #include <QDebug>
    Widget::Widget(QWidget *parent)
        : QTableView(parent)
    {
       model = new QStandardItemModel(this);
       model->setColumnCount(3);
       model->setHeaderData(0,Qt::Horizontal, "姓名");
       model->setHeaderData(1,Qt::Horizontal, "年龄");
       model->setHeaderData(2,Qt::Horizontal, "性别");
       model->setRowCount(3);
       model->setHeaderData(0,Qt::Vertical, "记录一");
       model->setHeaderData(1,Qt::Vertical, "记录二");
       model->setHeaderData(2,Qt::Vertical, "记录三");
       model->setItem(0, 0, new QStandardItem("张三"));
       model->setItem(0, 1, new QStandardItem("3"));
       model->setItem(0, 2, new QStandardItem(""));
       connect(model, SIGNAL(dataChanged(QModelIndex,QModelIndex,QVector<int>)), this, SLOT(dataChangedSlot(QModelIndex,QModelIndex,QVector<int>)));
       this->setModel(model);
    }
    void Widget::dataChangedSlot(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles)
    {
        qDebug() << model->data(topLeft).toString() << endl;
    }
    Widget::~Widget()
    {
    }

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

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

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

    6 常用函数

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

    7 QStandardItem被点选信号

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

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

    8 QItemDelegate代理

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

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

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

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

     widget.h

    #ifndef WIDGET_H
    #define WIDGET_H
    #include <QTableView>
    
    class QStandardItemModel;
    
    class Widget : public QTableView
    {
        Q_OBJECT
    public slots:
        void dataChangedSlot(const QModelIndex &topLeft, const QModelIndex &bottomRight,
                             const QVector<int> &roles = QVector<int> ());
    public:
        Widget(QWidget *parent = 0);
        QStandardItemModel* model;
        ~Widget();
    };
    
    #endif

    widget.cpp

    #include "widget.h"
    #include "spindelegate.h"
    #include <QStandardItemModel>
    #include <QDebug>
    
    Widget::Widget(QWidget  *parent)
        : QTableView(parent)
    {
        model = new QStandardItemModel(this);
        //设置列字段名
        model->setColumnCount(3);
        model->setHeaderData(0,Qt::Horizontal,"姓名");
        model->setHeaderData(1,Qt::Horizontal,"年龄");
        model->setHeaderData(2,Qt::Horizontal,"性别");
        //设置行字段名
        model->setRowCount(3);
        model->setHeaderData(0,Qt::Vertical, "记录一");
        model->setHeaderData(1,Qt::Vertical, "记录二");
        model->setHeaderData(2,Qt::Vertical, "记录三");
        //设置一条数据
        model->setItem(0, 0, new QStandardItem("张三"));
        model->setItem(0, 1, new QStandardItem("3"));
        model->setItem(0, 2, new QStandardItem(""));
        this->setModel(model);
        //设置代理
        this->setItemDelegate(new SpinDelegate(this));
        connect(model, SIGNAL(dataChanged(QModelIndex,QModelIndex,QVector<int>)),
                this,SLOT(dataChangedSlot(QModelIndex,QModelIndex,QVector<int>)));
        this->setModel(model);
    
    }
    
    void Widget::dataChangedSlot(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles)
    {
        qDebug() << model->data(topLeft).toString() << endl;
    }
    Widget::~Widget()
    {
    }

    spinDelegate.h

    #ifndef SPINDELEGATE_H
    #define SPINDELEGATE_H
    #include <QItemDelegate>
    
    class SpinDelegate : public QItemDelegate
    {
    public:
        SpinDelegate(QObject *parent = Q_NULLPTR);
        QWidget* createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const;
    };
    
    #endif // SPINDELEGATE_H

     spinDelegate.cpp

    #include "spindelegate.h"
    #include <QSpinBox>
    SpinDelegate::SpinDelegate(QObject *parent): QItemDelegate(parent)
    {
    
    }
    QWidget* SpinDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option,
                                        const QModelIndex &index) const
    {
        if(index.column() == 1) // 返回下拉框
        {
           QSpinBox* box = new QSpinBox(parent);
           box->setMinimum(1);
           box->setMaximum(99);
           return box;
        }
    return QItemDelegate::createEditor(parent, option, index); }

  • 相关阅读:
    【转+补充】在OpenCV for Android 2.4.5中使用SURF(nonfree module)
    Delphi StarOffice Framework Beta 1.0 发布
    Angular ngIf相关问题
    angularjs文档下载
    公众号微信支付开发
    公众号第三方平台开发 教程六 代公众号使用JS SDK说明
    公众号第三方平台开发 教程五 代公众号处理消息和事件
    公众号第三方平台开发 教程四 代公众号发起网页授权说明
    公众号第三方平台开发 教程三 微信公众号授权第三方平台
    公众号第三方平台开发 教程二 component_verify_ticket和accessToken的获取
  • 原文地址:https://www.cnblogs.com/fuqia/p/8916011.html
Copyright © 2011-2022 走看看