Qt模仿Windows文件夾縮略圖的三種實(shí)現(xiàn)方式
1、簡(jiǎn)介
本文講的不是簡(jiǎn)單的model/view或者widget的或者QML的基礎(chǔ)框架實(shí)現(xiàn),而是在這些框架之上的肉(文件夾縮略圖)的效果實(shí)現(xiàn)。本文將以QWidget、Qt Quick(QML)、以及QGraph三種實(shí)現(xiàn)方式來(lái)講解,如何做出和Windows類似的縮略圖……
2、效果圖
乍一看,好像把兩個(gè)圖片立起來(lái),然后做成一個(gè)類似Windows文件夾有點(diǎn)難。一步一步拆開來(lái)分解,貌似就不難了,無(wú)非就是4個(gè)透明圖層(底層、圖片1、圖片2、上層)的組合。
3、三種實(shí)現(xiàn)方式
QWidget最簡(jiǎn)單,但缺點(diǎn)也很明顯,mask形成QBitmap遮罩沒(méi)有辦法去鋸齒,我們會(huì)看到明顯的鋸齒,在追求完美的coder中是不可取的,不過(guò)你做著玩當(dāng)我沒(méi)說(shuō)……
3.1、QWidget的mask遮罩
3.1.1、bb叨
初學(xué)者可能有點(diǎn)懵,怎么講著講著講到了遮罩,那是什么,和實(shí)現(xiàn)這個(gè)東西又有什么關(guān)聯(lián)呢?遮罩這個(gè)東西,用途比較廣泛,但猶豫無(wú)法去鋸齒,也很少有完美主義者選擇mask。mask可以用來(lái)做QWidget組件或者窗體的遮罩,有啥用?比如說(shuō)想實(shí)現(xiàn)一個(gè)漩渦鳴人的窗體(ps:作者關(guān)注火影和海賊),很簡(jiǎn)單就能實(shí)現(xiàn)。
那么除了漩渦鳴人本身,其他都是透明的,因?yàn)槟阌幸粋€(gè)這樣的圖片,所以能很快就實(shí)現(xiàn)出來(lái)。如果需求反過(guò)來(lái),想把漩渦鳴人的這個(gè)圖的輪廓作為背景圖,里面的內(nèi)容是你想的用圖案來(lái)填充呢?那就會(huì)用到mask遮罩??梢钥吹接忻黠@的鋸齒,那我們模仿windows文件夾縮略圖也一樣會(huì)出現(xiàn)這個(gè)問(wèn)題,這個(gè)問(wèn)題源于mask本身是qbitmap,qbitmap的鋸齒目前版本的Qt是沒(méi)解決方案的。
3.1.2、核心源碼
SMaskWidget
void SMaskWidget::updatePixmap(QPixmap sourcePix, QPixmap maskPix) { m_pixCurrent = sourcePix; QBitmap bit = maskPix.mask(); this->setMask(bit);// 效果不好,QBitmap本身是有鋸齒的,機(jī)制問(wèn)題 update(); } void SMaskWidget::paintEvent(QPaintEvent *event) { Q_UNUSED(event) QPainter painter(this); painter.setRenderHint(QPainter::Antialiasing, true); painter.setRenderHint(QPainter::SmoothPixmapTransform, true); painter.setPen(QPen(Qt::transparent)); painter.drawPixmap(0, 0, width(), height(), m_pixCurrent); }
SPixmapWidget
SPixmapWidget::SPixmapWidget(QWidget *parent) : QWidget(parent) { m_down = new QLabel(this); m_pixMask1 = new SMaskWidget(this); m_pixMask2 = new SMaskWidget(this); m_up = new QLabel(this); m_down->setStyleSheet("border:0px solid red;background-color:transparent;"); m_up->setStyleSheet("border:0px solid red;background-color:transparent;"); } void SPixmapWidget::updatePixmap(QPixmap pix1, QPixmap pix2) { QString str_mask_down = "E:/MyPro/TillDream/application/TillDream/sqrc/png/down__2x.png"; QString str_mask_up = "E:/MyPro/TillDream/application/TillDream/sqrc/png/up__2x.png"; QString str_bg_down = "E:/MyPro/TillDream/application/TillDream/sqrc/png/back2x.png"; QString str_bg_up = "E:/MyPro/TillDream/application/TillDream/sqrc/png/pre2x.png"; m_down->resize(QPixmap(str_bg_down).size()); m_up->resize(QPixmap(str_bg_up).size()); m_pixMask1->resize(QPixmap(str_mask_down).size()); m_pixMask2->resize(QPixmap(str_mask_up).size()); m_down->setPixmap(QPixmap(str_bg_down)); QPixmap mask1; mask1.load(str_mask_down); m_pixMask1->updatePixmap(pix1, mask1.scaled(QPixmap(str_mask_down).size(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); QPixmap mask2; mask2.load(str_mask_up); m_pixMask2->updatePixmap(pix2, mask2.scaled(QPixmap(str_mask_up).size(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); m_up->setPixmap(QPixmap(str_bg_up)); }
3.2、QML的QtGraphicalEffects遮罩
3.2.1、bb小叨
QML的發(fā)展一直是近幾年來(lái)Qt發(fā)展的趨勢(shì),QML也發(fā)展的越來(lái)越好了,QML本身提供了對(duì)應(yīng)的QtGraphicalEffects包,效果非常nice,而且代碼簡(jiǎn)單。
3.2.2、核心源碼
import QtQuick 2.3 import QtQuick.Window 2.2 import QtGraphicalEffects 1.0 Item { visible: true Item{ width: 104 height: 116 Image { source: "file:///E:/MyPro/TillDream/application/TillDream/sqrc/png/back2x.png" anchors.fill: parent } } Item{ width: 104 height: 122 Image { id: person source: "file:///C:/Users/lenovo/Desktop/1.jpg" anchors.fill: parent visible: false } Image { id: mask source: "file:///E:/MyPro/TillDream/application/TillDream/sqrc/png/down__2x.png" anchors.fill: parent visible: false } OpacityMask { id:om anchors.fill: person source: person maskSource: mask } } Item{ width: 80 height: 134 Image { id: person2 source: "file:///C:/Users/lenovo/Desktop/2.jpg" anchors.fill: parent visible: false } Image { id: mask2 source: "file:///E:/MyPro/TillDream/application/TillDream/sqrc/png/up__2x.png" anchors.fill: parent visible: false } OpacityMask { anchors.fill: person2 source: person2 maskSource: mask2 } } Item{ width: 48 height: 134 Image { source: "file:///E:/MyPro/TillDream/application/TillDream/sqrc/png/pre2x.png" anchors.fill: parent } } }
3.3、QGraph的三板斧
3.3.1、bb一小會(huì)兒
這里提了QWidget和QML的實(shí)現(xiàn),其實(shí)都不滿足我的需要。怎么說(shuō)呢,QWidget的效果不是很好,顯而易見的鋸齒。QML效果雖好,但是整體的代碼都是用QWidget框架去寫的,如果要?jiǎng)討B(tài)打包的話,再額外引用QML的動(dòng)態(tài)鏈接庫(kù),沒(méi)必要給程序總大小增加負(fù)擔(dān)。所以這里嘗試用QGraph的三板斧來(lái)實(shí)現(xiàn),具體不會(huì)QGraph的可以參考我的示例,也可以踩著搜索引擎去學(xué)習(xí)。
3.3.2、核心源碼
SGraphicsItem
QRectF SGraphicsItem::boundingRect() const { QRectF rf; if (Type_down == m_type) { rf = QRectF(0, 0, 104, 122); } else if (Type_bg == m_type) { rf = QRectF(0, 0, 104, 116); } else if (Type_up == m_type) { rf = QRectF(0, 0, 80, 134); } else if (Type_pre == m_type) { rf = QRectF(0, 0, 48, 134); } else { rf = QRectF(0, 0, 104, 134); } return rf; } void SGraphicsItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) { Q_UNUSED(option) Q_UNUSED(widget) painter->setRenderHint(QPainter::Antialiasing, true); painter->setRenderHint(QPainter::SmoothPixmapTransform, true); painter->setPen(QPen(Qt::transparent)); painter->setBrush(QBrush(m_color)); QPainterPath path; QPolygonF ffl; if (m_type == Type_down) { ffl << QPointF(2.0, 2.0) << QPointF(boundingRect().width(), 16.0) << QPointF(boundingRect().width(), boundingRect().height()) << QPointF(2.0, 108.0); path.addPolygon(ffl); painter->setClipPath(path); painter->drawImage(QRectF(0,0, boundingRect().width(), boundingRect().height()),QImage(m_pix)); } else if (Type_bg == m_type) { painter->drawImage(QRectF(0,0, boundingRect().width(), boundingRect().height()),QImage(m_pix)); } else if (Type_up == m_type) { ffl << QPointF(2.0, 2.0) << QPointF(boundingRect().width(), 28.0) << QPointF(boundingRect().width(), boundingRect().height()) << QPointF(2.0, 108.0); path.addPolygon(ffl); painter->setClipPath(path); painter->drawImage(QRectF(0,0, boundingRect().width(), boundingRect().height()),QImage(m_pix)); } else if (Type_pre == m_type) { painter->drawImage(QRectF(0,0, boundingRect().width(), boundingRect().height()),QImage(m_pix)); } else { painter->drawRect(this->boundingRect()); } }
control
QGraphicsScene* m_scene = new QGraphicsScene(ui->graphicsView); SGraphicsItem *item1 = new SGraphicsItem(SGraphicsItem::Type_bg, str_bg_down); SGraphicsItem *item2 = new SGraphicsItem(SGraphicsItem::Type_down, str_d1); SGraphicsItem *item3 = new SGraphicsItem(SGraphicsItem::Type_up, str_d2); SGraphicsItem *item4 = new SGraphicsItem(SGraphicsItem::Type_pre, str_bg_up); m_scene->addItem(item1); m_scene->addItem(item2); m_scene->addItem(item3); m_scene->addItem(item4); ui->graphicsView->setSceneRect(0,0,104,134); ui->graphicsView->setScene(m_scene); ui->graphicsView->setStyleSheet("QGraphicsView{border:0px;background-color: rgba(255, 255, 255, 0);}"); QPixmap pix(QSize(104, 134)); pix.fill(Qt::transparent); QPainter painter(&pix); m_scene->render(&painter); //關(guān)鍵函數(shù) pix.save("123.png", "PNG"); ui->label_new->setStyleSheet("background-color:rgb(123,123,123);"); ui->label_new->setPixmap(pix); ui->label_new->setAlignment(Qt::AlignCenter);
以上就是Qt模仿Windows文件夾縮略圖的三種實(shí)現(xiàn)方式的詳細(xì)內(nèi)容,更多關(guān)于Qt文件夾縮略圖的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
vc++ 監(jiān)控指定路徑下文件變化實(shí)現(xiàn)代碼
這篇文章主要介紹了vc++ 監(jiān)控指定路徑下文件變化實(shí)現(xiàn)代碼,需要的朋友可以參考下2019-04-04C++算法計(jì)時(shí)器的實(shí)現(xiàn)示例
本文主要介紹了C++算法計(jì)時(shí)器的實(shí)現(xiàn)示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-05-05詳解C++ 臨時(shí)量與臨時(shí)對(duì)象及程序的相關(guān)優(yōu)化
這篇文章主要介紹了C++ 臨時(shí)量與臨時(shí)對(duì)象及程序的相關(guān)優(yōu)化,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-04-04