目錄
QWidget核心屬性
enab
geometry
WindowFrame的影響
windowTitle
windowIcon
qrc文件管理資源
windowOpacity
cursor
font
toolTip
focusPolicy
styleSheet
QWidget核心屬性
在Qt中使用QWidget類表示"控件",如按鈕、視圖、輸入框、滾動條等具體的控件類,都是繼承自Qwidget。可以認為QWidget中包含了Qt整個控件體系中的通用部分。
可以說,,QWidget 中就包含了Qt整個控件體系中,通用的部分。
在 Qt Designer 中,隨便拖?個控件過來,選中該控件,即可在右下方看到QWidget中的屬性:
解釋說明:
- 這些屬性既可以通過 QtDesigner 會直接修改, 也可以通過代碼的方式修改。
- 這些屬性的具體含義,在 Qt Assistant 中均有詳細介紹。
- 在 Qt Assistant 中搜索 QWidget,即可找到對應的文檔說明(或者在 Qt Creator 代碼中,選中QWidget,按 F1 也可以)
核心屬性概覽
屬性 | 作用 |
enabled | 設置控件是否可用(true為可用,false為禁用) |
geometry | 位置和尺寸,包含x、y、width、height四個部分 其中坐標是以父元素為參考進行設置的 |
windowTitle | 設置widget標題 |
windowIcon | 設置widget圖標 |
windowOpacity | 設置widget的不透明度 |
cursor | 設置鼠標懸停時顯示的圖標 |
font | 字體相關屬性 涉及到字體家族、字體大小、粗體、斜體、下劃線 |
toolTip | 鼠標懸停在widget上會在狀態欄中顯示的提示信息 |
toolTipDuring | toolTip顯示的持續時間 |
statusTip | widget狀態發生改變時顯示的提示信息(如按鈕被按下) |
whatsThis | 鼠標懸停并按下alt + F1時,顯示的幫助信息(顯示在一個彈出的窗口中) |
styleSheet | 允許使用CSS來設置widget的樣式 Qt 中支持的樣式非常豐富, 對于前端開發人員上手是非常友好的 |
focusPolicy | 該widget如何獲取到焦點 Qt::NoFocus:控件不參與焦點管理,即無法通過鍵盤或鼠標獲取焦點 Qt::TabFocus:控件可以通過Tab鍵獲得焦點 Qt::ClickFocus:控件可以通過鼠標點擊獲得焦點 Qt::StrongFocus:控件可以通過鍵盤和鼠標獲得焦點 Qt::WheelFocus:控件可以通過鼠標滾輪獲得焦點(在某些平臺或樣式中可能不可用) |
contextMenuPolicy | 上下文菜單的顯示策略 Qt::DefaultContextMenu:默認的上下文菜單策略,用戶可以通過鼠標右鍵或鍵盤快捷鍵觸發上下文菜單 Qt::NoContextMenu:禁用上下文菜單,即使用戶點擊鼠標右鍵也不會顯示菜單 Qt::PreventContextMenu:防止控件顯示上下文菜單,即使用戶點擊鼠標右鍵也不會顯示菜單 Qt::ActionsContextMenu:將上下文菜單替換為控件的“動作”菜單,用戶可以通過鼠標右鍵或鍵盤快捷鍵觸發這個菜單 Qt::CustomContextMenu:使用自定義的上下文菜單,用戶可以通過鼠標右鍵或鍵盤快捷鍵觸發這個菜單 |
locale | 設置語言與國家地區 |
acceptDrops | 該部件是否接受拖放操作。 若設置為true,那么該部件就可以接收來自其他部件的拖放操作。當一個部件被拖放到該部件上時,該部件會接收到相應的接收事件(如dropEvent)。 若設置為false,那么該部件不會接收任何拖放操作。 |
minimumSize | 控件最小尺寸,包括最小寬度與最小高度 |
maximumSize | 控件最大尺寸,包括最大寬度和最大高度 |
sizePolicy | 尺寸策略,控制控件在布局管理器中的縮放方式 |
windowModality | 指定窗口是否具有"模態"行為 |
sizeIncrement | 拖動窗口大小時的增量單位 |
baseSize | 窗口的基礎大小,用來搭配sizeIncrement調整組件尺寸是計算組件應該調整到的合適的值 |
palette | 調色板,可以設置widget的顏色風格 |
mouseTracking | 是否要跟蹤鼠標移動事件。 如果設為 true,標識需要跟蹤,則鼠標劃過的時候該widget就能持續收到鼠標移動事件。 如果設為 false,表示不需要跟蹤,則鼠標劃過的時候 widget 不會收到?標移動事件,只能收到鼠標按下或者釋放的事件。 |
tableTracking | 是否跟蹤觸摸屏的移動事件 類似于 mouseTracking,Qt 5.9 中引入的新屬性 |
layoutDirection | 布局方向 Qt::LeftToRight:文本從左到右排列(默認值) Qt::RightToLeft:文本從右到左排列 Qt::GlobalAtomics:部件的布局方向由全局原子性決定(即根據應用程序中的其他的widget布局方向確定) |
autoFillBackground | 是否自動填充背景顏色 |
windowFilePath | 能夠把widget和一個本地文件路徑關聯起來 |
accessibleName | 設置widget的可訪問名稱(該名稱可被輔助技術讀取) 該屬性用于實現無障礙程序的場景 |
accessibleDescription | 設置widget的詳細描述(作同accessibleName) |
inputMethodHints | 針對輸入框有效,用來提示用戶當前能輸入的合法數據的格式(如只能輸入數字、只能輸入日期等) |
下面介紹一些常用的屬性,沒有介紹到的可以自行查閱文檔
enable
API | 說明 |
isEnabled() | 獲取控件的可用狀態 |
setEnabled() | 設置控件是否可用,true表示可用,false表示禁用 |
說明:
- "禁用"是指該控件不能接收任何用戶的輸入事件,并且外觀往往是灰色的
- 若一個widget被禁用,則該widget的子元素也被禁用
代碼示例:設置一個按鈕的初始狀態為禁用,另一個按鈕用于切換該按鈕的狀態
widget.h:
#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>
#include <QPushButton>
#include <QDebug>QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();void Handle();void Change();private:Ui::Widget *ui;QPushButton* btn1;QPushButton* btn2;
};
#endif // WIDGET_H
#include "widget.h"
#include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);btn1 = new QPushButton("按鈕", this);btn1->move(200, 200);btn1->setEnabled(false);btn2 = new QPushButton("切換可用狀態", this);btn2->move(200, 400);connect(btn1, &QPushButton::clicked, this, &Widget::Handle);connect(btn2, &QPushButton::clicked, this, &Widget::Change);
}Widget::~Widget()
{delete ui;
}void Widget::Handle()
{qDebug() << "點擊按鈕成功";
}void Widget::Change()
{if(btn1->isEnabled()) btn1->setEnabled(false);else btn1->setEnabled(true);qDebug() << "切換狀態成功";
}
geometry
位置和尺寸,其實是四個屬性的統稱:x橫坐標、y縱坐標、width寬度、height高度
API | 說明 |
geometry | 獲取控件的位置和尺寸。返回結果是一個QRect,包含了x、y、width、height,其中x、y是左上角的坐標 |
setGeometry(QRect) setGeometry(int x, int y, int width, int height) | 設置控件的位置和尺寸,可以直接設置一個QRect,也可以各個屬性單獨設置 |
代碼示例:通過四個按鈕分別控制一個按鈕上下左右移動
#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_pushButtonRight_clicked()
{QRect rect = ui->pushButtonTarget->geometry();rect.setX(rect.x() + 5);ui->pushButtonTarget->setGeometry(rect);
}void Widget::on_pushButtonUp_clicked()
{QRect rect = ui->pushButtonTarget->geometry();rect.setY(rect.y() - 5);ui->pushButtonTarget->setGeometry(rect);
}void Widget::on_pushButtonLeft_clicked()
{QRect rect = ui->pushButtonTarget->geometry();rect.setX(rect.x() - 5);ui->pushButtonTarget->setGeometry(rect);
}void Widget::on_pushButtonDown_clicked()
{QRect rect = ui->pushButtonTarget->geometry();rect.setY(rect.y() + 5);ui->pushButtonTarget->setGeometry(rect);
}
運行程序可以發現,按下四個按鈕,就會控制target的左上角的位置,對應的按鈕整個尺寸也會發生改變。上述代碼中是直接設置的QRect中的x、y,實際上QRect內部存儲了左上和右下兩個點的坐標,再通過兩個點的坐標差值計算長寬,單純修改左上坐標就會引起整個矩形的長寬發生改變。
class Q_CORE_EXPORT QRect
{
public:Q_DECL_CONSTEXPR QRect() noexcept : x1(0), y1(0), x2(-1), y2(-1) {}Q_DECL_CONSTEXPR QRect(const QPoint &topleft, const QPoint &bottomright) noexcept;Q_DECL_CONSTEXPR QRect(const QPoint &topleft, const QSize &size) noexcept;Q_DECL_CONSTEXPR QRect(int left, int top, int width, int height) noexcept;Q_DECL_CONSTEXPR inline bool isNull() const noexcept;Q_DECL_CONSTEXPR inline bool isEmpty() const noexcept;Q_DECL_CONSTEXPR inline bool isValid() const noexcept;Q_DECL_CONSTEXPR inline int left() const noexcept;Q_DECL_CONSTEXPR inline int top() const noexcept;Q_DECL_CONSTEXPR inline int right() const noexcept;Q_DECL_CONSTEXPR inline int bottom() const noexcept;Q_REQUIRED_RESULT QRect normalized() const noexcept;Q_DECL_CONSTEXPR inline int x() const noexcept;Q_DECL_CONSTEXPR inline int y() const noexcept;Q_DECL_RELAXED_CONSTEXPR inline void setLeft(int pos) noexcept;Q_DECL_RELAXED_CONSTEXPR inline void setTop(int pos) noexcept;Q_DECL_RELAXED_CONSTEXPR inline void setRight(int pos) noexcept;Q_DECL_RELAXED_CONSTEXPR inline void setBottom(int pos) noexcept;Q_DECL_RELAXED_CONSTEXPR inline void setX(int x) noexcept;Q_DECL_RELAXED_CONSTEXPR inline void setY(int y) noexcept;Q_DECL_RELAXED_CONSTEXPR inline void setTopLeft(const QPoint &p) noexcept;Q_DECL_RELAXED_CONSTEXPR inline void setBottomRight(const QPoint &p) noexcept;Q_DECL_RELAXED_CONSTEXPR inline void setTopRight(const QPoint &p) noexcept;Q_DECL_RELAXED_CONSTEXPR inline void setBottomLeft(const QPoint &p) noexcept;Q_DECL_CONSTEXPR inline QPoint topLeft() const noexcept;Q_DECL_CONSTEXPR inline QPoint bottomRight() const noexcept;Q_DECL_CONSTEXPR inline QPoint topRight() const noexcept;Q_DECL_CONSTEXPR inline QPoint bottomLeft() const noexcept;Q_DECL_CONSTEXPR inline QPoint center() const noexcept;Q_DECL_RELAXED_CONSTEXPR inline void moveLeft(int pos) noexcept;Q_DECL_RELAXED_CONSTEXPR inline void moveTop(int pos) noexcept;Q_DECL_RELAXED_CONSTEXPR inline void moveRight(int pos) noexcept;Q_DECL_RELAXED_CONSTEXPR inline void moveBottom(int pos) noexcept;Q_DECL_RELAXED_CONSTEXPR inline void moveTopLeft(const QPoint &p) noexcept;Q_DECL_RELAXED_CONSTEXPR inline void moveBottomRight(const QPoint &p) noexcept;Q_DECL_RELAXED_CONSTEXPR inline void moveTopRight(const QPoint &p) noexcept;Q_DECL_RELAXED_CONSTEXPR inline void moveBottomLeft(const QPoint &p) noexcept;Q_DECL_RELAXED_CONSTEXPR inline void moveCenter(const QPoint &p) noexcept;Q_DECL_RELAXED_CONSTEXPR inline void translate(int dx, int dy) noexcept;Q_DECL_RELAXED_CONSTEXPR inline void translate(const QPoint &p) noexcept;Q_REQUIRED_RESULT Q_DECL_CONSTEXPR inline QRect translated(int dx, int dy) const noexcept;Q_REQUIRED_RESULT Q_DECL_CONSTEXPR inline QRect translated(const QPoint &p) const noexcept;Q_REQUIRED_RESULT Q_DECL_CONSTEXPR inline QRect transposed() const noexcept;Q_DECL_RELAXED_CONSTEXPR inline void moveTo(int x, int t) noexcept;Q_DECL_RELAXED_CONSTEXPR inline void moveTo(const QPoint &p) noexcept;Q_DECL_RELAXED_CONSTEXPR inline void setRect(int x, int y, int w, int h) noexcept;Q_DECL_RELAXED_CONSTEXPR inline void getRect(int *x, int *y, int *w, int *h) const;Q_DECL_RELAXED_CONSTEXPR inline void setCoords(int x1, int y1, int x2, int y2) noexcept;Q_DECL_RELAXED_CONSTEXPR inline void getCoords(int *x1, int *y1, int *x2, int *y2) const;Q_DECL_RELAXED_CONSTEXPR inline void adjust(int x1, int y1, int x2, int y2) noexcept;Q_REQUIRED_RESULT Q_DECL_CONSTEXPR inline QRect adjusted(int x1, int y1, int x2, int y2) const noexcept;Q_DECL_CONSTEXPR inline QSize size() const noexcept;Q_DECL_CONSTEXPR inline int width() const noexcept;Q_DECL_CONSTEXPR inline int height() const noexcept;Q_DECL_RELAXED_CONSTEXPR inline void setWidth(int w) noexcept;Q_DECL_RELAXED_CONSTEXPR inline void setHeight(int h) noexcept;Q_DECL_RELAXED_CONSTEXPR inline void setSize(const QSize &s) noexcept;QRect operator|(const QRect &r) const noexcept;QRect operator&(const QRect &r) const noexcept;inline QRect& operator|=(const QRect &r) noexcept;inline QRect& operator&=(const QRect &r) noexcept;bool contains(const QRect &r, bool proper = false) const noexcept;bool contains(const QPoint &p, bool proper=false) const noexcept;inline bool contains(int x, int y) const noexcept;inline bool contains(int x, int y, bool proper) const noexcept;Q_REQUIRED_RESULT inline QRect united(const QRect &other) const noexcept;Q_REQUIRED_RESULT inline QRect intersected(const QRect &other) const noexcept;bool intersects(const QRect &r) const noexcept;Q_DECL_CONSTEXPR inline QRect marginsAdded(const QMargins &margins) const noexcept;Q_DECL_CONSTEXPR inline QRect marginsRemoved(const QMargins &margins) const noexcept;Q_DECL_RELAXED_CONSTEXPR inline QRect &operator+=(const QMargins &margins) noexcept;Q_DECL_RELAXED_CONSTEXPR inline QRect &operator-=(const QMargins &margins) noexcept;#if QT_DEPRECATED_SINCE(5, 0)Q_REQUIRED_RESULT QT_DEPRECATED QRect unite(const QRect &r) const noexcept { return united(r); }Q_REQUIRED_RESULT QT_DEPRECATED QRect intersect(const QRect &r) const noexcept { return intersected(r); }
#endiffriend Q_DECL_CONSTEXPR inline bool operator==(const QRect &, const QRect &) noexcept;friend Q_DECL_CONSTEXPR inline bool operator!=(const QRect &, const QRect &) noexcept;#if defined(Q_OS_DARWIN) || defined(Q_QDOC)Q_REQUIRED_RESULT CGRect toCGRect() const noexcept;
#endifprivate:int x1;int y1;int x2;int y2;
};
下面的代碼可以正常實現功能
#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_pushButtonRight_clicked()
{QRect rect = ui->pushButtonTarget->geometry();ui->pushButtonTarget->setGeometry(rect.x() + 5, rect.y(), rect.width(), rect.height());
}void Widget::on_pushButtonUp_clicked()
{QRect rect = ui->pushButtonTarget->geometry();ui->pushButtonTarget->setGeometry(rect.x(), rect.y() - 5, rect.width(), rect.height());
}void Widget::on_pushButtonLeft_clicked()
{QRect rect = ui->pushButtonTarget->geometry();ui->pushButtonTarget->setGeometry(rect.x() - 5, rect.y(), rect.width(), rect.height());
}void Widget::on_pushButtonDown_clicked()
{QRect rect = ui->pushButtonTarget->geometry();ui->pushButtonTarget->setGeometry(rect.x(), rect.y() + 5, rect.width(), rect.height());
}
WindowFrame的影響
若widget作為?個窗口(帶有標題欄,最小化,最大化,關閉按鈕),那么在計算尺寸和坐標時就有兩種算法:包含window frame和不包含window frame
若一個不是作為窗口的widget,上述兩類方式得到的結果是一致的
API | 說明 |
x() | 獲取橫坐標 計算時包含window frame |
y() | 計算縱坐標 計算時包含window frame |
pos() | 返回QPoint對象,包含x()、y()、setX()、setY()等方法 計算時包含window frame |
frameSize() | 返回QSize對象,里面包含width()、height()、setWidth()、setHeight()等方法 計算時包含window frame |
frameGeometry() | 返回QRect對象,QRect相當于QPoint和QSize的結合體,可以獲取x、y、width、size 計算時包含window frame對象 |
------ | ------------------ |
width() | 獲取寬度,計算時不包含window frame |
height() | 獲取高度,計算時不包含window frame |
size() | 返回QSize對象,里面包含width()、height()、setWidth()、setHeight()等方法 計算時不包含window frame |
rect() | 返回QRect對象,計算時不包含window frame |
geometry() | 返回QRect對象,計算時不包含window frame |
setGeometry() | 直接設置窗口的位置和尺寸,可以設置x、y、width、height,或者QRect對象 計算時不包含window frame |
代碼示例:感受geometry()和frameGeometry()的區別
#include "widget.h"
#include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);QRect rect1 = this->geometry();QRect rect2 = this->frameGeometry();qDebug() << rect1;qDebug() << rect2;QPushButton* btn = new QPushButton("按鈕", this);connect(btn, &QPushButton::clicked, this, &Widget::Handle);
}Widget::~Widget()
{delete ui;
}void Widget::Handle()
{QRect rect1 = this->geometry();QRect rect2 = this->frameGeometry();qDebug() << rect1;qDebug() << rect2;
}
執行程序可以發現,構造函數中打印出的geometry和frameGeometry是相同的。但在點擊按鈕時,打印的geometry和frameGeometry則存在差異。
注意:
在構造方法中,widget剛剛創建出來,還沒有加入到對象樹中。此時也就不具備Window frame
在按鈕的slot函數中,由于用戶點擊時,對象樹已經構造好了,此時widget已經具備了Window frame,因此在位置和尺寸上均出現了差異。
windowTitle
API | 說明 |
windowTitle() | 獲取到控件的窗口標題 |
setWindowTitle(const?Qstring& title) | 設置控件的窗口標題 |
注意:上述設置操作針對不同的widget可能會有不同的行為。若是頂層widget(獨立窗口),這個操作才會有效;若是子widget,這個操作無任何效果
代碼示例:設置窗口標題
#include "widget.h"
#include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);setWindowTitle("窗口標題");QPushButton* btn = new QPushButton("按鈕", this);btn->setWindowTitle("按鈕標題");//無作用,不報錯
}Widget::~Widget()
{delete ui;
}
windowIcon
API | 說明 |
windowIcon() | 獲取到控件的窗口標題,返回QIcon對象 |
setWindowIcon(const QIcon& icon) | 設置控件的窗口標題 |
注意:同windowTitle,上述操作僅針對頂層widget有效
代碼示例:設置窗口圖標
先在D盤放置一張圖片,名為rose.png
#include "widget.h"
#include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);QIcon icon("D:/rose.png");this->setWindowIcon(icon);
}Widget::~Widget()
{delete ui;
}
注意:Windows下路徑的分隔符可以使用 / 也可以使用?\ ,但是若在字符串中使用?\ ,需要寫
作轉義字符的形式?\\ ,因此還是更推薦使用?/
推薦:尋找Icon圖片,iconfont-阿里巴巴矢量圖標庫
存在問題
實際開發中,?般不會在代碼中通過絕對路徑引入圖片,因為無法保證程序發布后,用戶的電腦上也有同樣的路徑。若使用相對路徑,則需要確保代碼中的相對路徑寫法和圖片實際所在的路徑匹配(如代碼中寫作"./image/rose.png",就需在當前工作目錄中創建image目錄,并將rose.png放入)
若將圖片文件放入構建目錄中,可能在不小心刪除后就丟失了。還是希望能夠將圖片和源代碼放到一起,并且使我們的程序無論移動到任何位置中都能正確使用圖片。Qt使用qrc機制自動完成了上述工作,更方便的來管理項目依賴的靜態資源。
qrc文件管理資源
qrc文件是?種XML格式的資源配置文件,用XML記錄硬盤上的文件和對應的隨意指定的資源名稱,應用程序通過資源名稱來訪問這些資源。
在Qt開發中,可以通過將資源文件添加到項目中來方便地訪問和管理這些資源,這些資源文件可以位于qrc文件所在目錄的同級或其子目錄下。
在構建程序的過程中,Qt會把資源文件的二進制數據轉成cpp代碼,編譯到exe中,從而使依賴的資源變得"路徑無關"。
這種資源管理機制并非Qt獨有,很多開發框架都有類似的機制。如Android的Resources和AssetManager也是類似的效果。
示例:通過qrc管理圖片作為圖標
右鍵項目,創建一個Qt Resource File(qrc文件),文件名任意(不要帶中文),此處取名為resource.qrc
在qrc編輯器中,添加前綴,此處將前綴設置成?/ 即可
前綴可以理解成"目錄",這個前綴決定了后續如何在代碼中訪問資源
在資源編輯器中,點擊add Files添加資源文件,此處需要添加的是rose.png
注意:添加的文件必須是在qrc文件的同級目錄,或者同級目錄的子目錄中,因此需要把之前D盤中的rose.png復制到上述目錄中
添加完畢后,可以在資源編輯器中看到添加好的文件
在代碼中使用rose.png
#include "widget.h"
#include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);QIcon icon(":/001.png");this->setWindowIcon(icon);
}Widget::~Widget()
{delete ui;
}
上述路徑的訪問規則:
- 使用:作為開頭,表示從qrc中讀取資源
- /是上面配置的前綴
- rose.png是資源的名稱
需確保代碼中編寫的路徑和添加到qrc中資源的路徑匹配,否則資源無法被訪問(同時也不會有報錯提示)
優缺點:
- 優點:確保了圖片、字體、聲音等資源能夠真正的"目錄無關",不會出現資源丟失的情況
- 缺點:不適合管理體積大的資源,若資源較大(如是幾個MB的問價),或者資源特別多,生成的最終的exe體積就會較大,程序運行消耗的內存也會增大,程序編譯的時間也會顯著增加
windowOpacity
API | 說明 |
windowOpacity() | 獲取控件的不透明值,返回類型為float,取值在0.0~1.0之間,0.0表示全透明,1.0表示完全不透明 |
setWindowOpacity(float n) | 設置控件的不透明值 |
代碼示例:兩個按鈕控制窗口的不透明度
#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_pushButtonAdd_clicked()
{float opacity = this->windowOpacity();if(opacity >= 1.0) return;else this->setWindowOpacity(opacity + 0.1);qDebug() << opacity + 0.1;
}void Widget::on_pushButtonSub_clicked()
{float opacity = this->windowOpacity();if(opacity <= 0.0) return;else this->setWindowOpacity(opacity - 0.1);qDebug() << opacity - 0.1;
}
注意:C++中float類型遵守IEEE?754標準,因此在進行運算時會有?定的精度誤差,因此1?- 0.1的數值并非是0.9
cursor
API | 說明 |
cursor() | 獲取當前widget的cursor屬性,返回QCursor對象 當鼠標懸停在該widget上時就會顯示出對應的形狀 |
setCursor(const QCursor& cursor) | 設置該widget光標的形狀,僅在鼠標停留在該widget上時生效 |
QGuiApplication::setOverrideCursor(const QCursor& cursor) | 設置全局光標的形狀,對整個程序中的所有widget生效,覆蓋之前setCursor設置的內容 |
在Qt Designer中設置按鈕的光標
在界面中創建一個按鈕
直接在右側屬性編輯區修改cursor屬性為"等待"
運行程序,鼠標懸停到按鈕上,即可看到光標的變化
代碼示例:通過代碼設置按鈕的光標
#include "widget.h"
#include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);QCursor cursor(Qt::WaitCursor);ui->pushButton->setCursor(cursor);
}Widget::~Widget()
{delete ui;
}
代碼示例:自定義鼠標光標?
#include "widget.h"
#include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);// 創建?個位圖對象, 加載?定義光標圖?QPixmap pixmap(":/rose.png");// 縮放圖?為 64 * 64 的尺?pixmap = pixmap.scaled(64, 64);// 創建 QCursor 對象, 并指定 "熱點" 為 (2, 2) 坐標位置// 所謂 "熱點" 就是?標點擊時?效的位置QCursor cursor(pixmap, 2, 2);// 設置光標this->setCursor(cursor);
}Widget::~Widget()
{delete ui;
}
font
API | 說明 |
font() | 獲取當前widget的字體信息,返回QFont對象 |
setFont(const QFont& font) | 設置當前的widget的字體信息 |
關于QFont的屬性
屬性 | 說明 |
family | 字體家族,如"楷體"、"宋體"、"微軟雅黑"等 |
pointSize | 字體大小 |
weight | 字體粗細,以數值的方式表示粗細的范圍[0, 99],數值越大越粗 |
bold | 是否加粗。若設置為true,相當于weight為75;若設置為false,weight為20 |
italic | 是否傾斜 |
underline | 是否帶有下劃線 |
strikeOut | 是否帶有刪除線 |
在Qt Designer中設置字體屬性
在界面上創建一個label
在右側的屬性編輯區,設置該label的font相關屬性(在這調整上述屬性,可以實時看到文字的變化)
執行程序,觀察效果
代碼示例:在代碼中設置字體屬性
#include "widget.h"
#include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);// 設置 label 的?本內容ui->label->setText("這是?段?本");// 創建字體對象QFont font;// 設置字體家族font.setFamily("仿宋");// 設置字體??font.setPointSize(20);// 設置字體加粗font.setBold(true);// 設置字體傾斜font.setItalic(true);// 設置字體下劃線font.setUnderline(true);// 設置字體刪除線font.setStrikeOut(true);// 設置字體對象到 label 上ui->label->setFont(font);
}Widget::~Widget()
{delete ui;
}
toolTip
API | 說明 |
setToolTip | 設置toolTip 鼠標懸停在該widget上時會有提示說明 |
setToolTipDuration | 設置toolTip的提示時間,單位ms 時間到后toolTip自動消失 |
toolTip只是給用戶看的,在代碼中?般不需要獲取到toolTip,但是使用toolTip()一樣可以獲取
代碼示例:設置按鈕的toolTip
#include "widget.h"
#include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);QPushButton* btn1 = new QPushButton("Yes", this);btn1->setToolTip("這是一個Yes按鈕");btn1->setToolTipDuration(3000);QPushButton* btn2 = new QPushButton("No", this);btn2->move(100, 100);btn2->setToolTip("這是一個No按鈕");btn2->setToolTipDuration(7000);
}Widget::~Widget()
{delete ui;
}
focusPolicy
設置控件獲取到焦點的策略,如某個控件能否用鼠標選中或者能否通過tab鍵選中
所謂"焦點"指的就是能選中這個元素,接下來的操作(如鍵盤操作)就都是針對該焦點元素進行的
了。這個屬性對于輸?框、單選框、復選框等控件非常有用。
API | 說明 |
focusPolicy() | 獲取該widget的focusPolicy,返回Qt::FocusPolicy |
setFocusPolicy(Qt::FocusPolicy policy) | 設置widget的focusPolicy |
Qt::FocusPolicy是一個枚舉類型,取值如下:
- Qt::NoFocus:控件不會接收鍵盤焦點
- Qt::TabFocus:控件可以通過Tab鍵接收焦點
- Qt::ClickFocus:控件在鼠標點擊時接收焦點
- Qt::StrongFocus:控件可以通過Tab鍵和鼠標點擊接收焦點(默認值)
- Qt::WheelFocus:類似于Qt::StrongFocus,同時控件也通過鼠標滾輪獲取到焦點(新增的選項,一般很少使用)
styleSheet
CSS(Cascading Style Sheets層疊樣式表)本身屬于網頁前端技術。主要用來描述界面的樣式
所謂"樣式",包括不限于大小、位置、顏色、間距、字體、背景、邊框等
Qt雖然是做GUI開發,但實際上和網頁前端有很多異曲同工之處。因此Qt也引如了對CSS的支持
CSS中可以設置的樣式屬性非常多,Qt只能支持其中一部分,稱為QSS(Qt Style Sheet)
具體的支持情況可以參考Qt文檔中"Qt Style Sheets Reference"章節
示例:設置文本樣式
在界面上創建label
編輯右側的styleSheet屬性,設置樣式
- 此處的語法格式同CSS,使用鍵值對的方式設置樣式,其中鍵和值之間使用?:?分割,鍵值對之間使用?;?分割
- Qt Designer只能對樣式的基本格式進行校驗,不能檢測出哪些樣式不被Qt支持
代碼示例:實現日夜間模式切換
#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_pushButtonLight_clicked()
{this->setStyleSheet("background-color: #f3f3f3");ui->textEdit->setStyleSheet("background-color: #fff; color: #000;");ui->pushButtonLight->setStyleSheet("color: #000");ui->pushButtonDark->setStyleSheet("color: #000");
}void Widget::on_pushButtonDark_clicked()
{this->setStyleSheet("background-color: #333");ui->textEdit->setStyleSheet("background-color: #333; color: #fff;");ui->pushButtonLight->setStyleSheet("color: #fff");ui->pushButtonDark->setStyleSheet("color: #fff");
}
關于計算機中的顏色表示
計算機中使用"像素"表示屏幕上的?個基本單位(也就是?個發亮的光點)
每個光點都使用三個字節表示顏色,分別是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色深等, 實際情況會更加復雜