中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

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

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

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

0 環(huán)境

  1. Windows 11
  2. Qt 5.15.2 MinGW x64

1 系列文章

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

《[Qt]QListView 重繪實例之一:背景重繪》

《[Qt]QListView 重繪實例之二:列表項覆蓋的問題處理》

《[Qt]QListView 重繪實例之三:滾動條覆蓋的問題處理》

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

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

2 開始

自定義 Qt 控件,無外乎兩個主要目的:

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

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

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

QListView

(之所以單獨寫一文,是因為自己動手實現(xiàn)時才發(fā)現(xiàn):雖然最后的實現(xiàn)代碼并不多,但要弄懂這些,還是要花費很多精力的。)

→ 解決方案直達 ←

3 paintEvent 重繪與問題

通常,重構(gòu)一個新控件,基本上都是直接重寫 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 問題 1 —— 繪圖對象

通常,進行重繪時,新建 QPainter 對象都是以父控件為對象,意即在父控件中進行繪制。

但是,如果這樣直接對 QListView 進行重繪,是會出錯的:

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

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

QListView 繼承樹如下:

QListView-inherittree

而一個默認 QListView 對象包含的子控件如下:

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

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

所以,對于 QListView 重繪,必須要針對視口 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 問題 2 —— 外邊線框

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

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

  • 繪制了一個圓角矩形;
  • 阻止了 QListView 的其它默認繪制;

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

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

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

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

效果如下:

QListView-noframe

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

QListView-noscrollbar

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

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

再回來看一看繪圖代碼,其中有一行如下:

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

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

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

效果如下:

QListView-viewport

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

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

滾動條的問題,先按下不提,具體詳見本系列后文說明。參考《[Qt]QListView 重繪實例之三:滾動條覆蓋的問題處理》。

3.4 問題 4 —— 滾動時殘留

先前為了重點顯示 QListView 的背景繪制效果,所以沒有繪制 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ù)整個控件區(qū)域QListView::paintEvent(event);
}

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

效果圖如下:

QListView-paint2

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

QListView-residual

這顯然不是想要的效果。

具體原因未深究,暫時未知,猜測應(yīng)該是底層代碼的原因。因為,上文中的重繪代碼其實很簡單,并未做多余的動作。

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

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

(考慮到添加委托會對列表項進行繪制,可能會影響到這個殘留問題。嘗試過添加委托,但這個殘留問題依然存在。)

4 解決方案

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

另,考慮到后來的 Qt 版本對于 Qss 的性能問題,本系列也不考慮 Qss 方案。

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

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

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

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

注意:

  • 需要刪除重寫函數(shù) void paintEvent(QPaintEvent *event),否則可能覆蓋效果。
  • 需要刪除對 QFrame 的樣式設(shè)置,不能再設(shè)置為 QFrame::NoFrame。因為代理樣式實際是對 QFrame 進行繪制的,如果設(shè)置了 QFrame::NoFrame,則繪制的樣式根本就不會顯示。

效果如下:

QListView-paintbg

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

但是,

但是,

但是,總有但是,哈哈。

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

QListView-residual2

從上圖可以看出有幾個問題:

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

其中:

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

5 參考資料

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

相關(guān)文章:

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