Qt-常用控件

1.控件概述

Widget 是 Qt 中的核⼼概念.英⽂原义是"⼩部件", 我们此处也把它翻译为 "控件" .控件是构成⼀个图形化界⾯的基本要素.

像上述⽰例中的, 按钮, 列表视图, 树形视图, 单⾏输⼊框, 多⾏输⼊框, 滚动条, 下拉框等,都可以称为 "控件".
Qt作为⼀个成熟的GUI开发框架,内置了⼤量的常⽤控件. 这⼀点在 Qt Designer 中就可以看到端倪.并且 Qt 也提供了"⾃定义控件" 的能⼒, 可以让程序猿在现有控件不能满⾜需求的时候,对现有控件做出扩展, 或者⼿搓出新的控件.

综上, 学习 Qt, 其中⼀个很重要的任务就是熟悉并掌握 Qt 内置的常⽤控件. 这些控件对于我们快速开发出符合需求的界⾯, 是⾄关重要的.

2.QWidget核心属性

在 Qt 中, 使⽤ QWidget 类表⽰ "控件" . 像按钮, 视图, 输⼊框, 滚动条 等具体的控件类, 都是继承⾃ QWidget.

可以说, QWidget 中就包含了 Qt 整个控件体系中, 通⽤的部分.

在 Qt Designer 中, 随便拖⼀个控件过来, 选中该控件, 即可在右下⽅看到 QWidget 中的属性.

这些属性既可以通过 QtDesigner 会直接修改, 也可以通过代码的⽅式修改.
这些属性的具体含义, 在 Qt Assistant 中均有详细介绍.

在Qt Assistant 中搜索 QWidget,即可找到对应的⽂档说明. (或者在 Qt Creator 代码中,选中QWidget, 按 F1 也可).
下列表格列出了 QWidget 中的属性及其作⽤.

属性 作⽤
enabled 设置控件是否可使⽤. true 表⽰可⽤, false 表⽰禁⽤.
geometry 位置和尺⼨.包含 x, y, width, height 四个部分.其中坐标是以⽗元素为参考进⾏设置的.
windowTitle 设置 widget 标题
windowIcon 设置 widget 图标
windowOpacity 设置 widget 透明度
cursor ⿏标悬停时显⽰的图标形状.是普通箭头, 还是沙漏, 还是⼗字等形状.在 Qt Designer 界⾯中可以清楚看到可选项.
font 字体相关属性.涉及到字体家族, 字体⼤⼩, 粗体, 斜体, 下划线等等样式.
toolTip ⿏标悬停在 widget 上会在状态栏中显⽰的提⽰信息.
toolTipDuring 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: 其实盲⼈也是可以使⽤电脑和⼿机的. 甚⾄盲⼈还能成为程序猿. 参⻅https://www.bilibili.com/video/BV1954y1d7z9
accessibleDescription 设置 widget 的详细描述. 作⽤同 accessibleName
inputMethodHints 针对输⼊框有效, ⽤来提⽰⽤⼾当前能输⼊的合法数据的格式. ⽐如只能输⼊数字, 只能输⼊⽇期等.

2.1 enabled

描述了一个控件是否处于"可用"状态.

API 说明
isEnabled() 获取到控件的可⽤状态.
setEnabled 设置控件是否可使⽤. true 表⽰可⽤, false 表⽰禁⽤.

所谓 "禁用 " 指的是该控件不能接收任何⽤⼾的输⼊事件, 并且外观上往往是灰⾊的.
如果⼀个 widget 被禁⽤, 则该 widget 的⼦元素也被禁⽤.

cpp 复制代码
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
	ui->setupUi(this);	
	QPushButton* btn = new QPushButton(this);
	btn->setText("这是个被禁⽤的按钮");
	btn->setEnabled(false);
}

运行后的结果:

运⾏程序, 可以看到按钮处于灰⾊状态, ⽆法被点击

2.2 geometry

位置和尺⼨. 其实是四个属性的统称:

  • x 横坐标
  • y 纵坐标
  • width 宽度
  • height ⾼度

    代表窗体种控件的大小尺寸和存在的位置
    但是实际开发中, 我们并不会直接使⽤这⼏个属性, ⽽是通过⼀系列封装的⽅法来获取/修改.
    对于 Qt 的坐标系, 不要忘记是⼀个 "左⼿坐标系". 其中坐标系的原点是当前元素的⽗元素的左上⻆.
API 说明
geometry() 获取到控件的位置和尺⼨.返回结果是⼀个 QRect, 包含了 x, y, width, height.其中 x, y 是左上⻆的坐标.
setGeometry(QRect) setGeometry(int x, int y,int width, int height) 设置控件的位置和尺⼨. 可以直接设置⼀个 QRect, 也可以分四个属性单独设置

代码⽰例: 控制按钮的位置

  1. 在界⾯中拖五个按钮.
    五个按钮的 objectName 分别为 pushButton_target , pushButton_up ,
    pushButton_down , pushButton_left , pushButton_right
    五个按钮的初始位置和⼤⼩都随意.
  2. 在 widget.cpp 中编写四个按钮的 slot 函数
cpp 复制代码
void Widget::on_pushButton_up_clicked()
{
	QRect rect = ui->pushButton_target->geometry();
	rect.setY(rect.y() - 5);
	ui->pushButton_target->setGeometry(rect);
}
void Widget::on_pushButton_down_clicked()
{
	QRect rect = ui->pushButton_target->geometry();
	rect.setY(rect.y() + 5);
	ui->pushButton_target->setGeometry(rect);
}
void Widget::on_pushButton_left_clicked()
{
	QRect rect = ui->pushButton_target->geometry();
	rect.setX(rect.x() - 5);
	ui->pushButton_target->setGeometry(rect);
}
void Widget::on_pushButton_right_clicked()
{
	QRect rect = ui->pushButton_target->geometry();
	rect.setX(rect.x() + 5);
	ui->pushButton_target->setGeometry(rect);
}

运⾏程序, 可以看到, 按下下⽅的四个按钮, 就会控制 target 的左上⻆的位置. 对应的按钮整个尺⼨也会发⽣改变.

上述代码中我们是直接设置的 QRect 中的 x, y . 实际上 QRect 内部是存储了左上和右下两个点的坐标, 再通过这两个点的坐标差值计算⻓宽.
单纯修改左上坐标就会引起整个矩形的⻓宽发⽣改变.

如果想让整个按钮都移动,可以改成下列代码:

cpp 复制代码
void Widget::on_pushButton_up_clicked()
{
	QRect rect = ui->pushButton_target->geometry();
	ui->pushButton_target->setGeometry(rect.x(), rect.y() - 5, rect.width(),
	rect.height();
}
void Widget::on_pushButton_down_clicked()
{
	QRect rect = ui->pushButton_target->geometry();
	ui->pushButton_target->setGeometry(rect.x(), rect.y() + 5, rect.width(),
	rect.height();
}
void Widget::on_pushButton_left_clicked()
{
	QRect rect = ui->pushButton_target->geometry();
	ui->pushButton_target->setGeometry(rect.x() - 5, rect.y(), rect.width(),
	rect.height();
}
void Widget::on_pushButton_right_clicked()
{
	QRect rect = ui->pushButton_target->geometry();
	ui->pushButton_target->setGeometry(rect.x() + 5, rect.y(), rect.width(),
	rect.height();
}

上述代码使⽤ move ⽅法也是可以的

代码式例:⼀个表⽩程序

  1. 往界⾯上拖拽两个按钮和⼀个 Label.
    Label 的 objectName 为 pushButton_accept 和 pushButton_reject , label 的
    objectName 为 label

    控件中⽂本如下图所⽰
  2. 在 widget.cpp 中添加 slot 函数
cpp 复制代码
void Widget::on_pushButton_accept_clicked()
{
	ui->label->setText("⼥神快来嘴⼀个! mua~~");
}
void Widget::on_pushButton_reject_pressed()
{
	// 获取窗⼝的宽度和⾼度
	int width = this->geometry().width();
	int height = this->geometry().height();
	// 重新⽣成按钮的位置.
	int x = rand() % width;
	int y = rand() % height;
	// 设置新的位置
	ui->pushButton_reject->move(x, y);
}

运⾏程序, 可以看到, 当点击 "残忍拒绝" 时, 按钮就跑了.

上述代码使⽤的是 pressed, ⿏标按下事件. 如果使⽤ mouseMoveEvent, 会更狠⼀些, 只要⿏标移动过来, 按钮就跑了.

对应的代码更⿇烦⼀些 (需要⾃定义类继承⾃ QPushButton, 重写 mouseMoveEvent ⽅法).此处暂时不展开.

3.WindowsFrame的影响

如果 widget 作为⼀个窗⼝ (带有标题栏, 最⼩化, 最⼤化, 关闭按钮), 那么在计算尺⼨和坐标的时候就有两种算法. 包含 window frame 和 不包含 window frame.
其中 x(), y(), frameGeometry(), pos(), move() 都是按照包含 window frame 的⽅式来计算的 .
其中 geometry(), width(), height(), rect(), size() 则是按照不包含 window frame 的⽅式来计算的 .

当然, 如果⼀个不是作为窗⼝的 widget , 上述两类⽅式得到的结果是⼀致的.

也就是window frame是整个窗口,而geometry()指的是窗口种不包含window Title的面板

相关 API

API 说明
x() 获取横坐标 计算时包含 window frame
y() 获取纵坐标 计算时包含 window frame
pos() 返回 QPoint 对象,里面包含 x(),y(),setX(),setY()等方法计算时包含 window frame
frameSize() 返回 QSize 对象,里面包含 width(),height(),setWidth(),setHeight()等方法计算时包含 window frame
frameGeometry() 返回 ORect 对象.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 对象.

认真观察上⾯的表格, 可以看到,其实这⾥的 API 有 frameGeometry 和 geometry 两个就⾜够完成所有的需求了.

代码⽰例: 感受geometry和frameGeometry 的区别.

  1. 在界⾯上放置⼀个按钮.
  2. 在按钮的 slot 函数中, 编写代码
cpp 复制代码
void Widget::on_pushButton_clicked()
{
	QRect rect1 = this->geometry();
	QRect rect2 = this->frameGeometry();
	qDebug() << rect1;
	qDebug() << rect2;
}
  1. 在构造函数中, 也添加同样的代码
cpp 复制代码
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
	ui->setupUi(this);
	QRect rect1 = this->geometry();
	QRect rect2 = this->frameGeometry();
	qDebug() << rect1;
	qDebug() << rect2;
}

执⾏程序, 可以看到, 构造函数中,打印出的 geometry 和 frameGeometry 是相同的.
但是在点击按钮时, 打印的 geometry 和 frameGeometry 则存在差异.

  1. 在构造方法中,Widget 刚刚创建出来,还没有加入到对象树中,此时也就不具备 Windowframe.
  2. 在按钮的 slot 函数中,由于用户点击的时候,对象树已经构造好了,此时 Widget 已经具备了Window frame,因此在位置和尺寸上均出现了差异
  3. 如果把上述代码修改成打印 pushButton的 geometry和 frameGeometry,结果就是完全相同的.因为 pushButton 并非是一个窗口

4. Window Title

API 说明
windowTitle() 获取到控件的窗口标题
setWindowTitle(constQString& title) 设置控件的窗口标题

注意!上述设置操作针对不同的 widget 可能会有不同的行为如果是顶层 widget (独立窗口),这个操作才会有效,

如果是⼦ widget, 这个操作⽆任何效果.

5.Windowlcon属性

API 说明
windowlcon() 获取到控件的窗口图标.返回 Olcon 对象
setWindowlcon(constQlcon& icon)

同 windowTitle, 上述操作仅针对顶层 widget有效.

代码⽰例: 设置窗⼝图标


2. 修改 widget.cpp

cpp 复制代码
#include <QIcon>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
	ui->setupUi(this);
	// 创建图标对象
	QIcon icon("d:/rose.jpg");
	// 设置图标
	this->setWindowIcon(icon);
}

注意: Windows 下路径的分隔符可以使⽤ / 也可以使⽤ \ . 但是如果在 字符串 中使⽤ \ , 需要写
作转义字符的形式 \ .因此我们还是更推荐使⽤ /

3. 运⾏程序, 可以看到窗⼝图标已经成为上述图⽚

注意:
实际开发中,我们一般不会在代码中通过绝对路径引入图片,因为我们无法保证程序发布后,用户的电脑上也有同样的路径.
如果使用相对路径,则需要确保代码中的相对路径写法和图片实际所在的路径匹配(比如代码中写作"./image/rose.jpg",就需要在当前工作目录中创建 image 目录,并把 rose.jpg 放进去),

6.qrc文件资源管理器

Qt 使用 qrc 机制帮我们自动完成了上述工作,更方便的来管理项目依赖的静态资源.
qrc 文件是一种XML格式的资源配置文件 ,它用XML记录硬盘上的文件和对应的随意指定的资源名称,应用程序通过资源名称来访问这些资源,在Ot开发中,可以通过将资源文件添加到项目中来方便地访问和管理这些资源,这些资源文件可以位于qrc文件所在目录的同级或其子目录下在构建程序的过程中,Qt 会把资源文件的二进制数据转成 cpp 代码,编译到 exe 中 .从而使依赖的资源变得"路径无关.这种资源管理机制并非 Qt 独有,很多开发框架都有类似的机制.例如 Android 的 Resources

和 AssetManager 也是类似的效果.

代码⽰例: 通过 qrc 管理图⽚作为图标

  1. 右键项⽬, 创建⼀个 Qt Resource File (qrc ⽂件), ⽂件名随意起(不要带中⽂), 此处叫 resource.qrc .
  2. 在 qrc 编辑器中, 添加前缀

    此处我们前缀设置成 / 即可.
    所谓的前缀,可以理解成 "⽬录" . 这个前缀决定了后续我们如何在代码中访问资源.
  3. 在资源编辑器中, 点击 add Files 添加资源⽂件.此处我们需要添加的是 rose.jpg

注意:添加的文件必须是在 qrc 文件的同级目录,或者同级目录的子目录中,因此我们需要把之前 D盘
中的 rose.jpg 复制到上述目录中.

  1. 在代码中使用 rose.jpg
    编辑 widget.cpp
cpp 复制代码
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
	ui->setupUi(this);
	// 访问到 rose.jpg 资源
	QIcon icon(":/rose.jpg");
	// 设置图标
	this->setWindowIcon(icon);
}

注意上述路径的访问规则

  • 使用 :作为开头,表示从 qrc 中读取资源,
  • /是上面配置的前缀
  • rose.jpg 是资源的名称
    需要确保代码中编写的路径和添加到 qrc 中资源的路径匹配,否则资源无法被访问(同时也不会有报错提示).
  1. 运⾏程序, 可以看到图标已经能正确设置

上述 qrc 这一套资源管理方案,优点和缺点都很明显优点: 确保了图片,字体,声音等资源能够真正做到"目录无关",无论如何都不会出现资源丢失的情况.

缺点:不适合管理体积大的资源,如果资源比较大 (比如是几个 MB 的文件),或者资源特别多,生成的最终的 exe 体积就会比较大,程序运行消耗的内存也会增大,程序编译的时间也会显著增加.

7.windowOpacity属性

API 说明
windowOpacity() 获取到控件的不透明数值,返回 float,取值为 0.0->1.0 其中 0.0 表示全透明,1.0 表示完全不透明.
setWindowOpacity(float n) 设置控件的不透明数值

代码示例: 调整窗口透明度

  1. 在界面上拖放两个按钮,分别用来增加不透明度和减少不透明度objectName分别为 pushButton add 和 pushButton sub
  2. 编写 wdiget.cpp,编写两个按钮的 slot 函数
    点击 pushButton_sub 会减少不透明度,也就是窗口越来越透明。
    点击 pushButton_add 会增加不透明度,窗口会逐渐恢复
cpp 复制代码
void Widget::on_pushButton_add_clicked()
{
	float opacity = this->windowOpacity();
	if (opacity >= 1.0) {
		return;
	}
	qDebug() << opacity;
	opacity += 0.1;
	this->setWindowOpacity(opacity);
}

void Widget::on_pushButton_sub_clicked()
{
	float opacity = this->windowOpacity();
	if (opacity <= 0.0) {
		return;
	}
	qDebug() << opacity;
	opacity -= 0.1;
	this->setWindowOpacity(opacity);
	
}
  1. 执行程序,可以看到,点击了几下-之后,就可以透过窗口看到后面的猫猫头了.点击+又会逐渐恢复.

    同时控制台中也可以看到 opacity 数值的变化

注意,C++ 中 float 类型遵守 IEEE 754 标准,因此在进行运算的时候会有一定的精度误差.因此 1
0.1的数值并非是 0.9

EEE 754 标准

规定了浮点数要使用 二进制 科学计数法 的方式来表示~~
把一个浮点数分成三个部分:
1)符号位
2)有效数字
3)指数部分

使用二进制表示的有效数字,而且这里是小于 0 的小数部分(默认整数部分是 1)

第一个有效数字位表示 0.5

第二个有效数字位表示 0.25

第三个表示 0.125

101 => 0.625门优化的)

0.1 这样的小数

由于 float 和 double 有效数字部分长度都是有限的导致无法凑出一个非常非常接近 0.1 这样的数字

8.cursor属性

API 说明
cursor() 获取到当前 widget 的 cursor属性,返回 OCursor 对象当鼠标悬停在该 widget 上时,就会显示出对应的形状
setCursor(const QCursor& cursor) 设置该 widget 光标的形状,仅在鼠标停留在该 widget 上时生效
OGuiApplication::setOverrideCursor(const OCursor& cursor) 设置全局光标的形状.对整个程序中的所有 widget 都会生效.覆盖上面的 setCursor 设置的内容.

1. 代码⽰例 : 在 Qt Designer 中设置按钮的光标

  1. 在界⾯中创建⼀个按钮.
  2. 直接在右侧属性编辑区修改 cursor 属性为 "等待"
  3. 运行程序,鼠标悬停到按钮上,即可看到光标的变化

2. 代码⽰例: 通过代码设置按钮的光标

  1. 编写 widget.cpp
    其中 Qt::WaitCursor就是自带的沙漏形状的光标
cpp 复制代码
#include <QPushButton>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
	// 创建按钮
	QPushButton* button = new QPushButton(this);
	button->resize(100, 50);
	button->move(100, 100);
	button->setText("这是⼀个按钮");
	// 设置按钮的 cursor
	button->setCursor(QCursor(Qt::WaitCursor));
}

系统内置的光标形状如下 :

Ctrl + 左键 点击 Qt::WaitCursor 跳转到源码即可看到

cpp 复制代码
enum CursorShape {
ArrowCursor,
UpArrowCursor,
CrossCursor,
WaitCursor,
IBeamCursor,
SizeVerCursor,
SizeHorCursor,
SizeBDiagCursor,
SizeFDiagCursor,
SizeAllCursor,
BlankCursor,
SplitVCursor,
SplitHCursor,
PointingHandCursor,
ForbiddenCursor,
WhatsThisCursor,
BusyCursor,
OpenHandCursor,
ClosedHandCursor,
DragCopyCursor,
DragMoveCursor,
DragLinkCursor,
LastCursor = DragLinkCursor,
BitmapCursor = 24,
CustomCursor = 25
}
  1. 运⾏程序, 观察效果.
  1. 代码⽰例: ⾃定义⿏标光标

Qt ⾃带的光标形状有限. 我们也可以⾃⼰找个图⽚, 做成⿏标的光标.⽐如我们有请滑稽⽼铁.

  1. 创建 qrc 资源⽂件, 添加前缀 / , 并加⼊ huaji.png


  2. 编写 widget.cpp
cpp 复制代码
#include <QPixmap>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
	// 创建⼀个位图对象, 加载⾃定义光标图⽚
	QPixmap pixmap(":/huaji.png");
	// 缩放图⽚为 64 * 64 的尺⼨.
	pixmap = pixmap.scaled(64, 64);
	// 创建 QCursor 对象, 并指定 "热点" 为 (2, 2) 坐标位置.
	// 所谓 "热点" 就是⿏标点击时⽣效的位置.
	QCursor cursor(pixmap, 2, 2);
	// 设置光标
	this->setCursor(cursor);
}

注意:访问图片的文件的类型是QPixmap

  1. 运⾏程序, 观察效果

9.font属性

API 说明
font() 获取当前 widget 的字体信息,返回 QFont 对象,
setFont(const QFont& font) 设置当前 widget 的字体信息.

关于 QFont

属性 说明
family 字体家族.比如"楷体""宋体""微软雅黑"等
pointSize 字体大小
weight 字体粗细,以数值方式表示粗细程度取值范围为[0,99],数值越大,越智
bold 是否加粗.设置为 true,相当于 weight为 75.设置为 false 相当于weight 为50.
italic 是否倾斜
underline 是否带有下划线
strikeOut 是否带有删除线

代码⽰例: 在 Qt Designer 中设置字体属性

  1. 在界⾯上创建⼀个 label
  2. 在右侧的属性编辑区,设置该 label的 font 相关属性
    在这里调整上述属性,可以实时的看到文字的变化
  3. 执⾏程序, 观察效果

代码⽰例2 :在代码中设置字体属性

  1. 在界⾯中创建 label, objectName 使⽤默认的 label 即可.
  2. 修改 widget.cpp
cpp 复制代码
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
	ui->setupUi(this);
	// 设置 label 的⽂本内容
	ui->label->setText("这是⼀段⽂本");
	// 创建字体对象
	QFont font;
	// 设置字体家族
	font.setFamily("仿宋");
	// 设置字体⼤⼩
	font.setPointSize(20);
	// 设置字体加粗
	font.setBold(true);
	// 设置字体倾斜
	font.setItalic(true);
	// 设置字体下划线
	font.setUnderline(true);
	// 设置字体删除线
	font.setStrikeOut(true);
	// 设置字体对象到 label 上
	ui->label->setFont(font);
}
  1. 运⾏程序, 观察效果

10.toolTip属性

鼠标放在控件上会出现

API 说明
setToolTip 设置 toolTip. 鼠标悬停在该 widget 上时会有提示说明
setToolTipDuring 设置 toolTip 提示的时间.单位 ms. 时间到后 toolTip 自动消失.

代码⽰例:设置按钮的 toolTip

  1. 在界⾯上拖放两个按钮. objectName 设置为 pushButton_yes 和 pushButton_no
  2. 编写 widget.cpp
cpp 复制代码
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
	ui->setupUi(this);
	ui->pushButton_yes->setToolTip("这个是 yes 按钮");
	ui->pushButton_yes->setToolTipDuration(3000);
	ui->pushButton_no->setToolTip("这个是 no 按钮");
	ui->pushButton_no->setToolTipDuration(10000);
}
  1. 运⾏程序, 观察效果
    可以看到⿏标停到按钮上之后, 就能弹出提⽰. 时间到后⾃⾏消失.

11.focusPolicy属性

设置控件获取到焦点的策略.比如某个控件能否用鼠标选中或者能否通过 tab 键选中
所谓"焦点",指的就是能选中这个元素,接下来的操作(比如键盘操作),就都是针对该焦点元素进行的了.这个对于 输入框,单选框,复选框等控件非常有用的.这个事情就和 war3 或者 sc2 中,先选中单位,再下达命令是一样的.

API 说明
focusPolicy() 获取该 widget 的 focusPolicy,返回 Qt::FocusPolicy
setFocusPolicy(Qt::FocusPolicy policy) 设置 widget 的 focusPolicy.

Qt::FocusPolicy 是一个枚举类型,取值如下

  • Qt::NoFocus:控件不会接收键盘焦点
  • Qt::TabFocus:控件可以通过Tab键接收焦点
  • Qt::clickFocus:控件在鼠标点击时接收焦点
  • Qt::StrongFocus:控件可以通过Tab键和鼠标点击接收焦点(默认值)Qt::WheelFocus:类似于 >- Qt::StrongFocus,同时控件也通过鼠标滚轮获取到焦点(新增的选项,一般很少使用).

代码⽰例: 理解不同的 focusPolicy

  1. 在界⾯上创建四个单⾏输⼊框 (Line Edit)
  2. 修改四个输⼊框的 focusPolicy 属性为 Qt::StrongFocus (默认取值, ⼀般不⽤额外修改)

    此时运⾏程序, 可以看到, 使⽤⿏标单击/tab, 就可以移动光标所在输⼊框. 从⽽接下来的输⼊就是针对这个获取焦点的输⼊框展开的了.
  3. 修改第⼆个输⼊框的 focusPolicy 为 Qt::NoFocus ,则第⼆个输⼊框不会被 tab / ⿏标左键选中.

    此时这个输⼊框也就⽆法输⼊内容了
  4. 修改第⼆个输⼊框 focusPolicy 为 Qt::TabFocus , 则只能通过 tab 选中, ⽆法通过⿏标选中.
  5. 修改第⼆个输⼊框 focusPolicy 为 Qt::ClickFocus , 则只能通过 tab 选中, ⽆法通过⿏标选中.

2.11 styleSheet

通过 CSS 设置 widget 的样式

CSS(Cascading Style Sheets 层叠样式表)本身属于网页前端技术,主要就是用来描述界面的样式.
所谓"样式",包括不限于 大小,位置,颜色,间距,字体,背景,边框等!

我们平时看到的丰富多彩的网页,就都会用到大量的 CSS.

Ot 虽然是做 GUI开发,但实际上和 网页前端 有很多异曲同工之处,因此 Ot也引入了对于 CSS的支持.
CSS 中可以设置的样式属性非常多.基于这些属性 Qt只能支持其中一部分,称为 QSS (Qt Style Sheet具体的支持情况可以参考 Qt 文档中"Ot Style Sheets Reference"章节.

代码⽰例: 设置⽂本样式

  1. 在界⾯上创建 label
  2. 编辑右侧的 styleSheet 属性, 设置样式


    此处的语法格式同 CSS,使用键值对的方式设置样式,其中键和值之间使用 : 分割.键值对之间使用;分割.
    另外,Qt Designer 只能对样式的基本格式进行校验,不能检测出哪些样式不被 Qt 支持.比如 text-align: center 这样的文本居中操作,就无法支持
    编辑完成样式之后,可以看到在 Qt Designer 中能够实时预览出效果
  3. 运⾏程序, 可以看到实际效果和预览效果基本⼀致

代码⽰例2 : 实现切换夜间模式.

  1. 在界⾯上创建⼀个多⾏输⼊框 (TextEdit)和两个按钮.
    objectName 分别为 pushButton_light 和 pushButton_dark
  2. 编写按钮的 slot 函数.
相关推荐
Mr.Q3 分钟前
OpenCV和Qt坐标系不一致问题
qt·opencv
时光の尘14 分钟前
C语言菜鸟入门·关键字·float以及double的用法
运维·服务器·c语言·开发语言·stm32·单片机·c
以后不吃煲仔饭28 分钟前
Java基础夯实——2.7 线程上下文切换
java·开发语言
进阶的架构师29 分钟前
2024年Java面试题及答案整理(1000+面试题附答案解析)
java·开发语言
前端拾光者33 分钟前
利用D3.js实现数据可视化的简单示例
开发语言·javascript·信息可视化
程序猿阿伟35 分钟前
《C++ 实现区块链:区块时间戳的存储与验证机制解析》
开发语言·c++·区块链
傻啦嘿哟1 小时前
如何使用 Python 开发一个简单的文本数据转换为 Excel 工具
开发语言·python·excel
大数据编程之光1 小时前
Flink Standalone集群模式安装部署全攻略
java·大数据·开发语言·面试·flink
初九之潜龙勿用1 小时前
C#校验画布签名图片是否为空白
开发语言·ui·c#·.net
Dola_Pan1 小时前
C语言:数组转换指针的时机
c语言·开发语言·算法