文章目录
前言
通常情况下在进行GUI开发时需要涉及很多控件, 而在QT中已经内置了很多实用的控件, 通常情况下可以使用这些内置控件进行开发;
在QT Designer中左侧控件栏可以看到QT内置的大多控件;

不同的控件有着不同的内置信号与内置的槽可以进行使用;
控件属性
控件的英译为Widget, 即在之前文章中所创建的框架名;
通常情况下在QT中, 几乎全部的控件都继承自QWidget类, 实际上QWidget几乎是所有控件的基类, 都基于该类进行开发;
通常情况下可以在QTDesigner中控件的右侧可以看到当前控件的某些属性, 这些属性包含该控件属性, 该控件父类的属性, 及其抽象类的属性;

控件的属性能够控制控件的状态(大小, 位置等);
当然这些控件也可以在相应的文档进行查看;

核心属性表
| 属性 | 作用 |
|---|---|
enabled |
设置控件是否可使用. true 表示可用, false 表示禁用. |
geometry |
位置和尺寸. 包含 x, y, width, height 四个部分. 其中坐标是以父元素为参考进行设置的. |
windowTitle |
设置 widget 标题 |
windowIcon |
设置 widget 图标 |
windowOpacity |
设置 widget 透明度 |
cursor |
鼠标悬停时显示的图标形状. 是普通箭头, 还是沙漏, 还是十字等形状. 在 Qt Designer 界面中可以清楚看到可选项. |
font |
字体相关属性. 涉及到字体家族, 字体大小, 粗体, 斜体, 下划线等等样式. |
toolTip |
鼠标悬停在 widget 上会在状态栏中显示的提示信息. |
toolTipDuration |
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 不会收到鼠标移动事件, 只能收到鼠标按下或者释放的事件. |
tabletTracking |
是否跟踪触摸屏的移动事件. 类似于 mouseTracking. Qt 5.9 中引入的新属性. |
layoutDirection |
布局方向. - Qt::LeftToRight: 文本从左到右排列,也是默认值。 - Qt::RightToLeft: 文本从右到左排列。 - Qt::GlobalAtomics: 部件的布局方向由全局原子性决定(PS 这个翻译其实有点尴尬. 其实就是根据应用程序中的其他 widget 布局方向确定的). |
autoFillBackground |
是否自动填充背景颜色. |
windowFilePath |
能够把 widget 和一个本地文件路径关联起来. PS: 其实作用不大. |
accessibleName |
设置 widget 的可访问名称. 这个名称可以被辅助技术 (像屏幕阅读器) 获取到. 这个属性用于实现无障碍程序的场景中 (也就是给盲人写的程序). PS: 其实盲人也是可以使用电脑和手机的. 甚至盲人还能成为程序猿. 参见 |
accessibleDescription |
设置 widget 的详细描述. 作用同 accessibleName |
inputMethodHints |
针对输入框有效, 用来提示用户当前能输入的合法数据的格式. 比如只能输入数字, 只能输入日期等. |
enable 属性 (控件是否可用)
通常情况下, 在各个控件中都存在一个enable属性, 该属性取决于该控件是否可用;
该属性通常有两种状态;
-
true表示控件可用;
-
false表示控件不可用;
当控件不可用时, 对应的控件会变成灰色, 该控件及他的子对象控件都将无法被使用;
假设存在一个Widget中存在两个QPushButton;

其中一个QPushButton的objectName为Button, 功能是采用qDebug()打印消息 "The Button clicked" ;
另一个QPushButton的objectName为changeEnable, 功能是改变Button的Enable属性状态;
cpp
private slots:
void on_Button_clicked();
void on_changeEnable_clicked();
在QT中, 可以使用QWidget::isEnabled()方法来获得一个bool值, 该值可以判断当前控件的enable属性状态;
同时可以使用QWidget::setEnabled()方法来设置enable属性的状态;
因此只需要先用isEnable来判断当前状态为true或是false后使用setEnabled对状态进行修改即可;
cpp
void Widget::on_Button_clicked()
{
qDebug()<<"The button clicked";
}
void Widget::on_changeEnable_clicked()
{
bool is_enable = ui->Button->isEnabled();
if(is_enable){
ui->Button->setEnabled(false);
qDebug() << "The Enabled for Button is false";
}
else{
ui->Button->setEnabled(true);
qDebug() << "The Enabled for Button is true";
}
}
运行结果如下:

当change button enable按下后, 按钮Button无法使用, 因为其enable可用状态被设置成了false;
geometry 属性 (几何位置属性)
geometry在英译中的结果是几何, 在QTDesigner中的右侧控件属性可以看到该属性;

其控制着控件的几个属性:
-
X0横坐标离控件左上角的距离(单位px, 即像素); -
Y0纵坐标离控件左上角的距离(单位px); -
height控件的高度(单位
px); -
width控件的宽度(单位
px);

通常情况下, 我们可以使用QWidget::geometry()来获取一个控件的geometry属性;
该方法所返回的是一个QRect;
Rect的意思是几何, 在QT中, 也对了部分的集合概念进行了封装, 其中QRect则包含了X, Y, Wdith以及Height;
在之前的文章中提到, move()方法能够修改控件的位置, 而通过setGeometry()方法可以既修改控件位置, 也可以修改控件大小;
假设存在一个程序, 有五个QPushButton, 其中一个QPushButton为测试所需的按钮, 而剩下的几个QPushButton则是修改测试所需的Button按钮的位置;

首先使用的方法是每个按钮的槽首先获取Button的geometry属性QRect, 将QRect进行修改最终setGeomery()将QRect修改回对应的geometry;
通常在进行QRect属性设置时, 我们可以使用类似于setX(), setY()等方法进行属性的修改, 但是使用setX()或者setY()时, 只会修改控件左上角基于原点的X或Y, 这样会导致Width与Height会因为原点的变化进行变化;
-
代码
cppvoid Widget::on_upButton_clicked() { QRect rect = ui->Button->geometry(); qDebug() << rect; rect.setY(rect.y()-5); ui->Button->setGeometry(rect); } void Widget::on_downButton_clicked() { QRect rect = ui->Button->geometry(); qDebug() << rect; rect.setY(rect.y()+5); ui->Button->setGeometry(rect); } void Widget::on_leftButton_clicked() { QRect rect = ui->Button->geometry(); qDebug() << rect; rect.setX(rect.x()-5); ui->Button->setGeometry(rect); } void Widget::on_rightButton_clicked() { QRect rect = ui->Button->geometry(); qDebug() << rect; rect.setX(rect.x()+5); ui->Button->setGeometry(rect); } -
运行结果

从结果看出, Button的大小一直根据左上角的原点移动进行变化, 从而影响width和height;
若是使用这种方式的话必须同时将其他参数进行固定, 如X的变化会影响到width, Y的变化会影响到height, 因此使用这种方式的时候还需要将其会变化的参数进行固定;
且在固定的时候要遵循下面的规则:
- 先临时存储对应的宽或高为
tmp - 使用
setX或setY设置控件左上角距原点的位置 - 将临时存储的宽或高
tmp通过setHeight(tmp)或setWidth(tmp)设置进QRect
这里遵循该规则的主要原因是, 在使用setX或setY设置控件左上角距原点位置时, 对应的宽或高会因为该参数的改变而跟着变化;
因此需要临时存储旧的宽或高, 当该控件的宽或高随着setX或setY变化时, 再将临时存储的原先的宽或高进行参数设置, 从而保持控件的宽或高;
-
代码
cppvoid Widget::on_upButton_clicked() { QRect rect = ui->Button->geometry(); int height = rect.height(); qDebug() << rect; rect.setY(rect.y()-5); rect.setHeight(height); ui->Button->setGeometry(rect); } void Widget::on_downButton_clicked() { QRect rect = ui->Button->geometry(); int height = rect.height(); qDebug() << rect; rect.setY(rect.y()+5); rect.setHeight(height); ui->Button->setGeometry(rect); } void Widget::on_leftButton_clicked() { QRect rect = ui->Button->geometry(); int width = rect.width(); qDebug() << rect; rect.setX(rect.x()-5); rect.setWidth(width); ui->Button->setGeometry(rect); } void Widget::on_rightButton_clicked() { QRect rect = ui->Button->geometry(); int width = rect.width(); qDebug() << rect; rect.setX(rect.x()+5); rect.setWidth(width); ui->Button->setGeometry(rect); } -
运行结果为

但使用这种方式还是过于复杂, 首先是需要固定的执行顺序, 若是存在对setX() / setY()不了解的人使用, 或许会疑惑只是修改了一行代码, 原始的功能却不能用了?
本质上是因为这里的某个参数会因为另一个参数的变化而变化, 那么是否有更好的办法解决这种问题?
- 有的 兄弟有的
QRect提供了能够直接传参来设置QRect的方式, 即为setRect();
cpp
void QRect::setRect(int x, int y, int width, int height);
能够直接对X, Y, width, height直接进行设定, 以确保其能够同步修改这些属性而不让某个属性因另一个属性的变化而发生变化;
-
代码
cppvoid Widget::on_upButton_clicked() { QRect rect = ui->Button->geometry(); qDebug() << rect; rect.setRect(rect.x(), rect.y()-5, rect.width(), rect.height()); ui->Button->setGeometry(rect); } void Widget::on_downButton_clicked() { QRect rect = ui->Button->geometry(); qDebug() << rect; rect.setRect(rect.x(), rect.y()+5, rect.width(), rect.height()); ui->Button->setGeometry(rect); } void Widget::on_leftButton_clicked() { QRect rect = ui->Button->geometry(); qDebug() << rect; rect.setRect(rect.x()-5, rect.y(), rect.width(), rect.height()); ui->Button->setGeometry(rect); } void Widget::on_rightButton_clicked() { QRect rect = ui->Button->geometry(); qDebug() << rect; rect.setRect(rect.x()+5, rect.y(), rect.width(), rect.height()); ui->Button->setGeometry(rect); }
其运行结果与上一个运行结果相同, 使用更简洁的代码来完成了相同的功能;