亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C++ > 正文

如何為Qt視圖中的文字實現彩虹漸變效果

2020-05-23 12:53:20
字體:
來源:轉載
供稿:網友

前言

將view中的文本內容用自定義的顏色顯示是一種十分常見的需求。今天我們稍微改變些“花樣”。下面話不多說了,來一起看看詳細的介紹吧

需求定義

我們的需求很簡單,現在有一些在view中的text內容需要使用彩色顯示,而且不使用單一的一種顏色,而是多種顏色漸變實現的彩虹效果。

文字描述可能比較抽象,所以我們先給出預想的效果圖:

Qt,視圖,彩虹漸變

現在讓我們想辦法實現圖中的效果。

需求分析

好在Qt的Model/View機制對于用戶自定義的外觀控制提供了極為豐富的支持,因此我們可以輕松地實現許多獨特的顯示效果。

通常情況下,對于像按特定顏色顯示內容的需求只需要在model的data接口中根據調用時的Qt::ItemDataRole返回對應的數據即可,比如控制文本顏色時我們只需要對Qt::ForegroundRole返回指定的QBrush對象就可以。

但是仔細思考之后你就會發現這種辦法并不能解決我們的需求。

我們想要實現漸變效果是不能只返回單一的一種顏色的,需要用到QLinearGradient,并且需要指定線性填充的坐標及大小。而我們光從Qt::ItemDataRole是拿不到文字的顯示范圍的,因此我們就不能指定漸變填充的范圍了。

不過正如本節開頭所說,Qt提供了足夠多的途徑讓你控制元素的外觀。所以我們很快就把目光投向了delegate,一種經常用來控制model中數據顯示的工具。

雖然delegate更多的是充當了顯示非文本數據以及控制顯示格式的責任,但是只要實現了它的paint方法。我們一樣可以繪制想要的效果。特別的,paint方法還會將待繪制區域的信息從參數中傳入,因此我們有充足的條件使用QLinearGradient實現文字的漸變效果了。

現在已經清楚實現我們的需求的思路了,接下來我們看看如何用代碼實現它。

代碼實現

我們只需要繼承QStyledItemDelegate并重寫它的paint和sizeHint方法:

class ColorDelegate : public QStyledItemDelegate {public: void paint(QPainter *painter, const QStyleOptionViewItem &option,    const QModelIndex &index) const override; QSize sizeHint(const QStyleOptionViewItem &option,     const QModelIndex &index) const override;};

其中paint用來繪制我們的顯示效果,而sizeHint則返回item的大小。

對于sizeHint沒有什么特別的操作,單純計算文字的長度和高度,然后基于這連個值指定item的大小:

QSize ColorDelegate::sizeHint(const QStyleOptionViewItem &option,        const QModelIndex &index) const { auto text = index.data().toString(); auto width = option.fontMetrics.width(text) + 20; return QSize{width, option.fontMetrics.height()};}

下面就要進入重點了:

void ColorDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,       const QModelIndex &index) const { auto text = index.data().toString(); auto myOpt = option; myOpt.displayAlignment = Qt::AlignCenter; auto sWidth = myOpt.fontMetrics.width(text); auto sHeight = myOpt.fontMetrics.height(); // 計算文字所在的范圍,因為是居中對齊,所以需要計算相應的起始位置 auto sRect = QRectF(myOpt.rect.x() + (myOpt.rect.width() - sWidth) / 2.0,      myOpt.rect.y() + ((myOpt.rect.height() - sHeight) / 2.0), sWidth, 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();}

運行之后你就會看到如下圖的界面:

Qt,視圖,彩虹漸變

雖然文字較短時某些位于邊緣的顏色有些難以辨認,但整體的彩虹色漸變效果是很明顯的。這樣我們就實現了文字的彩虹漸變效果。

思考題

最后我們留下一點思考。

雖然我們實現了需求,但是我們的delegate只能處理文字居中的情況,那么其他對齊的情況下呢?

或者如果我們已經在model設置了對齊方式,在delegate中不想改變它,這時候有辦法讓我們的delegate正常工作嗎?

答案是肯定的,只需要將文本范圍的計算邏輯做一些修改,因此各位讀者不防將其作為一個小練習:)。

 

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,謝謝大家對VEVB武林網的支持。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
中文字幕日韩av综合精品| 亚洲国产欧美一区二区丝袜黑人| 国产在线不卡精品| 91丨九色丨国产在线| 国产在线观看91精品一区| 国产精品精品视频一区二区三区| 国产精品视频久久| 尤物九九久久国产精品的特点| 精品偷拍各种wc美女嘘嘘| 日韩电影中文字幕在线| 久久久精品亚洲| 亚洲精品乱码久久久久久金桔影视| 欧美精品videos另类日本| 亚洲影院高清在线| 91免费综合在线| 国产91久久婷婷一区二区| 成人国内精品久久久久一区| 77777少妇光屁股久久一区| 亚洲aⅴ日韩av电影在线观看| 欧美日韩免费观看中文| 欧美精品制服第一页| 国产一区二区三区在线播放免费观看| 欧美日韩亚洲系列| 国产人妖伪娘一区91| 欧美夜福利tv在线| 亚洲xxx视频| 91经典在线视频| 欧美野外猛男的大粗鳮| 日韩视频欧美视频| 国产亚洲美女精品久久久| 国产成人精品电影| 中文字幕国产亚洲| 日本成人精品在线| 久久亚洲欧美日韩精品专区| 久久久久国色av免费观看性色| 亚洲经典中文字幕| 97久久国产精品| 一区二区三区四区精品| 欧美成人午夜激情| 久久久亚洲福利精品午夜| 国产91精品久久久久久| 久久国产精品久久久久久| 国产91在线高潮白浆在线观看| 91免费版网站入口| 国产精品久久久久久久7电影| 欧美电影免费在线观看| 欧美成人激情在线| 亚洲欧美一区二区三区情侣bbw| 亚洲国产精品大全| 91av视频在线| 亚洲国产天堂久久综合网| 久久精品成人一区二区三区| 久久久999精品| 久久九九热免费视频| 97视频在线看| 91精品啪在线观看麻豆免费| 亚洲精品国产拍免费91在线| 国内外成人免费激情在线视频网站| 亚洲色图国产精品| 久久成人国产精品| 日韩国产在线看| 成人午夜一级二级三级| wwwwwwww亚洲| 亚洲女同性videos| 亚洲аv电影天堂网| 亚洲成人激情小说| 国产亚洲精品美女久久久| 欧美激情国产日韩精品一区18| 欧美成人自拍视频| 亚洲国产天堂久久综合| 国产在线视频一区| 国产亚洲视频在线观看| 日韩一区二区三区国产| 91午夜理伦私人影院| 亚洲自拍小视频免费观看| 亚洲国产精品热久久| 国产精品久久久精品| 成人精品一区二区三区电影免费| 欧美视频中文在线看| 欧美性xxxx极品hd满灌| 久久久久久中文字幕| 国产精品美女999| 欧美与黑人午夜性猛交久久久| 国产91精品不卡视频| 亚洲国产精品久久精品怡红院| 精品亚洲va在线va天堂资源站| 日韩在线中文字幕| 亚洲国产古装精品网站| 欧美日韩激情网| 91在线免费看网站| 亚洲free性xxxx护士hd| 日韩av在线天堂网| 国产在线观看不卡| 红桃av永久久久| 91精品国产99久久久久久| 91亚洲人电影| 久久久久久久久电影| 国产精品久久久久久久久影视| 中文字幕日韩精品在线观看| 亚洲精品按摩视频| 日本精品免费一区二区三区| 精品国产999| 亚洲国产精品成人av| 久久人人爽人人爽爽久久| 久久99久国产精品黄毛片入口| 国产噜噜噜噜噜久久久久久久久| 久久91亚洲人成电影网站| 久久成人一区二区| 日韩欧美综合在线视频| 91久久久久久久一区二区| 亚洲成人久久久久| 久久激情五月丁香伊人| 日韩精品极品毛片系列视频| 亚洲欧美在线第一页| 亚洲第一网站男人都懂| 91天堂在线观看| 久久久久久综合网天天| 成人黄色免费在线观看| 91精品久久久久久久久不口人| 国产精品一区二区久久久久| 日韩免费在线看| 亚洲精品动漫100p| 久久久视频免费观看| 国产日韩欧美中文| 亚洲男人天堂久| 国产一区二区欧美日韩| 91久久国产精品| 欧美性xxxxx极品| 精品女同一区二区三区在线播放| 国产在线视频2019最新视频| 国产91在线高潮白浆在线观看| 日韩精品免费视频| 日韩在线视频线视频免费网站| 午夜精品久久久99热福利| 精品久久国产精品| 亚洲欧美成人在线| 美日韩精品免费视频| 亚洲一区二区三区成人在线视频精品| 日韩视频第一页| 欧美插天视频在线播放| 精品国产91久久久久久| 国产精品久久久久久久久久久新郎| 国产精品2018| 亚洲а∨天堂久久精品喷水| 日韩在线观看电影| 最新国产精品拍自在线播放| 欧美交受高潮1| 在线观看日韩www视频免费| 国产精品久久久久77777| 国产一区香蕉久久| 国产精品偷伦一区二区| 欧美日韩色婷婷| 中文字幕精品久久久久| 色偷偷av一区二区三区乱| 亚洲精品日产aⅴ| 国产精品亚发布| 久久久久久久久久久人体| 国产精品视频在线观看| 精品福利视频导航| 上原亚衣av一区二区三区| 久久6免费高清热精品| 国产欧美精品xxxx另类| 国内精品久久久久伊人av| 综合网日日天干夜夜久久|