QT學習(20):QStyle和自定義樣式

QStyle
樣式(繼承自QStyle類)代表控件的繪制并封裝GUI的外觀。QStyle是一個封裝了GUI外觀的抽象基類。Qt使用QStyle去執行幾乎所有的內置控件的繪制,確保控件外觀和原生控件風格風格相同。

class Q_WIDGETS_EXPORT QStyle : public QObject{};

QProxyStyle
為了自定義現有樣式,需要繼承QProxyStyle并重新實現所需的虛函數。QProxyStyle允許指定某個基本樣式,當基本樣式未指定時,將自動使用應用程序樣式。前者提供對基本樣式的完全控制,并且在自定義需要特定樣式行為時效果最佳,而后者提供一種與平臺無關的方式來自定義默認為本機平臺樣式的應用程序樣式。

class Q_WIDGETS_EXPORT QProxyStyle : public QCommonStyle{};

QCommonStyle
QCommonStyle為完全自定義樣式實現提供了一個方便的基類。這種方式與使用QProxyStyle相同,但是繼承自QCommonStyle并重新實現相應的虛函數。

class Q_WIDGETS_EXPORT QCommonStyle: public QStyle{};

QStyle實現
QStyle的API包含繪制控件的函數,用于執行常見和困難任務的靜態函數以及用于執行繪制時所需的各種計算的函數。該樣式也輔助控件內容的布局,此外還創建一個包含QBrush的QPalette對象。

QStyle繪制圖形元素,一個元素是一個控件,或者是一個控件部分(如按鈕斜角、窗口框架或滾動條等等)。大多數繪制函數采用四個函數:

  • 枚舉值指定繪制元素的類型;
  • QStyleOption對象指定呈現該元素的方式和位置;
  • QPainter對象表示執行繪圖的畫筆;
  • QWidget對象表示執行繪圖的控件。

當控件要求樣式繪制元素時,控件會為樣式提供QStyleOption對象(包含繪制所需信息的類)。QStyleOption類使得可以在不鏈接控件代碼的情況下繪制控件,從而在任何繪畫設備上使用QStyle的繪制函數成為可能。在Qt中,Item Views的items由委托繪制。Item Views的標題任由樣式繪制。

樣式元素
樣式元素是GUI的圖形部分。一個控件由樣式元素的層次結構(或樹)組成。比如,當樣式收到繪制按鈕的請求時(例如,從QPushButton),樣式會繪制一個標簽(文本和圖標)、一個按鈕斜角和一個焦點框。而按鈕斜角由斜角周圍的框架和另外兩個元素組成。

請添加圖片描述
繪制控件不一定是通過要求樣式只繪制一個元素來完成,控件可以多次調用來繪制不同元素。比如QTabWidget單獨繪制選項卡和框架。

元素類型分三種:基本元素、控制元素和復雜控制元素,元素由枚舉類型ComplexControl、ControlElement和PrimitiveElement enums定義。

  • 基本元素:

基本元素是常見的GUI元素。例如,框架frame、按鈕斜角button bavels以及用于輸入框spin boxes、滑動條scroll bars和下拉框combo boxes的箭頭。基本元素不能獨立存在,而是整體結構的一部分,不參與用戶交互,而是GUI中的被動裝飾。

  • 控制元素:

控制元素執行操作或者向用戶顯示信息。控制元素包括表和樹視圖中的按鈕、勾選框和標題部分。控制元素不一定是完整的小部件,也可以是控件的部分結構,比如滑動條滑塊和選項卡。控制元素與基本元素的不同之處在于其不是被動的,而是在交互中填充功能。有多個元素組成的控件通常使用樣式來計算元素的邊界矩形,可用的子元素由枚舉類型SubElement定義。此枚舉僅用于計算邊界矩形,子元素不是像基本元素、控制元素和復雜元素那樣需要繪制的圖形元素。

  • 復雜的控制元素:

復雜的控制元素包含子控件。復雜控件的行為會有所不同,具體取決于用戶使用鼠標的位置和按下的鍵盤鍵。這取決于鼠標處于或按鍵按下的子控件(如果有)。復雜控件元素有滾動條和組合框。可以通過鼠標移動滑動塊或者按向上和向下按鈕來使用滑動條。可用的子控件由枚舉SubControl枚舉類型定義。

除了繪圖之外,樣式還需要為控件提供有關鼠標在哪個子控件上進行操作的信息。例如,互動條需要知道用戶是否按下滑塊、滑塊凹槽或向上、向下按鈕。

和控制元素不同,不能使用樣式繪制子控件,樣式僅計算應在其中繪制子控件的邊界矩形。然而,復雜元素通常使用控制元素和基本元素來繪制子控件。

樣式選項
QStyleOption的子類包含設置各個元素樣式所需的所有信息。樣式選項通常在棧上被實例化,并由QStyle函數的調用方填寫。根據繪制的內容,樣式期望不同的樣式選項類。例如,QStyle::PE_FrameFocusRect元素需要一個QStyleOptionFocusRect參數,并且可以創建一個自定義樣式可以使用的自定義子類。出于性能原因,樣式選項保留公共變量

控件可以處于許多不同的狀態,這些狀態由State枚舉類型定義。根據控件的不同,狀態標志具有不同的含義,但像State_Disabled這樣的狀態標志對所有控件都是通用的。

最值得注意的是,樣式選項包含要繪制的控件的調色板和邊界矩形,大多數控件都有專門的樣式選項,例如QPushButton和QCheckBox使用QStyleOptionButton用作樣式選項,其中包含文本、圖標及其圖標的大小。

在重新實現帶有QStyleOption參數的QStyle函數時,通常需要將QStyleOption對象類型轉換為子類(如QStyleFocusRect)。為了安全起見,可以使用qstyleoption_cast()確保指針類型時正確的。如果類型指針不正確,qstyleoption_cast會返回nullptr。

QStyle函數
定義了三個虛函數,用來繪制基本元素、控制元素和復雜控制元素。

  • 繪制基本元素drawPrimitive
  • 繪制復雜控制元素drawComplexControl
  • 繪制控制元素drawControl

QStyle類還提供繪制元素時使用的輔助函數,drawItemText函數在指定的矩形內繪制文本,將調色板對象作為參數。drawItemPixmap函數在指定的邊界矩形內對齊像素圖。

其它QStyle函數為執行繪制的函數進行各種計算。如果控件繪制多個樣式元素,也使用這些函數來計算大小提示和邊界矩形。和繪制元素的函數一樣,輔助函數通常采用相同的參數。

  • subElementRect函數采用SubElement枚舉值并計算子元素的邊界矩形,樣式使用此函數來得到繪制元素不同部分的位置。
  • subControlRect函數用來計算復雜控制元素中的子控件的邊界矩形,實現新樣式時需要重新實現該函數并計算矩形。
  • pixelMetric函數返回像素度量,該指標是以屏幕像素為單位給出的與樣式相關的大小。采用PixelMetric枚舉值并返回正確的測量值。
  • hitTestComplexControl函數返回鼠標指針在復雜控制元素中的子控件上。

QStyle還定義了函數polish和unpolish函數,所有控件在顯示之前都會被發送到polish函數,在隱藏時會被發送到unpolish。可以使用這些函數在設置控件上的屬性,或者執行樣式所需的其它工作。例如,如果需要知道鼠標何時懸停在控件上,需要設置WA_Hover屬性,然后控件中的樣式選項中的State_MouseOver狀態位被設置。

QStyle也定義了一些靜態輔助函數,執行一些常見但困難的任務。例如,根據滑塊的值計算滑塊手柄的位置,并轉換矩形并繪制文本,考慮反向布局。

調色板
QPalette提供調色板,存儲不同控件狀態和顏色角色的顏色。每種樣式都提供調色板應用于控件的繪制。有一組顏色集合對應于不同的控件狀態:活動狀態(具有焦點)、非活動狀態和禁用狀態。可以通過查詢State_Enabled和State_Actived狀態標志得到當前的狀態。每一個顏色集合包含由枚舉類型QPalette::ColorRole確定的顏色職責。這些職責描述了在一種情況(繪制控件背景、文本和按鈕)下應該使用對應的顏色。

如何使用顏色職責取決于樣式,例如,如果樣式使用漸變,則可以使用使用QColor::darked或QColor::lighter使其更暗或更亮從而創建漸變。如果需要調色板沒有提供的畫布,通常應該繼承。

Java風格
實現一種類似于Java默認外觀的樣式。

設計與實現
設計樣式的第一步是選擇基類,通常選擇繼承QCommonStyle,該類實現了需要的大多數功能,而不是執行實際的繪圖。

改樣式在一個類中實現。

嘗試實現一個控件

公共的控件屬性和變量

某些狀態和變量對于所有控件來說是通用的,這些屬性通過QStyleOption::initFrom函數設置。并非所有元素都使用該函數。

狀態狀態設置條件
State_Enabled控件沒有禁用時
State_Focus控件有焦點
State_KeyboardFocusChange鍵盤焦點更改
State_MouseOver鼠標在控件上
State_Active控件是活動窗口的子窗口
State_HasEditFocus控件具有編輯焦點
變量內容
rect繪制元素的邊界矩形
direction布局方向
palette繪制元素使用的調色板
fontMetrics繪制文本的字體計量

QPushButton

按鈕的樣式結構圖下所示,通過對樹進行自上而下的遍歷,可以獲得繪制元素的順序。
請添加圖片描述
按鈕的布局(和元素邊界相關)因樣式而異。元素可能有相同的邊界。例如,PE_PushButtonBevel被用于在QCommonStyle中繪制三個元素:PE_FrameDefaultButton、PE_FrameButtonBevel和PE_PanelButtonCommand,這些元素在公共樣式中具有相同的邊界。

下面給出了一個按鈕圖像,該圖像顯示了元素的邊界矩形。顏色用于分隔圖像中的邊界矩形。
請添加圖片描述
QPushButton的樣式選項是QStyleOptionButton,QPushButton可以在樣式選項上設置的狀態表如下。

狀態狀態設置條件
State_Sunken按鈕按下或按下菜單顯示
State_On按鈕被選中
State_Raised按鈕沒按下也沒升起
成員變量內容
features描述各種按鈕屬性
icon按鈕圖標
iconSizeicon的大小
text按鈕文本

QCheckBox和QRadioButton

QCheckBox和QRadioButton的結構是相同的。
請添加圖片描述

狀態狀態設置條件
State_Sunken框被按下
State_NoChange框被部分選中
State_On框被選中
State_Off按鈕沒按下也沒升起

Tabs選項卡

在Qt中,QTabBar使用樣式來繪制選項卡。選項卡要么存在于包含QTabBar的QTabWidget,要么作為單獨的選項卡欄存在。

QTabBar和QTabWidget的樣式結構如下。
請添加圖片描述
tab bar形狀和標簽具有與CE_TabBarTab相同的邊界矩形。請注意,tabs和tab widget框架重疊,tab bar的底部是重疊的區域。

tabs的樣式QStyleOptionTab包含繪制tabs必須的信息。該樣式選項包含tab在tab bar中的位置,選擇tab的位置,tab的形狀,文本,圖標和圖標的大小。
請添加圖片描述
tab bar可以在tabs上設置的狀態表如下。

狀態狀態設置條件
State_Sunken選項卡被鼠標選中
State_Selected是當前選項卡
State_HasFocus選項卡欄具有焦點且選項卡處于選中狀態

QStyleOptionTab的成員表如下。

成員變量內容
cornerWidgets指示tab bar是否具有角控件以及具有哪些角控件
icontab圖標
iconSizeicon的大小
texttab文本
positiontab在tab bar上相對于其它tab的位置
rowtab所在的行
selectedPosition指示所選tab和tab相鄰還是tab
shape指示tab是圓角還是三角以及tab的方向

tab widget的外框使用QStyleOptionTabWidgetFrame作為樣式選項,除了通用的標志外,沒有其它狀態標志。

成員變量內容
cornerWidgets指示tab bar是否具有角控件以及具有哪些角控件
icontab圖標
iconSizeicon的大小
texttab文本
positiontab在tab bar上相對于其它tab的位置
rowtab所在的行
selectedPosition指示所選tab和tab相鄰還是tab
shape指示tab是圓角還是三角以及tab的方向

Scroll Bars
請添加圖片描述
QScrollBar只需創建樣式選項,然后繪制控件。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/18074.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/18074.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/18074.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【OpenCV】圖像通道合并與分離,ROI

介紹可以實現圖像通道合并與分離的API,這只是一種方式,后續還會介紹其他的合并與分離方法,以及ROI區域截取的方法。相關API: split() merge() Mat對象() 代碼: #include "iostream" #include "ope…

Hive的小文件處理

針對ORC存儲格式的小文件 --orc合并小文件的特定語法,使用concatenate(連接、使連續)關鍵字 --非分區表 alter table table_name concatenate;--分區表 alter table table_name partition(dtxxx) concatenate;針對TEXTFILE存儲格式的小文件 --將這些小文件進行合并,這里使用d…

MySQL進階之(九)數據庫的設計規范

九、數據庫的設計規范 9.1 范式的概念9.1.1 范式概述9.1.2 鍵和相關屬性 9.2 常見的范式9.2.1 第一范式9.2.2 第二范式9.2.3 第三范式9.2.4 第四范式9.2.5 第五范式(域鍵范式) 9.3 反范式化9.3.1 概述9.3.2 舉例9.3.3 反范式化新問題9.3.4 通用場景 9.4 …

18 - grace數據處理 - 補充 - 地下水儲量計算過程分解 - 地表水儲量變化Glads水文數據處理

18 - grace數據處理 - 補充 - 地下水儲量計算過程分解 - 地表水儲量變化 0 引言1 Grace陸地水儲量過程整合0 引言 由水量平衡方程可以將地下水儲量的計算過程分解為3個部分,第一部分計算陸地水儲量變化、第二部分計算地表水儲量變化、第三部分計算地下水儲量變化。本篇簡單介紹…

2024.05.28學習記錄

1. 小林coding 計網復習 2.代碼隨想錄刷題. 圖論.和復習數組.鏈表 3.rosebush完成select組件

在Go語言中如何實現變參函數和函數選項模式

在Go語言編程中,我們經常會遇到需要給函數傳遞可選參數的情況。傳統的做法是定義一個結構體,將所有可選參數作為結構體字段,然后在調用函數時創建該結構體的實例并傳遞。這種方式雖然可行,但是當可選參數較多時,創建結構體實例的代碼就會變得冗長???不太直觀。 Go語言的一個…

計算機筆記13(續20個)

210.辦公自動化服務是一種應用軟件實現的功能,不是網絡操作系統提供的服務 211.中文windows中包含的漢字庫文件庫文件是用來解決輸出時轉換為顯示或打印字模 212.漢字系統中的漢字字庫里存放的是漢字的字形碼 213.目前最為嚴重的病毒是木馬病毒 214.網絡安全服務…

景源暢信電商:做抖音運營怎么開始第一步?

在數字化時代的浪潮中,抖音作為一款短視頻平臺迅速崛起,成為許多人表達自我、分享生活的重要舞臺。隨著用戶量的激增,如何做好抖音運營,尤其是邁出成功的第一步,成為了眾多內容創作者和品牌主們關注的焦點。接下來&…

Web應用開發學習筆記————Vue框架

Vue框架快速入門 Vue入門 實現代碼&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>vue入門</title><!--引入vue.js文件--><script src"../js/vue.js"><…

就說說Java初學者求職準備項目的正確方式

當下不少Java初學者也知道求職時項目的重要程度&#xff0c;但在簡歷上寫項目和準備面試項目時&#xff0c;真有可能走彎路&#xff0c;這樣的話&#xff0c;加重學習負擔還是小事&#xff0c;還真有可能導致無法入職。 1 對于在校生和應屆生來說&#xff0c;你去跑通個學習項…

2024年4月—馬克思主義基本原理概論真題及答案解析(上海自考)

目錄 1.選擇題 2.簡答題 3.論述題 1.選擇題 2.簡答題

專業滲透測試 Phpsploit-Framework(PSF)框架軟件小白入門教程(九)

本系列課程&#xff0c;將重點講解Phpsploit-Framework框架軟件的基礎使用&#xff01; 本文章僅提供學習&#xff0c;切勿將其用于不法手段&#xff01; 繼續接上一篇文章內容&#xff0c;講述如何進行Phpsploit-Framework軟件的基礎使用和二次開發。 現在&#xff0c;我們…

STM32——定時器

一、簡介 *定時器可以對輸入的時鐘進行計數&#xff0c;并在計數值達到設定值時觸發中斷 *16位計數器、預分頻器、自動重裝寄存器的時基單元&#xff0c;在72MHz計數時鐘下可以實現最大59.65s的定時 *不僅具備基本的定時中斷功能&#xff0c;而且還包含內外時鐘源選擇、輸入…

基于SpringBoot的本科生考研率統計系統

基于SpringBoot的本科生考研率統計系統 一、開發技術二、功能模塊三、代碼結構四、數據庫設計五、運行截圖六、源碼獲取 一、開發技術 技術&#xff1a;SpringBoot、MyBatis-Plus、Redis、MySQL、Thymeleaf、Html、Vue、Element-ui。 框架&#xff1a;基于開源框架easy-admin開…

景源暢信:抖音小店新手小白如何做好運營?

在數字時代的浪潮中&#xff0c;抖音小店成為了眾多創業者和商家的新寵。但面對激烈的市場競爭和不斷變化的平臺規則&#xff0c;新手小白如何才能在抖音小店的海洋里穩健航行&#xff0c;捕捉到屬于自己的商機呢?接下來的內容將為你揭曉答案。 一、精準定位&#xff0c;明確目…

視頻監控平臺AS-V1000 的場景管理,一鍵查看多畫面視頻的場景配置、調用、管理(一鍵瀏覽多路視頻)

目錄 一、場景管理的定義 二、場景管理的功能和特點 1、功能 &#xff08;1&#xff09;場景配置 &#xff08;2&#xff09;實時監控 &#xff08;3&#xff09;權限管理 2、特點 三、AS-V1000的場景配置和調用 1、場景配置 &#xff08;1&#xff09;實時視頻預覽 …

React@16.x(12)ref 轉發-forwardRef

目錄 1&#xff0c;介紹2&#xff0c;類組件如何使用4&#xff0c;應用場景-高階組件HOC 1&#xff0c;介紹 上篇文章中提到&#xff0c;ref 只能對類組件使用&#xff0c;不能對函數組件使用。 而 ref 轉發可以對函數組件實現類似的功能。 使用舉例&#xff1a; import Re…

為什么選擇CleanMyMac軟件呢?推薦理由

你是否曾經遇到過這樣的問題&#xff1a;電腦運行緩慢&#xff0c;存儲空間不足&#xff0c;不知道如何清理垃圾文件&#xff1f;別擔心&#xff0c;我們為你找到了解決方案——CleanMyMac軟件。這款強大的工具可以幫助你輕松解決這些問題&#xff0c;讓你的電腦煥然一新&#…

深入理解Python中的包與模塊

新書上架~&#x1f447;全國包郵奧~ python實用小工具開發教程http://pythontoolsteach.com/3 歡迎關注我&#x1f446;&#xff0c;收藏下次不迷路┗|&#xff40;O′|┛ 嗷~~ 目錄 一、包的概述與功能 代碼案例&#xff1a;包的結構 二、模塊的劃分與組合 劃分模塊的方法…

開源內網穿透神器:中微子代理(neutrino-proxy)實現內網穿刺

&#x1f604; 19年之后由于某些原因斷更了三年&#xff0c;23年重新揚帆起航&#xff0c;推出更多優質博文&#xff0c;希望大家多多支持&#xff5e; &#x1f337; 古之立大事者&#xff0c;不惟有超世之才&#xff0c;亦必有堅忍不拔之志 &#x1f390; 個人CSND主頁——Mi…