`
qimo601
  • 浏览: 3415607 次
  • 性别: Icon_minigender_1
  • 来自: 苏州
社区版块
存档分类
最新评论

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

    博客分类:
  • Qt
阅读更多

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

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

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

3、实现在QTableView中绘制QCheckBox

4、实现在QTableView中绘制星星

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

 

 

 

1、实现在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);  
    }  
}  
  

2、实现在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);
    }
    
}

  3、实现在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);
    }
    
}

    //生成QCheckBox

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());
}
 

 

4、实现在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();
}

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

详细请看具体例子 Qt-在表格(QTableView)中插入图片

 

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);  
}  
 

参考文章

 

Qt-在表格(QTableView)中插入图片 

基于QItemDelegate的例子2 trackeEditorDelegate

基于QItemDelegate的例子1 SpinBoxDelegate 

(六)Qt Delgate的使用 简单说明

3
0
分享到:
评论
1 楼 美丽的小岛 2014-08-24  

相关推荐

Global site tag (gtag.js) - Google Analytics