Qt自定义委托在QTableView中绘制控件、图片、文字

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/lengyuezuixue/article/details/82502577

    自定义委托,继承于QStyledItemDelegate类,重载Paint()函数

      1、实现在QTableView中绘制 格式字符串

       2、实现在QTableView中绘制进度条

       3、实现在QTableView中绘制QCheckBox

       4、实现在QTableView中绘制星星

       5、实现在QTableView中绘制Pixmap图片

实现QTableView中绘制 格式字符串

/重载绘制函数  
void DelReconQueue::paint(QPainter *painter, const QStyleOptionViewItem &option,  
                          const QModelIndex &index) const  
{  
    //如果是第2列'病人Id'  
    if (index.column() == 2)  
    {  
        //获得当前项值  
        int patientId = index.model()->data(index, Qt::DisplayRole).toInt();  
        //设置'病人Id'格式字符串: P:00000x;6位10进制数,不足补0;  
        QString text = QString("P:%1").arg(patientId, 6, 10, QChar('0'));  
  
  
        //获取项风格设置  
        QStyleOptionViewItem myOption = option;  
        myOption.displayAlignment = Qt::AlignRight | Qt::AlignVCenter;  
    //绘制文本  
    QApplication::style()->drawItemText ( painter, myOption.rect , myOption.displayAlignment, QApplication::palette(), true,text );  
          
          
    }  
else  
    {  
        //否则调用默认委托  
        QStyledItemDelegate::paint(painter, option, index);  
    }  
      
}  

      如果自定义委托继承于QItemDelegate类,绘制字符串,可以直接用QItemDelegate中的drawDisplay();

void TrackDelegate::paint(QPainter *painter,    
                          const QStyleOptionViewItem &option,    
                          const QModelIndex &index) const    
{    
    //保存音轨的列    
    if (index.column() == durationColumn) {    
        //获得索引对应Model中的数据    
        int secs = index.model()->data(index, Qt::DisplayRole).toInt();    
        //设置时间格式字符串 分:秒    
        QString text = QString("%1:%2")    
                       .arg(secs / 60, 2, 10, QChar('0'))    
                       .arg(secs % 60, 2, 10, QChar('0'));    
        //获取项风格设置    
        QStyleOptionViewItem myOption = option;    
        myOption.displayAlignment = Qt::AlignRight | Qt::AlignVCenter;    
        //绘制文本    
        drawDisplay(painter, myOption, myOption.rect, text);    
        //如果当前有焦点,就绘制一个焦点矩形,否则什么都不做    
        drawFocus(painter, myOption, myOption.rect);    
    } else{    
        //否则默认    
        QItemDelegate::paint(painter, option, index);    
    }    
} 

实现在QTableView中绘制进度条

//重载绘制函数  
void DelReconQueue::paint(QPainter *painter, const QStyleOptionViewItem &option,  
                          const QModelIndex &index) const  
{  
    //如果是'已经完成子任务数'  
     if (index.column() == 9)  
    {  
        const QAbstractItemModel *itemModel = index.model();  
        //获得索引对应Model中的数据  
        int finishedSubTaskNum = itemModel->data(index, Qt::DisplayRole).toInt();  
        int subTaskNum = itemModel->data(itemModel->index(index.row(),8), Qt::DisplayRole).toInt();  
  
        //进度条的风格选项  
        QStyleOptionProgressBarV2 *progressBarOption = new QStyleOptionProgressBarV2();  
        progressBarOption->rect = option.rect;  
        progressBarOption->minimum = 0;  
        progressBarOption->maximum = subTaskNum;  
        progressBarOption->progress = finishedSubTaskNum;  
        int t = finishedSubTaskNum/subTaskNum;  
        progressBarOption->text = QString::number(t) + "%";  
        progressBarOption->textVisible = true;  
        //绘制进度条  
        QApplication::style()->drawControl(QStyle::CE_ProgressBar, progressBarOption, painter);  
  
    }  
   else  
    {  
        //否则调用默认委托  
        QStyledItemDelegate::paint(painter, option, index);  
    }  
      
}  

实现在QTableView中绘制QCheckBox

#include <QtGui>  
#include <QItemDelegate>  
#include <QStyleOptionProgressBarV2>  
#include "DelReconQueue.h"  
//重载绘制函数  
void DelReconQueue::paint(QPainter *painter, const QStyleOptionViewItem &option,  
                          const QModelIndex &index) const  
{  
     if (index.column() == 11)  
    {  
        //获取值  
        bool checked = index.model()->data(index, Qt::DisplayRole).toBool();  
        //按钮的风格选项  
        QStyleOptionButton *checkBoxOption = new QStyleOptionButton();  
        checkBoxOption->state |= QStyle::State_Enabled;  
        //根据值判断是否选中  
        if(checked)  
        {  
            checkBoxOption->state |= QStyle::State_On;  
        }  
        else  
        {  
            checkBoxOption->state |= QStyle::State_Off;  
        }  
        //返回QCheckBox几何形状  
        checkBoxOption->rect = CheckBoxRect(option);  
        //绘制QCheckBox  
        QApplication::style()->drawControl(QStyle::CE_CheckBox,checkBoxOption,painter);  
  
    }  
  
    else  
    {  
        //否则调用默认委托  
        QStyledItemDelegate::paint(painter, option, index);  
    }  
      
}  
QRect DgSystemLog::CheckBoxRect(const QStyleOptionViewItem &viewItemStyleOptions)const  
{  
    //绘制按钮所需要的参数  
    QStyleOptionButton checkBoxStyleOption;  
    //按照给定的风格参数 返回元素子区域  
    QRect checkBoxRect = QApplication::style()->subElementRect( QStyle::SE_CheckBoxIndicator, &checkBoxStyleOption);  
    //返回QCheckBox坐标  
    QPoint checkBoxPoint(viewItemStyleOptions.rect.x() + viewItemStyleOptions.rect.width() / 2 - checkBoxRect.width() / 2,  
                         viewItemStyleOptions.rect.y() + viewItemStyleOptions.rect.height() / 2 - checkBoxRect.height() / 2);  
    //返回QCheckBox几何形状  
    return QRect(checkBoxPoint, checkBoxRect.size());  
}  

实现在QTableView中绘制自定义类 星星

//重载绘制函数  
void StarDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,  
                         const QModelIndex &index) const  
{  
    //如果某项数据是星星类型  
    if (qVariantCanConvert<StarRating>(index.data())) {  
        //获取该项数据,并转换成StarRating类型  
        StarRating starRating = qVariantValue<StarRating>(index.data());  
        //如果有控件被选中,我们就让选中的控件变亮  
        if (option.state & QStyle::State_Selected)  
            painter->fillRect(option.rect, option.palette.highlight());  
  
        starRating.paint(painter, option.rect, option.palette,  
                         StarRating::ReadOnly);  
    }  
    //如果没有控件选中,调用默认委托  
    else {  
        QStyledItemDelegate::paint(painter, option, index);  
    }  
}  

星星自定义源文件

#ifndef STARRATING_H  
#define STARRATING_H  
  
#include <QMetaType>  
#include <QPointF>  
#include <QVector>  
  
class StarRating  
{  
public:  
    enum EditMode { Editable, ReadOnly };  
  
    StarRating(int starCount = 1, int maxStarCount = 5);  
  
    void paint(QPainter *painter, const QRect &rect,  
               const QPalette &palette, EditMode mode) const;  
    QSize sizeHint() const;  
    int starCount() const { return myStarCount; }  
    int maxStarCount() const { return myMaxStarCount; }  
    void setStarCount(int starCount) { myStarCount = starCount; }  
    void setMaxStarCount(int maxStarCount) { myMaxStarCount = maxStarCount; }  
  
private:  
    QPolygonF starPolygon;  
    QPolygonF diamondPolygon;  
    int myStarCount;  
    int myMaxStarCount;  
};  
  
//让所有模板类型都知道该类,包括QVariant  
Q_DECLARE_METATYPE(StarRating)  
  
#endif  
  
  
  
#include <QtGui>  
#include <math.h>  
  
#include "starrating.h"  
  
const int PaintingScaleFactor = 20;  
  
StarRating::StarRating(int starCount, int maxStarCount)  
{  
    myStarCount = starCount;  
    myMaxStarCount = maxStarCount;  
  
    starPolygon << QPointF(1.0, 0.5);  
    for (int i = 1; i < 5; ++i)  
        starPolygon << QPointF(0.5 + 0.5 * cos(0.8 * i * 3.14),  
                               0.5 + 0.5 * sin(0.8 * i * 3.14));  
  
    diamondPolygon << QPointF(0.4, 0.5) << QPointF(0.5, 0.4)  
                   << QPointF(0.6, 0.5) << QPointF(0.5, 0.6)  
                   << QPointF(0.4, 0.5);  
}  
  
QSize StarRating::sizeHint() const  
{  
    return PaintingScaleFactor * QSize(myMaxStarCount, 1);  
}  
  
void StarRating::paint(QPainter *painter, const QRect &rect,  
                       const QPalette &palette, EditMode mode) const  
{  
    painter->save();  
  
    painter->setRenderHint(QPainter::Antialiasing, true);  
    painter->setPen(Qt::NoPen);  
  
    if (mode == Editable) {  
        painter->setBrush(palette.highlight());  
    } else {  
        painter->setBrush(palette.foreground());  
    }  
  
    int yOffset = (rect.height() - PaintingScaleFactor) / 2;  
    painter->translate(rect.x(), rect.y() + yOffset);  
    //画笔坐标  
    painter->scale(PaintingScaleFactor, PaintingScaleFactor);  
  
    for (int i = 0; i < myMaxStarCount; ++i) {  
        if (i < myStarCount) {  
            painter->drawPolygon(starPolygon, Qt::WindingFill);  
        } else if (mode == Editable) {  
            painter->drawPolygon(diamondPolygon, Qt::WindingFill);  
        }  
        painter->translate(1.0, 0.0);  
    }  
  
    painter->restore();  

实现在QTableView中绘制Pixmap图片

void MyItemDelegate::paint(QPainter * painter,    
                           const QStyleOptionViewItem & option,    
                           const QModelIndex & index) const    
{    
    if(index.column()!=0){    
        QItemDelegate::paint(painter,option,index);    
        return;    
    }    
    const QAbstractItemModel * model=index.model();    
    QVariant var=model->data(index,Qt::CheckStateRole);    
    if(var.isNull()) var=false;    
    const QPixmap & star=var.toBool()?    
favouritePixmap:notFavouritePixmap;    
    
    int width=star.width();    
    int height=star.height();    
    QRect rect=option.rect;    
    int x=rect.x()+rect.width()/2-width/2;    
    int y=rect.y()+rect.height()/2-height/2;    
    
    painter->drawPixmap(x,y,star);    
}    

猜你喜欢

转载自blog.csdn.net/lengyuezuixue/article/details/82502577
今日推荐