【QT】常用控件(一):初识控件,熟悉QWidget

🎬 个人主页艾莉丝努力练剑
专栏传送门 :《C语言》《数据结构与算法》《C/C++干货分享&学习过程记录
Linux操作系统编程详解》《笔试/面试常见算法:从基础到进阶》《Python干货分享

⭐️为天地立心,为生民立命,为往圣继绝学,为万世开太平


🎬 艾莉丝的简介:


文章目录

  • [1 ~> 控件概述](#1 ~> 控件概述)
    • [1.1 Widget](#1.1 Widget)
    • [1.2 关于控件体系的发展](#1.2 关于控件体系的发展)
      • [1.2.1 第一阶段](#1.2.1 第一阶段)
      • [1.2.2 第二阶段](#1.2.2 第二阶段)
      • [1.2.3 第三阶段](#1.2.3 第三阶段)
  • [2 ~> QWidget核心属性](#2 ~> QWidget核心属性)
    • [2.1 核心属性概览](#2.1 核心属性概览)
    • [2.2 一些比较重要比较常用的属性](#2.2 一些比较重要比较常用的属性)
      • [2.2.1 enabled](#2.2.1 enabled)
      • [2.2.2 geometry](#2.2.2 geometry)
        • [2.2.2.1 相关API](#2.2.2.1 相关API)
      • [2.2.3 windowTitle](#2.2.3 windowTitle)
      • [2.2.4 windowIcon](#2.2.4 windowIcon)
      • [2.2.5 windowOpacity](#2.2.5 windowOpacity)
      • [2.2.6 cursor](#2.2.6 cursor)
      • [2.2.7 font](#2.2.7 font)
      • [2.2.8 toolTip](#2.2.8 toolTip)
      • [2.2.9 focusPolicy](#2.2.9 focusPolicy)
      • [2.2.10 styleSheet](#2.2.10 styleSheet)
  • 结尾


1 ~> 控件概述

1.1 Widget

WidgetQt中的核心概念。

  • 英文原义是"小部件",我们此处也把它翻译为 "控件"

控件是构成一个图形化界面的基本要素。

像上述示例中的:按钮、列表视图、树形视图、单行输入框、多行输入框、滚动条、下拉框 等,都可以称为 "控件"

Qt作为一个成熟的GUI开发框架,内置了大量的常用控件。

  • 这一点在Qt Designer中就可以看到端倪。

并且Qt也提供了 "自定义控件" 的能力,可以让程序猿在现有控件不能满足需求的时候,对现有控件做出扩展,或者手搓出新的控件。

综上,学习Qt ,其中一个很重要的任务 就是熟悉并掌握Qt内置的常用控件

这些控件对于我们快速开发出符合需求的界面,是至关重要的。

1.2 关于控件体系的发展

  • 控件是GUI开发中的通用概念,不仅仅局限在Qt中。

1.2.1 第一阶段

完全没有控件,此时需要通过一些绘图API手动的绘制出按钮或者输入框等内容,代码编写繁琐。

例如:文曲星的Lava平台开发.

1.2.2 第二阶段

只包含粗略的控件,只是提供了按钮、输入框、单选框、复选框等最常用的控件。

例如html的原生控件。

一则老新闻:

1.2.3 第三阶段

更完整的控件体系,基本可以覆盖到GUI开发中的大部分场景。

例如早期的 MFCVBC++ BuilderQtDelphi,后来的Android SDKJava FX、前端的各种UI库等。

下面艾莉丝给大家推荐一个网站:Element-ui

  • 上图是前端中的Element-ui中的控件概览,无论是丰富程度还是颜值,都比Qt自带的控件更胜一筹。

2 ~> QWidget核心属性

在Qt中,使用QWidget类表示 "控件" 。像按钮、视图、输入框、滚动条 等具体的控件类,都是继承自QWidget

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

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

这些属性既可以通过Qt Designer会直接修改,也可以通过代码的方式修改。

这些属性的具体含义,在Qt Assistant中均有详细介绍。

  • Qt Assistant中搜索QWidget,即可找到对应的文档说明。

  • 或者在Qt Creator代码中,选中QWidget,按F1也可。

2.1 核心属性概览

下列表格列出了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 鼠标悬停在 widget 上时会以当前焦点(显示在一个弹出的窗口中)。
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: 将上下文菜单替换为控件的"动作"菜单,用户可以通过鼠标右键或键盘快捷键触发这个菜单
locale 设置语言和区域。
acceptDrops 该控件是否接受拖放操作。 如果设置为 true,那么该控件就可以接收来自其他部件的拖放操作。当一个部件被拖放到该控件上时,该部件会接收到相应的拖放事件(如 dropEvent)。 如果设置为 false,那么该部件将不会接收到任何拖放事件。
minimumSize 控件的最小尺寸。包含最小宽度和最小高度。
maximumSize 控件的最大尺寸。包含最大宽度和最大高度。
sizePolicy 尺寸策略。设置控件在布局管理器中的缩放方式。
windowModality 指定窗口是否具有"模态"行为。
sizeIncrement 拖动窗口大小的增量单位。
baseSize 窗口的基础大小,用来搭配 sizeIncrement 调整组件尺寸是计算组件应该调整到的合适的值。
palette 调色板。可以设置 widget 的颜色风格。
mouseTracking 是否要跟踪鼠标移动事件。 如果设为 true,表示需要跟踪,则鼠标划过的时候该 widget 就能持续收到鼠标移动事件。 如果设为 false,表示不需要跟踪,则鼠标划过的时候 widget 不能收到鼠标移动事件,只能收到鼠标按下或者释放的事件。
tabletTracking 是否要跟踪触摸屏的移动事件。 如果设为 true,表示需要跟踪,则鼠标划过的时候该 widget 能够持续收到鼠标移动事件。 如果设为 false,表示不需要跟踪,则鼠标划过的时候 widget 不能收到鼠标移动事件,只能收到鼠标按下或者释放的事件。

接下来我们会介绍其中一些比较重要比较常用的属性,并附有代码示例。

  • 注意: 本章节的每个代码示例都是创建了单独的Qt项目,课件中省略了创建项目的具体步骤。

2.2 一些比较重要比较常用的属性

2.2.1 enabled

API 说明
isEnabled() 获取到控件的可用状态。
setEnabled 设置控件是否可使用。true表示可用,false表示禁用。
  • 所谓 **"禁用"**指的是该控件不能接收任何用户的输入事件,并且外观上往往是灰色的。
  • 如果一个widget被禁用,则该widget的子元素也被禁用。

代码示例: 使用代码创建一个禁用状态的按钮。

widget.cpp
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切换按钮1的禁用状态。

1)使用Qt Designer拖两个按钮到Widget中。

两个按钮的objectName分别为 pushButton 和pushButton_2。

cpp 复制代码
class Ui_Widget
{
public:
	QPushButton *pushButton;
	QPushButton *pushButton_2;
	// . . . . . .
};

2)生成两个按钮的 slot 函数.

  • 使用isEnabled获取当前按钮的可用状态。
  • 使用setEnabled修改按钮的可用状态。此处是直接针对原来的可用状态进行取反后设置。
cpp 复制代码
void Widget::on_pushButton_clicked()
{
	qDebug() << "按下按钮";
}

void Widget::on_pushButton_2_clicked()
{
	bool flag = this->ui->pushButton->isEnabled();
	this->ui->pushButton->setEnabled(!flag);
}

运行程序,可以看到,初始情况下,上面的按钮是可用状态。

点击下方按钮,即可使上方按钮被禁用;再次点击下方按钮,上方按钮就会解除禁用,(禁用状态的按钮为灰色,且不可点击)。

Qt Designer中创建按钮的时候,可以设置按钮的初始状态是"可用"还是"禁用"。

如果把enabled这一列的对钩去掉,则按钮的初始状态就是"禁用"状态。

2.2.2 geometry

位置和尺寸,其实是四个属性的统称:

  • x横坐标

  • y纵坐标

  • width宽度

  • height高度

但是实际开发中,我们并不会直接使用这几个属性,而是通过一系列封装的方法来获取 / 修改。

  • 对于Qt的坐标系,不要忘记是一个"左手坐标系"其中坐标系的原点是当前元素的父元素的左上角。
API 说明
geometry() 获取控件的位置和尺寸。返回一个 QRect 对象,包含 x、y、width、height,其中 (x, y) 为左上角坐标。
setGeometry() 设置控件的位置和尺寸。该函数有两个重载版本: • setGeometry(QRect):直接传入一个 QRect 对象; • setGeometry(int x, int y, int width, int height):分别指定左上角坐标和宽高。
API 说明
geometry() 获取控件的位置和尺寸。返回一个 QRect,包含 x、y、width、height,其中 (x, y) 为左上角坐标。
setGeometry(QRect) 设置控件的位置和尺寸,通过 QRect 对象指定。
setGeometry(int x, int y, int width, int height) 设置控件的位置和尺寸,分别通过左上角坐标 (x, y) 以及宽度和高度指定。

代码示例: 控制按钮的位置。

1)在界面中拖五个按钮

五个按钮的 objectName分别为pushButton_targetpushButton_uppushButton_downpushButton_leftpushButton_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_acceptpushButton_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方法),此处暂时不展开。

2.2.2.1 相关API

相关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() 返回 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 对象。

代码示例: 感受geometry和 frameGeometry的区别。

1)在界面上放置一个按钮

2)在按钮的slot函数中,编写代码:

cpp 复制代码
void Widget::on_pushButton_clicked()
{
    QRect rect1 = this->geometry();
    QRect rect2 = this->frameGeometry();
    qDebug() << rect1;
    qDebug() << rect2;
}

3)在构造函数中,也添加同样的代码

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则存在差异。


2.2.3 windowTitle


代码示例: 设置窗口标题

修改 widget.cpp

cpp 复制代码
Widget::Widget(QWidget* parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    // 设置窗⼝标题 
    this->setWindowTitle("这是标题");
}

执行结果:

2.2.4 windowIcon

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

代码示例: 设置窗口图标

1)先在D盘中放一个图片,名字为 rose.jpg

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)运行程序,可以看到窗口图标已经成为上述图片

于此同时,程序在任务栏中的图表也发生改变------


对于Qt程序来说,当前工作目录可能是变化的。比如通过Qt Creator运行的程序,当前工作目录是项目的构建目录;直接双击exe运行,工作目录则是exe所在目录。

所谓构建目录,是和Qt项目并列的,专门用来放生成的临时文件和最终exe的目录。

代码示例: 获取当前的工作目录

1)在界面上创建一个比较大的label,确保能把路径显示完整。objectName使用默认的label即可。

2)修改widget.cpp

  • 使用QDir::currentPath()即可获取到当前工作目录
cpp 复制代码
#include <QDir>

Widget::Widget(QWidget* parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    // 获取到当前⼯作⽬录 
    QString currentDir = QDir::currentPath();
    // 设置⼯作⽬录到 label 中.  
    ui->label->setText(currentDir);
}

3)直接在QtCreator中执行程序,可以看到当前工作目录是项目的构建目录。

4)进入上述构建目录,把里面的exe拷贝到其他目录中,比如D:中,再次执行程序,可以看到当前工作目录已经发生改变。

  • 要想直接能双击exe运行,需要先把Qt的路径添加到path环境变量中,否则会提示找不到动态库。 这一点我们最开始搭建开发环境的时候已经操作过,此处不再赘述。

注意,上述构建目录是随时可删除的,比如点击菜单栏中的 "构建"~>"清理项目",就会把这个目录中的内容清空掉。

因此如果我们把图片文件放到构建目录中,可能在不小心删除后就丢失了,我们还是希望能够把图片和源代码放到一起,并且使我们的程序无论拷贝到任何位置中都能正确使用图片。

Qt使用qrc机制帮我们自动完成了上述工作,更方便的来管理项目依赖的静态资源。

代码示例: 通过qrc管理图片作为图标

1)右键项目,创建一个Qt Resource File(qrc文件),文件名随意起(不要带中文),此处叫做resource.qrc

2)在qrc 编辑器中,添加前缀。

此处我们前缀设置成/即可。

  • 所谓的前缀,可以理解成"目录",这个前缀决定了后续我们如何在代码中访问资源。

3)在资源编辑器中,点击add Files添加资源文件.此处我们需要添加的是rose.jpg

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

添加完毕后,可以在资源编辑器中看到添加好的文件。

4)在代码中使用 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);
}

5)运行程序,可以看到图标已经能正确设置。

接下来,我们可以进入到项目的构建目录,可以看到,目录中多了一个qrc_resource.cpp文件.直接打开这个文件,可以看到类似如下代码:

bash 复制代码
static const unsigned char qt_resource_data[] = {
    // D:/project/ke/qt/DemoCode/DemoWindowIconQrc/rose.jpg
 0x0,0x0,0x33,0x2,
 0xff,
 0xd8,0xff,0xe0,0x0,0x10,0x4a,0x46,0x49,0x46,0x0,0x1,0x1,0x0,0x0,0x1,0x0,
 0x1,0x0,0x0,0xff,0xfe,0x0,0x3b,0x43,0x52,0x45,0x41,0x54,0x4f,0x52,0x3a,0x20,

0x67,0x64,0x2d,0x6a,0x70,0x65,0x67,0x20,0x76,0x31,0x2e,0x30,0x20,0x28,0x75,0x73
,

0x69,0x6e,0x67,0x20,0x49,0x4a,0x47,0x20,0x4a,0x50,0x45,0x47,0x20,0x76,0x36,0x32
,

0x29,0x2c,0x20,0x71,0x75,0x61,0x6c,0x69,0x74,0x79,0x20,0x3d,0x20,0x39,0x35,0xa,
 0xff,0xdb,0x0,0x43,0x0,0x2,0x1,0x1,0x1,0x1,0x1,0x2,0x1,0x1,0x1,0x2,
 0x2,0x2,0x2,0x2,0x4,0x3,0x2,0x2,0x2,0x2,0x5,0x4,0x4,0x3,0x4,0x6,
 0x5,0x6,0x6,0x6,0x5,0x6,0x6,0x6,0x7,0x9,0x8,0x6,0x7,0x9,0x7,0x6,
 0x6,0x8,0xb,0x8,0x9,0xa,0xa,0xa,0xa,0xa,0x6,0x8,0xb,0xc,0xb,0xa,
 0xc,0x9,0xa,0xa,0xa,0xff,0xdb,0x0,0x43,0x1,0x2,0x2,0x2,0x2,0x2,0x2,
    // .............

上述代码其实就是通过unsignedchar数组,把rose.jpg中的每个字节都记录下来.这些代码会被编译到exe中,后续无论exe被复制到哪个目录下,都确保能够访问到该图片资源。

2.2.5 windowOpacity

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

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);
}

3)执行程序,可以看到,点击了几下-之后,就可以透过窗口看到后面的猫猫头了,点击+又会逐渐恢复。

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

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

2.2.6 cursor

代码示例: 在QtDesigner中设置按钮的光标

1)在界面中创建一个按钮。

2)直接在右侧属性编辑区修改cursor属性为 "等待"

3)运行程序,鼠标悬停到按钮上,即可看到光标的变化。

  • 截图无法截到鼠标光标,同学们自行运行验证。

代码示例: 通过代码设置按钮的光标

1)编写 widget.cpp

  • 其中Qt::WaitCursor就是自带的沙漏形状的光标。
cpp 复制代码
#include <QPushButton>

Widget::Widget(QWidget* parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    // 创建按钮 
    QPushButton* button = new QPushButton(this);
    button->resize(100, 50);
    button->move(100, 100);

    button->setText("这是⼀个按钮");
    // 设置按钮的 cursor 
    button->setCursor(QCursor(Qt::WaitCursor));
}

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

  • Ctrl +左键点击Qt::WaitCursor跳转到源码即可看到。
bash 复制代码
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
}

2)运行程序,观察效果。

  • 截图无法截到鼠标光标,同学们自行运行验证。

代码示例: 自定义鼠标光标

Qt自带的光标形状有限,我们也可以自己找个图片,做成鼠标的光标,比如我们有请滑稽老铁------

1)创建qrc资源文件,添加前缀/,并加入huaji.png

2)编写widget.cpp

cpp 复制代码
#include <QPixmap>

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

3)运行程序,观察效果

截图无法截到鼠标光标,请uu们自行运行验证。

2.2.7 font

关于QFont

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

代码示例: 在QtDesigner中设置字体属性

1)在界面上创建一个label

2)在右侧的属性编辑区,设置该label的font相关属性

  • 在这里调整上述属性,可以实时的看到文字的变化。

3)执行程序,观察效果

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

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);
}

3)运行程序,观察效果

2.2.8 toolTip

  • toolTip只是给用户看的.在代码中一般不需要获取到toolTip。

代码示例: 设置按钮的 toolTip

1)在界面上拖放两个按钮,objectName设置为pushButton_yespushButton_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);
}

3)运行程序,观察效果

可以看到鼠标停到按钮上之后,就能弹出提示,时间到后自行消失。

系统截图无法截取到鼠标光标,uu们自行尝试。

2.2.9 focusPolicy

设置控件获取到焦点的策略,比如某个控件能否用鼠标选中或者能否通过tab键选中。

  • 所谓 "焦点",指的就是能选中这个元素,接下来的操作(比如键盘操作),就都是针对该焦点元素进行的了。这个对于输入框,单选框,复选框等控件非常有用的。
  • 这个事情就和war3或者sc2中,先选中单位,再下达命令是一样的。

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

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

代码示例: 理解不同的 focusPolicy

1)在界面上创建四个单行输入框(LineEdit)

2)修改四个输入框的focusPolicy属性为Qt::StrongFocus(默认取值,一般不用额外修改)

此时运行程序,可以看到,使用鼠标单击 / tab,就可以移动光标所在输入框,从而接下来的输入就是针对这个获取焦点的输入框展开的了。

3)修改第二个输入框的focusPolicyQt::NoFocus,则第二个输入框不会被tab/鼠标左键选中

此时这个输入框也就无法输入内容了。

4)修改第二个输入框focusPolicyQt::TabFocus,则只能通过tab / 选中,无法通过鼠标选中。

5)修改第二个输入框focusPolicyQt::ClickFocus,则只能通过tab选中,无法通过鼠标选中。

2.2.10 styleSheet

通过CSS设置widget 的样式。

CSS中可以设置的样式属性非常多------基于这些属性Qt只能支持其中一部分 ,称为QSS(QtStyleSheet)。具体的支持情况可以参考Qt文档中 "Qt Style Sheets Reference"章节

此处只是进行一个简单的演示。

代码示例: 设置文本样式

1)在界面上创建label

2)编辑右侧的styleSheet属性,设置样式

  • 此处的语法格式同CSS,使用键值对的方式设置样式.其中键和值之间使用:分割,键值对之间使用;分割。

  • 另外,QtDesigner只能对样式的基本格式进行校验,不能检测出哪些样式不被Qt支持.比如text-align: center这样的文本居中操作,就无法支持。

编辑完成样式之后,可以看到在QtDesigner中能够实时预览出效果。

3)运行程序,可以看到实际效果和预览效果基本一致。

代码示例: 实现切换夜间模式。

1)在界面上创建一个多行输入框(Text Edit)和两个按钮

objectName分别为pushButton_lightpushButton_dark

2)编写按钮的 slot 函数。

  • #333 是深色, 但是没那么黑;
  • #fff 是纯白色;
  • #000 是纯黑色。

使用在线调色板或者画图板,都可以看到数字对应的颜色,参考:在线调色板

cpp 复制代码
void Widget::on_pushButton_dark_clicked()
{
    this->setStyleSheet("background-color: #333");
    ui->textEdit->setStyleSheet("background-color: #333; color: #fff;");
    ui->pushButton_light->setStyleSheet("color: #fff");
    ui->pushButton_dark->setStyleSheet("color: #fff");
}
void Widget::on_pushButton_light_clicked()
{
    this->setStyleSheet("background-color: #f3f3f3");

    ui->textEdit->setStyleSheet("background-color: #fff; color: #000;");
    ui->pushButton_light->setStyleSheet("color: #000");
    ui->pushButton_dark->setStyleSheet("color: #000");
}

3)运行程序,点击"日间模式",就是浅色背景,深色文字;点击"夜间模式",就是深色背景,浅色文字。


结尾

uu们,本文的内容到这里就全部结束了,艾莉丝在这里再次感谢您的阅读!

结语:希望对学习QT相关内容的uu有所帮助,不要忘记给博主"一键四连"哦!

往期回顾

【QT】QT快捷键整理

🗡博主在这里放了一只小狗,大家看完了摸摸小狗放松一下吧!🗡 ૮₍ ˶ ˊ ᴥ ˋ˶₎ა

相关推荐
liuluyang5301 小时前
Linux IIO ADC 驱动简介
linux
大母猴啃编程1 小时前
Socket编程UDP
linux·网络·c++·网络协议·udp
jgyzl2 小时前
2026.3.10 Apache POI的学习及思考
学习·apache
2501_915918412 小时前
iOS App HTTPS 抓包工具,代理抓包和数据线直连 iPhone 抓包的流程
android·ios·小程序·https·uni-app·iphone·webview
娇娇yyyyyy2 小时前
QT编程(5):几种常用的对话框
windows·qt·microsoft
悟凡爱学习2 小时前
Linux 操作系统&消息队列
linux·运维·服务器
i建模2 小时前
Ubuntu增加安装桌面环境
linux·运维·ubuntu
嵌入式×边缘AI:打怪升级日志2 小时前
2.3.2 目录与文件操作命令(保姆级详解)
linux·运维·服务器
deng-c-f2 小时前
Linux C/C++ 学习日记(74):Kafka(二):环境的搭建及常用的指令
学习·karfka