QTableView利用自定义委托实现日期显示下拉菜单文字颜色等

精帖
0 873
索鸟 2021-04-01
需要:0索币

本文主要记录QTableView 使用代理添加进度条、下拉选择框、日历等,并实现复制粘贴,右键菜单等,效果如下图所示,最后有动态展示。

图片说明

1:图中红色1处是√和×,双击可以相互切换显示

2:图中红色2处是Qspinbox,实现整数输入

3:图中红色3处是QDateTimeEdit

4:图中红色4处是QCheckBox

5:图中红色5处是进度条


6:图中红色6处是下拉选择框

继承QStyledItemDelegate,实现编辑器控件和项目渲染等

头文件comboboxdelegate.h

#ifndef COMBOBOXDELEGATE_H

#define COMBOBOXDELEGATE_H

 

#include <QStyledItemDelegate>

#include <QPixmap>

#include <QRect>

 

class comboboxdelegate : public QStyledItemDelegate

{

    Q_OBJECT

public:

    comboboxdelegate();

    ~comboboxdelegate();

protected:

    QWidget* createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const;

    void  paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;

    void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const;

    void setEditorData(QWidget *editor, const QModelIndex &index) const;

    void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const;

    bool editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index);

public:

    QRect CheckBoxRect(const QStyleOptionViewItem &option)const;

 

private:

    QPixmap pixmap1;

    QPixmap pixmap2;

 

 

};

 

#endif // COMBOBOXDELEGATE_H

源文件comboboxdelegate.cpp


#include "comboboxdelegate.h"

#include <QComboBox>

#include <QPainter>

#include <QApplication>

#include <QProgressBar>

#include <QColor>

#include <QCheckBox>

#include <QMouseEvent>

#include <QEvent>

#include <QDateTimeEdit>

#include <QSpinBox>

 

comboboxdelegate::comboboxdelegate()

{

    if(pixmap1.load(":/accept.png"))

    {

        printf("load-----233333\n");

    }

    else

    {

        printf("load-----55555\n");

    }

}

comboboxdelegate::~comboboxdelegate()

{

}

 

QWidget* comboboxdelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const

{

    if(index.column()==2&&index.row() ==4)//在第4行第2列创建一个下拉选择框,上图6

    {

        QComboBox *comBox = new QComboBox(parent);//创建编辑器控件,并设置父对象

        comBox->addItem("combox1");

        comBox->addItem("combox2");

        comBox->addItem("combox3");

       // comBox->setCurrentIndex(0);

        comBox->setStyleSheet(

                              "QComboBox::drop-down{subcontrol-origin:padding;subcontrol-position:top right;width:15px;\

                                                    border-left-width:1px;\

                                                    border-left-color:darkgray;\

                                                    border-left-style:solid;\

                                                    border-top-right-radius:3px;\

                                                    border-bottom-right-radius:3px;}");

        return comBox;

    }

    else if(index.column() ==1&&index.row() ==2)//在第2行第1列创建日历,上图3

    {

        QDateTimeEdit *timeEdit = new QDateTimeEdit(parent);//创建编辑器控件,并设置父对象

        timeEdit->setDisplayFormat("yyyy-MM-dd HH:mm:ss");//显示日期及时间格式

       // timeEdit->setCalendarPopup(true);  //下拉菜单的方式

        return timeEdit;

    }

    else if(index.column() ==1&&index.row() ==1)//在第1行第1列创建一个QSpinBox ,上图2

    {

        QSpinBox *spinEdit = new QSpinBox(parent);//创建编辑器控件,并设置父对象

        spinEdit->setRange(0,10000);

        return spinEdit;

    }

    else if(index.column() ==0)//第1列不可编辑,直接返回null即可

    {

        return NULL;

    }

    else

    {

        return QStyledItemDelegate::createEditor(parent,option,index);

    }

}

void  comboboxdelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const

{

   /* QStyleOptionViewItem view_option(option);

    initStyleOption(&view_option,index);

    if(view_option.state & QStyle::State_HasFocus)

    {

        view_option.state = view_option.state ^ QStyle::State_HasFocus;

    }  */

 

    if(option.state & QStyle::State_Selected)//选中高亮

    {

        painter->fillRect(option.rect,option.palette.highlight());

    }

    if(index.column() ==1&&index.row() ==4)//在第4行第1列处绘制一个进度条,上图5

    {

        int V = index.data(Qt::UserRole).toInt();

        QStyleOptionProgressBarV2 progressBarOption;

        progressBarOption.state =  QStyle::State_Enabled ;

        progressBarOption.direction = QApplication::layoutDirection();

        progressBarOption.rect = option.rect;

        progressBarOption.fontMetrics = QApplication::fontMetrics();

        progressBarOption.minimum =0;

        progressBarOption.maximum =100;

        progressBarOption.textAlignment = Qt::AlignCenter;

        progressBarOption.textVisible =true;

        progressBarOption.progress = V;

        progressBarOption.text = QString("%1%").arg(V);

        QProgressBar bar;

        bar.setStyleSheet("QProgressBar{border:none;text-align:center;}"

                          "QProgressBar::chunk{background:rgb(0,160,230);}");//设置进度条颜色

        bar.style()->drawControl(QStyle::CE_ProgressBar,&progressBarOption,painter,&bar);

 

    }

    else if(index.column() ==1&&index.row() ==3)//在第3行第1列处绘制一个复选框,上图4

    {

        bool checkFlag = index.data(Qt::UserRole).toBool();

        QStyleOptionButton checkBoxStyle;

        checkBoxStyle.state = checkFlag ? QStyle::State_On:QStyle::State_Off;

        checkBoxStyle.state |= QStyle::State_Enabled;

        checkBoxStyle.rect = CheckBoxRect(option);//改变复选框指示器位置,中心位置

       // checkBoxStyle.rect = option.rect;

        QCheckBox checbox;

        checbox.style()->drawControl(QStyle::CE_CheckBox,&checkBoxStyle,painter,&checbox);

    }

    else if(index.column() ==0)//绘制文本,颜色为红色

    {

      QString strValue = index.data().toString();

      QPen pen(Qt::red);

      painter->save();

      painter->setPen(pen);

      painter->setFont(QFont("Times",10,QFont::Bold));

      QApplication::style()->drawItemText(painter,option.rect,Qt::AlignCenter,QApplication::palette(),true,strValue);

      painter->restore();

    }

    else if(index.row() ==5 && index.column() ==1)//绘制图片,处于中心位置

    {

        const QPixmap &star = pixmap1;

        int x = option.rect.x()+option.rect.width()/2 - star.width()/2;

        int y = option.rect.y()+option.rect.height()/2 - star.height()/2;

        painter->drawPixmap(x,y,star);

    }

    else

    {

        QStyledItemDelegate::paint(painter,option,index);

    }

 

}

void comboboxdelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const

{

    if(index.column()==2&&index.row() ==4)

    {

        QComboBox* combox = static_cast<QComboBox*>(editor);

        model->setData(index,combox->currentText(),Qt::DisplayRole);

        model->setData(model->index(4,1),50,Qt::UserRole);

    }

    else if(index.column() ==1&&index.row() ==2)

    {

        QDateTimeEdit *timeEdit = static_cast<QDateTimeEdit*>(editor);

        QDateTime date = timeEdit->dateTime();//日期及时间格式---年月日是日期,时分秒是时间

        model->setData(index,date.toString("yyyy-MM-dd HH:mm:ss"));//日期及时间格式

    }

    else if(index.column() ==1&&index.row() ==1)

    {

        QSpinBox *spinEdit = static_cast<QSpinBox*>(editor);

        model->setData(index,spinEdit->value());

    }

    else

    {

        QStyledItemDelegate::setModelData(editor,model,index);

    }

}

void comboboxdelegate::setEditorData(QWidget *editor, const QModelIndex &index) const

{

 

    if(index.column()==2&&index.row() ==4)

    {

        QComboBox* combox = static_cast<QComboBox*>(editor);

        int textindex = combox->findText(index.data().toString());

        if(textindex !=-1)

        {

            combox->setCurrentIndex(textindex);

 

        }

    }

    else if(index.column() ==1&&index.row() ==2)

    {

        QString dateStr = index.data().toString();

        printf("----%s--------\n",dateStr.toAscii().data());

        QDateTime date = QDateTime::fromString(dateStr,"yyyy-MM-dd HH:mm:ss");//日期及时间格式

        QDateTimeEdit *timeEdit = static_cast<QDateTimeEdit*>(editor);

        timeEdit->setDateTime(date);//日期及时间格式

    }

    else if(index.column() ==1&&index.row() ==1)

    {

        int iValue = index.data().toInt();

        QSpinBox *spinEdit = static_cast<QSpinBox*>(editor);

        spinEdit->setValue(iValue);

    }

    else

    {

        QStyledItemDelegate::setEditorData(editor,index);

    }

 

 

}

void comboboxdelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const

{

    editor->setGeometry(option.rect);

}

 

bool comboboxdelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index)

 {

     QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event);

     if(event->type() == QEvent::MouseButtonPress && option.rect.contains(mouseEvent->pos()))

     {

         if(index.column() ==1&&index.row() ==3)//单击改变复选框状态

         {

             bool data = model->data(index,Qt::UserRole).toBool();

             model->setData(index,!data,Qt::UserRole);

         }

     }

     if(event->type() == QEvent::MouseButtonDblClick && option.rect.contains(mouseEvent->pos()))

     {

         if(index.column() ==1&&index.row() ==0)//双击实现×和√切换

         {

             bool data = model->data(index,Qt::UserRole).toBool();

             model->setData(index,!data,Qt::UserRole);

             model->setData(index,data?QString::fromLocal8Bit("√"):QString::fromLocal8Bit("×"),Qt::DisplayRole);

         }

 

     }

     return QStyledItemDelegate::editorEvent(event,model,option,index);

 }

 QRect comboboxdelegate::CheckBoxRect(const QStyleOptionViewItem &option)const

 {

     QStyleOptionButton checkBoxbuttonOption;

     QRect checkBoxRect = QApplication::style()->subElementRect(QStyle::SE_CheckBoxIndicator,&checkBoxbuttonOption);

     QPoint checkBoxPoint(option.rect.x()+option.rect.width()/2 - checkBoxRect.width()/2,option.rect.y()+option.rect.height()/2 - checkBoxRect.height()/2);

     return QRect(checkBoxPoint,checkBoxRect.size());

 }

 


 


 


源文件widget.cpp--------- 设置QTableView、菜单、复制粘贴等功能


#include "widget.h"

#include "comboboxdelegate.h"

 

widget::widget(QWidget *parent) : QWidget(parent)

{

 

 

   // this->setFocusPolicy(Qt::StrongFocus);

 

    this->resize(500,500);

    QHBoxLayout* hlayout = new QHBoxLayout;

    model = new QStandardItemModel;

 

 

    view = new QTableView();

    hlayout->addWidget(view);

    this->setLayout(hlayout);

    view->horizontalHeader()->setStretchLastSection(true);//最后一列自适应宽度

    view->setAlternatingRowColors(true);//表格颜色交替

    view->setModel(model);

    view->setMouseTracking(true);//鼠标跟踪

    view->setItemDelegate(new comboboxdelegate);//设置代理

    //view->setSelectionBehavior(QAbstractItemView::SelectRows);

    //view->setSelectionMode(QAbstractItemView::SingleSelection);

    view->setStyleSheet("QTableView::item:hover{background-color:red;}");//鼠标悬浮在item上的样式表

 

 

    model->setColumnCount(3);

    model->setHeaderData(0,Qt::Horizontal,QObject::tr("name"));

    model->setHeaderData(1,Qt::Horizontal,QObject::tr("age"));

    model->setHeaderData(2,Qt::Horizontal,QObject::tr("sex"));

 

    model->setItem(0,0,new QStandardItem("tom"));

    QStandardItem* item4 = new QStandardItem;

    item4->setData(0,Qt::UserRole);//用于判断当前项的状态,0显示×,1显示√

    item4->setData(QString::fromLocal8Bit("×"),Qt::DisplayRole);

    item4->setEditable(false);//设置为不可编辑

    item4->setTextAlignment(Qt::AlignCenter);//文本居中显示

    model->setItem(0,1,item4);//√

    model->setItem(0,2,new QStandardItem(QString::fromLocal8Bit("总线")));

 

 

    model->setItem(1,0,new QStandardItem("tom2"));

    model->setItem(1,1,new QStandardItem("19"));

    QStandardItem* item5 = new QStandardItem;

    item5->setData(0,Qt::CheckStateRole);//设置可选数据角色

    item5->setCheckable(true);//设置为可选择

    item5->setEditable(false);//不可编辑

    model->setItem(1,2,item5);

 

    model->setItem(2,0,new QStandardItem("qqqq"));

    model->setItem(2,1,new QStandardItem("2021-01-16 10:04:21"));//给一个初始日期和时间

    model->setItem(2,2,new QStandardItem("f"));

 

    model->setItem(3,0,new QStandardItem("www"));

    QStandardItem* item3 = new QStandardItem;

    item3->setData(0,Qt::UserRole);//用于判断当前项的状态,0表示未选中,1表示选中

    item3->setEditable(false);//设置为不可编辑

    model->setItem(3,1,item3);

    model->setItem(3,2,new QStandardItem("f"));

 

    QStandardItem*  item11=model->itemFromIndex(model->index(3,2));

    item11->setEditable(false);

 

 

 

 

    QStandardItem* item = new QStandardItem;

    item->setEditable(false);

    item->setData("eee",Qt::DisplayRole);

    item->setData("tips",Qt::ToolTipRole);

    model->setItem(4,0,item);

    QStandardItem* item2 = new QStandardItem;

    item2->setData(22,Qt::UserRole);//进度条的初始值,数据角色为Qt::UserRole,这样可以避免进度条处的项目显示文本值

    item2->setEditable(false);

    model->setItem(4,1,item2);

 

    QStandardItem* item1 = new QStandardItem;

    item1->setData("combox1",Qt::DisplayRole);

    model->setItem(4,2,item1);

 

  /* QModelIndex index = model->index(4,2);

    QComboBox * box = new QComboBox;

    box->addItem("aa");

    box->addItem("bb");

    view->setIndexWidget(index,box);*/

 

 

 

 

    model->setItem(5,0,new QStandardItem("ddd"));

    model->setItem(5,1,new QStandardItem(30));

    model->setItem(5,2,new QStandardItem("mmm"));

 

 

  //  model->setData(model->index(6,0),"zzx");

   // model->setData(model->index(6,1),18);

  //  model->setData(model->index(6,2),"27");//尽量不要使用setData()和insertXXX()等函数,如果指定位置不存在,则可能添加失

回帖
  • 消灭零回复
相关主题
2020年最新最新Kubernetes视频教程(K8s)教程 2
程序员转型之制作网课变现,月入过万告别996 1
索鸟快传2.0发布啦 1
两个不同网络的电脑怎么实现文件的互相访问呢? 1
网盘多账号登录软件 1
Java实战闲云旅游项目基于vue+element-ui 1
单点登录技术解决方案基于OAuth2.0的网关鉴权RSA算法生成令牌 1
QT5获取剪贴板上文本信息QT设置剪贴板内容 1
springboot2实战在线购物系统电商系统 1
python web实战之爱家租房项目 1
windows COM实用入门教程 1
C++游戏开发之C++实现的水果忍者游戏 1
计算机视觉库opencv教程 1
node.js实战图书管理系统express框架实现 1
C++实战教程之远程桌面远程控制实战 1
相关主题
PHP7报A non well formed numeric value encountered 0
Linux系统下关闭mongodb的几种命令分享 0
mongodb删除数据、删除集合、删除数据库的命令 0
Git&Github极速入门与攻坚实战课程 0
python爬虫教程使用Django和scrapy实现 0
libnetsnmpmibs.so.31: cannot open shared object file 0
数据结构和算法视频教程 0
redis的hash结构怎么删除数据呢? 0
C++和LUA解析器的数据交互实战视频 0
mongodb errmsg" : "too many users are authenticated 0
C++基础入门视频教程 0
用30个小时精通C++视频教程可能吗? 0
C++分布式多线程游戏服务器开发视频教程socket tcp boost库 0
C++培训教程就业班教程 0
layui的util工具格式时间戳为字符串 0
C++实战教程之远程桌面远程控制实战 1
网络安全培训视频教程 0
LINUX_C++软件工程师视频教程高级项目实战 0
C++高级数据结构与算法视频教程 0
跨域问题很头疼?通过配置nginx轻松解决ajax跨域问题 0