Qt是一个实现图形化程序的程序。为了便于我们开发,Qt为我们提供了许多“控件”。我们需要熟悉并掌握这些控件的使用。
一.什么是控件
控件是构成⼀个图形化界⾯的基本要素.
示例一:
像上述⽰例一中的,按钮,列表视图,树形视图,单⾏输⼊框,多⾏输⼊框,滚动条,下拉框等,都可以称为"控 件".
示例二:Qt designer中的控件
Qt作为⼀个成熟的GUI开发框架,内置了⼤量的常⽤控件.并且Qt也提供了"⾃定义控件"的能⼒,可以让程序猿在现有控件不能满⾜需求的时候,对现有控件做 出扩展,或者⼿搓出新的控件。
二.QWidget核心属性
在Qt中,使⽤QWidget类表⽰"控件".像按钮,视图,输⼊框,滚动条等具体的控件类,都是继承自QWidget.
可以说,QWidget中就包含了Qt整个控件体系中,通⽤的部分.
在Qt Designer中,随便拖⼀个控件过来,选中该控件,即可在右下⽅看到QWidget中的属性
这些属性,既可以通过Qt designer直接修改,也可以通过代码修改。
注:想了解具体属性及含义,可以再帮助文档中查询。
1.简述Qwidget核心属性
表格中列出来核心属性及其作用:
属性 | 作用 |
enabled | 表示控件是否可用。true表示可用,false表示不可用 |
geometry | 位置和尺寸,包含x,y,width,height 四个部分. 其中坐标是以⽗元素为参考进⾏设置的. |
windowTitle | 设置widget标题 |
windowlcon | 设置widget图标 |
windowOpacity | 设置widget透明度 |
cursor | 鼠标悬停时的图标形状 |
font | 字体相关属性 |
toolTip | 鼠标悬停在widget上会在状态栏中显示的提示信息 |
toolTipDuring | toolTip 显⽰的持续时间 |
statusTip | Widget 状态发⽣改变时显⽰的提⽰信息(⽐如按钮被按下等). |
styleSheet | 允许使⽤ CSS来设置widget 中的样式. |
focusPolicy | 该 widget 如何获取到焦点. Qt::NoFocus:控件不参与焦点管理,即⽆法通过键盘或⿏标获取焦点 Qt::TabFocus:控件可以通过Tab键获得焦点 • • • Qt::ClickFocus:控件可以通过⿏标点击获得焦点 • Qt::StrongFocus:控件可以通过键盘和⿏标获得焦点 • Qt::WheelFocus:控件可以通过⿏标滚轮获得焦点(在某些平台或样式中可能不可 ⽤) |
windowModality | 指定窗⼝是否具有"模态"⾏为. |
accessibleName | 设置widget的可访问名称.这个名称可以被辅助技术(像屏幕阅读器)获取到.这个属性⽤于实现⽆障碍程序的场景中(也就是给盲⼈写的程序). |
接下来让我们详细了解每个属性吧。
三.QWidget的enabled属性
1.概念
enabled属性用于表示部件是否可用,一个可用的部件可以接收和处理鼠标和键盘事件,当部件不可用时则无法接收和处理鼠标和键盘事件。
2.API
api | 作用 |
isEnabled() | 获取到控件的可⽤状态. |
setEnabled() | 设置控件是否可使⽤.true 表⽰可⽤,false 表⽰禁⽤. |
• 所谓"禁⽤"指的是该控件不能接收任何⽤⼾的输⼊事件,并且外观上往往是灰⾊的.
• 如果⼀个widget被禁⽤,则该widget的⼦元素也被禁⽤.
3.代码示例
eg1:使⽤代码创建⼀个禁⽤状态的按钮
结果:
eg2:通过按钮2切换按钮1的禁⽤状态
步骤一:在designer中创建两个按钮,并右键,为其创建槽函数
步骤2:编写对应槽函数
QObject 的 objectName 属性介绍:
obiectName是QObject的重要属性。Qwidget继承QObject,也具有了该属性。
在⼀个 Qt 程序中,objectName 相当于对象的⾝份标识, 彼此之间不能重复.
在使⽤ Qt Designer 时,尤其是界⾯上存在多个widget 的时候,可以通过objectName 获 取到指定的widget对象.
结果:
四.geometry属性
1.概念
位置和尺寸。本质是四个属性的统称:
• x 横坐标
• y 纵坐标
• width 宽度
• height ⾼度
如图示:
注:
1.实际开发中,我们并不会直接使⽤这⼏个属性,⽽是通过⼀系列封装的⽅法来获取/修改
2.Qt坐标系为左手坐标系,左上角为原点。
2.API
api | 作用 |
geometry() | 获取到控件的位置和尺⼨. 返回结果是⼀个QRect,包含x,y,width,height.其 中 x, y是左上⻆的坐标. |
setGeometry(QRect) setGeometry(int x,int y, int width,int height) | 设置控件的位置和尺⼨. 可以直接设置⼀个QRect, 也可以分四个属性单独设置. |
3.代码示例
eg1:控制按钮的位置
步骤一:在designer界⾯中拖五个按钮.
步骤二:转到按钮clicked()信号对应的槽函数,编写代码
结果:
问题:
运行程序我们看到,点击按钮只改变target按钮左上角位置,并且会影响尺寸变化,这不是我们预期的效果。
原因:
上述代码中我们是直接设置的 QRect 中的x,y.相当于修改左上点坐标。
实际上QRect内部是存储了左上和右下两个点的坐标,再通过这两个点的坐标差值计算⻓宽. 单纯修改左上坐标就会引起整个矩形的⻓宽发⽣改变.
优化:
设置左上点坐标的同时,设置尺寸使其和之前保持一致
优化版控制按钮位置:
结果:
eg2:表白恶搞
步骤一:往界⾯上拖拽两个按钮和⼀个Label.
步骤二:编写槽函数
结果:
五.window frame 的影响
window frame 窗口框架 是操作系统自带的
1. 影响
如果 widget 作为⼀个窗⼝ (带有标题栏, 最⼩化, 最⼤化, 关闭按钮), 那么在计算尺⼨和坐标的 时候就有两种算法. 包含window frame 和 不包含 window frame.
在Qt中,关于位置尺寸,提供了很多的API 有的API的位置是以Widget本体左上角为原点的不包含 window frame.有的API的位置是以window frame为左上角为原点.
其中 x(), y(), frameGeometry(), pos(), move() 都是按照包含 window frame 的⽅式来计算的.
其中 geometry(), width(), height(), rect(), size() 则是按照不包含 window frame 的⽅式来计算的.
当然, 如果⼀个不是作为窗⼝的 widget , 上述两类⽅式得到的结果是⼀致的.
2.API
api | 作用 |
x() | 获取横坐标,计算时包含 window frame |
y() | 获取纵坐标,计算时包含 window frame |
pos() | 返回 QPoint 对象, ⾥⾯包含 x(), y(), setX(), setY() 等⽅法.计算时包含 window frame |
frame Size() | 返回 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 对象. QRect 相当于 QPoint 和 QSize 的结合体. 可以获取并设置 x,y, width, size.计算时不包含 window frame 对象. |
geometry() | 返回 QRect 对象. QRect 相当于 QPoint 和 QSize 的结合体. 可以获取 x, y,width, size.计算时不包含 window frame 对象. |
setGeometry() | 直接设置窗⼝的位置和尺⼨. 可以设置 x, y, width, height, 或者 QRect 对象.计算时不包含 window frame 对象 |
3.代码示例
geometry 和 frameGeometry 的区别
步骤:创建一个按钮,查看geometry 和 frameGeometry的返回值
结果:
问题:
执行程序, 可以看到
构造函数中, 打印出的 geometry 和 frameGeometry 是相同的.
但是在点击按钮时, 打印的 geometry 和 frameGeometry 则存在差异.原因:
在构造⽅法中, Widget刚刚创建出来,还没有加⼊到对象树中.此时也就不具备 Window frame.
在按钮的slot函数中,由于⽤⼾点击的时候,对象树已经构造好了,此时Widget 已经具备了 Window frame,因此在位置和尺⼨上均出现了差异.
注意:
如果把上述代码修改成打印 pushButton 的 geometry和frameGeometry,结果就是完全相 同的.因为 pushButton 并⾮是⼀个窗⼝.