
🌈 個人主頁:Zfox_
🔥 系列專欄:Qt

目錄
- 一:🔥 控件概述
- 🦋 控件體系的發展階段
- 二:🔥 QWidget 核心屬性
- 🦋 核心屬性概覽
- 🦋 用件可用(Enabled)
- 🦋 坐標系(Geometry)
- 🎀 實例 1: 控制按鈕的位置
- 🎀 實例 2: 表白 程序
- 🦋 窗口標題(windowTiltle)
- 🦋 窗口圖標(windowlcon)
- 🦋 窗口透明度(windowOpacity)
- 🦋 光標屬性(cursor)
- 🦋 字體屬性(QFont)
- 三:🔥 Window Frame 的影響
- 🦋 Geometry 和 FrameGeometry 的區別
- 四:🔥 API 設計理念
- 五:🔥 資源管理與路徑使用
- 🦋 圖片路徑的選擇
- 🦋 路徑類型說明
- 🦋 構建目錄的作用
- 六:🔥 qrc 文件
- 🦋 qrc 文件的特點
- 🦋 通過 qrc 管理圖片作為圖標
- 七:🔥 其他
- 🦋 ToolTip 設置
- 🦋 Focus Policy 設置
- 🦋 Style Sheet(QSS)
- 八:🔥 共勉
一:🔥 控件概述
- Widget:Qt 中的核心概念,指圖形化界面的基本構成元素(如按鈕、列表視圖等),即 “控件” 。
- Qt 的優勢:內置大量常用控件,并支持自定義控件,便于快速開發符合需求的界面
像上面示例中的,按鈕、列表視圖、樹形視圖、單行輸?框,多行輸入框,滾動條、下拉框等等都可以稱為 “控件”
Qt
作為一個成熟的 GUI 開發框架,內置了大量的常用控件。- 這一點在
Qt Designer
中就可以看出來,并且Qt
也提供了 “自定義控件” 的能力,可以讓我們在現有控件不能滿足需求的時候,對現有控件做出擴展,或者手搓出新的控件。
🔥 所以,學習 Qt
其中一個很重要的任務就是熟悉并掌握 Qt
內置的常用控件,這些控件對于我們快速開發出符合需求的界面是至關重要的
🦋 控件體系的發展階段
-
無控件階段:完全沒有控件。此時需要通過一些繪圖 API 手動的繪制出按鈕或者輸入框等內容,代碼編寫繁瑣。
-
粗略控件階段:提供基本控件,如按鈕和輸入框,簡化了GUI開發。(例如 html 的原生控件)
-
成熟控件體系:更完整的控件體系,基本可以覆蓋到 GUI 開發中的大部分場景。(例如早期的 MFC、VB、C++ Builder、Qt、Delphi、后來的 Android SDK、Java FX、前端的各種 UI 庫等)
上圖是前端中的 Element-ui 中的控件概覽,無論是豐富程度還是顏值,都比 Qt 自帶的控件更勝一籌
QT
近幾年還提供了 Qt Desiign Studio
=> 對比現代化的界面體系
- 制作的界面的美觀程度是業界非常領先的
- 但是收費比較貴
二:🔥 QWidget 核心屬性
-
在 Qt 中,使用
QWidget
類表示 “控件”,像按鈕、視圖、輸入框、滾動條等具體的控件類,都是繼承自QWidget
。QWidget
中包含了 Qt 整個控件體系中通用的部分。 -
在
Qt Designer
中,隨便拖一個控件過來,選中該控件,即可在右下方可以看到QWidget
中的屬性。
這些屬性既可以通過 QtDesigner 直接修改,也可以通過代碼的方式修改。這些屬性的具體含義在 Qt Assistant 中均有詳細介紹。
在 Qt Assistant 中搜索 QWidget,即可找到對應的文檔說明 (或者在 Qt Creator 代碼中選中 QWidget,按 F1(+Fn) 也可)
🦋 核心屬性概覽
下面是后面我羅列出的其中一些比較重要和常用的屬性,等下后面會著重進行介紹
QWidget
屬性及其作用:
屬性 | 作用 |
---|---|
enabled | 設置控件是否可使用。true 表示可用,false 表示禁用。 |
geometry | 控制控件的位置和尺寸,包含 x , y , width , height 四個部分。坐標是以父元素為參考進行設置的。 |
windowTitle | 設置 widget 的標題。 |
windowIcon | 設置 widget 的圖標。 |
windowOpacity | 設置 widget 的透明度。 |
cursor | 設置鼠標懸停時顯示的圖標形狀,如普通箭頭、沙漏或十字等。可通過 Qt Designer 查看選項。 |
font | 控制字體相關屬性,包括字體家族、大小、粗體、斜體、下劃線等樣式。 |
toolTip | 當鼠標懸停在 widget 上時,在狀態欄中顯示的提示信息。 |
toolTipDuration | toolTip 顯示的持續時間。 |
statusTip | 當 widget 狀態發生改變時(如按鈕被按下)顯示的提示信息。 |
whatsThis | 當鼠標懸停并按下 Alt+F1 時,顯示的幫助信息(顯示在一個彈出窗口中)。 |
styleSheet | 允許使用 CSS 來設置 widget 中的樣式,支持豐富的樣式,便于前端開發者上手。 |
focusPolicy | 定義 widget 如何獲取焦點:NoFocus , TabFocus , ClickFocus , StrongFocus , WheelFocus 。 |
contextMenuPolicy | 設置上下文菜單的顯示策略:DefaultContextMenu , NoContextMenu , PreventContextMenu , ActionsContextMenu , CustomContextMenu 。 |
ocale | 設置語言和國家地區。 |
acceptDrops | 設置該部件是否接受拖放操作。true 表示可以接收來自其他部件的拖放操作;false 則表示不接收任何拖放操作。 |
minimumSize | 控件的最小尺寸,包含最小寬度和最小高度。 |
maximumSize | 控件的最大尺寸,包含最大寬度和最大高度。 |
sizePolicy | 設置控件在布局管理器中的縮放方式。 |
windowModality | 指定窗口是否具有 “模態” 行為。 |
sizeIncrement | 拖動窗口大小時的增量單位。 |
baseSize | 窗口的基礎大小,用于配合 sizeIncrement 調整組件尺寸。 |
palette | 設置 widget 的顏色風格。 |
mouseTracking | 是否跟蹤鼠標移動事件。true 表示需要跟蹤;false 表示不需要跟蹤。 |
tabletTracking | 是否跟蹤觸摸屏的移動事件,類似于 mouseTracking 。Qt 5.9 引入的新屬性 |
layoutDirection | 設置布局方向:LeftToRight , RightToLeft , LayoutDirectionAuto 。 |
autoFillBackground | 是否自動填充背景顏色。 |
windowFilePath | 將 widget 和一個本地文件路徑關聯起來。 |
accessibleName | 設置 widget 的可訪問名稱,輔助技術(如屏幕閱讀器)可以獲取到這個名稱。 |
accessibleDescription | 設置 widget 的詳細描述,作用同 accessibleName 。 |
inputMethodHints | 針對輸入框有效,用來提示用戶當前能輸入的合法數據格式,如只能輸入數字、只能輸入日期等。 |
🦋 用件可用(Enabled)
API | 說明 |
---|---|
isEnabled() | 獲取到控件的可用狀態 |
setEnabled() | 設置控件是否可使用,code 表示可用,false 表示禁用 |
- 所謂 “禁用” 指的是該控件不能接收任何用戶的輸入事件,并且外觀上往往是灰色的。
- 如果一個
widget
被禁用,則該widget
的子元素也被禁用。
🧀 案例1:創建一個禁用狀態的按鈕:
運行程序,可以看到按鈕處于灰色狀態,無法被點擊:
🧀 通過按鈕 2 切換按鈕 1 的禁用狀態
(1)使用 Qt Designer 拖兩個按鈕到 Widget 中
- 兩個按鈕的
objectName
分別為pushButton
和pushButton_2
QObject 的 objectName 屬性介紹:
QObject
是QWidget
的父類,里面最主要的屬性就是objectName
。在一個 Qt 程序中,objectName
相當于對象的身份標識,彼此之間不能重復。- 在使用
Qt Designer
時,尤其是界面上存在多個widget
的時候,可以通過objectName
獲取到指定的 widget 對象。 Qt Designer
生成的 ui 文件,本身是 xml 格式的,qmake
會把這個 xml 文件轉換成 C++ 的 .h 文件(這個文件生成在 build 目錄中),構成一個 ui_widget 類。- 每個
widget
的objectName
最終就會成為ui_widget
類的屬性名字。最終這個類的實例就是:Ui::Widget *ui
,因此就可以通過形如ui->pushButton
或者ui->pushButton_2
這樣的代碼獲取到界面上的 widget 對象了。 - 當前自動生成的
objectName
是有規律的:控件的類型 + 下劃線 + 數字。很明顯,以數字的方式命名并不是一個好的編程習慣,這里我將它修改為如下所示:
(2)生成兩個按鈕的 slot 函數
- 使用
isEnabled
獲取當前按鈕的可用狀態。 - 使用
setEnabled
修改按鈕的可用狀態,此處是直接針對原來的可用狀態進行取反后設置。
運行程序可以看到:初始情況下,上面的按鈕是可用狀態。接著點擊下方按鈕,即可使上方按鈕被禁用
- 在
Qt Designer
中創建按鈕的時候可以設置按鈕的初始狀態是 “可用” 還是 “禁用”。如果把enabled
這一列的對鉤去掉,則按鈕的初始狀態就是 “禁用” 狀態。
🦋 坐標系(Geometry)
位置和尺寸是四個屬性的統稱:
- x 橫坐標
- y 縱坐標
- width 寬度
- height 高度
在實際開發中,我們通常不會直接使用這四個屬性來獲取或修改控件的位置和大小。
Qt
提供了一系列封裝的方法,這些方法更方便操作,并且考慮到了 Qt
的左手坐標系——其中原點位于父元素的左上角。
API | 說明 |
---|---|
geometry() | 獲取到控件的位置和尺寸,返回結果是一個QRect,包含 x, y, width, height,其中 x, y 是左上角坐標 |
setGeometry(QRect) seGeometry(int x, int y, int width, int height) | 設置控件的位置和尺寸,可以直接設置一個 QRect,也可以分四個屬性單獨設置 |
💡 move VS setGeometry
move
只是修改位置setGeometry
既可以修改位置,又可以修改尺寸
🎀 實例 1: 控制按鈕的位置
① 創建界面布局:
- 在界面上拖拽五個按鈕,分別命名為
pushButton_target(目標按鈕)
、pushButton_up(向上移動按鈕)
、pushButton_down(向下移動按鈕)
、pushButton_left(向左移動按鈕)
和pushButton_right(向右移動按鈕)
。這些按鈕的初始位置和大小可以隨意設置。
② 編寫槽函數:
- 在
widget.cpp
文件中為每個方向的按鈕添加槽函數,用于改變pushButton_target
的位置。當點擊相應的方向按鈕時,會調整目標按鈕的 x 和 y 坐標,從而實現位置變化 - 注意,這樣做會 導致按鈕的整個矩形區域發生位移,而不僅僅是其左上角
③ 優化移動邏輯:
- 如果希望按鈕只移動而不改變尺寸,應該避免直接修改
QRect
對象中的 x 和 y 值。 - 相反,可以通過
setGeometry()
方法的第二個版本來重新設定按鈕的位置,保持寬度和高度不變
🎀 實例 2: 表白 程序
① 設計界面:
- 向界面上添加兩個按鈕(接受
pushButton_forever
和拒絕pushButton_moment
)以及一個標簽label
,用來顯示文本信息
② 實現交互邏輯:
- 在
widget.cpp
中定義槽函數,使得當用戶點擊 “forever…” 拒絕按鈕時,觸發按鈕逃跑的行為。 - 此行為可以通過監聽
clicked
事件(即鼠標點擊后釋放)實現。
運行程序可以看到:當點擊 “forever…” 時,按鈕就跑了。
上述代碼使用的是 clicked(一下一上是點擊),如果使用 pressed(鼠標按下事件)。
- 這里我們需要鼠標點擊才能跑,我們現在讓其變成按下就跑,如下:
如果使用 mouseMoveEvent
,會更狠一些, 只要鼠標移動到這個按鈕上面,按鈕就跑了。
對應的代碼更麻煩?些,需要使用到 Qt 的事件機制(需要自定義類繼承自 QPushButton
,重寫 mouseMoveEvent
方法)這里就暫時不展開了。
🦋 窗口標題(windowTiltle)
API | 說明 |
---|---|
windowTitle() | 獲取控件的窗口標題。 |
setWindowTitle(const QString& title) | 設置控件的窗口標題 |
- 注意,僅對頂層 widget 有效,如果是 子 widget ,上該操作無效。
代碼示例:設置窗口標題
🦋 窗口圖標(windowlcon)
API | 說明 |
---|---|
windowIcon() | 獲取控件的窗口圖標,返回 QIcon 對象。 |
setWindowIcon(const QIcon& icon) | 設置控件的窗口圖標。同 windowTitle ,僅對頂層 widget 有效。 |
這兩個 API 類似于 windowTitle
,上述操作僅針對頂層 widget 有效。
圖標網站:Yesicon 或者 iconfont-阿里巴巴矢量圖標庫
(1)設置窗口圖標
A. 先在 D 盤中保存一張圖片,我這里命名為 qt_bao.jpg
B. 修改 widget.cpp
-
前面推薦使用堆來創建對象 ,主要是因為要確保當前控件的生命周期是足夠的,要通過 Qt 對象樹來釋放對象。
-
但是對于 QIcon來說,QIcon 自身是一個比較小的對象。創建出來之后,就是要設置到某個 QWidget 里面,
QIcon
對象本身是否釋放并不影響圖標最終的顯示。 -
QIcon
也不支持對象樹,無法給它執行父對象。
注意:
- 路徑里面最好不要帶中文
Windows
下路徑的分隔符可以使用 / ,也可以使用 \- 但是如果在字符串中使用 \,需要寫作轉義字符的形式 \\,避免在字符串中被認為成轉義字符
- 因此還是更推薦使用 /
并且程序在任務欄中的圖標也發生了變化:
🦋 窗口透明度(windowOpacity)
API | 說明 |
---|---|
windowOpacity() | 獲取控件的不透明數值,取值范圍為 0.0(全透明)到 1.0(完全不透明)。 |
setWindowOpacity(float n) | 設置控件的不透明數值。 |
調整窗口透明度
(1)在界面上拖放兩個按鈕,分別用來增加不透明度和減少不透明度
objectName
分別為 pushButton_add 和 pushButton_sub:
(2)編寫 wdiget.cpp
, 編寫兩個按鈕的 slot 函數
- 點擊
pushButton_sub
會減少不透明度,也就是窗口越來越透明 - 點擊
pushButton_add
會增加不透明度,窗口會逐漸恢復
(3)執行程序
點擊了幾下 ‘-’ 之后,就可以透過窗?看到后面的內容了,點擊 ‘+’ 又會逐漸恢復:
同時控制臺中也可以看到 opacity 數值的變化,發現其窗口得到不透明度變化并非是精確的
注意 :
- C++ 中 float 類型遵守 IEEE 754 標準,因此在進行運算的時候會有一定的精度誤差
- IEEE 754 標準 規定浮點數使用 二進制 科學計數法的方式來表示,把一個浮點數分成 符號位、有效數字、指數部分 三個部分
- 其中有效數字是用二進制表示的,比如 .1(B),表示0.5,.01(B) 表示 0.25,而 0.1 這樣的小數無法用二進制精確表示出來,只能湊一個非常接近 0.1 的數
- 因此 1 - 0.1 的數值并非是 0.9
- 這里還要提一句:平時最好不要把兩個浮點數直接用 == 進行比較,比如 0.1 + 0.2 == 0.3 (false)
還有個問題,我們上面加了判定條件
- 其實不加也是可以的,超過 1.0 的數字設置不進去,因為
setWindowOpacity
內部也進行了判定
🦋 光標屬性(cursor)
API | 說明 |
---|---|
cursor() | 獲取當前 widget 的光標屬性,返回 QCursor 對象。 |
setCursor(const QCursor& cursor) | 設置該 widget 的光標形狀,僅在鼠標停留在該 widget 上時生效。 |
QGuiApplication::setOverrideCursor(const QCursor& cursor) | 設置全局光標的形狀,覆蓋 setCursor 設置的內容。 |
1. 在 Qt Designer 中設置按鈕的光標
(1)在界面中創建一個按鈕
(2)直接在右側屬性編輯區修改 cursor
屬性為 “打開手勢”
(3)運行程序
鼠標懸停到按鈕上之后,就可以看到光標的變化。
2. 通過代碼設置按鈕的光標
(1) 編寫 widget.cpp
其中 Qt::WaitCursor
就是自帶的沙漏 / 轉圈形狀的光標。
系統內置的光標形狀如下:
Ctrl + 左鍵點擊 Qt::WaitCursor
跳轉到源碼即可看到:
3. 自定義鼠標光標
Qt 自帶的光標形狀有限,我們也可以自己找個圖片,做成鼠標的光標,比如我們這里用我們上面圖標那用到的寶可夢當鼠標光標
(1)用下面說到的,創建 qrc 的方法,來創建 qrc 資源文件,添加前綴 /,并加入圖片
注意: 這里 pixmap = pixmap.scaled(10, 10);
- 通過這個函數對圖片進行縮放
- 注意:這里的縮放不是修改圖片對象本身,而是返回一個新的圖片對象副本
🦋 字體屬性(QFont)
字體屬性是界面設計中重要的組成部分,它們影響著文本的外觀。Qt 提供了多種方式來設置和獲取字體屬性。
API 說明
- font():用于 獲取 當前 widget 的字體信息。返回一個 QFont 對象。
- setFont(const QFont& font):用于 設置 當前 widget 的字體信息。
屬性列表
屬性 | 說明 |
---|---|
family | 字體家族,例如 “楷體”, “宋體”, “微軟雅黑” 等 |
pointSize | 字體大小 |
weight | 字體粗細,以數值表示粗細程度,取值范圍為 [0, 99],數值越大,越粗 |
bold | 是否加粗,設置為 true 相當于 weight 為 75;false 則為 50 |
italic | 是否傾斜 |
underline | 是否帶有下劃線 |
strikeOut | 是否帶有刪除線 |
1. 在 Qt Designer 中設置字體屬性
1)在界面上創建一個 label
2)在右側的屬性編輯區,設置該 label
的 font
相關屬性在這里調整上述屬性,Qt Designer
能夠對界面的屬性設置支持 “實時預覽”,因此我們可以實時的看到文字的變化。
3)執行程序,就可以看到上面的效果了
- 通過屬性編輯這樣的方式,雖然能夠快速方便的修改文字相關的屬性,但是還不夠靈活。如果程序運行過程中需要修改文字相關屬性,就需要代碼操作了
2. 在代碼中設置字體屬性
編寫 widget.cpp
,然后運行程序即可
- 在實際開發中,字體屬性如何選擇是一個 “審美問題”,而不是 “技術問題”,往往需要有一定的藝術細胞。
- 幸運的是,公司中 往往有專業的 “美工” / “設計” 這樣的崗位,去做這方面的工作,我們程序員只要按照人家給的設計稿,把代碼寫出來即可,不必過多考慮怎樣搭配才好看的問題。
三:🔥 Window Frame 的影響
當 widget 作為一個窗口時(例如帶有標題欄等),計算尺寸和坐標有兩種算法:
-
包含
window frame
的方式(如x(), y(), frameGeometry(), pos(), move()
) -
不包含
window frame
的方式(如geometry(), width(), height(), rect(), size()
)
對于非窗口的 widget,這兩種計算方式的結果是一致的。
🦋 Geometry 和 FrameGeometry 的區別
(1) 在按鈕的 slot
函數中編寫代碼 & 在構造函數中也添加同樣的代碼
(2)執行程序
- 可以看到:在構造函數中打印出的
geometry
和frameGeometry
是相同的。 - 但是在點擊按鈕時,打印的
geometry
和frameGeometry
則存在差異。
💡 原因:
-
在構造方法中,
Widget
剛剛創建出來,還沒有加入到對象樹中,此時也就不具備Window frame
。 -
在按鈕的
slot
函數中,由于用戶點擊的時候,對象樹已經構造好了,此時Widget
已經具備了Window frame
,因此在位置和尺寸上均出現了差異。 -
如果把上述代碼修改成打印
pushButton
的geometry
和frameGeometry
,結果就是完全相同的。因為pushButton
并非是一個窗口
因此我們具體使用的時候,需要明確使用的坐標系原點究竟是誰
四:🔥 API 設計理念
API | 說明 |
---|---|
x() | 獲取橫坐標。計算時包含 window frame。 |
y() | 獲取縱坐標。計算時包含 window frame。 |
pos() | 返回 QPoint 對象,包含 x() 和 y() 的值及設置方法。計算時包含 window frame。 |
frameSize() | 返回 QSize 對象,包含 width() 和 height() 及其設置方法。計算時包含 window frame。 |
frameGeometry() | 返回 QRect 對象,相當于 QPoint 和 QSize 的結合體,可以獲取 x, y, width, size。計算時包含 window frame 對象。 |
width() | 獲取寬度。計算時不包含 window frame。 |
height() | 獲取高度。計算時不包含 window frame。 |
size() | 返回 QSize 對象,包含 width() 和 height() 及其設置方法。計算時不包含 window frame。 |
rect() | 返回 QRect 對象,可以獲取并設置 x, y, width, size。計算時不包含 window frame 對象。 |
geometry() | 返回 QRect 對象,可以獲取 x, y, width, size。計算時不包含 window frame 對象。 |
setGeometry() | 設置窗口的位置和尺寸,可以設置 x, y, width, height 或 QRect 對象。計算時不包含 window frame 對象。 |
認真觀察上面的表格,可以看到,其實這里的 API 有 frameGeometry
和 geometry
兩個就足夠完成所有的需求了。
為什么要提供這么多功能重復的 API 呢?
這涉及到 Qt API 的設計理念:盡量符合人的直覺。例如,Qt 的
QVector
提供了多種尾插元素的方法:
push_back
append
+=
<<
上述方法的效果都是等價的,即使不翻閱文檔,單純的憑借直覺就能把代碼寫對。減少了記憶負擔,使編程變得更加直觀和友好
五:🔥 資源管理與路徑使用
🦋 圖片路徑的選擇
- 避免絕對路徑:實際開發中,通常不會在代碼中通過絕對路徑引入圖片。因為無法保證程序發布后,用戶的電腦上也有同樣的路徑。
- 相對路徑的要求:如果選擇使用相對路徑,則需要確保代碼中的相對路徑寫法和圖片實際所在的路徑匹配。例如,代碼中寫作
"./image/Q&A.jpg"
,就需要在當前工作目錄中創建 image 目錄,并把Q&A.jpg
放進去。
🦋 路徑類型說明
- 絕對路徑:以盤符(Windows)或者以 /(Linux)開頭的路徑。
- 相對路徑:以 .(表示當前路徑)或者以 …(表示當前路徑上級路徑)開頭的路徑。其中 . 經常也會省略。使用相對路徑的前提是明確“當前工作目錄”。
對于 Qt 程序來說,當前工作目錄可能是變化的:
- 通過 Qt Creator 運行的程序,當前工作目錄是項目的構建目錄
- 直接雙擊 exe 運行時,工作目錄則是 exe 所在目錄
🦋 構建目錄的作用
所謂構建目錄,是和 Qt 項目并列的,專門用來放生成的臨時文件和最終 exe 的目錄
Qt 使用 qrc 機制 來自動管理項目依賴的靜態資源,解決了以下兩個關鍵問題:
- 確保我們的 圖片所在路徑在目標用戶機器上存在
- 確保我們的 圖片不會被用戶誤刪或修改
如果我們不知道這個路徑在哪,可以輸入下面代碼來 查看運行程序的 工作目錄 與 程序所在的目錄
六:🔥 qrc 文件
🦋 qrc 文件的特點
-
qrc 文件是一種 XML 格式的資源配置文件
-
它用 XML 記錄硬盤上的文件和對應的隨意指定的資源名稱,應用程序通過資源名稱來訪問這些資源
-
在 Qt 開發中,可以通過將資源文件添加到項目中來方便地訪問和管理這些資源,這些資源文件可以位于 qrc 文件所在目錄的同級或其子目錄下
-
在構建程序的過程中,Qt 會把資源文件的二進制數據轉成 cpp 代碼,編譯到 exe 中,從而使依賴的資源變得 “路徑無關”。
這種資源管理機制并非 Qt 獨有,很多開發框架都有類似的機制。例如 Android
的 Resources
和 AssetManager
也提供了類似的功能。
qrc 的局限性
- 不適合大文件:qrc 不適合導入太大的資源文件,因為這會導致最終 exe 文件體積增大,程序運行內存消耗增加及編譯時間顯著增長。
🦋 通過 qrc 管理圖片作為圖標
(1)右鍵項目,創建一個 Qt Resource File(qrc 文件), 文件名隨意起(不要帶中文),此處叫做 resource.qrc
如下:
(2)在 qrc 編輯器中 添加 前綴
此處我們前綴設置成 / 即可。
所謂的前綴,可以理解成 “虛擬的目錄”,這個目錄在我們的電腦中并不是真實存在的,是 Qt 自己抽象出來的,它決定了后續我們如何在代碼中訪問資源。
(3)在資源編輯器中,點擊 add Files 添加資源文件
此處我們需要添加的是:qt_bao.jpg:
注意 :
- 添加的文件必須是在 qrc 文件的同級目錄或者同級目錄的子目錄中
- 因此我們需要把之前 D 盤中的 .jpg 復制到上述目錄中。
(4)在代碼中使用 qt_bao.jpg
代碼中需要訪問 qrc 中管理的文件時,就需要在路徑上帶有 : 前綴。創建的前綴叫什么名字,代碼中就寫什么名字:前綴 + 文件名。
注意上述路徑的訪問規則:
-
使用 : 作為開頭,表示從 qrc 中讀取資源
-
/ 是上面配置的前綴
-
qt_bao.jpg 是資源的名稱
🔥 需要確保代碼中編寫的路徑 和添加到 qrc 中資源的路徑匹配,否則資源無法被訪問(同時也不會有報錯提示)。
運行成功后,我們可以進入到項目的構建目錄中可以看到:目錄中多了一個
qrc_resource.cpp
文件,直接打開這個文件可以看到:
qrc 中導入的圖片資源會被轉成這個 qrc_resource.cpp
(自動生成)這個 c++ 代碼,代碼查看如下:
上述代碼其實就是通過 unsigned char
數組,把 qt_bao.jpg
中的每個字節都記錄下來。
這些代碼會被編譯到 exe 中,后續無論 exe 被復制到哪個目錄下都確保能夠訪問到該圖片資源。
上述 qrc 這一套資源管理方案的優點和缺點都很明顯:
-
優點:確保了圖片、字體、剩余等資源能夠真正做到 “目錄無關”,無論如何都不會出現資源丟失的情況。
-
缺點:不適合管理體積大的資源。如果資源比較大(比如是幾個 MB 的文件),或者資源特別多,生成的最終的 exe 體積就會比較大,程序運行消耗的內存也會增大,程序編譯的時間也會顯著增加。
七:🔥 其他
🦋 ToolTip 設置
一個 GUI 程序,界面比較復雜,按鈕很多,那么就需要提供一個功能:當我們鼠標懸停到這個控件的時候,就能彈出一個提示
Tooltip
是用戶 懸停在 widget 上時顯示的提示信息,有助于提高用戶體驗。
API | 說明 |
---|---|
setToolTip(const QString &tooltip) | 設置 tooltip 文本 |
setToolTipDuration(int msec) | 設置 tooltip 顯示的 時間,單位為毫秒 |
設置按鈕的 toolTip
(1)在界面上拖放兩個按鈕:objectName
設置為 pushButton_moment
和pushButton_forever
(2)編寫 widget.cpp
- 觀察效果,可以看到鼠標停到按鈕上之后,就能彈出提示,時間到后自行消失。
🦋 Focus Policy 設置
Focus policy 決定了控件是否及如何接收 鍵盤焦點
設置控件獲取到焦點的策略,比如某個控件 能否用鼠標選中 或者 能否通過 tab 鍵選中
- 所謂 “焦點”,指的就是能選中這個元素。接下來的操作(比如鍵盤操作),就都是針對該焦點元素進行的了。
- 比如界面上有一個輸入框,此時必須要選中最高輸入框,接下來的鍵盤按鍵才會輸入到輸入框中,如果選擇別的控件或窗口,此時鍵盤的輸入就不會到這個輸入框中
- 這個對于輸入框、單選框、復選框等控件非常有用的。
API | 說明 |
---|---|
focusPolicy() | 獲取當前 widget 的 focus policy |
setFocusPolicy(Qt::FocusPolicy policy) | 設置 widget 的 focus policy |
Qt::FocusPolicy 是一個枚舉類型,如下:
Qt::NoFocus
:控件不會接收鍵盤焦點。Qt::TabFocus
:控件可以通過 Tab 鍵接收焦點。Qt::ClickFocus
:控件在鼠標點擊時接收焦點。Qt::StrongFocus
:默認值,控件可以通過 Tab 鍵和鼠標點擊接收焦點。Qt::WheelFocus
:類似于Qt::StrongFocus
,同時控件也通過鼠標滾輪獲取到焦點。
💡 代碼示例:理解不同的 focusPolicy
(1)在界面上創建四個單行輸入框(Line Edit)
(2)修改四個輸入框的 focusPolicy 屬性分別為 Qt::StrongFocus (默認取值,一般不用額外修改)、Qt::NoFucus、Qt::TabFucus、Qt::ClickFucus
結果如下:
- 此時運行程序可以看到,使用鼠標單擊 / tab,就可以移動光標所在輸入框,從而接下來的輸入就是針對這個獲取焦點的輸入框展開的
- 第一個輸入框 Tab / 鼠標單擊都可以選中
- 第二個輸入框無法輸入內容
- 第三個輸入框只能通過 Tab 選中
- 第四個輸入框只能通過鼠標選中
GUI 中,窗口/控件的 焦點是非常主要的
比如:我們在網頁做題的時候,網頁時屬于始終獲取到焦點的狀態,但是如果我們一旦切到網頁/程序,則該網頁立刻就能感受到失去焦點,然后從此收集我們的動作來衡量 ”作弊“
🦋 Style Sheet(QSS)
CSS(Cascading Style Sheets 層疊樣式表)本身屬于網頁前端技術,主要用于 描述界面的樣式。
- 所謂“樣式”,包括但不限于大小、位置、顏色、間距、字體、背景、邊框等。我們日常看到的豐富多彩的網頁都會用到大量的 CSS。
- 盡管 Qt 主要用于 GUI 開發,但它與網頁前端有著許多相似之處。
- 因此,Qt 引入了對 CSS 的支持,允許開發者使用類似的樣式規則來定義 widgets 的外觀。
然而,Qt 只能支持部分 CSS 樣式屬性,這些被支持的屬性稱為 QSS(Qt Style Sheet)。具體的支持情況可以參考 Qt 文檔中的 "Qt Style Sheets Reference"
章節。
設置文本樣式
(1)在界面上創建 label,然后編輯右側的 styleSheet 屬性,設置樣式
或者右擊,選擇下面這種方式打開
然后對樣式表,編寫如下:
font-family: '微軟雅黑';
font-size: 30px;
font-style: bond;
color: red;
- 此處的語法格式 同 CSS,使用鍵值對的方式設置樣式。其中 鍵和值之間使用 : 分割;鍵值對之間使用 ; 分割。
- 注意:Qt Designer 只能對樣式的基本格式進行校驗,不能檢測出哪些樣式不被 Qt 支持,例如
text-align: center
這樣的文本居中操作,在某些情況下可能無法支持。
編輯完成樣式之后,可以看到在 Qt Designer 中能夠實時預覽出效果:
實現切換夜間模式
- 日間模式:文字是黑色的,背景是白色的。
- 夜間模式:文字是白色的,背景是黑色的。
(1)在界面上創建一個多行輸入框(Text Edit)和兩個按鈕objectName
分別為 pushButton_light
和 pushButton_dark
(2)編寫按鈕的 slot 函數
#333
是深色,但不是完全黑色。#fff
是純白色。#000
是純黑色。
關于顏色,我們可以使用在線調色板或畫圖板工具可以查看顏色對應的數值。
通過截圖的取色器就可以發先界面上的顏色rpg了
關于計算機中的顏色表示
- 計算機中使用“像素”表示屏幕上的一個基本單位(即一個發光點)。每個像素都使用三個字節表示顏色,分別是 R(red)、G(green)、B(blue),每個字節取值范圍是 0-255 或者 0x00-0xFF。
混合三種不同顏色的數值比例可以搭配出千千萬萬的顏色出來。
rgb(255, 0, 0) 或者 #FF0000 或者 #F00 表示純紅色。
rgb(0, 255, 0) 或者 #00FF00 或者 #0F0 表示純綠色。
rgb(0, 0, 255) 或者 #0000FF 或者 #00F 表示純藍色。
rgb(255, 255, 255) 或者 #FFFFFF 或者 #FFF 表示純白色。
rgb(0, 0, 0) 或者 #000000 或者 #000 表示純黑色。
上述規則適用于一般程序的顏色設定。
實際顯示器可能會有8bit 色深或者 10bit 色深等,具體情況會更加復雜。
運行程序
- 點擊“日間模式”按鈕,界面將顯示淺色背景和深色文字。
- 點擊“夜間模式”按鈕,界面將顯示深色背景和淺色文字。
八:🔥 共勉
😋 以上就是我對 【QT】QWidget 概述與核心屬性(API)
的理解, 覺得這篇博客對你有幫助的,可以點贊收藏關注支持一波~ 😉