首页 > 编程知识 正文

ae文字颜色渐变,qt图形视图类框架

时间:2023-05-04 01:08:36 阅读:51799 作者:4739

者: @apocelipes

本文是作者原创,请注明出处。 http://www.cn blogs.com/apocelipes/archive/2019/03/10/10503835.html

用自定义的颜色显示view文本内容是非常常见的需要。 今天稍微改变一下“图案”。

正文索引

需求定义需求分析代码很容易实现思维问题的需求定义。 目前,view的一些文本内容需要彩色显示。 此外,彩虹的效果不是单一颜色,而是多种颜色的渐变。

因为文字的说明可能是抽象的,所以首先展示预期的效果图:

现在,考虑一下实现图的效果的方法吧。

需求分析由于Qt的Model/View机制为用户定制的外观控件提供了非常丰富的支持,我们可以轻松实现很多独特的显示效果。

通常,对于以特定颜色显示内容的需要,在model的data接口上根据调用时的Qt:ItemDataRole返回对应的数据即可,例如在控制文本的颜色的情况下为Qt :33333:

但是仔细想想,你会发现这种方法并不能解决我们的需要。

要获得渐变效果,只能返回单一颜色。 必须使用QLinearGradient指定线性填充的坐标和大小。 不能指定渐变填充的范围,因为仅从Qt:ItemDataRole获取字符的显示范围。

但是,正如本节开头所述,Qt提供了足够的方法来控制元素的外观。 于是我们很快就把目光投向了delegate。 是控制model数据显示的常用工具。

delegate经常负责显示文本以外的数据并控制显示格式,如果做到这一点,paint方法就会实现。 我们可以用同样的方式描绘希望的效果。 特别是,paint方法从参数中传递要绘制的区域的信息,因此具有使用QLinearGradient实现字符渐变效果的充分条件。

这样,实现需求的思路就明确了。 接下来,我们来看看如何使用代码实现它。

代码实现只是继承QStyledItemDelegate并重写其paint和sizeHint方法。

classcolordelegate : publicqstyleditemdelegate { public : void paint (qpainter * painter, constqstyleoptionviewitemoption qsizesizehint (constqstyleoptionviewitemoption,const qmodelindex索引) const override; (; 其中,paint用于绘制我们的显示效果,sizeHint返回item的大小。

sizeHint没有特别的操作。 简单地计算字符的长度和高度,并根据此连续值指定item的大小。

qsizecolordelegate :3360 size hint (constqstyleoptionviewitemoption,const qmodelindex索引) const { AutoText=index.dadex return QSize{width,option.fontmetrics.height(}; }接下来进入重点:

voidcolordelegate :3360 paint (qpainter * painter,constqstyleoptionviewitemoption,const qmodelindex索引) const { auto my opt.display alignment=Qt :3360 align center; autos width=my opt.font metrics.width (text ); autos height=my opt.font metrics.height (; //计算文本所在的范围是居中对齐的,因此相应的起始位置autos rect=qrectf (my opt.rect.y.x ) (myOpt.rect.width )- sWidth )/2.0,my opt

, sHeight); // 将渐变填充的范围设置成文字所在的范围 QLinearGradient l(sRect.x(), sRect.y(), sRect.x() + sRect.width(), sRect.y() + sRect.height()); // 设置彩虹色渐变效果,彩虹由赤橙黄绿青蓝紫的颜色组成 // 因此我们除去起始点为红色,每隔1/6就设置一种颜色 l.setColorAt(0, Qt::red); l.setColorAt(1.0 / 6, QColor(255, 97, 0)); l.setColorAt(2.0 / 6, QColor(255, 255, 0)); l.setColorAt(3.0 / 6, Qt::green); l.setColorAt(4.0 / 6, Qt::cyan); l.setColorAt(5.0 / 6, Qt::blue); l.setColorAt(1, QColor(255, 0, 255)); // 这里并不使用painter,只需要QStyle即可实现效果 // QPalette::Text为文本显示效果的role auto role = QPalette::Text; if (option.state & QStyle::State_Selected) { // 当前item被选中时绘制高亮的选中框 role = QPalette::HighlightedText; painter->fillRect(option.rect, option.palette.highlight()); } myOpt.palette.setBrush(role, QBrush(l)); // 注意最后一个参数role,只有设置了它才能让QStyle正确地绘制自定义的文本显示效果 QApplication::style()->drawItemText(painter, myOpt.rect, myOpt.displayAlignment, myOpt.palette, true, text, role);}

需要注意的都已经在注释中说明,可以看到paint的逻辑实际上并不复杂,只需要正确计算文字的显示范围后调用相应的绘制接口即可。

可能你会有些疑惑,为什么要计算文本的范围?答案是因为如果将整个item作为填充范围的话,那么文本之外的空白部分也会被计算进去,因此文本的显示效果会被view的拉伸的缩小所影响,显然不是我们希望的结果,因此只填充文本所在的范围就很有必要了。

至于delegate的其他功能,我们选择继续使用父类的默认实现,因为我们只是使用delegate控制显示效果的功能,并不需要实现和数据的交互。

下面我们测试下自定义的ColorDelegate:

#include <QApplication>#include <QStandardItemModel>#include <QListView>#include <QVBoxLayout>#include "ColorDelegate.h"int main(int argc, char **argv) { QApplication app(argc, argv); auto win = new QWidget{}; auto model = new QStandardItemModel{win}; model->appendRow(new QStandardItem{"C++"}); model->appendRow(new QStandardItem{"GoLang"}); model->appendRow(new QStandardItem{"JavaScript"}); model->appendRow(new QStandardItem{"Object C"}); model->appendRow(new QStandardItem{"Rust"}); model->appendRow(new QStandardItem{"这是一串非常非常长的被作为测试用例的样本字符串。"}); model->appendRow(new QStandardItem{"██████████████████"}); auto view = new QListView{}; view->setModel(model); view->setItemDelegate(new ColorDelegate{}); // 设置自定义delegate auto layout = new QVBoxLayout{}; layout->addWidget(view); win->setLayout(layout); win->show(); app.exec();}

运行之后你就会看到如下图的界面:

虽然文字较短时某些位于边缘的颜色有些难以辨认,但整体的彩虹色渐变效果是很明显的。这样我们就实现了文字的彩虹渐变效果。

思考题

最后我们留下一点思考。

虽然我们实现了需求,但是我们的delegate只能处理文字居中的情况,那么其他对齐的情况下呢?

或者如果我们已经在model设置了对齐方式,在delegate中不想改变它,这时候有办法让我们的delegate正常工作吗?

答案是肯定的,只需要将文本范围的计算逻辑做一些修改,因此各位读者不防将其作为一个小练习:)。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。