
🌈个人主页: 南桥几晴秋
🌈C++专栏: 南桥谈C++
🌈C语言专栏: C语言学习系列
🌈Linux学习专栏: 南桥谈Linux
🌈数据结构学习专栏: 数据结构杂谈
🌈数据库学习专栏: 南桥谈MySQL
🌈Qt学习专栏: 南桥谈Qt
🌈菜鸡代码练习: 练习随想记录
🌈git学习: 南桥谈Git
🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈 本科在读菜鸡一枚,指出问题及时改正
QWidget的enable属性
| API | 说明 |
|---|---|
| isEnabled() | 获取到控件的可⽤状态. |
| setEnabled | 设置控件是否可使⽤. true 表⽰可⽤, false 表⽰禁⽤. |
- 所谓"禁⽤"指的是该控件不能接收任何⽤⼾的输⼊事件,并且外观上往往是灰⾊的.
- 如果⼀个widget被禁⽤,则该widget的⼦元素也被禁⽤.
代码创建一个按钮被禁用
c++
//使⽤代码创建⼀个禁⽤状态的按钮
QPushButton *button = new QPushButton(this);
button->setText("禁用按钮");
button->setEnabled(false);
示例:

通过按钮2切换按钮1的禁用状态
- 代码示例
cpp
void Widget::on_pushButton_clicked()
{
qDebug()<<"执行了第一个按钮";
qDebug()<<"点击按钮";
}
void Widget::on_pushButton_2_clicked()
{
//切换第一个按钮的状态:如果可用,按下后第一个按钮就禁用;如何不可用,按下后第一个按钮就可用
//1.获取第一个按钮的状态
bool enable = ui->pushButton->isEnabled();
if(enable){
ui->pushButton->setEnabled(false);
qDebug()<<"第一个按钮变成禁用";
}else{
ui->pushButton->setEnabled(true);
qDebug()<<"第一个按钮变成可用";
}
}

- 在QtDesigner中创建按钮的时候,可以设置按钮的初始状态是"可⽤"还是"禁⽤"
如果把enabled这⼀列的对钩去掉,则按钮的初始状态就是"禁⽤"状态
geometry
表示当前控件的位置和尺寸:x、y、widget、hight
对 于Qt的坐标系,不要忘记是⼀个"左⼿坐标系".其中坐标系的原点是当前元素的⽗元素的左上⻆
API
geometry():获取到控件的位置和尺⼨.返回结果是⼀个QRect,包含了x,y,width,height.其中x,y是左上⻆的坐标.setGeometry(QRect)、setGeometry(int x, int y, int width, int height):设置控件的位置和尺⼨.可以直接设置⼀个QRect,也可以分四个属性单独设置.
注意:move只能修改位置,但是不能修改尺寸
代码示例
通过up、down、left、right按钮控制target按钮上下左右移动
cpp
void Widget::on_pushButton_up_clicked()
{
//获取当前target属性
QRect rect = ui->pushButton_target->geometry();
qDebug() << rect;
ui->pushButton_target->setGeometry(rect.x(), rect.y()-5, rect.width(), rect.height());
}
void Widget::on_pushButton_left_clicked()
{
//获取当前target属性
QRect rect = ui->pushButton_target->geometry();
qDebug() << rect;
ui->pushButton_target->setGeometry(rect.x()-5, rect.y(), rect.width(), rect.height());
}
void Widget::on_pushButton_down_clicked()
{
//获取当前target属性
QRect rect = ui->pushButton_target->geometry();
qDebug() << rect;
ui->pushButton_target->setGeometry(rect.x(), rect.y()+5, rect.width(), rect.height());
}
void Widget::on_pushButton_right_clicked()
{
//获取当前target属性
QRect rect = ui->pushButton_target->geometry();
qDebug() << rect;
ui->pushButton_target->setGeometry(rect.x()+5, rect.y(), rect.width(), rect.height());
}
windowframe的影响
如果widget作为⼀个窗⼝(带有标题栏,最⼩化,最⼤化,关闭按钮),那么在计算尺⼨和坐标的 时候就有两种算法.包含windowframe和不包含windowframe.

- 其中
x(),y(), frameGeometry(), pos(), move()都是按照包含windowframe的⽅式来计算的 - 其中
geometry(),width(), height(), rect(), size()则是按照不包含windowframe的⽅式来计算的.
| 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 对象,可获取 x, y, width, height(计算时 包含 window frame) |
width() |
获取宽度(计算时 不包含 window frame) |
height() |
获取高度(计算时 不包含 window frame) |
size() |
返回 QSize 对象,含 width(), height(), setWidth(), setHeight() 等方法(计算时 不包含 window frame) |
rect() |
返回 QRect 对象,可获取并设置 x, y, width, height(计算时 不包含 window frame) |
geometry() |
返回 QRect 对象,可获取 x, y, width, height(计算时 不包含 window frame) |
setGeometry() |
直接设置窗口的位置和尺寸,可传入 x, y, width, height 或 QRect 对象(计算时 不包含 window frame) |
代码示例
写在 Widget 的构造函数里,此时窗口(Widget)刚刚被 new 出来,还没有被窗口管理器装饰(即还没加上标题栏、边框等 window frame)。
geometry()------ 返回的是 客户区 的几何(不含 window frame)。frameGeometry()------ 理论上应该返回"客户区 + window frame"的几何,但此刻 frame 尚不存在,所以两者得到的数值完全一样。
cpp
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
QRect rect1 = this->geometry();
QRect rect2 = this->frameGeometry();
qDebug() << "geometry:" << rect1;
qDebug() << "frameGeometry:" <<rect2;
}
打印结果:
geometry: QRect(0,0 800x600)
frameGeometry: QRect(0,0 800x600)
但是在点击按钮时,打印的geometry和frameGeometry则存在差异:
cpp
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
QPushButton *mybutton = new QPushButton(this);
mybutton->setText("Qrect");
connect(mybutton, &QPushButton::clicked, this, &Widget::handle);
}
void Widget::handle()
{
QRect rect1 = this->geometry();
QRect rect2 = this->frameGeometry();
qDebug() << "geometry:" << rect1;
qDebug() << "frameGeometry:" <<rect2;
}
打印结果:
geometry: QRect(560,204 800x600)
frameGeometry: QRect(559,159 802x646)
windowTitle
windowTitle():获取控件的窗口标题。setWindowTitle(const QString &title):设置控件的窗口标题。
如果是顶层widget(独⽴窗⼝),这个操作才会有效,如果是⼦widget,这个操作⽆任何效果。
cpp
// 设置窗⼝标题
this->setWindowTitle(" 这是标题 ");
windowIcon
windowIcon():获取控件的窗口图标,返回QIcon对象。setWindowIcon(const QIcon &icon):设置控件的窗口图标。
同windowTitle,上述操作仅针对顶层widget有效。
QIcon 本身很轻量,只是"图标描述",真正绘图数据由 Qt 内部缓存;它既不参与对象树,也无法设置父对象。
因此:
- 只要图标已经通过
setWindowIcon()设置到控件,QIcon 对象本身随后销毁也不会影响界面显示。 - 用栈对象、临时对象或直接写
setWindowIcon(QIcon(":/res/icon.png"))都可以,无需刻意new。
代码示例
- 设置窗⼝图标--绝对路径
cpp
#include "widget.h"
#include "ui_widget.h"
#include <QIcon>
#include <QDir>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
QIcon icon("d:/1.png");
this->setWindowIcon(icon);
}
实际开发中,我们⼀般不会在代码中通过绝对路径引⼊图⽚.
因为我们⽆法保证程序发布后,⽤ ⼾的电脑上也有同样的路径.
如果使⽤相对路径,则需要确保代码中的相对路径写法和图⽚实际所在的路径匹配(⽐如代码 中写作"./image/rose.jpg", 就需要在当前⼯作⽬录中创建image⽬录,并把rose.jpg放进 去).
- 使用
QRC机制
QRC机制的本质是把图片的二进制数据转成C++代码,最终会在代码中看到一个很大的char数组(在内存中),里面存放的是二进制数据。
为了在QT代码中能够访问代码,因此QT就自己创建一个虚拟目录。
注意:在导入图片的时候需要确保导入的图片在resource.qrc文件的同级目录或者同级目录的子目录中。
-
优点:确保了图⽚,字体,声⾳等资源能够真正做到"⽬录⽆关 ",⽆论如何都不会出现资源丢失的情况。
-
缺点:不适合管理体积⼤的资源.如果资源⽐较⼤(⽐如是⼏个MB的⽂件),或者资源特别多, ⽣成的最终的exe体积就会⽐较⼤,程序运⾏消耗的内存也会增⼤,程序编译的时间也会显著 增加。
cpp
#include "widget.h"
#include "ui_widget.h"
#include <QIcon>
#include <QDir>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
QIcon icon(":/1.png"); //qrc机制
this->setWindowIcon(icon);
}
windowOpacity
windowOpacity()
获取控件的不透明度,返回float,范围 0.0(全透明)到 1.0(完全不透明)。setWindowOpacity(float n)
设置控件的不透明度。
代码示例
cpp
void Widget::on_pushButton_add_clicked()
{
float opacity = this->windowOpacity();
if(opacity >= 1.0) return; //这个判定条件不加也可以,超过1.0的数字实际上设不进去
qDebug() << opacity;
opacity += 0.1;
this->setWindowOpacity(opacity);
}
void Widget::on_pushButton_sub_clicked()
{
float opacity = this->windowOpacity();
if(opacity <= 0) return;
qDebug() << opacity;
opacity -= 0.1; //这个判定条件不加也可以,小于0.0的数字实际上设不进去
this->setWindowOpacity(opacity);
}
注意:C++ 的 float 遵循 IEEE 754 标准,运算存在精度误差。
因此 1 - 0.1 的结果并不精确等于 0.9 ,可能显示为 0.899 999 976... 左右。
对透明度或其他需要精确比较的场景,请避免直接 == 判断,改用区间或误差范围比较。
因此,在计算浮点数运算时一定要注意:
-
不准:二进制无法精确表示十进制小数,0.1 存的是"约等于 0.1 的无穷级数截断值"。
于是0.1 + 0.2 == 0.3→ false,实际得到 0.300 000 000 000 000 04。 -
绝不用
==直接比较浮点数; -
用"作差取绝对值 < ε"方式判断相等;
-
涉及钱、税务、报表等"一分不能差"的场景,改用整数分 / 定点库 / Decimal 类型,彻底避开 float/double。
cursor
cursor()
返回当前 widget 的光标对象(QCursor)。鼠标悬停在该控件上时,会显示此形状。setCursor(const QCursor &cursor)
仅对本控件设置光标形状;鼠标离开控件即失效。QGuiApplication::setOverrideCursor(const QCursor &cursor)
设置全局 光标,覆盖所有控件的光标设置;直到调用restoreOverrideCursor()才恢复。
在QtDesigner中设置按钮的光标

过代码设置按钮的光标
QT中内置的光标形状:
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
}
代码示例:
cpp
QCursor cursor =(Qt::CrossCursor);
ui->pushButton_add->setCursor(cursor);
ui->pushButton_sub->setCursor(cursor);
自定义鼠标光标
Qt允许用户自定义的图片来设置鼠标光标
- 创建qrc资源⽂件,添加前缀
/,并加⼊图片 - 编写widget.cpp
cpp
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
//创建一个位图对象,加载一个自定义的图片
QPixmap pixmap(":/dog.png");
//缩放图片
pixmap = pixmap.scaled(64, 64);
//确定鼠标有效点
QCursor cursor(pixmap,10,10);
this->setCursor(cursor);
}
font
font()
获取当前 widget 的字体信息,返回QFont对象。setFont(const QFont &font)
设置当前 widget 的字体。
QFront
family
字体家族,如"楷体""宋体""微软雅黑"。pointSize
字体大小(点)。weight
粗细数值,范围 0--99,越大越粗。bold
是否加粗;true等价于weight = 75,false等价于50。italic
是否倾斜。underline
是否带下划线。strikeOut
是否带删除线。
代码示例
cpp
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
QLabel *label = new QLabel(this);
label->setText("这是一段文字");
QFont font;
font.setFamily("楷体"); // 字体家族
font.setPointSize(20); // 字号
font.setBold(true); // 加粗
font.setItalic(true); // 倾斜
font.setUnderline(true); // 下划线
font.setStrikeOut(true); // 删除线
label->setFont(font); // 应用到 label
}
toolTip
作用:鼠标悬停在某个控件上时,会显示文本提示这个按键的作用
setToolTip(const QString &text)
设置鼠标悬停时显示的提示文本。setToolTipDuration(int msec)
设置提示文本自动消失的延时,单位毫秒;设为 -1 则使用系统默认时长。
代码示例
cpp
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
ui->pushButton_add->setToolTip("增加透明度");
ui->pushButton_add->setToolTipDuration(3000);
ui->pushButton_sub->setToolTip("降低透明度");
ui->pushButton_sub->setToolTipDuration(3000);
}
focusPolicy
焦点 = 选中状态。
只有获得焦点的控件才能接收键盘、快捷键等后续操作,就像即时战略里先点选单位再下指令。
通过 setFocusPolicy() 可决定控件能否被鼠标点击或 Tab 键选中,对输入框、单选框、复选框等尤其重要。
focusPolicy()
返回当前控件的焦点策略,类型为Qt::FocusPolicy。setFocusPolicy(Qt::FocusPolicy policy)
设置控件如何获得焦点。可取值:Qt::NoFocus------ 无法通过任何方式获得焦点。Qt::TabFocus------ 仅 Tab 键 可聚焦。Qt::ClickFocus------ 仅 鼠标点击 可聚焦。Qt::StrongFocus------ Tab 键 + 鼠标点击 均可聚焦(默认)。Qt::WheelFocus------ 同StrongFocus,额外支持 滚轮聚焦(极少用)。

styleSheet
Qt 借用了网页的 CSS 概念,把子集叫做 QSS(Qt Style Sheets) 。
用一串类似网页的样式字符串就能一次性描述控件的大小、位置、颜色、字体、边框、背景等,无需逐条调 API。
完整支持列表见官方文档「Qt Style Sheets Reference」。
cpp
void Widget::on_pushButton_dark_clicked()
{
this->setStyleSheet("background-color: #333333;");
ui->textEdit->setStyleSheet("background-color: #333333; color: #ffffff;");
ui->pushButton_light->setStyleSheet("color: #ffffff;");
ui->pushButton_dark->setStyleSheet("color: #ffffff;");
}
void Widget::on_pushButton_light_clicked()
{
this->setStyleSheet("background-color: #f3f3f3;");
ui->textEdit->setStyleSheet("background-color: #ffffff; color: #000000;");
ui->pushButton_light->setStyleSheet("color: #000000;");
ui->pushButton_dark->setStyleSheet("color: #000000;");
}