Qt:QWidget
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() |
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性