前言:
在上一講《QT 第七講 --- 控件篇 (二)window系列與qrc機制》中,我們探討了應用程序窗口(QMainWindow
,?QWidget
)的基礎結構、窗口標志、狀態以及Qt強大的資源管理機制(.qrc
文件),這些都是構建應用框架的核心要素。掌握了窗口的宏觀管理后,我們本講將視角聚焦到構成用戶界面的微觀單元——控件(Widgets)本身的外觀與交互細節上。
本次《QT 第八講 --- 控件篇 (三)界面系列》將深入講解如何精細化地定制控件的視覺呈現和用戶體驗。我們將學習如何控制光標(cursor)在控件上的形態,如何設置控件的字體(font)屬性,如何提供即時的信息提示(tooltip),如何管理控件的焦點獲取策略(focusPolicy),以及最強大也最靈活的界面美化工具——樣式表(stylesheet)。這些知識是打造專業、美觀、用戶友好的QT界面的關鍵基石。
目錄
前言:
一、curser
演示一:
演示二:
?演示三:
二、font
演示一:通過圖形化界面的方式來設置。
演示二:通過代碼實現我們的目的
三、tooltip
演示:
四、focusPolicy
演示:
五、stylesheet
演示:
六、一個小程序
總結:
一、curser
我們首先明白curser是鼠標,這個控件正是控制我們的鼠標演示的。
我們下面看一下這個控件對應的API。
函數名 | 函數介紹 |
---|---|
cursor() | 獲取當前 widget 的 cursor 屬性,返回 QCursor 對象,當鼠標懸停在該 widget 上時,會顯示對應的形狀 |
setCursor(const QCursor& cursor) | 設置該 widget 光標的形狀,僅在鼠標停留在該 widget 上時生效 |
QGuiApplication::setOverrideCursor(const QCursor& cursor) | 設置全局光標的形狀,對整個程序中的所有 widget 都會生效,覆蓋上面的 setCursor 設置的內容 |
但是我們也要明白,前兩個函數是Widget 級別的,即同一個界面中,不同的控件可以設置成不同的光標。而最后一個函數是對全局生效的,只是針對的當前的程序。
我們廢話少說,直接演示一下使用方式。
代碼?例: 在 Qt Designer 中設置按鈕的光標
其實就是一些枚舉的值。?
演示一:
1) 在界?中創建?個按鈕.
當然為了代碼效果的演示,我們先創建一個按鈕,觀察鼠標在按鈕上的區別,由于按鈕這個控件是繼承的QWidget,所以我們可以直接在按鈕的圖形化界面上更改。
2) 直接在右側屬性編輯區修改 cursor 屬性為 "等待"?
我們直接運行程序看下效果。
下面我們通過API接口去實習這個效果。
演示二:
代碼?例: 通過代碼設置按鈕的光標
1) 編寫 widget.cpp
其中 Qt::WaitCursor 就是?帶的沙漏形狀的光標.
系統內置的光標形狀如下:
Ctrl + 左鍵 點擊 Qt::WaitCursor 跳轉到源碼即可看到.
下面代碼很好理解,我們就不進行講解了。
代碼:
#include "widget.h"
#include "ui_widget.h"
#include <QPushButton>
Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);QPushButton* button=new QPushButton(this);button->setCursor(Qt::WaitCursor);// button->setCursor(QCursor(Qt::WaitCursor));//由于我們選擇的鼠標圖像時Qt自帶的,上面兩行代碼的效果是一樣的。//但是我們下面講解的自定義的圖標,只能使用第二種方案了。button->resize(300,300);button->move(200,200);button->setText("這是一個切換鼠標圖片的按鈕");}Widget::~Widget()
{delete ui;
}
演示效果:
?
?演示三:
Qt允許我們通過自定義的圖片來設置光標,先準備一個圖片,把圖導入到項目中(qrc管理)
在代碼中訪問到這個圖片,基于這個圖片構造出光標對象并設置就好了。
關于這個qrc機制上一講有介紹,這里就不再贅言了。
這里的圖像我們還是使用上一講的狗頭圖像。?
但是這里的訪問不是像我們上面代碼演示的那樣,我們必須先訪問到這個圖片文件,然后借助這個圖片對象來設置光標。
這里我們的訪問圖片的方式是通過“QPixmap”這個類,具體可以看后面的代碼。
? ? ? ?這個函數的后面兩個參數,是用來控制鼠標的點擊位置。同時如果這兩個參數設置的太大了,Qt會直接擴大鼠標圖標的大小。
同時我們想通過常規方式修改鼠標圖像的大小可以直接模仿下面的偽代碼。
pixmap = pixmap.scaled(100, 100);
通過這個函數對圖片進行縮放,然后再設置進鼠標當中
注意縮放不是修改圖片對象本身,而是返回一個新的圖片對象副本,所以要賦值。
?代碼:
#include "widget.h"
#include "ui_widget.h"
#include <QPushButton>
#include <QCursor>
#include <QPixmap>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);QPushButton* button=new QPushButton(this);QPixmap tmp(":/dog.jpg");tmp=tmp.scaled(20,20);button->setCursor(QCursor(tmp,10,10));button->resize(300,300);button->move(200,200);button->setText("這是一個切換鼠標圖片的按鈕");}Widget::~Widget()
{delete ui;
}
由于截屏軟件無法截取到鼠標,所以我們就不演示了,大家要是有興趣可以直接實驗。
?補充說明:
我們每次想要使用鼠標圖像,還要自己找圖片太挫了,這里推薦一個免費的圖標網站。
iconfont-阿里巴巴矢量圖標庫
二、font
font是什么意思呢?我們直接看一下翻譯。
其實看到字體,我們已經大概猜出來這個屬性的作用了。廢話不多說,font這個屬性就是負責控制文本的字體,大小,粗細程度,傾斜等屬性。
我們下面看一下對應的API和具體的屬性。
API:
?屬性:
屬性 | 說明 |
---|---|
family | 字體家族,比如 "楷體"、"宋體"、"微軟雅黑" 等 |
pointSize | 字體大小 |
不小心多打了一行 | |
weight | 字體粗細,以數值方式表示粗細程度,取值范圍為 [0, 99],數值越大越粗 |
bold | 是否加粗,設置為 true 相當于 weight 為 75,設置為 false 相當于 weight 為 50 |
italic | 是否傾斜 |
underline | 是否帶有下劃線 |
strikeOut | 是否帶有刪除線 |
?上述屬性具體怎么設置,實際開發中,往往有專門的美工/設計/UED來進行確定,但是如果是一些小公司,沒有美工甚至都沒有產品經理,這個情況,咱們作為一個程序員,就可以參考一下別人的程序是怎么安排的,或者別人寫的網頁是怎么安排的。
我們下面直接演示一下,這些屬性的具體表現。
演示一:通過圖形化界面的方式來設置。
演示效果:
QtDesigner能夠對界面的屬性設置支持"實時預覽”,改了啥屬性,這邊就能立即顯示出來
通過屬性編輯這樣的方式,雖然能夠快速方便的修改文字相關的屬性,但是還不夠靈活
如果程序運行過程中,需要修改文字相關的屬性就需要通過代碼來操作了。
演示二:通過代碼實現我們的目的
1) 在界?中創建 label, objectName 使?默認的 label 即可.
2) 修改 widget.cpp
代碼:
#include "widget.h"
#include "ui_widget.h"
#include <QPushButton>
#include <QCursor>
#include <QPixmap>
#include <QFont>
Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);QPushButton* button=new QPushButton(this);QPixmap tmp(":/dog.jpg");tmp=tmp.scaled(20,20);button->setCursor(QCursor(tmp,10,10));button->resize(300,300);button->move(200,200);button->setText("這是一個切換鼠標圖片的按鈕");//這是修改文本屬性的代碼;QFont font;//這是設置字體家族,就是設置字體樣式font.setFamily("微軟雅黑");//設置字體大小font.setPointSize(20);//設置字體是否加粗font.setBold(true);//設置字體是否傾斜font.setItalic(true);//設置字體下劃線font.setUnderline(true);//設置字體刪除線font.setStrikeOut(true);//最后將我們的font設置到我們的Label當中。ui->label_2->setFont(font);
}Widget::~Widget()
{delete ui;
}
3) 運?程序, 觀察效果
三、tooltip
我們還是先看一下這個單詞的含義,我們再去推測這個屬性的作用。
?我們知道當一個GUI程序,界面比較復雜,按鈕啥的很多,這個時候我們把鼠標懸停到這個控件上的時候,就能彈出一個提示。
這個跳出來的文本框就是我們的tooltip的功能。
那我們下面看一下對應的API
?這個屬性的功能還是很簡單的,我們下面直接演示一波。
這里我們使用代碼的方式編寫,目標是在一個小按鈕上跳出提示。
演示:
代碼:
#include "widget.h"
#include "ui_widget.h"
#include <QPushButton>
#include <QCursor>
#include <QPixmap>
#include <QFont>
Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);QPushButton* button=new QPushButton(this);QPixmap tmp(":/dog.jpg");tmp=tmp.scaled(20,20);button->setCursor(QCursor(tmp,10,10));button->resize(300,300);button->move(200,200);button->setText("這是一個切換鼠標圖片的按鈕");//這是修改文本屬性的代碼;QFont font;//這是設置字體家族,就是設置字體樣式font.setFamily("微軟雅黑");//設置字體大小font.setPointSize(20);//設置字體是否加粗font.setBold(true);//設置字體是否傾斜font.setItalic(true);//設置字體下劃線font.setUnderline(true);//設置字體刪除線font.setStrikeOut(true);//最后將我們的font設置到我們的Label當中。ui->label_2->setFont(font);//tooltip的演示代碼QPushButton* button_1=new QPushButton(this);button_1->setToolTip("這是一個簡單的小提示");button_1->setText("小按鈕");
}Widget::~Widget()
{delete ui;
}
效果圖:
注:如果想要使用控制顯示時間的函數,要注意時間單位的轉化關系。
1s = 1000 ms,1ms = 1000 us。?
四、focusPolicy
這個屬性的意思是焦點,就是我們平時在操作電腦的時候,計算機怎么知道我們鍵盤輸入是向誰輸入的呢?就是通過這個屬性。
計算機中的"焦點”,對于鍵盤操作的效果非常明顯,界面上有一個輸入框,此時必須要選中這個輸入框,接下來鍵盤按鍵才會輸入到輸入框中,如果選中的是別的控件,或者別的窗口,此時鍵盤的輸入就不會進入到這個輸入框中。
例如:
這個屬性比較常見的應用就是我們在線筆試防作弊了。?
我們在人家的網頁中去做題,網頁是屬于始終獲取到焦點的狀態的,一旦你切到百度/其他程序(比如VS/IDEA)立刻人家的網頁就能感知到"失去焦點”。服務器就能收集到你這樣的動作
從而衡量你是否涉嫌作弊。
那我們下面來看一下,這個屬性對應的API吧
一般來說,一個控件獲取到焦點,主要是兩種方式1. 鼠標點擊,2. 鍵盤的 tab。
這個兩個函數接口還是很好理解的,我們再來看一下什么是FocusPolicy。
Qt::FocusPolicy 是?個枚舉類型.
取值如下 :
? Qt::NoFocus :控件不會接收鍵盤焦點
? Qt::TabFocus :控件可以通過Tab鍵接收焦點
? Qt::ClickFocus :控件在?標點擊時接收焦點
? Qt::StrongFocus :控件可以通過Tab鍵和?標點擊接收焦點 (默認值)
? Qt::WheelFocus : 類似于 Qt::StrongFocus , 同時控件也通過?標滾輪獲取到焦點 (新增 的選項, ?般很少使?).?
下面我們通過四個輸入框,來演示focusPolicy的效果。?
演示:
效果圖:
我們發現選擇對應選項的文本框,只能接受對應的方式的焦點。
第一個文本框什么方式都不接受,第二個文本框只能使用tab得到焦點,第三個文本框只能是鼠標左鍵,而第四個文本框這是兩種方法都可以。
五、stylesheet
下面終于到了,我們本節博客的最后部分了。
這個屬性就是可以讓我們通過 CSS 設置 widget 的樣式。
CSS (Cascading Style Sheets 層疊樣式表) 本?屬于??前端技術.
主要就是?來描述界?的 樣式. 所謂 "樣式", 包括不限于 ??, 位置, 顏?, 間距, 字體, 背景, 邊框等.
我們平時看到的豐富多彩的??, 就都會?到?量的 CSS.
Qt 雖然是做 GUI 開發, 但實際上和 ??前端 有很多異曲同?之處. 因此 Qt 也引?了對于 CSS 的?持.
CSS 中可以設置的樣式屬性?常多.
基于這些屬性 Qt 只能?持其中?部分, 稱為 QSS (Qt Style Sheet) .
具體的?持情況可以參考 Qt ?檔中 "Qt Style Sheets Reference" 章節. 此處只是進??個簡單的演?.?
和CSS類似.QSS設置的樣式也是鍵值對的格式,鍵和值之間使用:分隔。鍵值對和鍵值對之間,使用;分隔。
另外, Qt Designer 只能對樣式的基本格式進?校驗, 不能檢測出哪些樣式不被 Qt ?持. ?如 textalign: center 這樣的?本居中操作, 就?法?持。
所以我們下面進行一個小的展示。
演示:
這個stylesheet的使用還是很簡單的,我們是直接在designer的界面設置還是直接以硬編碼的方式都是可以的。
由于不好截屏,這里就不對圖形化界面的方式進行解釋,我們明白它是右鍵對應的控件然后找到
“改變樣式表”就好了
這是我們的選擇的樣式結構。
效果圖:
六、一個小程序
在上面結合我們前面學習到的東西,我們現在結合一下,寫個小程序吧,不復雜,就是實現一個夜間模式。
代碼?例: 實現切換夜間模式.
1) 在界?上創建?個多?輸?框 (Text Edit) 和兩個按鈕.
objectName 分別為 pushButton_light 和 pushButton_dark
2) 編寫按鈕的 slot 函數.
這兩個槽函數的作用是切換Widget的顏色,這里我們想要切換顏色,就要使用stylesheet了,我們可以根據這個直接設置顏色
預備知識:#333 是深?, 但是沒那么?. #fff 是純??. ?#000 是純??
演示:
我們發現我們的白天模式,并沒有回到最開始的顏色,這是我們的顏色設置的問題,但是我們如何設置成原來相同的顏色呢?
那我們需要先了解一下關于顯示器顯示顏色的方法。
關于計算機中的顏?表? 計算機中使? "像素" 表?屏幕上的?個基本單位(也就是?個發亮的光點).
每個光點都使?三個字節表?顏?, 分別是 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 ?深等, 實際情況會更加復雜
所以我們只要得知原來顏色的rgb是多少就可以了。如何獲取呢,我們可以通過QQ截圖自帶的取色器獲取。?
這樣我們就知道了,不過這里,博主就不再演示在博客里了。
代碼:
#include "widget.h"
#include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);
}Widget::~Widget()
{delete ui;
}void Widget::on_pushButton_dark_clicked()
{//我們的夜間模式,是不是要把我們的除文字以外的地方改變成黑色,文字變為白色。this->setStyleSheet("background-color: #333");ui->textEdit->setStyleSheet("background-color: #333; color: #fff;");//backgroud-color是指的是控件的背景色,而color是值指的是文字的顏色。ui->pushButton_light->setStyleSheet("color: #fff");ui->pushButton_dark->setStyleSheet("color: #fff");
}void Widget::on_pushButton_light_clicked()
{this->setStyleSheet("background-color: #f3f3f3");ui->textEdit->setStyleSheet("background-color: #fff; color: #000;");ui->pushButton_light->setStyleSheet("color: #000");ui->pushButton_dark->setStyleSheet("color: #000");
}
千萬要注意這里的單詞拼寫,這里如果拼寫出錯,不會有任何報錯,但是樣式會不生效!?
總結:
至此,我們完成了《QT 第八講 --- 控件篇 (三)界面系列》的學習。我們詳細探討了如何通過cursor
、font
、tooltip
、focusPolicy
以及強大的stylesheet
來全方位地定制控件的外觀、提示信息、交互行為和視覺效果。這些技術點賦予了我們精確控制用戶界面細節的能力,是提升應用專業度和用戶體驗不可或缺的部分。
掌握了這些界面定制的基礎后,我們將在下一講《QT 第九講 --- 控件篇 (四)button》中,聚焦于用戶交互中最頻繁使用的控件之一——按鈕(QPushButton
及其變種)。我們將深入探討按鈕的各種狀態、信號、常用功能以及如何利用本講所學知識(特別是樣式表)來創建形態各異、功能豐富的按鈕,實現更生動的用戶交互體驗。
我們下期見!