zoukankan      html  css  js  c++  java
  • 继承QAbstractTableModel QStyledItemDelegate实现自定义表格,添加进度条和选中框。

    由于项目要求,需要实现一个列表目录显示信息,并且需要实现每一项提供进度条和选项框功能,所以需要继承QAbstractTableModel和QStyledItemDelegate进行自定义。

    -自定义数据

    itemdata.h

    #ifndef ITEMDATA_H
    #define ITEMDATA_H
    #include <QMetaType>
    #include <QString>
    #include <QDebug>
    
    typedef enum{
        level_0 = 0,
        level_1,
        level_2,
        level_3,
        level_4,
        level_5,
        level_6,
        level_7,
        level_8,
        level_9,
        level_none,
    } Priority;
    
    typedef enum{
        state_0 = 0,
        state_1,
        state_2,
        state_3,
        state_4,
        state_5,
        state_6,
        state_7,
        state_8,
        state_9,
    }State;
    
    struct Data{
        Priority priority;
        State taskState;
        QString taskCode;
        QString taskName;
        QString taskType;
        QString tubeType;
        int tubeNumber;
        int rackNumber;
        int beginTime;
        int processed; //[0-100]
        QString taskOwner;
        bool select = false;
    };
    
    Q_DECLARE_METATYPE(Data)
    
    #endif // ITEMDATA_H

    -继承QAbstractTableModel自定义数据

    mytablemodel.h

    #ifndef MYTABLEMODEL_H
    #define MYTABLEMODEL_H
    #include
    <QAbstractTableModel> #include <QList> #include "itemdata.h" class myTableModel:public QAbstractTableModel { Q_OBJECT public: myTableModel(QAbstractTableModel *parent = 0); ~myTableModel(); QVariant data(const QModelIndex &index, int role) const;// 重写,用于返回数据 int rowCount(const QModelIndex &parent = QModelIndex()) const; // 重写, 反回行数 int columnCount(const QModelIndex &parent = QModelIndex()) const;// 重写,返回列数 QVariant headerData(int section, Qt::Orientation, int role)const;// 重写, 返回列标题 Qt::ItemFlags flags(const QModelIndex &index) const; // 重写, 每一项的操作标识 bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);// 重写, 设置数据 void addData(Data data);// 添加模型数据 private: QStringList _roleNames; QList<Data> _dataList; }; #endif // MYTABLEMODEL_H
    #include "mytablemodel.h"
    
    myTableModel::myTableModel(QAbstractTableModel *parent):QAbstractTableModel(parent),
        _roleNames({"priority","taskState","taskCode","taskName","taskType","tubeType","tubeNumber","rackNumber","beginTime","processed","taskOwner","select"}){
    
    }
    
    myTableModel::~myTableModel(){
    
    }
    
    QVariant myTableModel::data(const QModelIndex &index, int role) const{
        QVariant v;
        switch (role - (Qt::UserRole+1)) {// 自定义角色从Qt::UserRole + 1开始
          case 0:
            v = QVariant(_dataList[index.row()].priority);
            break;
         case 1:
            v = QVariant(_dataList[index.row()].taskState);
            break;
        case 2:
            v = QVariant(_dataList[index.row()].taskCode);
            break;
        case 3:
            v = QVariant(_dataList[index.row()].taskName);
            break;
        case 4:
            v = QVariant(_dataList[index.row()].taskType);
            break;
        case 5:
            v = QVariant(_dataList[index.row()].tubeType);
            break;
        case 6:
            v = QVariant(_dataList[index.row()].tubeNumber);
            break;
        case 7:
            v = QVariant(_dataList[index.row()].rackNumber);
            break;
        case 8:
            v = QVariant(_dataList[index.row()].beginTime);
            break;
        case 9:
            v = QVariant(_dataList[index.row()].processed);
            break;
        case 10:
             v = QVariant(_dataList[index.row()].taskOwner);
            break;
        case 11:
            v= QVariant(_dataList[index.row()].select);
            break;
        }
        return v;
    }
    
    int myTableModel::rowCount(const QModelIndex &parent) const
    {
        Q_UNUSED(parent)
        return _dataList.size();// 行数
    }
    
    int myTableModel::columnCount(const QModelIndex &parent) const
    {
        Q_UNUSED(parent)
        return _roleNames.size();//列数
    }
    
    //QHash<int, QByteArray> myTableModel::roleNames() const
    //{
    //    QHash<int,QByteArray> roleName;
    //    for(int i = 0; i < _roleNames.size(); ++i){
    //        roleName.insert(Qt::UserRole+1+i,_roleNames[i].toLocal8Bit());
    //    }
    //    return roleName;
    //}
    
    QVariant myTableModel::headerData(int section, Qt::Orientation orientation, int role)const{
        if(role ==  Qt::DisplayRole && orientation == Qt::Orientation::Horizontal){ //返回列标题
            QString sectionName;
            switch (section) {
            case 0:
            sectionName = tr("优先级");
            break;
            case 1:
            sectionName = tr("状态");
            break;
            case 2:
            sectionName = tr("编码");
            break;
            case 3:
            sectionName = tr("名称");
            break;
            case 4:
            sectionName = tr("类型");
            break;
            case 5:
            sectionName = tr("冻存管型号");
            break;
            case 6:
            sectionName = tr("管数量");
            break;
            case 7:
            sectionName = tr("盒数量");
            break;
            case 8:
            sectionName = tr("开始时间");
            break;
            case 9:
            sectionName = tr("进度");
            break;
            case 10:
            sectionName = tr("发起人");
            break;
            case 11:
            sectionName = tr("选中");
            break;
    
    
            }
            return sectionName;
        }
        return QVariant();
    }
    
    void myTableModel::addData(Data data){
       beginInsertRows(QModelIndex(),_dataList.count(),_dataList.count()); //添加数据之前进行通知并告知添加到什么位置
        _dataList.push_back(data);
        endInsertRows();
    }
    
    Qt::ItemFlags myTableModel::flags(const QModelIndex &index) const {
        if(!index.isValid()){
            return Qt::NoItemFlags;
        }
        Qt::ItemFlags flags;
        flags = QAbstractItemModel::flags(index);
        if(index.column() == 11){
            flags |= Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable|Qt::ItemIsUserCheckable;// 选项框设置为可选中
        } else {
    
            flags |= Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable;
        }
        return flags;
    }
    bool myTableModel::setData(const QModelIndex &index, const QVariant &value, int role) {
        if(role == Qt::UserRole + 1 + 11){// 设置选项框数据true or false
            QVector<int> changeRoles;
            changeRoles.push_back(Qt::UserRole + 1 + 11);
            for(QList<Data>::iterator it = _dataList.begin(); it != _dataList.end(); ++it){
                if((*it).taskCode == index.data(Qt::UserRole +1 + 2).toString()){ // 根据taskCode定位选中的数据行
                    (*it).select = value.toBool();
                }
            }
            emit dataChanged(index,index,changeRoles);
            return true;
        } else{
            return QAbstractTableModel::setData(index, index,role); // 调用默认父类默认实现
        }
    }

    -继承QStyledItemDelegate重写数据项代理,显示各个项,并接收接收处理用户事件

    myitemdelegate.h

    #ifndef MYITEMDELEGATE_H
    #define MYITEMDELEGATE_H
    #include <QStyledItemDelegate>
    #include <QPainter>
    #include <QStyleOptionViewItem>
    #include <QRect>
    #include <QPainterPath>
    #include <QDate>
    #include <QTime>
    #include <QApplication>
    
    #include "itemdata.h"
    
    class myItemDelegate:public QStyledItemDelegate
    {
        Q_OBJECT
    public:
        myItemDelegate(QStyledItemDelegate * parent = 0);
        ~myItemDelegate();
    
        void paint(QPainter * painter,const QStyleOptionViewItem & option,const QModelIndex & index) const; // 重写,绘制每一项
        QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const;//重写, 返回项尺寸
        bool editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index);// 重写,处理项事件
        QRect checkBoxRect(const QStyleOptionViewItem &viewItemStyleOptions) const;//返回选中框尺寸
    
    };
    
    #endif // MYITEMDELEGATE_H
    #include "myitemdelegate.h"
    #include <QMouseEvent>
    
    myItemDelegate::myItemDelegate(QStyledItemDelegate *parent):QStyledItemDelegate(parent)
    {
    
    }
    
    myItemDelegate::~myItemDelegate(){
    
    }
    
    void myItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const{
        if(index.isValid()){
            painter->save();
            int column = index.column();
            QVariant v = index.data(column + (Qt::UserRole+1)); //获取数据
    //        painter->drawRect(option.rect);
    
            QStyleOptionViewItem viewOption(option);
           if(0 == column){
                Priority priority = (Priority)v.toInt();
                painter->drawText(option.rect, Qt::AlignCenter, QString::number(priority));
           }else if(1 == column){
                State state = (State)v.toInt();
                painter->drawText(option.rect, Qt::AlignCenter, QString::number(state));
           }
           else if(2 == column){
                QString taskCode = v.toString();
                painter->drawText(option.rect, Qt::AlignCenter,taskCode);
                  }
           else if(3 == column){
                QString taskName = v.toString();
                painter->drawText(option.rect, Qt::AlignCenter,taskName);
                  }
           else if(4== column){
                QString taskType = v.toString();
                painter->drawText(option.rect, Qt::AlignCenter,taskType);
                  }
           else if(5 == column){
                QString tubeType = v.toString();
                  painter->drawText(option.rect, Qt::AlignCenter,tubeType);
                  }
           else if(6 == column){
                int tubeNumber = v.toInt();
                  painter->drawText(option.rect, Qt::AlignCenter, QString::number(tubeNumber));
                  }
           else if(7 == column){
                int rackNumber = v.toUInt();
                  painter->drawText(option.rect, Qt::AlignCenter, QString::number(rackNumber));
                  }
           else if(8== column){
                int  beginTime = v.toInt();
                QRect timeRect = QRect(option.rect.left(),option.rect.top(),option.rect.width(),option.rect.height()/2);
                QRect dateRect = QRect(option.rect.left(),option.rect.top()+(option.rect.height()/2),option.rect.width(),option.rect.height()/2);
                painter->drawText(timeRect,Qt::AlignCenter,QDateTime::fromSecsSinceEpoch(beginTime).toString("hh:mm:ss"));
                painter->drawText(dateRect,Qt::AlignCenter,QDateTime::fromSecsSinceEpoch(beginTime).toString("yyyy-MM-dd"));
                  }
           else if(9 == column){// 绘制进度条
                int processed = v.toInt();
    
                QStyleOptionProgressBar *processBar = new QStyleOptionProgressBar();
               processBar->rect = QRect(option.rect.left(),option.rect.top()+(option.rect.height()/3),option.rect.width(),option.rect.height()/3);
               processBar->minimum = 0;
               processBar->maximum = 100;
               processBar->progress = processed;
               processBar->text = QString::number(processed)+"%";
               processBar->textAlignment = Qt::AlignBottom;
               processBar->textVisible = true;
                QApplication::style()->drawControl(QStyle::CE_ProgressBar, processBar, painter);
    //              painter->drawText(option.rect, Qt::AlignCenter, QString::number(processed));
                  }
           else if(10 == column){
                  QString taskOwner = v.toString();
                    painter->drawText(option.rect, Qt::AlignCenter,taskOwner);
                  }
           else if(11 == column){ // 绘制选项框
              bool checked = v.toBool();
              QStyleOptionButton checkButton;
              checkButton.state |= QStyle::State_Enabled;
              checkButton.state |= checked ? QStyle::State_On : QStyle::State_Off;// 根据模型值设定是否选中
              checkButton.rect = checkBoxRect(option);
              QApplication::style()->drawControl(QStyle::CE_CheckBox, &checkButton, painter);
           }
           painter->restore();
    
        }
    }
    
    QSize myItemDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const{
        qDebug()<< option.rect.width()<< option.rect.height();
        //return QSize(option.rect.size());
        //return QSize(40,60);
        return QSize(option.rect.width(), 200);
    }
    QRect myItemDelegate::checkBoxRect(const QStyleOptionViewItem &viewItemStyleOptions) const {
        QStyleOptionButton checkBoxStyleOption;
        QRect checkBoxRect = QApplication::style()->subElementRect(QStyle::SE_CheckBoxIndicator, &checkBoxStyleOption);
        QPoint checkBoxPoint(viewItemStyleOptions.rect.x() + (viewItemStyleOptions.rect.width()- checkBoxRect.width())/2,
                             viewItemStyleOptions.rect.y() + (viewItemStyleOptions.rect.height()- checkBoxRect.height())/2);
        return QRect(checkBoxPoint, checkBoxRect.size());
    }
    bool myItemDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index) {
        if(index.column() == 11){
            if(event->type() == QEvent::MouseButtonRelease){
                QMouseEvent *mouseEvent = (QMouseEvent*)event;
                if(mouseEvent->button() == Qt::LeftButton && checkBoxRect(option).contains(mouseEvent->pos())){
                    bool checked = index.data(Qt::UserRole + 1 + 11).toBool();
                    return model->setData(index, !checked, Qt::UserRole + 1 + 11);// 单击选中框设置相反的选中状态
                }
            }
        }
        return QStyledItemDelegate::editorEvent(event, model, option, index); //其余事件调用默认实现
    }

    -测试

    .../
    QSortFilterProxyModel *sortModel = new QSortFilterProxyModel(); myTableModel *model = new myTableModel(); myItemDelegate *itemDelegate = new myItemDelegate(); ui->tableView->setItemDelegate(itemDelegate); sortModel->setSourceModel(model); sortModel->setDynamicSortFilter(true); sortModel->setSortRole(Qt::UserRole+1); //按照权限排序 ui->tableView->setSortingEnabled(true); ui->tableView->setModel(sortModel); ui->tableView->setSelectionBehavior(QAbstractItemView::SelectRows); ui->tableView->setSelectionMode ( QAbstractItemView::SingleSelection); // ui->tableView->setEditTriggers(QAbstractItemView::NoEditTriggers); ui->tableView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); ui->tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); ui->tableView->resizeColumnsToContents(); ui->tableView->setShowGrid(false); for(int i = 0 ;i < 10 ; ++i){ Data d; d.priority = static_cast<Priority>(i); d.taskState = static_cast<State>(9-i); d.taskCode = QString("taskCode%1").arg(i); d.taskName = QString("taskName%1").arg(i); d.taskType = QString("taskType%1").arg(i); d.tubeType = QString("tubeType%1").arg(i); d.tubeNumber = i+100; d.rackNumber = i+10; d.beginTime = QDateTime::currentDateTime().toTime_t(); d.processed = 50+i; d.taskOwner = QString("owner%1").arg(i); model->addData(d); }
    /...

  • 相关阅读:
    背景qwq
    关于Oracle数据库空表无法导出问题
    Linux 备份 Oracle11g 数据库
    Linux Tomcat安装
    Linux JDK安装
    Oracle 监听与服务器
    Xftp强制更新
    Linux 安装 Oracle11g 数据库
    Vue 动态获取组件与动态路由获取组件
    Linux 防火墙
  • 原文地址:https://www.cnblogs.com/ohsolong/p/12808753.html
Copyright © 2011-2022 走看看