自定义委托,继承于,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);
}
参考文章