0、說明
QWidget類是所有用戶界面對象的基類。
QWidget是用戶界面的原子類。它接收鼠標、鍵盤和來自系統的其他事件,並在屏幕上將它們繪制出來。每個Widget都是矩形的,並按照Z-order(Z軸)進行排序。一個Widget夾在它的Parent和它前面的Widget之間。
沒有嵌入parent widget中的Widget稱為Window。通常情況下,Windows有一個Frame和標題欄(當然也可以通過window flags來取消這些項)。Qt中,QMainWindow和QDialog的多種多樣的子類是最常見的Window類型。
每個Widget的構造函數接收一或兩個參數:
- QWidget *parent = nullptr:新Widget的Parent。如果它是nullptr(這也是默認選項),那么新Widget將會是一個Window;如果不是,那么它將成為parent的子孫,並且將限制在parent的幾何空間內(除非指明Qt::Window為Window Flag)。
- Qt::WindowFlags f = { } :Window Flags。實際上默認的參數已經滿足絕大多數Widget了;不過一些特殊情況下,例如產生一個不需要Frame的Window時,我們需要一些特殊的Flags。
QWidget有許多成員函數,但是其中一些幾乎沒有直接功能;例如,QWidget有一個font屬性,但是它自己從不使用它。也有許多子類提供了真實的功能,如QLabel, QPushButton, QListWidget 和 QTabWidget
1)頂層(Top-Level)和子Widget
沒有Parent的Widget是獨立Window(頂層Widget)。對於這類Widget,setWindowTitle() 可以用 setWindowIcon()來設置標題和圖標。
非Window Widget(有Parent)是子Widget,它在Parent Widget中顯示。Qt中的大多數Widget都是作為子Widget應用的。例如,QLabel, QPushButton等小的常見控件。
上圖展示了QGroupBox Widget,它用於承接多種子Widget,這些子Widget通過QGridLayout進行布局。QLabel被紅框框中指示它們的完整大小。
如果你想用一個QWidget來保留子Widget,我們通常需要往Parent Widget中添加布局,方法見Layout Management。
2)組合Widget
當一個Widget被用於一組Child Widgets組合的容器時,它被視為一個組合Widget。可以在Qt Designer中很方便地構造一個組合Widget。
還可以在創造Widget時指定Layout和Child Widget,來構造組合Widget。許多Qtl例子都用到了這種方法(examples provided with Qt),這些在Qt教程(Tutorials.)中也有提到。
3)定制Widget與繪制
由於QWidget是QPaintDevice的子類,所以Child Widget可以用QPainter對象來自定義繪制內容。
每個Widget都從它的paintEvent()函數中執行全部繪圖操作。每當Widget需要重繪,比如一些外部改變或內部應用請求,都會調用它。
一個例子:Analog Clock example展示了一個Widget如何處理繪圖事件。
4)大小提示與大小策略
當實現一個新Widget時,通常用sizeHint()來設置Widget的默認大小;用setSizePolicy()來設置正確的大小策略。
默認情況下,沒有給出大小提示的組合Widget的大小將根據其Child Widget的控件需要來自適應。
大小策略給我們提供了用於布局管理的默認行為,這樣其他的Widgets就能很方便地管理我們的Widgets。默認的大小策略指示了Widget合適的大小,而且對大多數Widgets來說都是夠用的。
注意:
頂層Widget的大小限制為桌面長寬的2/3。如果嫌不合適,可以用resize()來手動修改Widget大小。
5)事件
Widget通過調用QEvent規定的函數來處理事件。
如果我們的Widget只包含了Child Widgets,那么通常情況下我們不需要實現任何事件響應。如果我們想檢測Child Widget中的鼠標點擊,可以在Widget的mousePressEvent()中調用Child的underMouse()函數。
例子:Scribble example實現了更廣泛的事件集合來處理鼠標移動、按鈕按下、窗口大小重定義。
我們需要為我們的Widgets提供行為和內容,以下是與QWidget相關的事件的概述:
鼠標
- paintEvent():每當Widget需要重繪時調用;每個展示自定義內容的Widget必須實現該方法。QPainter的繪制只能用於paintEvent()或被paintEvent()調用的函數中;
- resizeEvent():每當窗口大小重定義時調用該方法;
- mousePressEvent():每當鼠標光標在Widget中並且被按下時、或者每當Widget通過grabMouse()抓取鼠標時使用該方法。此外,按住鼠標不放開時,和調用grabMouse()的效果相同;
- mouseReleaseEvent():每當放開鼠標按鈕時調用該方法;
- mouseDoubleClickEvent():每當雙擊鼠標時調用該方法。
鍵盤
- keyPressEvent():每當鍵盤按鍵按下時調用;Tab和Shift+Tab鍵只有在沒有focus-change機制時才會傳給Widget。
- focusInEvent():當Widget獲取到了鍵盤focus(假設已經調用了setFocusPolicy())時才會被調用。
- focusOutEvent():當Widget失去鍵盤focus時調用該方法。
其他一些事件
- mouseMoveEvent() :按住鼠標鍵移動時發送該信號,常用於拖拽操作;
- keyReleaseEvent():松開鍵盤;
- wheelEvent():鼠標滾輪;
- enterEvent():鼠標進入Widget;
- leaveEvent():鼠標離開Widget;
- moveEvent():Widget相對於其Parent移動時;
- closeEvent():關閉Widget時。
事件和機制可以參考The Event System。
6)函數、屬性組
類別 |
函數、屬性 |
說明 |
窗口函數 | show(), hide(), raise(), lower(), close(). |
|
頂層窗口 | showNormal(). |
|
窗口內容 | update(), repaint(), scroll(). |
|
幾何、位置 | pos, x(), y(), rect, size, width(), height(), move(), resize(), sizePolicy, sizeHint(), layout(), adjustSize(), mapToGlobal(), mapToParent(), |
|
Mode | isVisibleTo(), isEnabledTo(), isWindow(), |
|
視覺效果 | style(), setStyle(), font, fontInfo(), fontMetrics(). |
|
鍵盤焦點 | setFocus(), clearFocus(), setTabOrder(), |
|
鼠標、鍵盤抓取 | grabMouse(), releaseMouse(), grabKeyboard(), mouseGrabber(), |
|
事件處理 | event(), focusInEvent(), wheelEvent(), enterEvent(), leaveEvent(), paintEvent(), moveEvent(), resizeEvent(), closeEvent(), dropEvent(), childEvent(), showEvent(), hideEvent(), customEvent(). changeEvent(), |
|
系統函數 | parentWidget(), window(), setParent(), winId(), find(), metric(). |
|
上下文菜單 | actions() |
|
交互 | setToolTip(), |
7)Widget樣式表
除了標准Widget樣式外,Widget也可以通過style sheet指定的規則進行樣式設置。該特性允許我們定制Widget的外觀。
8)透明度與雙重緩存(double-buffer)
從Qt 4.0開始,QWidget將在繪制時自動進行雙重緩存,所以我們不需要在paintEvent()中寫雙重緩存的代碼。
從Qt 4.1開始,只要沒有設置Qt::WA_PaintOnScreen,那么Parent Widget就會自動傳播到它的每一個Child Widget中。定制的Widget可以利用這一特定的優勢來更新不規則的區域(創建非矩形子部件)。下圖展示了如何修改定制Widget的屬性來更好地實現不同的效果。
上圖中,一個半透明的矩形Child Widget中有一些區域被移除了,之后把它加到一個Parent Widget中。之后,修改不同的屬性來實現不同的效果:
- 左邊:不設置任何屬性和參數。這種默認狀態適合大多數使用了透明度、不規則形狀的定制Widget。
- 中間:設置了autoFillBackground屬性,會自動填充背景。
- 右邊:設置了Qt::WA_OpaquePaintEvent參數,使用不透明的顏色繪制整個區域。Widget的區域最初是未初始化的,在圖中用紅色對角網格表示並覆蓋這些區域。該屬性對於需要快速繪制特定內容和不需要填充背景的Widget的小部件很有用。
1、模塊和加載項
Header: | #include <QWidget> |
qmake: | QT += widgets |
Inherits: | QObject and QPaintDevice |
2、構造
QWidget(QWidget *parent = nullptr, Qt::WindowFlags f = Qt::WindowFlags()) |
3、靜態字段
enum | RenderFlag { DrawWindowBackground, DrawChildren, IgnoreMask } | 調用QWidget::render()時如何呈現Widget |
flags | RenderFlags |
4、實例字段
類型 |
字段 |
說明 |
getter、setter方法 |
類型 |
字段 |
說明 |
getter、setter方法 |
bool | acceptDrops | 是否允許drop事件 | acceptDrops() setAcceptDrops(bool on) |
int | minimumWidth | 最小寬度 | minimumWidth() setMinimumWidth(int minw) |
QString | accessibleDescription | Widget的描述性語句 | accessibleDescription() setAccessibleDescription(const QString &description) |
bool | modal | 該Widget是否是模態Widget | isModal() |
QString | accessibleName | Widget的名字 | accessibleName() setAccessibleName(const QString &name) |
bool | mouseTracking | 是否啟用鼠標追蹤 | hasMouseTracking() setMouseTracking(bool enable) |
bool | autoFillBackground | 背景是否自動填充 | autoFillBackground() setAutoFillBackground(bool enabled) |
QRect | normalGeometry | ||
QSize | baseSize | 基本大小 | baseSize() setBaseSize(const QSize &) setBaseSize(int basew, int baseh) |
QPalette | palette | Palette | palette() setPalette(const QPalette &) |
QRect | childrenRect | 該Widget的Child相關矩形 | childrenRect() | QPoint | pos | Widget在Parent Widget中的位置 | pos() move(int x, int y) move(const QPoint &)
|
QRegion | childrenRegion | 該Widget的Child相關Region | childrenRegion() | QRect | rect | 該Widget對應的內部幾何形狀 | rect() |
Qt::ContextMenuPolicy | contextMenuPolicy | Widget如何顯示上下文菜單 | contextMenuPolicy() setContextMenuPolicy(Qt::ContextMenuPolicy policy) |
QSize | size | 該Widget對應的內部幾何形狀的大小 | size() resize(int w, int h) resize(const QSize &)
|
QCursor | cursor | 光標形狀 | cursor() setCursor(const QCursor &) unsetCursor()
|
QSize | sizeHint | Widget的推薦大小 | sizeHint() |
bool | enabled | 是否啟用 | isEnabled() setEnabled(bool) |
QSize | sizeIncrement | 縮放時的大小增量 | sizeIncrement() setSizeIncrement(const QSize &) setSizeIncrement(int w, int h)
|
bool | focus | Widget是否有個鍵盤輸入焦點 | hasFocus() | QSizePolicy | sizePolicy | 默認布局策略 | sizePolicy() setSizePolicy(QSizePolicy) setSizePolicy(QSizePolicy::Policy horizontal, QSizePolicy::Policy vertical)
|
Qt::FocusPolicy | focusPolicy | Widget接收鍵盤焦點的方式 | focusPolicy() setFocusPolicy(Qt::FocusPolicy policy) |
QString | statusTip | 狀態標簽 | statusTip() setStatusTip(const QString &) |
QFont | font | 當前Widget采用的字體 | font() setFont(const QFont &) |
QString | styleSheet | 樣式表 | styleSheet() setStyleSheet(const QString &styleSheet) |
QRect | frameGeometry | 框架矩形(包含Window Frame) | frameGeometry() | bool | tabletTracking | 是否啟用平板跟蹤 | hasTabletTracking() setTabletTracking(bool enable) |
QSize | frameSize | 框架大小 | frameSize() | QString | toolTip | 工具標簽 | toolTip() setToolTip(const QString &) |
bool | fullScreen | 是否全屏 | isFullScreen() | int | toolTipDuration | 工具標簽持續時間 | toolTipDuration() setToolTipDuration(int msec) |
QRect | geometry | 框架矩形(不包含Window Frame) | geometry() setGeometry(int x, int y, int w, int h) setGeometry(const QRect &)
|
bool | updatesEnabled | 是否允許更新 | updatesEnabled() setUpdatesEnabled(bool enable) |
int | height | 高度 | height() | bool | visible | 是否可見 | isVisible() setVisible(bool visible) |
Qt::InputMethodHints | inputMethodHints | QString | whatsThis | "幫助"文本 | whatsThis() setWhatsThis(const QString &) |
||
bool | isActiveWindow | 是否活動 | isActiveWindow() | int | width | 寬度 | width() |
Qt::LayoutDirection | layoutDirection | 布局方向 | layoutDirection() setLayoutDirection(Qt::LayoutDirection direction) unsetLayoutDirection()
|
QString | windowFilePath | Widget相關的文件路徑 | windowFilePath() setWindowFilePath(const QString &filePath) |
QLocale | locale | 本地配置 | locale() setLocale(const QLocale &locale) unsetLocale()
|
Qt::WindowFlags | windowFlags | Window Flags | windowFlags() setWindowFlags(Qt::WindowFlags type) |
bool | maximized | 是否最大化 | isMaximized() | QIcon | windowIcon | Widget的圖標 | windowIcon() setWindowIcon(const QIcon &icon) |
int | maximumHeight | 最大高度 | maximumHeight() setMaximumHeight(int maxh) |
Qt::WindowModality | windowModality | ||
QSize | maximumSize | 最大尺寸 | maximumSize() setMaximumSize(const QSize &) setMaximumSize(int maxw, int maxh)
|
bool | windowModified | Window是否修改(未保存) | isWindowModified() setWindowModified(bool) |
int | maximumWidth | 最大寬度 | maximumWidth() setMaximumWidth(int maxw) |
double | windowOpacity | 不透明度 | windowOpacity() setWindowOpacity(qreal level) |
bool | minimized | 是否最小化 | isMinimized() | QString | windowTitle | 標題 | windowTitle() setWindowTitle(const QString &) |
int | minimumHeight | 最小高度 | minimumHeight() setMinimumHeight(int minh) |
int | x | Widget在Parent中的x坐標 | x() |
QSize | minimumSize | 最小尺寸 | minimumSize() setMinimumSize(const QSize &) setMinimumSize(int minw, int minh)
|
int | y | Widget在Parent中的y坐標 | y() |
QSize | minimumSizeHint | 推薦的最小尺寸 | minimumSizeHint() |