【QT】QWidget 概述與核心屬性(API)

🌈 個人主頁: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 的優勢內置大量常用控件,并支持自定義控件,便于快速開發符合需求的界面

img

像上面示例中的,按鈕、列表視圖、樹形視圖、單行輸?框,多行輸入框,滾動條、下拉框等等都可以稱為 “控件”

  • Qt 作為一個成熟的 GUI 開發框架,內置了大量的常用控件。
  • 這一點在 Qt Designer 中就可以看出來,并且 Qt 也提供了 “自定義控件” 的能力,可以讓我們在現有控件不能滿足需求的時候,對現有控件做出擴展,或者手搓出新的控件。

img

🔥 所以,學習 Qt 其中一個很重要的任務就是熟悉并掌握 Qt 內置的常用控件,這些控件對于我們快速開發出符合需求的界面是至關重要的


🦋 控件體系的發展階段

  • 無控件階段完全沒有控件。此時需要通過一些繪圖 API 手動的繪制出按鈕或者輸入框等內容,代碼編寫繁瑣。

  • 粗略控件階段提供基本控件,如按鈕和輸入框,簡化了GUI開發。(例如 html 的原生控件)

  • 成熟控件體系更完整的控件體系,基本可以覆蓋到 GUI 開發中的大部分場景。(例如早期的 MFC、VB、C++ Builder、Qt、Delphi、后來的 Android SDK、Java FX、前端的各種 UI 庫等)

img

上圖是前端中的 Element-ui 中的控件概覽,無論是豐富程度還是顏值,都比 Qt 自帶的控件更勝一籌

QT 近幾年還提供了 Qt Desiign Studio => 對比現代化的界面體系

  • 制作的界面的美觀程度是業界非常領先的
  • 但是收費比較貴

二:🔥 QWidget 核心屬性

  • 在 Qt 中,使用 QWidget 類表示 “控件”,像按鈕、視圖、輸入框、滾動條等具體的控件類,都是繼承自 QWidgetQWidget 中包含了 Qt 整個控件體系中通用的部分。

  • Qt Designer 中,隨便拖一個控件過來,選中該控件,即可在右下方可以看到 QWidget 中的屬性。

img

這些屬性既可以通過 QtDesigner 直接修改,也可以通過代碼的方式修改。這些屬性的具體含義在 Qt Assistant 中均有詳細介紹。

Qt Assistant 中搜索 QWidget,即可找到對應的文檔說明 (或者在 Qt Creator 代碼中選中 QWidget,按 F1(+Fn) 也可)

🦋 核心屬性概覽

下面是后面我羅列出的其中一些比較重要和常用的屬性,等下后面會著重進行介紹

img

QWidget 屬性及其作用:

屬性作用
enabled設置控件是否可使用。true 表示可用,false 表示禁用。
geometry控制控件的位置和尺寸,包含 x, y, width, height 四個部分。坐標是以父元素為參考進行設置的。
windowTitle設置 widget 的標題。
windowIcon設置 widget 的圖標。
windowOpacity設置 widget 的透明度。
cursor設置鼠標懸停時顯示的圖標形狀,如普通箭頭、沙漏或十字等。可通過 Qt Designer 查看選項。
font控制字體相關屬性,包括字體家族、大小、粗體、斜體、下劃線等樣式。
toolTip當鼠標懸停在 widget 上時,在狀態欄中顯示的提示信息。
toolTipDurationtoolTip 顯示的持續時間。
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 中

img

img

  • 兩個按鈕的 objectName 分別為 pushButtonpushButton_2

QObject 的 objectName 屬性介紹:

  • QObjectQWidget 的父類,里面最主要的屬性就是 objectName。在一個 Qt 程序中,objectName 相當于對象的身份標識,彼此之間不能重復。
  • 在使用 Qt Designer 時,尤其是界面上存在多個 widget 的時候,可以通過 objectName 獲取到指定的 widget 對象。
  • Qt Designer 生成的 ui 文件,本身是 xml 格式的,qmake 會把這個 xml 文件轉換成 C++ 的 .h 文件(這個文件生成在 build 目錄中),構成一個 ui_widget 類。
  • 每個 widgetobjectName 最終就會成為 ui_widget 類的屬性名字。最終這個類的實例就是:Ui::Widget *ui,因此就可以通過形如 ui->pushButton 或者 ui->pushButton_2 這樣的代碼獲取到界面上的 widget 對象了。
  • 當前自動生成的 objectName 是有規律的:控件的類型 + 下劃線 + 數字。很明顯,以數字的方式命名并不是一個好的編程習慣,這里我將它修改為如下所示:

img

(2)生成兩個按鈕的 slot 函數

  • 使用 isEnabled 獲取當前按鈕的可用狀態。
  • 使用 setEnabled 修改按鈕的可用狀態,此處是直接針對原來的可用狀態進行取反后設置。

img

運行程序可以看到:初始情況下,上面的按鈕是可用狀態。接著點擊下方按鈕,即可使上方按鈕被禁用

在這里插入圖片描述

  • Qt Designer 中創建按鈕的時候可以設置按鈕的初始狀態是 “可用” 還是 “禁用”。如果把 enabled 這一列的對鉤去掉,則按鈕的初始狀態就是 “禁用” 狀態。

在這里插入圖片描述

🦋 坐標系(Geometry)

位置和尺寸是四個屬性的統稱:

  • x 橫坐標
  • y 縱坐標
  • width 寬度
  • height 高度

img

在實際開發中,我們通常不會直接使用這四個屬性來獲取或修改控件的位置和大小。

Qt 提供了一系列封裝的方法,這些方法更方便操作,并且考慮到了 Qt左手坐標系——其中原點位于父元素的左上角。

img

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 坐標,從而實現位置變化
  • 注意,這樣做會 導致按鈕的整個矩形區域發生位移,而不僅僅是其左上角

img
在這里插入圖片描述

③ 優化移動邏輯:

  • 如果希望按鈕只移動而不改變尺寸,應該避免直接修改 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_addpushButton_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)在右側的屬性編輯區,設置該 labelfont 相關屬性在這里調整上述屬性,Qt Designer 能夠對界面的屬性設置支持 “實時預覽”,因此我們可以實時的看到文字的變化。

在這里插入圖片描述

3)執行程序,就可以看到上面的效果了

  • 通過屬性編輯這樣的方式,雖然能夠快速方便的修改文字相關的屬性,但是還不夠靈活。如果程序運行過程中需要修改文字相關屬性,就需要代碼操作了

2. 在代碼中設置字體屬性

編寫 widget.cpp,然后運行程序即可

在這里插入圖片描述

  • 在實際開發中,字體屬性如何選擇是一個 “審美問題”,而不是 “技術問題”,往往需要有一定的藝術細胞。
  • 幸運的是,公司中 往往有專業的 “美工” / “設計” 這樣的崗位,去做這方面的工作,我們程序員只要按照人家給的設計稿,把代碼寫出來即可,不必過多考慮怎樣搭配才好看的問題。

三:🔥 Window Frame 的影響

當 widget 作為一個窗口時(例如帶有標題欄等),計算尺寸和坐標有兩種算法:

  • 包含 window frame 的方式(如 x(), y(), frameGeometry(), pos(), move()

  • 不包含 window frame 的方式(如 geometry(), width(), height(), rect(), size()

對于非窗口的 widget,這兩種計算方式的結果是一致的。

img

🦋 Geometry 和 FrameGeometry 的區別

(1) 在按鈕的 slot 函數中編寫代碼 & 在構造函數中也添加同樣的代碼

img

(2)執行程序

  • 可以看到:在構造函數中打印出的 geometryframeGeometry 是相同的。
  • 但是在點擊按鈕時,打印的 geometryframeGeometry 則存在差異。

在這里插入圖片描述

💡 原因:

  • 在構造方法中,Widget 剛剛創建出來,還沒有加入到對象樹中,此時也就不具備 Window frame

  • 在按鈕的 slot 函數中,由于用戶點擊的時候,對象樹已經構造好了,此時 Widget 已經具備了 Window frame,因此在位置和尺寸上均出現了差異。

  • 如果把上述代碼修改成打印 pushButtongeometryframeGeometry,結果就是完全相同的。因為 pushButton 并非是一個窗口

因此我們具體使用的時候,需要明確使用的坐標系原點究竟是誰

四:🔥 API 設計理念

API說明
x()獲取橫坐標。計算時包含 window frame。
y()獲取縱坐標。計算時包含 window frame。
pos()返回 QPoint 對象,包含 x()y() 的值及設置方法。計算時包含 window frame。
frameSize()返回 QSize 對象,包含 width()height() 及其設置方法。計算時包含 window frame。
frameGeometry()返回 QRect 對象,相當于 QPointQSize 的結合體,可以獲取 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 有 frameGeometrygeometry 兩個就足夠完成所有的需求了。

為什么要提供這么多功能重復的 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 機制 來自動管理項目依賴的靜態資源,解決了以下兩個關鍵問題:

  1. 確保我們的 圖片所在路徑在目標用戶機器上存在
  2. 確保我們的 圖片不會被用戶誤刪或修改

如果我們不知道這個路徑在哪,可以輸入下面代碼來 查看運行程序的 工作目錄 程序所在的目錄

在這里插入圖片描述

六:🔥 qrc 文件

🦋 qrc 文件的特點

  • qrc 文件是一種 XML 格式的資源配置文件

  • 用 XML 記錄硬盤上的文件和對應的隨意指定的資源名稱,應用程序通過資源名稱來訪問這些資源

  • 在 Qt 開發中,可以通過將資源文件添加到項目中來方便地訪問和管理這些資源,這些資源文件可以位于 qrc 文件所在目錄的同級或其子目錄下

  • 在構建程序的過程中,Qt 會把資源文件的二進制數據轉成 cpp 代碼,編譯到 exe 中,從而使依賴的資源變得 “路徑無關”。

這種資源管理機制并非 Qt 獨有,很多開發框架都有類似的機制。例如 AndroidResourcesAssetManager 也提供了類似的功能。

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 中管理的文件時,就需要在路徑上帶有 : 前綴。創建的前綴叫什么名字,代碼中就寫什么名字:前綴 + 文件名。

注意上述路徑的訪問規則:

  1. 使用 : 作為開頭,表示從 qrc 中讀取資源

  2. / 是上面配置的前綴

  3. 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_momentpushButton_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::NoFucusQt::TabFucusQt::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 屬性,設置樣式

在這里插入圖片描述

或者右擊,選擇下面這種方式打開

img

然后對樣式表,編寫如下:

font-family: '微軟雅黑';
font-size: 30px;
font-style: bond;
color: red;
  • 此處的語法格式 同 CSS,使用鍵值對的方式設置樣式。其中 鍵和值之間使用 : 分割;鍵值對之間使用 ; 分割。
  • 注意:Qt Designer 只能對樣式的基本格式進行校驗,不能檢測出哪些樣式不被 Qt 支持,例如 text-align: center 這樣的文本居中操作,在某些情況下可能無法支持。

編輯完成樣式之后,可以看到在 Qt Designer 中能夠實時預覽出效果:

在這里插入圖片描述

實現切換夜間模式

  • 日間模式:文字是黑色的,背景是白色的。
  • 夜間模式:文字是白色的,背景是黑色的。

(1)在界面上創建一個多行輸入框(Text Edit)和兩個按鈕objectName 分別為 pushButton_lightpushButton_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 色深等,具體情況會更加復雜。

運行程序

  • 點擊“日間模式”按鈕,界面將顯示淺色背景和深色文字。
  • 點擊“夜間模式”按鈕,界面將顯示深色背景和淺色文字。

img

八:🔥 共勉

😋 以上就是我對 【QT】QWidget 概述與核心屬性(API) 的理解, 覺得這篇博客對你有幫助的,可以點贊收藏關注支持一波~ 😉
在這里插入圖片描述

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

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

相關文章

Redis 在處理并發請求時,如何保證高效性和數據一致性

1. 單線程模型&#xff08;核心命令處理&#xff09; 單線程優勢&#xff1a;Redis 的核心命令處理是單線程的&#xff08;基于內存操作&#xff0c;避免多線程競爭&#xff09;&#xff0c;所有命令按順序執行&#xff0c;天然避免了多線程的鎖競爭和上下文切換開銷。非阻塞 …

flutter-Text等組件出現雙層黃色下劃線的問題

文章目錄 1. 現象2. 原因3. 解決方法 1. 現象 這天我正在寫Flutter項目的頁面功能&#xff0c;突然發現我的 Text 文字出現了奇怪的樣式&#xff0c;具體如下&#xff1a; 文字下面出現了雙層黃色下劃線文字的空格變得很大&#xff0c;文字的間距也變得很大 我百思不得其解&a…

cursor+高德MCP:制作一份旅游攻略

高德開放平臺 | 高德地圖API (amap.com) 1.注冊成為開發者 2.進入控制臺選擇應用管理----->我的應用 3.新建應用 4.點擊添加Key 5.在高德開發平臺找到MCP的文檔 6.按照快速接入的步驟&#xff0c;進行操作 一定要按照最新版的cursor, 如果之前已經安裝舊的版本卸載掉重新安…

使用 IP 代理改 IP 后注意事項如何防封號

在使用一鍵換IP軟件輔助網絡營銷賬號切換時&#xff0c;需注意以下關鍵事項以確保賬號安全并降低封號風險。 一、IP有效性及質量驗證 確保更換的IP地址有效且質量高&#xff0c;低質量或失效的IP可能導致賬號存活時間縮短。優先選擇動態住宅IP&#xff08;如“兔子IP代理”提…

qt designer 創建窗體選擇哪種屏幕大小

1. 新建窗體時選擇QVGA還是VGA 下面這個圖展示了區別 這里我還是選擇默認&#xff0c;因為沒有特殊需求&#xff0c;只是在PC端使用

數據可視化 —— 折線圖應用(大全)

一、導入需要的庫 # Matplotlib 是 Python 最常用的繪圖庫&#xff0c;pyplot 提供了類似 MATLAB 的繪圖接口 import matplotlib.pyplot as plt import numpy as np import pandas as pd 二、常用的庫函數 plt.plot(x軸,y軸)&#xff1a;plot()是畫折線圖的函數。 plt.xlabe…

ubuntu 20.04 安裝源碼編譯 ros humble過程

公司要兼容ros1還需要ros2 這個時候不得不使用ubuntu20.04 安裝 humble 但實際上在20.04上安裝humble是需要在源碼編譯的。 根據這個帖子 https://blog.csdn.net/m0_62353836/article/details/129730981 重寫一份,以應對無法下載的問題 系統配置 #檢查是否為UTF-8編碼,是則跳…

CVPR‘25 SOTA——GoalFlow論文精讀

1&#xff09;第一遍___粗讀 Q: 這篇論文試圖解決什么問題&#xff1f; A: 這篇論文提出了一個名為 GoalFlow 的端到端自動駕駛方法&#xff0c;旨在解決自動駕駛場景中高質量多模態軌跡生成的問題。具體而言&#xff0c;它試圖解決以下問題&#xff1a; 軌跡選擇的復雜性&am…

關于 CSDN的C知道功能模塊 的詳細解析,包括 新增的AI搜索(可選深度思考) 和 智能體功能 的具體說明及對比分析

以下是關于 CSDN的C知道功能模塊 的詳細解析&#xff0c;包括 新增的AI搜索&#xff08;可選深度思考&#xff09; 和 智能體功能 的具體說明及對比分析&#xff1a; 一、C知道核心功能模塊詳解&#xff08;基礎功能&#xff09; &#xff08;參考前文內容&#xff0c;此處略…

forms實現快讀閱讀器

forms實現快讀閱讀器 主要功能包括&#xff1a; ??1.文本自動分塊顯示??&#xff1a;按設定的速度逐詞顯示文本內容。 ??2.閱讀控制??&#xff1a;開始/停止按鈕以及回車鍵控制。 ??3.界面自定義??&#xff1a;包括字體、顏色&#xff08;前景色和背景色&#xff…

PowerBI 條形圖顯示數值和百分比

數據表: 三個度量值 銷售額 VAR Sales SUM(銷量表[銷售量]) RETURNIF(ISBLANK(sales), 0, sales) //希望Y軸顯示所有產品(沒有記錄顯示0)就加這個代碼&#xff0c;不希望顯示就不加//注意, 因為Y軸顯示的產品&#xff0c;會被篩選&#xff0c;所以用ALLSELECTED來獲取當前篩…

python: audioFlux XXCC 提取梅爾頻率倒譜系數 MFCC

承上一篇&#xff1a;python&#xff1a;audioFlux 使用教程 XXCC: 倒譜系數&#xff0c;支持所有頻譜類型. 可以提取梅爾頻率倒譜系數&#xff08;MFCC&#xff09; Cepstrum coefficients, supports all spectrum types. 以下是使用 audioflux 庫中 XXCC 類計算倒譜系數…

為 docker 拉取鏡像配置代理

為 Docker 配置代理&#xff0c;有 兩個層面 的操作&#xff1a;(1) Docker 守護進程&#xff08;用于拉取鏡像等操作&#xff09;&#xff0c;(2) Docker 容器內部&#xff08;容器內應用的網絡流量&#xff09;。 我們這篇文章著重于前者&#xff0c;以下是詳細步驟&#xff…

最新的es版本忘記密碼,重置密碼

剛剛安裝了最新的es版本,就忘了密碼,怎么重置密碼呢? 一、進入es的斌目錄 #進入es文件/bin 目錄 ./elasticsearch-reset-password -u elastic 二 、輸入對應的密碼 然后再次訪問 我的是去掉了ssl的訪問 三、如果報錯:解決 [main] WARN

cursor如何集成MCP服務

本文主要介紹 Cursor IDE 是如何通過 Model Context Protocol (MCP) 服務來增強其功能的。本文將重點介紹兩個核心 MCP 服務的集成&#xff1a;GitHub MCP 服務和 Filesystem MCP 服務。 MCP 服務簡介 MCP&#xff08;Model Context Protocol&#xff09;是一個允許 IDE 與各…

Linux LED驅動(gpio子系統)

0. gpio子系統 gpio子系統是linux內核當中用于管理GPIO資源的一套系統&#xff0c;它提供了很多GPIO相關的API接口&#xff0c;驅動程序中使用GPIO之前需要向gpio子系統申請。 gpio子系統的主要目的就是方便驅動開發者使用gpio&#xff0c;驅動開發者在設備樹中添加gpio相關信息…

go中new和make有什么異同?

相同點&#xff1a;都是給變量分配內存 不同點&#xff1a; 作用類型不同。new通常給int、string、數組類型的變量分配內存&#xff0c;而make通常給slice、map、channel分配內存。返回值類型不同。new返回指向變量的指針&#xff0c;make返回的是變量本身new分配內存空間后&…

C/C++基礎知識點

隨著工作中瑣事越來越多&#xff0c;靜下來好好敲代碼的時間越來越少&#xff0c;基礎知識雖然簡單&#xff0c;但常看常新&#xff0c;并記錄下來共勉。 一、基礎知識點 1. 內存區域中數據管理 在C和C中&#xff0c;內存分為多個區域&#xff0c;每個區域負責存儲不同類型的…

消息中間件kafka,rabbitMQ

在分布式系統中,消息中間件是實現不同組件之間異步通信的關鍵技術。Kafka 和 RabbitMQ 是兩個非常流行的消息中間件系統,它們各自有著不同的特點和應用場景。下面將分別介紹 Kafka 和 RabbitMQ,并討論它們在消息隊列中的使用。 一、Kafka (Apache Kafka) 主要特點: 高吞吐…

2k1000LA , 調試串口改成通信串口, uart.

客戶的問題解決了&#xff0c;但是 調試串口 改成通信串口的問題&#xff0c;并沒有解決&#xff0c;我走的其他的路徑。 先準備一些資料。 以備以后使用。 網上的資料。 總結&#xff1a; 實際上 有幾種思路了。 1 就是更改 設備樹的 chosen 節點&#xff0c; 瑞芯微又單獨…