10

Qt Model_View教程之Delegate

 4 years ago
source link: http://mp.weixin.qq.com/s?__biz=MzUxMTk4MzY3MA%3D%3D&%3Bmid=2247484321&%3Bidx=1&%3Bsn=506dfe840f5f7c79df1cab78831cc545
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

在之前的文章里主要介绍了Qt Model/View 的一些基本用法,接下来结合 Delegate 做最后的说明。

在之前的所有例子中,cell中填充的要么是 text 文本或是 checkbox ,那么如果我们想要填充自己定义的一些东西时该怎么做呢?这就涉及到了 Delegate 。在之前的 view 中我们一直使用的是默认的 Delegate ,现在我们想要填充自己定义的内容,比如说在 cell 中填充五角星,这就需要我们重新实现 Delegate 。效果如下:

fi6N73Q.png!web

在View中使用setItemDelegate()方法代替使用默认的Delegate并使用自定义的 Delegate 。新的 Delegate 可以通过继承QStyledItemDelegate来重新实现。为了简化功能,填充的五角星并没有可编辑的能力,而我们只需要重新实现QStyledItemDelegate类中的paint和 sizeHint 方法即可。

一、  StarDelegate

头文件如下:

class StarDelegate : public QStyledItemDelegate

{

Q_OBJECT


public:

StarDelegate(QWidget *parent = 0) : QStyledItemDelegate(parent) {}


void paint(QPainter *painter, const QStyleOptionViewItem &option,

const QModelIndex &index) const Q_DECL_OVERRIDE;

QSize sizeHint(const QStyleOptionViewItem &option,

const QModelIndex &index) const Q_DECL_OVERRIDE;


};

paint 通过原始数据的内容来绘制五角星,数据的获取与之前的 Model 类似,使用 index.data();sizeHint() 用来获取每个五角星的维度, cell 则可以有足够的空间来适应五角星的大小。

源文件如下:

void StarDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,

const QModelIndex &index) const

{


if (index.data().canConvert<StarRating>())

{

StarRating starRating = qvariant_cast<StarRating>(index.data());


starRating.paint(painter, option.rect, option.palette);

}

else

{

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

}


}



QSize StarDelegate::sizeHint(const QStyleOptionViewItem &option,

const QModelIndex &index) const

{

if (index.data().canConvert<StarRating>())

{

StarRating starRating = qvariant_cast<StarRating>(index.data());

return starRating.sizeHint();

}

else

{

return QStyledItemDelegate::sizeHint(option, index);

}

}

只有当 index.data() StarRating 时我们才使用自己定义的五角星,否则使用 QStyledItemDelegate 来进行绘制。

如果想要使用自定义图形来填充View 栅格中的 cell ,这时我们可以使用自定义 Delegate ,但如果不想使用 View 中的栅格,则需自定义 View

二、 StarRating类

这个主要是画五角星,五角星点位的计算有数学公式,可自行百度。

头文件:

class StarRating

{

public:


explicit StarRating(int starCount = 1, int maxStarCount = 5);


void paint(QPainter *painter, const QRect &rect,

const QPalette &palette) 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;


int myStarCount;

int myMaxStarCount;

};

源文件:

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 * std::cos(0.8 * i * 3.14),

0.5 + 0.5 * std::sin(0.8 * i * 3.14)); //使用公式

}




QSize StarRating::sizeHint() const

{

return PaintingScaleFactor * QSize(myMaxStarCount, 1);

}


void StarRating::paint(QPainter *painter, const QRect &rect,

const QPalette &palette) const

{

painter->save();


painter->setRenderHint(QPainter::Antialiasing, true);

painter->setPen(Qt::NoPen);


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

}


painter->translate(1.0, 0.0);

}


painter->restore();


}

三、 总结

之后会把所有关于的Qt  Model/View的内容重新梳理下。

欢迎关注公众号:

MZzeIjR.png!web


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK