Qt - QWidget
01. 描述
QWidget类
- 所有窗口类的基类
- 是QObject和QPaintDevice的子类
- 可内嵌到其他窗口的内部(无边框);创建一个窗口指定了父对象;例如WidgetSon* w = new WidgetSon(this)
- 可以作为独立的窗口显示(有边框);创建一个窗口没有指定父对象;例如WidgetSon* w = new WidgetSon()
属性
widget是用户界面最基本的组成部分:它接收来自于windows系统的鼠标、键盘以及其他事件,然后将它自己绘制在屏幕上。每一个widget都是矩形形状,以Z-order顺序排列。一个widget会被它的父窗口或者在它前面的widgets所截断。
如果一个widget没有被嵌入到另外一个widget中,那么这个widget就叫做window,即一个独立的窗口。尽管我们可以通过设置window flags创建一个没有任何修饰的window,但是通常情况下,一个window都有一个边框和一些菜单栏等。在Qt中,QMainWindow以及QDialog的子类都是最为常见的window类型。
一个widget的构造函数可以接受一个或者两个标准参数:
(1) QWidget *parent = 0 ,为新创建的widget指定其父widget。如果parent为0(默认值),那么这个新widget就会变成一个独立的window。如果parent不为0,那么新创建的widget是parent的一个子窗口,但是此时我们新创建的widget的形状会受其父窗口形状的约束。(除非你指定这个新创建的widget的window flag为Qt::Window)
(2) Qt::WindowFlags f = 0,这个参数用来设置新创建的widget的window flags(例如是否有最大化按钮等)。默认的参数几乎对所有的widget都是适用的。但是如果你需要一个没有边框的widget,你必须使用特定的flag。
QWidget有很多成员函数,但是有一些成员函数并不会被使用。例如,QWidget有font(字体)属性,但是基本上不会调用这个函数。
02. 顶层widget和子widget
一个没有父widget的widget是一个独立的window,即是一个顶层widget。对于这些widget,setWindowTitle()函数和setWindowIcon()分别设置窗口的标题和图标。
非window类型的widget是子widget,在父widget中显示。Qt中的大多数widget主要是作为子widget。例如,我们可以把一个按钮作为一个顶层窗口,但是大多数人倾向于把他们的按钮放在widget里面,例如把按钮放在QDialog(对话框类)中。
上图中展示了把一个QGroupBox作为widget来容纳QGridLayout中的各种各样的子widget。QLabel被设置为自适应大小
如果你想用一个QWidget来容纳子widget,通常情况下你应该给父QWidget添加一个layout(布局)。更多信息参见Layout Management
。
03. 复合型Widget
如果要把一个widget作为一个容器来存放一组子widget,这个widget就称之为复合型widget。可以通过构造一个带有可视属性的widget-一个QFrame来实现。例如,通常我们通过该widget的layout(布局)来添加一个子widget。上图中的widget便是通过Qt Designer创建的。
复合型的widget也可以是标准widget的一个子类,例如QWidget或者QFrame,然后在这个子类中添加必要的layout(布局)和子widget。Qt中的许多例子以及教程中的例子中的复合型widget都是使用该方法创建的。
04. 自定义控件和绘制方式
因为QWidget是QPaintDevice
的一个子类,因此QWidget可以通过实例化一个QPainter的对象,然后使用一系列的绘制方式来显示自定义的内容。该方法与Graphics View Framework
(我猜指的是通过拖拽控件来制作一个特定窗口的方法)的canvas-style approach(画布风格方法)完全不同。在Graphics View Framework中,每一个被应用程序添加的控件都由framework自身来渲染。
每一个widget的绘制操作都由自己的paintEvent()
来执行。无论何时,只要有一些变化发生或者是应程序的要求而导致这个widget需要被重新绘制时,就会调用这个函数。
这个模拟时钟的例子展示了一个简单的窗口是如何处理绘制事件的。
05. Size Hints和Size Policies
当实例化了一个新的widget的时候,重载SizeHint()函数使得窗口有一个合理的默认大小,重载setSizePolicy()使得该窗口有正确的大小策略,这两个方法都是非常有用的。
默认情况下,不提供大小提示的复合窗口小部件将根据其子窗口小部件的空间要求来调整大小。
size policy使得layout management system(布局管理系统)拥有良好的默认大小变化管理依据。这使得其他的widget更加容易管理和容纳你的widget。默认的size policy表示widget的大小可以自由变化,一般倾向于采用sizeHint()返回的大小,这对大多数的widget来说已经足够好了。
提示:
顶层widget的大小一般约束为桌面大小长度和宽度的的2/3,但我们也可以通过resize()函数来手动改变大小。
06. 事件(Events)
用户的行为引起了widget对事件的响应。Qt通过实例化QEvent的子类的一个对象,该对象包括每个事件的相关信息,然后通过调用对应的事件处理函数将事件传送给widget。
如果你的widget中只有些许widget,你很有可能不需要实现事件处理函数。如果你想在一个子widget中捕捉鼠标点击事件,只需要在这个子widget中的mousePressEvent()中调用underMouse()函数即可。
Scribble Example实现了更多的有关于鼠标移动、按钮点击和窗口重设大小的事件处理过程。
你需要给自己的widget添加一些行为和内容,如下是一些简单的和QWidget有关的事件概览,我们从最常见的说起:
- paintEvent(),只要widget需要重新绘制就会被调用。每一个自定义的widget都需要实现这个函数。使用QPainter进行绘制只能发生在一个PaintEvent()中,或者是以paintEvent()的形式调用它。
- resizeEvent(),当widget大小被重新设置的时候就会被调用
- mousePressEvent()当按下一个鼠标按钮时鼠标光标是widget内部时,或当使用窗口小部件已经抓住了鼠标被称为grabMouse()。在不释放鼠标的情况下按下鼠标,实际上与调用grabMouse()相同。
- mouseReleaseEvent(),将调用mouseReleaseEvent()。当窗口小部件收到相应的鼠标按下事件时,它将接收鼠标释放事件。这意味着,如果用户按下里面的鼠标你的小部件,然后松开鼠标按钮之前拖动鼠标别的地方,你的小部件接收的释放事件。有一个例外:如果在按住鼠标按钮的同时出现弹出菜单,则该弹出窗口会立即窃取鼠标事件。
- mouseDoubleClickEvent() ,当用户在widget中双击鼠标就会被调用。如果用户双击,widget会收到一个mouse press 事件,一个 mouse release 事件,(一个mouse click 事件)和另外一个mouse press 事件,一个 mouseDoubleclick 事件,和一个mouse release 事件。如果在双击过程中发生了鼠标抖动,就会收到一个mouse move 事件。在没有收到第二次点击鼠标的事件前是不可能区分鼠标单击事件和鼠标双击事件的。(这就是为什么大多数GUI书推荐把双击事件作为单击事件的一个扩展而不是定义为另外一个不同的操作)
如果widget接受键盘输入,则需要实现一些其它的事件处理函数:
- keyPressEvent(),用户按下一个键时就会被调用,如果长按一个键,这个函数会被重复调用。如果焦点变化机制没有使用Tab和Shift+Tab键,那么这两个键仅仅会传递给Widget。如果要强行使你的widget处理这两个键的信息,则需要实现QWidget::event()。
- focusInEvent() ,如果widget获得键盘焦点,该函数就会被调用。(假定你提前调用了setFocusPolicy()函数),功能良好的widget意味着它们会以明确的方式获得焦点。
- focusOutEvent() ,widget失去焦点时该函数就会被调用。
也许你还需要实现一些不太常见的事件处理函数:
- mouseMoveEvent(),当你按下鼠标,并且移动的时候该函数会被调用。在拖拽操作中这个函数非常有用。如果你调用了setMouseTracking(true),那么即使鼠标没有被按下,但是只要鼠标在移动,这个函数就会被调用。(见 Drag and Drop板块)
- keyReleaseEvent(),一个按键被松开时,或者持续按住一个键(这个键必须是自动重复的)时该函数就会被调用。如果是第二种情况,那么widget会在按键每次重复时收到一对key release和key press事件。如果焦点变化机制没有使用Tab和Shift+Tab键,那么这两个键仅仅会传递给Widget。如果要强行使你的widget处理这两个键的信息,则需要实现QWidget::event()。
- wheelEvent(),鼠标滑轮滚动时该函数被调用
- enterEvent(),鼠标进入该widget所在屏幕区域时被调用(该widget的屏幕区域不包括其子widget的屏幕区域)
- leaveEvent(),鼠标离开widget所在屏幕区域时被调用,但是如果鼠标进入了子widget屏幕区域时该函数不会被调用
- moveEvent(),widget相对于其父widget被移动时调用该函数
- closeEvent(),用户关闭widget时或者调用close()函数时该函数被调用
还有一些鲜为人知的事件,详见QEvent::Type,如果要处理这些事件,你还需要亲自实现event
默认的event会处理Tab和Shift+Tab键(用来改变键盘焦点),同时也会传递上述的一个或者多个事件。
事件及其传递机制在事件系统中介绍。
07. 函数和属性组
08. Widget样式表
除了在每一个平台上标准的widget风格外,widget也可以style sheet(样式表)指定的风格。这个特性使得我们可以依照用户的目的将widget改造为特定的样式。例如,可以把一个按钮设置为一种特定的样式来表明它的销毁行为。
widget风格样式表的更多内容详见Qt Style Sheets 文档
09. 透明和双缓冲
自从Qt4.0开始,QWidget在绘制过程中自带双缓冲机制,因此不需要再paintEvent()中额外编写双缓冲的代码来避免闪烁问题。
自从Qt4.1开始, 只要没有设置 Qt::WA_PaintOnScreen,parent widgets(父窗口)的内容会默认传递给它的子窗口。可以利用这个特点来编写一个自定义的窗口,该窗口拥有不规则的区域(创建非矩形形状的子窗口),或者用小于全alpha组件的颜色进行绘制(原文:or painting with colors that have less than full alpha component)。下图展示了通过调整自定义widget的属性和性能来达到不同的效果。
上图中,构造了一个被挖去中间部分只留下边框的半透明矩形子窗口,然后将其添加到一个父窗口中(该父窗口其实是一个显示pixmap的QLabel), 然后我们设置了不同的属性和性能达到了不同的效果:
- 左边的widget没有额外的性能设置,也没有进行属性设置。这个默认的状态适合大多数自定义的使用透明属性的widget,是不规则的形状,同时没有用不透明的刷子来绘制它们的全部区域。
- 中间的widget设置了 autoFillBackground 属性,这个属性适用于那些父窗口已经提供了默认的背景的自定义子窗口。此时,也不会用不透明的刷子来绘制他们的全部区域。
- 右边的widget设置了Qt::WA_OpaquePaintEvent,该属性表明这个widget将会用不透明的颜色来绘制它的全部区域。widget的区域初始状态是未初始化的,在右边的图中表现为红色的对角线方格模型穿过被绘制过的区域,Qt::WA_OpaquePaintArea属性对于需要快速绘制特定内容而不需要默认填充背景的widget非常有用。
要想快速的更新拥有简单背景色的widget,例如实时绘图或者是图形widget,最好定义一个合适的背景色(采用 QPalette::Window 来设置setBackgroundRole() ),然后设置autoFillBackground属性,然后在paintEvent()中实现必要的绘制功能。
要想快速更新含有非透明内容的widget,例如视频流widget,最好设置 Qt::WA_OpaquePaintEvent,避免任何不必要的背景绘制。
如果一个widget同时拥有 Qt::WA_OpaquePaintEvent 的属性和autoFillBackground属性,那么Qt::WA_OpaquePaintEvent属性拥有优先权。视你的需求而定,你应该从其中挑选一个。
自Qt4.1以来,父窗口的内容也会传标准的子窗口。如果一个父widget并没有以标准窗口的修饰方法进行修饰,就会导致一些预料不到的结果,例如下图所示:
一个标准Qt widget的自定义的绘制范围,不依赖于其子类,会略低于自定义widget的绘制范围。通常,我们期望的标准widget的外观可以通过设置autoFillBackground来实现。
10. 创建半透明窗口
从Qt 4.5开始,可以在支持合成的窗口系统上创建具有半透明区域的窗口。
在一个顶层窗口中实现启用这个特性,用setAttribute来设置Qt::WA_TranslucentBackground,同时还要保证你想获得的透明区域使用透明颜色绘制。
平台相关性:
- X11:此功能依赖于使用支持ARGB视觉效果的X服务器和合成窗口管理器。
- Windows:窗口小部件需要设置Qt :: FramelessWindowHint窗口标志,以使半透明起作用。
11. Native Widgets和 Alien Widgets
Alien widgets从Qt4.4引入,指的是不在窗口系统中的widget,它们并不拥有本地窗口句柄;这一特性显著的加速了widget绘制、重新定制大小以及去除闪烁。
如果你需要使得Native Widgets拥有以前的属性,你需要选择以下属性之一:
1.在开发环境中指定QT_USE_NATIVE_WINDOWS=1
2.在你的应用程序中设置 Qt::AA_NativeWindows 属性。所有的widget都会成为Native widgets
3.在widgets上设置Qt::WA_NativeWindow属性。这个widge本身以及其祖先都会成为Native Widget(除非设置了Qt::WA_DontCreateNativeAncestors )
4.调用QWidget::winld强制变成一个native window(同第3个选项)
5.设置Qt::WA_PaintOnScreen属性强制变为一个native window(同3选项)
12. 成员类型文档
enum QWidget::RenderFlag
flags QWidget::RenderFlags
这个枚举类型描述了调用QWidget::render()函数时如何渲染widget
13. 属性文档
13.1 acceptDrops: bool
该属性表示该widget的拖放属性事件是否开启。
设置该属性为true即告诉系统该窗口可能接受拖放事件
如果该widget是桌面(windowType()==Qt::Desktop),如果另外一个应用程序正在使用桌面,该属性可能失效。你可以调用acceptDrops()来测试是否会出现这种情况。
警告:不要在一个拖和放(drag and drop)的事件处理函数中修改这个属性
默认该属性为false
相关函数
bool acceptDrops() const
void setAcceptDrops(bool on)
13.2 accessibleDescription : QString
该属性控制widget的描述是否可以通过辅助技术可见
可访问性描述应该传达这个widget的功能信息。accessibleName应该是简单明了的字符串(例如 保存),而描述性信息应该给出更多的内容,例如 保存当前文档。
这个属性应该被localized,(区域化)
默认情况下,该属性包括一个空字符串,此时Qt选择用工具提示来提供这些信息
相关函数
QString accessibleDescription() const
void setAccessibleDescription(const QString &description)
13.3 accessibleName : QString
该属性控制widget的名称是否可以通过辅助技术可见
这是诸如屏幕阅读器之类的辅助技术宣布此小部件的主要名称。对于大多数窗口小部件,不需要设置此属性。例如,对于QPushButton,将使用按钮的文本。
当窗口小部件不提供任何文本时,设置此属性很重要。例如,仅包含图标的按钮需要设置此属性才能与屏幕阅读器一起使用。该名称应简短,并且与小部件传达的视觉信息等效。
此属性必须本地化。
默认情况下,此属性包含一个空字符串。
相关函数
QString accessibleName() const
void setAccessibleName(const QString &name)
13.4 autoFillBackground : bool
该属性控制widget是否自动填充背景
如果启用该属性,则会导致Qt在调用绘制事件之前会填充widget背景。而自动填充所用的颜色是来自于widget的palette中的QPalette::Window
除此之外,窗口(这里特指Windows,而不是widget)经常会用QPalette::Window 填充。除非设置了WA_OpaquePaintEvent 或者 WA_NoSystemBackground 属性
如果其父窗口有对背景设置了static gradient,named该属性不能被禁用(即传入参数为false)
警告:当与Qt样式表 一起使用的时候需要注意,当一个widget有一个拥有有效的背景图的样式表Qt Style Sheet或者一个border-image时,这个属性会被自动禁用。
默认情况下该属性是false
相关函数
bool autoFillBackground() const
void setAutoFillBackground(bool enabled)
13.5 baseSize : QSize
该属性控制widget的基本大小
如果widget定义了sizeIncrement(),base size就会计算一个合适的大小。
默认情况下,对于一个新创建的widget,这个属性包含一个宽度和高度都为0的尺寸
相关函数
QSize baseSize() const
void setBaseSize(const QSize &)
void setBaseSize(int basew, int baseh)
13.6 childrenRect : const QRect
该属性获取widget的子窗口的矩形边界
隐藏的子窗口除外(即不能控制)
默认情况下,一个没有子窗口的widget,该属性包括一个长度和宽度都为0,位置在原点的矩形。
相关函数
QRect childrenRect() const
13.7 childrenRegion : const QRegion
该属性获取被widget的子窗口门占据的所有区域
隐藏的子窗口除外
默认情况下,一个没有子窗口的widget,这个属性会返回一个空region
相关函数
QRegion childrenRegion() const
13.8 contextMenuPolicy : Qt::ContextMenuPolicy
该属性控制widget显示一个上下文菜单的方式。
该属性默认值为 Qt::DefaultContextMenu,也就是说默认调用contextMenuEvent()函数。其他可选值有: Qt::NoContextMenu, Qt::PreventContextMenu, Qt::ActionsContextMenu, 以及 Qt::CustomContextMenu。如果设置了Qt::CustomContextMenu,那么 signal(信号)customContextMenuRequested()会被传递给窗口
相关函数
Qt::ContextMenuPolicy contextMenuPolicy() const
void setContextMenuPolicy(Qt::ContextMenuPolicy policy)
13.9 cursor : QCursor
该属性控制widget中鼠标的形状
当鼠标在该widget区域内时就会改变为设置的形状。鼠标的形状可以参见预定义鼠标对象列表
一个编辑器可能会采用一个I-beam形状,例如:
setCursor(Qt::IBeamCursor);
如果并没有设置光标样式,或者调用了unsetCursor()
函数之后,会采用其父窗口的光标样式。
默认情况下,该属性包含一个我们常见的箭头样式的光标- Qt::ArrowCursor
即使是在按下鼠标后离开widget的区域之后,一些底层窗口会重新设置光标样式,如果你想为所有的widget,即使是在窗口范围外也要设置一个光标样式的话,可以考虑一下QApplication::setOverrideCursor()
相关函数
QCursor cursor() const
void setCursor(const QCursor &)
void unsetCursor()
13.10 enabled : bool
该属性控制widget是否启用(处于enabled状态)
默认情况下一个enabled的widget会处理键盘和鼠标事件。一个disabled widget却不会处理。但是QAbstractButton却是个例外。
有些widget在disabeld情况下会有不同的表现状态。例如一个按钮会将其置灰。如果你的widget需要知道什么时候widget处于enabled或者disabled状态,可以使用QEvent::EvabledChange
类型的changeEvent()
默认情况下,该属性为true
相关函数
bool isEnabled() const
void setEnabled(bool)
13.11 focus : const bool
该属性控制widget是否处于键盘输入的焦点
默认情况下,该属性为false
Note:获取该属性的值等同于调用 QApplication::focusWidget()
来检查程序焦点是否是这个widget
相关函数
bool hasFocus() const
13.12 focusPolicy : Qt::FocusPolicy
该属性控制widget获取键盘焦点的方式:
- 如果widget接受Tab键来获取键盘焦点,则为
Qt::TabFocus
方式 - 如果接受点击来获取焦点,则为
Qt::ClickFocus
方式 - 如果以上两种方式都接受,则为
Qt::StrongFocus
方式 - 如果不接受任何焦点,则为
Qt::NoFocus
方式
如果一个widget要处理键盘事件,named你必须启用其键盘焦点。这项工作通常在widget的构造函数中完成。例如,QLineEdit函数就会在其构造函数中调用setFocusPolicy(Qt::StrongFocus).
如果该widget有个焦点代理,那么其获取焦点的方式也会传递给代理。
相关函数
Qt::FocusPolicy focusPolicy() const
void setFocusPolicy(Qt::FocusPolicy policy)
13.13 font : QFont
该属性控制widget的当前字体
该属性描述了widget所需要的字体,即当渲染标准的组件时会采用当前字体。同时这也是使得自定义的widget与所属的平台的外观风格保持一致性的一种方式。一般地,不同的平台或者不同的风格都会对应用程序定义不同的字体。
当我们给widget赋予一个新的字体时,新字体就会和widget默认的字体共同组成了widget最后的字体(我们称之为 final font)。可以调用fianlFont()函数获取widget final font 的信息。final font 也会被用来初始化QPainter的字体。
QWidget类中父类会显式(explicit和implict对应)的将其字体传递给子widget。如果你对一个字体做了特殊的改变并且将其赋值给一个widget,那么这个字体会传递给其所有子widget。但是默认的字体不会传递给window(参见 isWindow()函数)除非我们启用了Qt::WA_WindowPropagation属性
QWidget的字体传播方式和其调色板(palette)的字体传播方式相同
当前Qt中渲染标准qt widget的风格,可以任意的的选用widget中的字体,或者在某些情况下忽略这些字体(部分忽略或者全部忽略)。尤其是,GTK 风格,Windows 风格,Mac 风格,Windows XP 和Windows Vista 风格,对widget的字体做出一些特殊的改变来匹配平台的外观风格。正因为如此,对一个widget赋予一个新的字体并不能保证能够使得widget发生改变。相反的,你可以选择应用一个styleSheet。
Note:如果同时对一个widget使用了setFont()函数和Qt Style Sheets而发生风格上的冲突,那么style sheets会拥有更高的优先级。
相关函数
const QFont &font() const
void setFont(const QFont &)
13.14 frameGeometry : const QRect
该属性控制widget相对于其父窗口的几何结构, 包括窗口边框(window frame)
窗口形状问题详见我的另一篇文章Qt 中的窗口和对话框组件
默认情况下,该属性包含一个依赖于平台和屏幕几何结构的值
相关函数
QRect frameGeometry() const
13.15 frameSize : const QSize
该属性控制widget,包括窗口边框在内的大小
默认下,该属性包含一个依赖于用户的平台及屏幕结构的值
相关函数
QSize frameSize() const
13.16 fullScreen : const bool
该属性控制widget是否以全屏模式显示
一个全屏模式显示的widget会占据全部的屏幕区域,并且不会显示其它诸如标题栏之类的玩意儿。
默认情况,该属性为false
相关函数
bool isFullScreen() const
13.17 geometry : QRect
该属性控制widget相对于其父窗口的几何结构,但不包括窗口边框,注意和frameGeometry区别。
当改变几何结构时,widget,如果可见的话,会立即收到一个移动事件(moveEnvent())以及/或者 一个重新绘制大小的事件(resizeEvent())如果widget当前状态下不可见,那么在它显示之前会收到合适的事件。
当窗口的大小被设置的超出了 minimumSize()和 maximumSize()设置的范围时,其大小会自动变化以适应
警告: 在resizeEvent()函数或者moveEvent()中调用 setGeometry()函数会导致无限迭代
窗口形状问题详见我的另一篇文章Qt 中的窗口和对话框组件
默认下,该属性包含一个依赖于用户的平台及屏幕结构的值
注意:geometry和framGeometry()中的几何数据必须在 show()调用后 才有效!
相关函数
const QRect &geometry() const
void setGeometry(int x, int y, int w, int h)
void setGeometry(const QRect &)
13.18 height : const int
该属性控制widget除去窗口边框的客户区的高度
有关Windows几何问题的概述,请参见“窗口几何”文档。
注意:请勿使用此功能在多屏幕桌面上查找屏幕的高度。请阅读此说明以获取详细信息。
默认情况下,该属性包含一个依赖于用户平台和屏幕结构的值
相关函数
int height() const
13.19 inputMethodHints : Qt::InputMethodHints
该属性控制widget拥有怎样的输入提示
这只和输入类型的widget有关。该属性被输入方法用检索从而确定具体的输入方法的操作方式。例如,如果设置了Qt::ImhFormattedNumbersOnly,那么输入方法会改变其可见的组件来告知用户只能输入数字。
警告:一些widget需要确定的标志来完成其任务。要设置flag(标志),使用w->setInputMethodHints(w->inputMethodHints()|f)来代替w->setInputMethodHints(f)
注:flags仅仅起到提示的作用,所以特定的输入方法可以忽略这些提示。如果你想让用户输入一些特定的字符,你应该对widget设置QValidator。
默认的属性值为Qt::ImhNone
该属性于Qt4.6中引入
相关函数
Qt::InputMethodHints inputMethodHints() const
void setInputMethodHints(Qt::InputMethodHints hints)
13.20 isActiveWindow : const bool
该属性获取当前widget的窗口是否为活动的窗口
活动窗口即该窗口下的widget拥有键盘输入焦点(一个窗口如果没有widget或者它的widget都不接受键盘输入,它仍然可以拥有焦点)
当一个弹出窗口可见时,该属性对于弹出窗口和当前活动窗口都为true
默认情况下,该属性为false
相关函数
bool isActiveWindow() const
13.21 layoutDirection : Qt::LayoutDirection
该属性控制widget的布局方向
默认情况下,该属性设置为 Qt::LeftToRight
当一个widget的布局方向已经被设置时,该属性会被传递给其子widget,但是不会传递给一个显式的调用了setLayoutDirection()的子widget。同样的,在给父widget设置了布局方向后,给其添加子widget时,子widget也不会继承其布局方向。
注:从Qt4.7以后该属性不再影响文本的布局方向
相关函数
Qt::LayoutDirection layoutDirection() const
void setLayoutDirection(Qt::LayoutDirection direction)
void unsetLayoutDirection()
13.22 locale : QLocale
该属性控制widget 的语言环境
只要没有设置特定的locale,那么该widget的local属性要么是其父widget的属性,要么是默认的属性(该widget是一个顶级窗口)
如果该widget会显示时间和日期,那么由于不同区域有不同表示方式,这些属性应该由widget的locale进行格式化
该属性在Qt4.3中引入。
相关函数
QLocale locale() const
void setLocale(const QLocale &locale)
void unsetLocale()
13.23 maximized : const bool
该属性获取widget是否最大化
该属性仅仅对window有意义,对子窗口无意义
注:由于一些窗口系统限制,并非每次调用都会返回预期的结果。(例如在window系统中,用户通过window系统的窗口管理机制将窗口最大化,Qt则无法将最大化和其他大小区别开来)。但这个问题会随着window管理协议的发展而得到改进。
默认情况下,该属性为false
相关函数
bool isMaximized() const
13.24 maximumHeight : int
此属性获取widget的最大高度(以像素为单位)
此属性对应于maximumSize属性所保持的高度。
默认情况下,此属性包含值16777215。
注意:QWIDGETSIZE_MAX
宏的定义限制了小部件的最大大小。
相关函数
int maximumHeight() const
void setMaximumHeight(int maxh)
13.25 maximumSize : QSize
该属性控制widget的最大像素尺寸
一个widget的最大尺寸不能超过其最大尺寸
默认情况下,一个widget的最大尺寸,高度和宽度都为16777215
注:由于QWIDGETSIZE_MAX的原因,会限制widget的最大尺寸
相关函数
QSize maximumSize() const
void setMaximumSize(const QSize &)
void setMaximumSize(int maxw, int maxh)
13.26 maximumWidth : int
该属性控制widget的最大像素宽度
该属性对应于maximumSize对应的最大宽度
默认请款下,该属性值为16777215
注:由于QWIDGETSIZE_MAX的原因,会限制widget的最大尺寸
相关函数
int maximumWidth() const
void setMaximumWidth(int maxw)
13.27 minimized : const bool
该属性返回widget是否窗口最小化
该属性只对window有意义,对于子窗口无意义
默认情况下,该属性为false
相关函数
bool isMinimized() const
13.28 minimumHeight : int
该属性控制widget的最小像素高度
该属性受到minimumSize属性中高度的限制
默认情况下,该属性值为0
相关函数
int minimumHeight() const
void setMinimumHeight(int minh)
13.29 minimumSize : QSize
该属性控制widget的最小尺寸
widget不能被调整为一个小于最小尺寸的widget。如果当前size比最小尺寸更小,widget会被强制转化为最小的尺寸
该函数设置的最小尺寸会覆盖QLayout中定义的最小大小。如果不想设置最小大小,可以使用QSize(0,0)
默认情况下,这个属性中高度和宽度都为0
相关函数
QSize minimumSize() const
void setMinimumSize(const QSize &)
void setMinimumSize(int minw, int minh)
13.30 minimumSizeHint : const QSize
该属性控制widget的推荐的最小尺寸
如果该属性是一个无效值,那么不会进行最小尺寸推荐
默认情况下,如果该widget没有一个布局,那么推荐的最小尺寸函数会返回一个无效值。否则会返回widget的布局的最小大小。大多数内嵌的widget都会重载minimumSizeHint()函数
QLayout永远不会把一个widget的尺寸设置的比推荐尺寸更小。除非设置了minimumSize()或者其尺寸控制模式被设置为QSizePolicy::Ignore。如果设置了minimumSize(),那么推荐的最小尺寸函数就会被忽略。
相关函数
virtual QSize minimumSizeHint() const
13.31 minimumWidth : int
该属性控制widget的最小像素宽度
该属性对应于minimumSize对应的最小宽度
默认情况下,该属性为0
相关函数
int minimumWidth() const
void setMinimumWidth(int minw)
13.32 modal : const bool
该属性控制widget是否是一个模态的widget
该属性只对window有意义,一个模态窗口阻断其他任何窗口获取输入信息
默认情况下,该属性为false
相关函数
bool isModal() const
13.33 mouseTracking : bool
该属性控制鼠标跟踪是否在该widget中启用
如果鼠标跟踪处于禁用状态(默认状态),那么至少在鼠标移动过程中按下一个鼠标按钮,widget才会收到mouse move(鼠标移动)事件
如果启用了鼠标跟踪属性,那么只要鼠标在widget中移动,widget就会收到mouse move鼠标移动事件
相关函数
bool hasMouseTracking() const
void setMouseTracking(bool enable)
13.34 normalGeometry : const QRect
该属性返回widget作为顶级窗口正常显示情况下的矩形尺寸。(非最大化或者全屏状态)
对于子窗口来说,该属性返回一个空的矩形
默认情况下,该属性包含一个空的矩形
相关函数
QRect normalGeometry() const
13.35 palette : QPalette
该属性控制widget的调色板
该属性描述了widget的调色板。widget的风格会在渲染标准组件时使用调色板,它也是一种保证自定义的widget与本地平台在外观和风格上保持一致的一种有效方法。一般地,不同的平台,不同的风格,都有着不同的调色板。
当给widget指定一个新的调色板的时候,widget默认的调色板会和新的调色板组合起来构成了widget最终的调色板。来自于调色板的背景色会填充widget的背景,同时,调色板中的前景色会初始化QPainter的画笔.
默认的调色板依赖于系统环境。QApplication会为所有的widget维护一个系统默认或者当前风格的调色板。对于特定的widget,可能有特定的特殊的调色板。(例如,在Windows XP和Vista系统中,所有来自于QMenuBar的类都有特定的默认调色板)。也可以通过把自定义的调色板和对应的widget传递给QApplication::setPalette()函数来给widget设定特定的调色板。最后,调色板还有一个可选功能,即对赋予的颜色进行polishing(润色)(见QStyle::polish())
QWidget会显式的将调色板成员传递给其子widget。如果你将一个brush或者一个color传递给调色板,然后将该调色板赋值给widget,那么该调色板会被传递给该widget的所有子widget,从而覆盖系统默认的调色板。需要注意的是,默认的调色板并不会传递给窗口,除非我们启用了Qt::WA_WindowPropagation属性
QWidget的调色板传递和其字体的传递方式相似
当前渲染标准的Qt widget的风格,可以自由地从widget的调色板中选择颜色和画刷,抑或是忽略调色板(部分忽略或者全部忽略)。尤其是GTk、Mac、WIndows XP 和 Vista风格下,这些依赖于第三方API来渲染组件的风格并不会遵从调色板。正因为如此,给一个widget赋予一个新的调色板并不能保证能够改变widget的外观。因此,你或许会选择styleSheet取而代之。更多内容,见这里
警告:不要把该函数和Qt Style Sheets一起结合使用。当使用style sheets时,widget的调色板可以使用”color”,”background-color”,”selection-color”,”selection-background-color”,”alternate-background-color”来自定义
相关函数
const QPalette &palette() const
void setPalette(const QPalette &)
13.36 pos : QPoint
该属性控制widget相对于其父widget的位置
如果该widget是一个window,那么pos会返回widget在桌面上的位置,包括其边框
当改变一个widget的位置时,这个widget,如果可见的话,会立即收到一个移动事件(moveEvent())。如果该widget当前处于不可见状态,那么在该widget显示之前也会收到移动事件。
默认情况下,该属性包括一个位置,指向其初始位置
警告:在setGeometry()和moveEvent()中调用move()函数会导致无限迭代。
窗口形状问题详见我的另一篇文章Qt 中的窗口和对话框组件
相关函数
QPoint pos() const
void move(int x, int y)
void move(const QPoint &)
13.37 rect : const QRect
该属性控制widget除去窗口边框的内在几何矩形
该属性等同于QRect(0,0,width(),height())
默认情况下,该属性依赖于用户平台及其屏幕结构
相关函数
QRect rect() const
13.38 size : QSize
该属性控制widget除去边框之外的大小
如果该widget可见,并且被重新调整了大小,则会立即收到一个调整大小事件(resizeEvent()),如果widget在当前状态下不可见,那么则会在其显示之前收到该事件
如果widget超出了minimumSize()和maxmumSize()定义的范围,则会自适应大小
默认情况下,该属性包含一个依赖于用户平台和屏幕结构的值
警告:在SetGeometry()和resizeEvent()中调用resize()会导致无限迭代
**注意:**将大小设置为QSize(0, 0)
将会导致窗口小部件不出现在屏幕上。这也适用于Windows。
相关函数
QSize size() const
void resize(int w, int h)
void resize(const QSize &)
13.39 sizeHint : const QSize
该属性中包含widget的推荐尺寸
如果该属性值是一个无效值,那么不会推荐尺寸
如果widget没有一个布局,那么默认的sizeHint()函数会返回一个无效值。如果有布局,那么会返回布局中的合适大小
相关函数
virtual QSize sizeHint() const
注:你可以对所有的widget定义sizeIncrement尺寸,但是这仅仅对window有意义(对widget不管用)
默认情况下,这个属性中高度和宽度都为0
警告:该属性在Windows 系统下可能无效,还可能会被Windows系统下的窗口管理系统给忽略。
13.40 sizeIncrement : QSize
该属性控制widget的尺寸增量步幅(每次宽度,长度增加的量)
当我们对window调整其大小时,宽度将会以sizeIncrement()函数中定义的sizeIncrement().width(),高度将会以sizeIncrement().height()定义的高度进行增长。而增长中基本大小尺寸是baseSize()函数的返回值。优先的尺寸是非负整数i和j的组合:
width = baseSize().width() + i * sizeIncrement().width();
height = baseSize().height() + j * sizeIncrement().height();
相关函数
QSize sizeIncrement() const
void setSizeIncrement(const QSize &)
void setSizeIncrement(int w, int h)
13.41 sizePolicy : QSizePolicy
该属性控制widget的默认布局方式
如果有一个QLayout管理widget的子widget,则会调用该QLayout制定的布局方式,如果没有QLayout,那么会调用该函数的返回结果
默认策略是Preferred / Preferred,这意味着可以自由调整窗口小部件的大小,但更喜欢使用sizeHint()返回的大小。类似于按钮的小部件将大小策略设置为指定它们可以水平拉伸但垂直固定。这同样适用于lineedit控件(例如QLineEdit,QSpinBox或可编辑的QComboBox)和其他水平定向的小部件(例如QProgressBar)。QToolButton通常是正方形的,因此它们允许双向增长。支持不同方向的小部件(例如QSlider,QScrollBar或QHeader)指定仅在相应方向上拉伸。可以提供滚动条的小部件(通常是QScrollArea的子类)往往会指定它们可以使用额外的空间,并且可以用不到sizeHint()的大小来实现。
相关函数
QSizePolicy sizePolicy() const
void setSizePolicy(QSizePolicy)
void setSizePolicy(QSizePolicy::Policy horizontal, QSizePolicy::Policy vertical)
13.42 statusTip : QString
该属性控制widget的状态提示信息
默认情况下,该属性包含一个空字符串
相关函数
QString statusTip() const
void setStatusTip(const QString &)
13.43 styleSheet : QString
该属性控制widget的风格样式表
该属性包含自定义的widget的文本描述信息。在Qt Style Sheets中有详细描述
警告:Qt 风格样式表目前对于自定义QStyle并不支持,以后会解决该问题。
相关函数
QString styleSheet() const
void setStyleSheet(const QString &styleSheet)
13.44 tabletTracking : bool
此属性保存是否为小部件启用数位板跟踪
如果禁用了数位板跟踪(默认设置),则在移动笔时,小部件仅在手写笔与数位板接触或至少按下一个手写笔按钮时接收数位板移动事件。
如果启用了数位板跟踪,则即使将鼠标悬停在附近,小部件也将接收数位板移动事件。这对于监视位置以及辅助属性(例如旋转和倾斜)以及在UI中提供反馈很有用。
此属性在Qt 5.9中引入。
相关函数
bool hasTabletTracking() const
void setTabletTracking(bool enable)
13.45 toolTip : QString
概属性控制widget的提示信息
注:默认的提示信息只会显示给活动窗口的子widget。但是我们可以通过给window设置属性 Qt::WA_AlwaysShowToolTips从而将提示信息显示在window上而不是其子widget上。
如果你想控制提示信息的行为,你可以拦截event()函数,然后截获QEvent::ToolTip 事件(也就是说,你可以自定义提示信息显示的位置)
默认情况下,该属性为空
相关函数
QString toolTip() const
void setToolTip(const QString &)
13.46 toolTipDuration : int
该属性控制widget的提示信息持续时间
指定提示信息显示的事件,按照毫秒计算。如果其值为-1(默认值),那么其持续时间依赖于提示信息的长度
该属性从Qt5.2引入
相关函数
int toolTipDuration() const
void setToolTipDuration(int msec)
13.47 updatesEnabled : bool
该属性控制更新是否启用
一个启用该属性的widget可以接收paint事件,进而拥有一个系统背景,一个禁用该属性的widget却不会接收事件,更不会有系统背景。这意味着在禁用该属性情况下调用updata()函数和repaint()函数没有任何卵用
默认情况下该属性为true
setUpdateEnabled()函数,通常用于在一段短时间内禁止widget的更新,例如避免屏幕在一些较大变化情况下发生闪烁。在Qt中,widget通常不会发生闪烁,但是在windows系统上,当widget1被其他widget替代,于是widget1隐藏起来的那个时候,服务器或许会擦除屏幕区域。禁用该属性可以解决这个问题。例如如下代码:
setUpdatesEnabled(false);
bigVisualChanges();
setUpdatesEnabled(true);
禁用一个widget会隐式的禁用其子widget。启用一个widget会隐式的启用其除了顶级窗口之外的其他子widget或者是那些被显式禁用的widget。再次启用update属性会隐式的调用updata()函数。
相关函数
bool updatesEnabled() const
void setUpdatesEnabled(bool enable)
13.48 visible : bool
该属性控制widget是否可见
在widget的父widget可见情况下,调用setVisible(true)或者show()函数会使得widget可见。如果有一个祖先widget(父widget或者父widget的父widget等)不可见,那么该widget就不可见。如果大小或者位置发生了改变,那么Qt保证在其显示之前肯定会收到移动或者调整大小的事件。如果widget一直没有被调整过大小,Qt会调用adjustSize()来自适应的显示其大小。
显式调用setVisible(false)或者hide()函数会隐藏该widget。一个显式隐藏的widget,即使其祖先widget可见,该widget也不会显示,除非你调用函数将其显示。
一个widget的可见状态发生改变,会收到显示或者隐藏事件。在隐藏和显示事件之间,不需要等待CPU周期或者给用户显示信息。例如,一个视频应用程序,可以简单的停止生成下一帧。
一个被其他窗口遮挡的widget会被视为可见状态。图标化窗口或者存在于虚拟桌面的窗口也被视为可见状态。一个widget的映射状态被窗口管理系统改变时会自发的收到一个显示或者隐藏的事件。当用户最小化widget时会自己触发隐藏事件,当widget恢复时会自己出发显示事件。
一般我们根本不需要重载setVisible()函数,如果想在widget显示之前做一些改变,你可以用showEvent().如果你想做一些延迟的初始化动作,那么可以把polish事件传递给event()函数。
相关函数
bool isVisible() const
virtual void setVisible(bool visible)
13.49 whatsThis : QString
该属性控制widget的帮助按钮的文本信息
默认情况下,该属性包含的信息为空
相关函数
QString whatsThis() const
void setWhatsThis(const QString &)
13.50 width : const int
此属性保存窗口小部件的宽度,不包括任何窗口边框。
有关Windows几何问题的概述,请参见“窗口几何”文档。
**注意:**请勿使用此功能在多屏幕桌面上查找屏幕的宽度。请阅读此说明以获取详细信息。
默认情况下,此属性包含一个值,该值取决于用户的平台和屏幕的几何形状。
相关函数
int width() const
13.51 windowFilePath : QString
该属性控制与widget相关的文件路径
该属性只对窗口window有用,对于子窗口没有任何用。它将一个文件路径和该窗口关联起来。如果你设置了文件路径但是没有设置窗口标题,Qt会把文件路径设置为该窗口标题,获取名字可以用QFileInfo::fileName()
如果在任何时候设置了窗口标题,那么窗口标题拥有更高的优先级,窗口的标题会是你设置的内容而不是文件路径。
除此之外,在苹果系统中,如果路径存在的话,也就同时给窗口设置了proxy icon
如果没有关联文件路径,named该属性包含一个空字符串
默认情况下,该属性包含一个空字符串
相关函数
QString windowFilePath() const
void setWindowFilePath(const QString &filePath)
13.52 windowFlags : Qt::WindowFlags
窗口标志是一个类型(例如Qt::Dialog)的并集,或者是空,或者给窗口系统的提示信息Qt::FramelessWindowHint
如果窗口小部件的类型为Qt :: Widget或Qt :: SubWindow并成为窗口(Qt :: Window,Qt :: Dialog等),则将其放置在桌面上的位置(0,0)。如果窗口小部件是一个窗口并变为Qt :: Widget或Qt :: SubWindow,则将其放置在相对于其父窗口小部件的位置(0,0)。
注:如果window的窗口标志发生改变,会调用其setParent()函数,从而引起该窗口隐藏。因此你必须手动的再次调用show()函数。
相关函数
Qt::WindowFlags windowFlags() const
void setWindowFlags(Qt::WindowFlags type)
13.53 windowIcon : QIcon
该属性控制widget的图标
该属性只对window起作用。如果已经设置了图标,windowIcon()函数返回应用程序图标
**注意:**在macOS上,窗口图标表示活动文档,除非使用setWindowFilePath设置了文件路径,否则将不会显示窗口图标。
相关函数
QIcon windowIcon() const
void setWindowIcon(const QIcon &icon)
通知信号
void windowIconChanged(const QIcon &icon)
13.54 windowModality : Qt::WindowModality
该属性控制被模态widget锁住的window
该属性只对window有意义。一个模态widget阻止了对其他window的输入。该属性的值包括了在widget可见的情况下被锁住的窗口。window可见的情况下改变该属性没有任何用。你首先应该隐藏窗口,再显示窗口。
默认情况下,该属性是Qt::NonModal
相关函数
Qt::WindowModality windowModality() const
void setWindowModality(Qt::WindowModality windowModality)
13.55 windowModified : bool
该属性获取window中显示的文本是否发生了变化并且没有保存
一个被修改了的窗口,即该窗口内容发生了变化并且没有被写入磁盘。该属性在不同平台有不同的效果。例如在OS X系统上会有一个修改的图标,而window系统会有一个’*’号。
窗口的标题必须包含一个”[]” 号,占位符,来表明该符号应该出现的位置。正常情况下,该符号应该出现在文件名之后。(例如,”document1.txt[] - Text Editor)。如果该窗口没有被修改,就不会出现’*’号。
如果一个widget被设置为被修改的状态,其所有祖先都会被设置为被修改状态。但是如果对一个widget设置setWindowModified(false),那么该未修改属性不会传递给其父widget,因为其他子widget或许被修改了。
相关函数
bool isWindowModified() const
void setWindowModified(bool)
13.56 windowOpacity : double
该属性控制窗口的透明性
该属性值范围是(1.0~0.0)
默认该属性为1.0
警告:将该属性从非透明改变为透明,在窗口显示前会引起一个paint事件。这会影响到QPixmap::grabWindow()大部分的使用功能。同时需要指出的是,半透明窗口的更新和调整大小的速度比非透明窗口要慢。
相关函数
qreal windowOpacity() const
void setWindowOpacity(qreal level)
13.57 windowTitle : QString
该属性控制窗口标题
该属性只对顶级窗口有用,例如window和对话框。如果没有设置窗口标题,那么窗口标题默认为windowFilePath,如果窗口文件路径也没有设置,那么标题是一个空字符串。
如果你会使用窗口是否改变机制,named窗口标题应该有一个“”的占位符,以表明窗口是否被修改过。正常情况下,“”应该出现在标题之后。(例如e.g., “document1.txt[*] - Text Editor”)。如果windowModified属性为false(默认值),那么该占位符也可以很轻松的删除。
相关函数
QString windowTitle() const
void setWindowTitle(const QString &)
通知信号
void windowTitleChanged(const QString &title)
13.58 x : const int
此属性保存窗口小部件相对于其父窗口的x坐标,包括任何窗口框架
有关Windows几何问题的概述,请参见“窗口几何”文档。
默认情况下,此属性的值为0。
相关函数
int x() const
13.59 y : const int
此属性保存窗口小部件相对于其父窗口的y坐标,包括任何窗口框架
有关Windows几何问题的概述,请参见“窗口几何”文档。
默认情况下,此属性的值为0。
相关函数
int y() const
14. 窗口类型
Qt 窗口标志枚举类型用于指定小部件的各种窗口系统属性。其中一些标志取决于底层窗口管理器是否支持它们。以下是窗口类型作用一览表:
窗口类型 | 描述 |
Qt::Widget | 这是 QWidget 的默认类型。如果它们有父级,这种类型的部件是子部件,如果没有父控件,则为独立窗口。 |
Qt::Window | 通常具有窗口系统框架和标题栏。请注意,如果部件没有父控件,则无法取消设置此标记(可以用在弹出子窗口比父窗口大很多的情况下)。 |
Qt::Dialog | 对话框(通常标题栏中没有最大化或最小化按钮)。dget这是 QDialog 的默认类型。如果要将其用作模态对话框,则应从另一个窗口启动它。 |
Qt::Sheet | macOS 表单式窗口。由于使用工作表意味着窗口模态,推荐的方法是使用QWidget :: setWindowModality()或QDialog :: open()。 |
Qt::Drawer | macOS 抽屉式窗口。 |
Qt::Popup | 弹出式顶层窗口,即它是模态的,但具有适合弹出菜单的窗口系统框架。 |
Qt::Tool | 工具窗口。工具窗口通常是一个小窗口,其标题栏和装饰比通常小,通常用于工具按钮的集合。 如果有父部件,则工具窗口将始终保持在其上。 |
Qt::Tooltip | 工具提示窗口。 这在内部用于实现工具提示,没有标题栏和窗口边框。 |
Qt::SplashScreen | 闪屏。 这是 QSplashScreen 的默认类型。 |
Qt::SubWindow | 子窗口,例如 QMdiSubWindow 窗口小部件。 |
Qt::ForeignWindow | 表示由另一个进程创建的本机平台窗口或手动使用本机代码的句柄。 |
Qt::CoverWindow | 代表一个封面窗口,例如,当应用程序在 BlackBerry 平台上最小化时显示。 |
通过 setWindowFlags() 函数可以对 QWidget 对象设置窗口类型。
常用示例:
w->setWindowFlags(Qt::Widget | Qt::FramelessWindowHint);//(窗口类型Widget | 去掉标题栏)
w->setWindowFlags(Qt::Dialog | Qt::FramelessWindowHint);//(窗口类型Dialog | 去掉标题栏)
15. 窗口标志
以下为可以设置多个的窗口标志对照表:
窗口标志 | 描述 |
Qt::MSWindowsFixedSizeDialogHint | Windows系统固定大小窄边框窗口 |
Qt::X11BypassWindowManagerHint | 无窗口边框的窗口,完全忽视窗口管理器和用户无法使用键盘进行输入 (除非手动调用QWidget::activateWindow()函数 |
Qt::FramelessWindowHint | 无法移动和改变大小的无窗口边框的窗口 |
Qt::NoDropShadowWindowHint | 禁用窗口阴影 |
Qt::WindowTitleHint | 带标题栏的窗口 |
Qt::WindowSystemMenuHint | 带系统菜单和尽可能地添加一个关闭按钮的窗口 |
Qt::CustomizeWindowHint | 关闭默认窗口标题提示栏 |
Qt::WindowMinimizeButtonHint | 窗口添加一个最小化按钮 |
Qt::WindowMaximizeButtonHint | 窗口添加一个最大化按钮 |
Qt::WindowCloseButtonHint | 窗口添加一个关闭按钮 |
Qt::WindowContextHelpButtonHint | 窗口添加一个帮助按钮 |
Qt::WindowShadeButtonHint | 如果窗口管理器支持,则在最小化按钮的位置添加一个阴影按钮 |
Qt::WindowStaysOnTopHint | 通知窗口系统置顶窗口 |
Qt::WindowStaysOnBottomHint | 通知窗口系统置于最底层窗口 |
通过 setWindowFlags() 函数可以对 QWidget 对象设置窗口标志。
常用示例:
this->setWindowFlags(Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint);// 设置无窗口边框 | 窗口置顶
16. 窗口属性
通过 setAttribute() 函数可以对 QWidget 对象设置 Qt::WidgetAttribute 枚举属性,从而改变 QWidget 对象的某些特性。
- Qt::WA_AcceptDrops:接受拖放,QWidget::setAcceptDrops()是此设置的便捷函数。
- Qt::WA_DeleteOnClose:QWidget 关闭时被 delete。
- Qt::WA_Disabled:设置小部件(注意是小部件,对窗口无效)被禁用(相对于调用setEnabled(false);)。
- Qt::WA_ForceUpdatesDisabled:禁用更新,即使其所有祖先都设置为启用更新状态,它仍将保持禁用状态。(相当于调用QWidget::setUpdatesEnabled())。
- Qt::WA_Hover:当鼠标进入或离开小部件时,强制 Qt 生成绘制事件。此功能通常在实现自定义样式时使用。
- Qt::WA_InputMethodEnabled:启用亚洲语言的输入法。创建自定义文本编辑小部件时必须设置。
- Qt::WA_KeyboardFocusChange:当用户使用键盘(tab、backtab 或快捷键)时更改焦点。用于顶层窗口设置。
- Qt::WA_NoChildEventsForParent:小部件不希望将 ChildAdded 或 ChildRemoved 事件发送到其父级。
- Qt::WA_NoChildEventsFromChildren:小部件不希望接收从其子部件发送的 ChildAdded 或 ChildRemoved 事件。
- Qt::WA_NoMousePropagation:禁止将鼠标事件传播到小部件的父级。默认情况下禁用此属性。
- Qt::WA_TransparentForMouseEvents:将禁用向小部件及其子部件传递鼠标事件。默认情况下禁用此属性。
- Qt::WA_NoSystemBackground:小部件没有背景,即当小部件接收到绘制事件时,背景不会自动重新绘制。窗口设置这个效果就是全黑。
- Qt::WA_OpaquePaintEvent:小部件在接收到绘制事件时绘制其所有像素。因此,在生成绘制事件之前,不需要更新、调整大小、滚动和焦点更改等操作来擦除小部件。
- Qt::WA_PaintUnclipped:使在此小部件上操作的所有 QPainter 对象的绘制都不裁剪(即 QPainter 设置裁剪区域无效)。只有设置了Qt::WA_PaintOnScreen标志的小部件才支持此标志。
- Qt::WA_PaintOnScreen:表示小部件要直接在屏幕上绘制。具有此属性集的小部件不参与组合管理,即它们不能是半透明的或通过半透明重叠小部件发光。它将禁用双缓冲。
- Qt::WA_QuitOnClose:小部件作为最后一个接受closeEvent()时,使 Qt 退出应用程序。可以使用QApplication::quitOnLastWindowClosed属性修改此行为。默认情况下,该属性为 Qt::Window 类型的所有小部件设置。
- Qt::WA_Resized:指示小部件具有明确的大小。该标志由QWidget::resize()和QWidget::setGeometry()设置或清除。
- Qt::WA_AlwaysShowToolTips:设置窗口(注意是窗口,当 QWidget 作为子部件时无效)为非活动时也显示提示信息。(setToolTip()设置了窗口提示信息)
下面重点介绍几个常用或特殊的属性:
16.1 Qt::WA_TransparentForMouseEvents
Qt 助手中对Qt::WA_TransparentForMouseEvents的解释如下:
When enabled, this attribute disables the delivery of mouse events to the widget and its children. Mouse events are delivered to other widgets as if the widget and its children were not present in the widget hierarchy; mouse clicks and other events effectively "pass through" them. This attribute is disabled by default.
大意是:
当该属性被激活启用时,将会使所有发送到窗体和窗体内部子控件的鼠标事件无效。鼠标事件被分发到其它的窗体部件,就像本窗体部件及本窗体内的子控件没有出现在窗体层次体系中。鼠标单击和鼠标其它事件高效地穿过(即绕开)本窗体部件及其内的子控件,这个属性默认是禁用未开启的。
16.2 Qt::WA_StaticContents
Qt 官方对Qt::WA_StaticContents解释如下:
Indicates that the widget contents are north-west aligned and static. On resize, such a widget will receive paint events only for parts of itself that are newly visible. This flag is set or cleared by the widget's author.
翻译为中文的意思就是:指示窗体内容靠西北方向即左上角对齐且是静态的。当窗体大小调整时,仅仅只有那些新露出来的可见窗体部分才会绘制。这个标识由窗体的开发者清除或设置。
通常情况下,当重新定义一个窗口部件大小时,Qt 会为窗口部件的整个可见区域生成一个绘制事件。但是如果该窗口部件在创建时使用了 Qt::WA_StaticContens 属性,那么绘制事件的区域就会被严格限定在之前没有被显示最近刚露出的部分上。这也就意味着,如果重新把窗口部件改变为比原来还要小的尺寸,那么就根本不会产生任何绘制事件。这在某些情况下,可以提到性能,降低 cpu 效率,当以前绘制的东西很费时间时(如:某个曲线、某个图形是经过某个复杂的数学运算得出的),不重绘、不重新计算,这将节约很多 cpu 时间,大大提高效率。
16.3 Qt::WA_OpaquePaintEvent
Qt 助手中对Qt::WA_OpaquePaintEvent解释如下:
Indicates that the widget paints all its pixels when it receives a paint event. Thus, it is not required for operations like updating, resizing, scrolling and focus changes to erase the widget before generating paint events. The use of WA_OpaquePaintEvent provides a small optimization by helping to reduce flicker on systems that do not support double buffering and avoiding computational cycles necessary to erase the background prior to painting. Note: Unlike WA_NoSystemBackground, WA_OpaquePaintEvent makes an effort to avoid transparent window backgrounds. This flag is set or cleared by the widget's author.
其含义大体是说:
指示窗体在收到绘制事件时,绘制它的所有像素。因此,在收到绘制事件之前,对于更新、大小调整、滚动条滚动、焦点更变等操作时,并不要求窗体擦除窗体背景。使用该标志对那些不支持双缓冲区的系统提供了小小的优化,从而减小闪烁;同时避免在绘制之前因擦除背景需要计算而耗费时间。不同于 WA_NoSystemBackground 标志,WA_OpaquePaintEvent 尽量避免窗体背景透明,这个标志是由窗体的开发者设置或清除。
注:有时候设置 WA_OpaquePaintEvent 属性,会影响用样式表设置窗口的背景颜色。
以上是 Qt 官方的解释。个人理解如下:
- 指示窗体在收到绘制事件时,绘制它的所有像素。这里“收到绘制事件”个人理解应该是第一次收到绘制事件时,也即窗体构建时,就把窗体所有的像素绘制一遍。
- 窗体一旦在完成,上面说的绘制完一遍所有像素后,此后所有有关窗体的更新、大小改变,焦点改变、滚动条滚动等操作都不会擦除窗体背景。也就是说以前画的东西都不会擦除重绘。也就是以前画的不重新计算、不重新绘制。当以前绘制的东西很费时间时(如:某个曲线、某个图形是经过某个复杂的数学运算得出的),不重绘、不重新计算,这将节约很多 cpu 时间大大提高效率(这也就是设置本标志后,不闪烁的原因吧)。
16.4 Qt::WA_NoMousePropagation
在 Qt 中,鼠标事件包含:鼠标按键按下,鼠标按键释放,鼠标双击事件,鼠标移动事件。分别由下面的 event handler(事件处理器,实际上就是一些可override的函数)来处理:
virtual void mousePressEvent(QMouseEvent *event);
virtual void mouseReleaseEvent(QMouseEvent *event);
virtual void mouseDoubleClickEvent(QMouseEvent *event);
virtual void mouseMoveEvent(QMouseEvent *event);
鼠标事件属于冒泡事件,鼠标事件会一直随着其父链一直路由下去,直到有其祖先所在的 widget 接受它,或者有事件过滤器消耗它。
注意:如果鼠标事件被路由到包含Qt:: WA_NoMousePropagation窗口属性(即该属性设置为 true)的窗口小部件,该鼠标事件不会进一步沿着父控件链路由。
17. 设置背景图
17.1 使用paintEvent()
实现
paintEvent()
是QWidget的一个虚函数:
void QWidget::paintEvent(QPaintEvent *event)
则可以重载这个函数,然后在这个函数中使用QPainter
设置背景图片。如下代码:
void Widget::paintEvent(QPaintEvent *event)
{
Q_UNUSED(event)
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing);
painter.drawPixmap(rect(),QPixmap(":/images/bk.png"));
}
该种方式本质上是利用绘制事件来完成的,绘制事件是一个请求,用于重新绘制全部或部分小部件。发生在以下几种情况下:
1、repaint()
或update()
被调用。
2、小部件由遮挡变为显示的情况。
3、一些未知的情况,哈哈。
为了提高性能,可以使用QPixmap提前将待绘制的图片加载进来,然后进行绘制。
17.2 使用样式表实现
样式表是Qt的一大亮点,可以使用setStyleSheet()
设置样式表来设置窗体的背景图,代码如下:
Widget::Widget(QWidget *parent)
: QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
setAttribute(Qt::WA_StyledBackground);
this->setStyleSheet("border-image:url(:/images/bk.png)");
}
17.3 使用QLabel实现
在QLabel
这个标签类中有一个void setPixmap(const QPixmap &)
可用于为QLabel设置一个Pixmap,所以可以使用这种方法设置背景图:把QLabel
的大小设置成与窗体的大小一样,然后使用setPixmap
设置背景图片即可,这样QLabel
的背景图就会完全填充整个窗体的背景。
如果想要设置背景图片(此处准备了一张背景图top_bk.png),使用下述代码即可(此处设置一个QLabel,其他的一样):
ui->label->setPixmap(QPixmap(":/images/top_bk.png"));
注意:使用QLabel进行背景图片拼接时,必须要保证QLabel的大小与待拼接的图片的大小一样,才能显示出完整的效果。
17.4 使用QPalette实现
可以直接在构造函数中使用QPalette
设置背景图片,如下代码:
QPalette palette = this->palette();
palette.setBrush(QPalette::Window,QBrush(QPixmap(":/images/bk.png")));
this->setPalette(palette);