国产亚洲精品福利在线无卡一,国产精久久一区二区三区,亚洲精品无码国模,精品久久久久久无码专区不卡

當(dāng)前位置: 首頁(yè) > news >正文

做優(yōu)惠卷網(wǎng)站倒閉了多少錢(qián)剪輯培訓(xùn)班一般學(xué)費(fèi)多少

做優(yōu)惠卷網(wǎng)站倒閉了多少錢(qián),剪輯培訓(xùn)班一般學(xué)費(fèi)多少,南昌網(wǎng)站設(shè)計(jì)哪家專業(yè)好,南京網(wǎng)站制作0 環(huán)境 Windows 11Qt 5.15.2 MinGW x64 1 系列文章 簡(jiǎn)介:本系列文章,是以純代碼方式實(shí)現(xiàn) Qt 控件的重構(gòu),盡量不使用 Qss 方式。 《[Qt]QListView 重繪實(shí)例之一:背景重繪》 《[Qt]QListView 重繪實(shí)例之二:列表項(xiàng)覆…

0 環(huán)境

  1. Windows 11
  2. Qt 5.15.2 MinGW x64

1 系列文章

簡(jiǎn)介:本系列文章,是以純代碼方式實(shí)現(xiàn) Qt 控件的重構(gòu),盡量不使用 Qss 方式。

《[Qt]QListView 重繪實(shí)例之一:背景重繪》

《[Qt]QListView 重繪實(shí)例之二:列表項(xiàng)覆蓋的問(wèn)題處理》

《[Qt]QListView 重繪實(shí)例之三:滾動(dòng)條覆蓋的問(wèn)題處理》

《[Qt]QListView 重繪實(shí)例之四:效果一講解》

《[Qt]QListView 重繪實(shí)例之五:效果二講解》

2 開(kāi)始

自定義 Qt 控件,無(wú)外乎兩個(gè)主要目的:

  • 實(shí)現(xiàn)更漂亮的樣式;
  • 實(shí)現(xiàn)更強(qiáng)大的/更合適的功能;

要實(shí)現(xiàn)以上兩個(gè)主要目的,基本上都需要對(duì) Qt 原生控件進(jìn)行一定的重繪,以適應(yīng)需求。

本節(jié)中,主要講解 QListView 的背景繪制。

QListView

(之所以單獨(dú)寫(xiě)一文,是因?yàn)樽约簞?dòng)手實(shí)現(xiàn)時(shí)才發(fā)現(xiàn):雖然最后的實(shí)現(xiàn)代碼并不多,但要弄懂這些,還是要花費(fèi)很多精力的。)

→ 解決方案直達(dá) ←

3 paintEvent 重繪與問(wèn)題

通常,重構(gòu)一個(gè)新控件,基本上都是直接重寫(xiě) void paintEvent(QPaintEvent *event) 方法。

void PListView::paintEvent(QPaintEvent *event)
{Q_UNUSED(event)QPainter painter(this);		// Errorpainter.setRenderHint(QPainter::Antialiasing);painter.setPen(QPen(Qt::red));painter.setBrush(QBrush(Qt::white));painter.drawRoundedRect(rect(), 5, 5);
}

3.1 問(wèn)題 1 —— 繪圖對(duì)象

通常,進(jìn)行重繪時(shí),新建 QPainter 對(duì)象都是以父控件為對(duì)象,意即在父控件中進(jìn)行繪制。

但是,如果這樣直接對(duì) QListView 進(jìn)行重繪,是會(huì)出錯(cuò)的:

QWidget::paintEngine: Should no longer be called
QPainter::begin: Paint device returned engine == 0, type: 1
QPainter::setRenderHint: Painter must be active to set rendering hints
QPainter::setPen: Painter not active
QPainter::setBrush: Painter not active

(猜測(cè))原因大致應(yīng)該是:QListView 是由多個(gè)子控件組成,實(shí)際負(fù)責(zé)顯示內(nèi)容的只是其中的一個(gè)子控件,所以繪制對(duì)象需要具體指定到負(fù)責(zé)顯示的對(duì)象。

QListView 繼承樹(shù)如下:

QListView-inherittree

而一個(gè)默認(rèn) QListView 對(duì)象包含的子控件如下:

(QWidget(0x1eb4600, name = "qt_scrollarea_viewport"),
QStyledItemDelegate(0x1eb1840),
QItemSelectionModel(0x1eb1ba0),
QWidget(0x1eb1010, name = "qt_scrollarea_hcontainer"),
QWidget(0x1eb1150, name = "qt_scrollarea_vcontainer"))

其中,實(shí)際顯示內(nèi)容的對(duì)象就是 “qt_scrollarea_viewport”,也就是 QListView 的視口(viewport)。這樣做的主要原因,是要實(shí)現(xiàn)對(duì) QListView 內(nèi)容的滾動(dòng)顯示(顯示部分內(nèi)容)。

所以,對(duì)于 QListView 重繪,必須要針對(duì)視口 viewport()。

void PListView::paintEvent(QPaintEvent *event)
{Q_UNUSED(event)QPainter painter(viewport());painter.setRenderHint(QPainter::Antialiasing);painter.setPen(QPen(Qt::red));painter.setBrush(QBrush(Qt::white));painter.drawRoundedRect(rect(), 5, 5);
}

效果如下圖示:

QListView-paint1

3.2 問(wèn)題 2 —— 外邊線框

從上圖看,這次倒是繪制出背景框。但首先注意到的問(wèn)題是 QListView 默認(rèn)外連線框,非常顯眼。因此,首要目的是要去掉這個(gè)外連線框。

上文實(shí)現(xiàn)代碼中的重繪過(guò)程,僅做了兩件事:

  • 繪制了一個(gè)圓角矩形;
  • 阻止了 QListView 的其它默認(rèn)繪制;

因此 ,基本可以肯定,外連線框并不是由 paintEvent() 繪制過(guò)程中引起的??磥?lái)原因得到 QListView 里層查找。

原因查找的具體過(guò)程略過(guò)不述,QListView 的外邊線框其實(shí)就是其父類 QFrame 的邊框(可以理解為一個(gè)底層,其它內(nèi)容都繪制在這個(gè)底層之上,畢竟 QListView 是 UI 控件)。

只需要對(duì) QListView 進(jìn)行如下設(shè)置,改變一下 QFrame 樣式即可去掉外邊線框:

PListVeiw::PListView(QWidget *parent) : QListView(parent)
{setFrameStyle(QFrame::NoFrame);
}

效果如下:

QListView-noframe

強(qiáng)制隱藏/關(guān)閉垂直滾動(dòng)條,效果如下:

QListView-noscrollbar

3.3 問(wèn)題 3 —— 繪制區(qū)域

從上圖可知,繪制的背景效果基本出來(lái)了。但是,也被垂直滾動(dòng)條擋住了一部分。

再回來(lái)看一看繪圖代碼,其中有一行如下:

	painter.drawRoundedRect(rect(), 5, 5);

此時(shí),指定的繪圖區(qū)域?yàn)?rect(),即針對(duì)控件的整個(gè)顯示區(qū)域。而我們指定的繪圖對(duì)象是 QListView 的視口,原則上為了保證一致性,在什么上繪圖,就應(yīng)該在該對(duì)象的區(qū)域內(nèi)進(jìn)行繪制。所以,修改以上那行的代碼:

	painter.drawRoundedRect(viewport()->rect(), 5, 5);

效果如下:

QListView-viewport

這種效果,也還可以。一些樣式也確實(shí)是將滾動(dòng)條置于控件之外的。

本文不針對(duì)此樣式進(jìn)行講解,主要考慮滾動(dòng)條內(nèi)含在列表內(nèi)的樣式。

滾動(dòng)條的問(wèn)題,先按下不提,具體詳見(jiàn)本系列后文說(shuō)明。參考《[Qt]QListView 重繪實(shí)例之三:滾動(dòng)條覆蓋的問(wèn)題處理》。

3.4 問(wèn)題 4 —— 滾動(dòng)時(shí)殘留

先前為了重點(diǎn)顯示 QListView 的背景繪制效果,所以沒(méi)有繪制 QListView 的內(nèi)容。

現(xiàn)在,加上內(nèi)容的繪制代碼:

void PListView::paintEvent(QPaintEvent *event)
{QPainter painter(viewport());painter.setRenderHint(QPainter::Antialiasing);painter.setPen(QPen(Qt::red));painter.setBrush(QBrush(Qt::white));painter.drawRoundedRect(rect(), 5, 5);	// 理解為視口占據(jù)整個(gè)控件區(qū)域QListView::paintEvent(event);
}

說(shuō)明:繪制順序是有要求的。應(yīng)該先繪制背景,然后繪制列表內(nèi)容(即前景)。

效果圖如下:

QListView-paint2

但是,如果我們使用鼠標(biāo)滾輪滾動(dòng)或拖動(dòng)滾動(dòng)條,滾動(dòng) QListView 的內(nèi)容,卻出現(xiàn)了如下效果:

QListView-residual

這顯然不是想要的效果。

具體原因未深究,暫時(shí)未知,猜測(cè)應(yīng)該是底層代碼的原因。因?yàn)?#xff0c;上文中的重繪代碼其實(shí)很簡(jiǎn)單,并未做多余的動(dòng)作。

但這種殘留效果,顯然不可接受。

因此,至少到目前,這種方式繪制 QListView 的背景是不可行的。

(考慮到添加委托會(huì)對(duì)列表項(xiàng)進(jìn)行繪制,可能會(huì)影響到這個(gè)殘留問(wèn)題。嘗試過(guò)添加委托,但這個(gè)殘留問(wèn)題依然存在。)

4 解決方案

從上文得知,采用 paintEvent() 對(duì) QListView 背景進(jìn)行繪制的方案不可行。

另,考慮到后來(lái)的 Qt 版本對(duì)于 Qss 的性能問(wèn)題,本系列也不考慮 Qss 方案。

于是,已知可行的方案只剩使用 QProxyStyle 代理樣式定制了。

(之前也沒(méi)有實(shí)際使用過(guò)代理樣式,通過(guò)學(xué)習(xí)/練習(xí)/測(cè)試得出了合適的效果。)

關(guān)于 QProxyStyle 的具體內(nèi)容,查找資料的過(guò)程中有發(fā)現(xiàn),有不少介紹的好博文,請(qǐng)酌情參考(文末參考資料有鏈接),本文不另述。

4.1 定義背景繪制樣式

/* .h */
class PListViewStyle : public QProxyStyle
{
public:PListViewStyle();void drawControl(QStyle::ControlElement element,const QStyleOption *option,QPainter *painter,const QWidget *widget = nullptr) const override;
};/* .cpp */
PListViewStyle::PListViewStyle()
{
}
void PListViewStyle::drawControl(QStyle::ControlElement element,const QStyleOption *option,QPainter *painter,const QWidget *widget) const
{switch(element){case QStyle::CE_ShapedFrame:{const QStyleOptionFrame *opt = qstyleoption_cast<const QStyleOptionFrame *>(option);if(nullptr == opt) { return; }painter->save();painter->setRenderHint(QPainter::Antialiasing);painter->setPen(QPen(Qt::red));painter->setBrush(QBrush(Qt::white));painter->drawRoundedRect(opt->rect, 5, 5);painter->restore();return;}default:break;}QProxyStyle::drawControl(element, option, painter, widget);
}

4.2 使用代理樣式

PListVeiw::PListView(QWidget *parent) : QListView(parent)
{// setFrameStyle(QFrame::NoFrame);	// Must delete or comment itsetStyle(new PListViewStyle);
}

注意:

  • 需要?jiǎng)h除重寫(xiě)函數(shù) void paintEvent(QPaintEvent *event),否則可能覆蓋效果。
  • 需要?jiǎng)h除對(duì) QFrame 的樣式設(shè)置,不能再設(shè)置為 QFrame::NoFrame。因?yàn)榇順邮綄?shí)際是對(duì) QFrame 進(jìn)行繪制的,如果設(shè)置了 QFrame::NoFrame,則繪制的樣式根本就不會(huì)顯示。

效果如下:

QListView-paintbg

至少看上去,基本達(dá)到了預(yù)期的效果。

但是,

但是,

但是,總有但是,哈哈。

將背景的圓角矩形圓角半徑加大一下,再來(lái)看看效果圖:

QListView-residual2

從上圖可以看出有幾個(gè)問(wèn)題:

  • 列表項(xiàng)在背景的上層,即背景繪制先于列表項(xiàng)。而列表項(xiàng)也是有背景的(以及高亮/選中背景),可以理解為列表項(xiàng)就是一個(gè)個(gè)小矩形(默認(rèn)沒(méi)有圓角)。由上可以看出,視口的最上/最下一行,都有矩形直角覆蓋了背景(圓角矩形),因此破壞了背景的效果;
  • 同理,滾動(dòng)條也在背景上層,滾動(dòng)條也是一個(gè)直角矩形,矩形直角覆蓋了背景,因此也破壞了背景的效果;

其中:

  • 對(duì)于列表項(xiàng)產(chǎn)生的覆蓋問(wèn)題,可以通過(guò)使用委托,控制列表項(xiàng)背景(默認(rèn)背景/高亮背景/選中背景)的繪制,使繪制視口最上/最下一行時(shí),繪制合適的圓角效果。
  • 對(duì)于滾動(dòng)條的問(wèn)題,就復(fù)雜得多,具體詳見(jiàn)本系列后文內(nèi)容。參考《[Qt]QListView 重繪實(shí)例之三:滾動(dòng)條覆蓋的問(wèn)題處理》。

5 參考資料

  1. 《C++ GUI Qt 4編程(第二版)》,第 19 章,19.2 子類化 QStyle
  2. QStyle類用法總結(jié)(一)
  3. 繪制自定義QSlider
http://aloenet.com.cn/news/44291.html

相關(guān)文章:

  • 企業(yè)網(wǎng)站營(yíng)銷優(yōu)缺點(diǎn)搜索
  • 架設(shè)一個(gè)網(wǎng)站太原今日新聞最新頭條
  • 使用網(wǎng)站效果圖b站推廣軟件
  • 制作團(tuán)購(gòu)網(wǎng)站搜索引擎優(yōu)化關(guān)鍵詞的處理
  • iis怎么建網(wǎng)站最新的網(wǎng)絡(luò)營(yíng)銷的案例
  • 東莞長(zhǎng)安網(wǎng)站設(shè)計(jì)軟件培訓(xùn)班
  • 無(wú)錫 網(wǎng)站建設(shè)公司北京做網(wǎng)站公司哪家好
  • 網(wǎng)站菜單素材湖北seo
  • 網(wǎng)頁(yè)游戲網(wǎng)站斗地主青島seo關(guān)鍵詞優(yōu)化公司
  • 新媒體營(yíng)銷案例有哪些百度seo如何優(yōu)化關(guān)鍵詞
  • 網(wǎng)站設(shè)為主頁(yè)功能怎么做下載谷歌瀏覽器并安裝
  • 網(wǎng)絡(luò)規(guī)劃的內(nèi)容廣東網(wǎng)站營(yíng)銷seo費(fèi)用
  • 惠州建設(shè)網(wǎng)站搜索引擎營(yíng)銷案例分析
  • wordpress 關(guān)閉自動(dòng)保存功能seo自動(dòng)排名軟件
  • 浙江高端網(wǎng)站熱點(diǎn)新聞
  • 設(shè)計(jì)公司 網(wǎng)站個(gè)人網(wǎng)頁(yè)設(shè)計(jì)作品模板
  • 公司做影視網(wǎng)站侵權(quán)全國(guó)疫情防控最新數(shù)據(jù)
  • 網(wǎng)站系統(tǒng)與網(wǎng)站源碼的關(guān)系上海今天發(fā)生的重大新聞
  • 湖南衡陽(yáng)網(wǎng)站建設(shè)開(kāi)發(fā)網(wǎng)站的流程是
  • 湖北華亞建設(shè)工程有限公司網(wǎng)站超級(jí)優(yōu)化
  • 蘇州市相城區(qū)住房和城鄉(xiāng)建設(shè)局網(wǎng)站網(wǎng)絡(luò)媒體推廣方案
  • 鄭州網(wǎng)站制作怎么樣江蘇seo平臺(tái)
  • app界面模板免費(fèi)下載百度網(wǎng)站排名優(yōu)化
  • 網(wǎng)上發(fā)布信息的網(wǎng)站怎么做的百度廣告競(jìng)價(jià)
  • 提供佛山順德網(wǎng)站建設(shè)網(wǎng)站seo優(yōu)化軟件
  • 專業(yè)廣州網(wǎng)站建設(shè)臨沂網(wǎng)站建設(shè)方案服務(wù)
  • 做網(wǎng)站必須要購(gòu)買(mǎi)空間嗎谷歌瀏覽器 免費(fèi)下載
  • 網(wǎng)頁(yè)編輯軟件中文版seo英文全稱
  • 外貿(mào)怎么做網(wǎng)站外鏈seo網(wǎng)站結(jié)構(gòu)優(yōu)化的方法
  • 做調(diào)查賺錢(qián)網(wǎng)站有哪些網(wǎng)站推廣