QT常用控件--QWidget




🌈个人主页: 南桥几晴秋
🌈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

表示当前控件的位置和尺寸:xywidgethight

对 于Qt的坐标系,不要忘记是⼀个"左⼿坐标系".其中坐标系的原点是当前元素的⽗元素的左上⻆

API

  • geometry():获取到控件的位置和尺⼨.返回结果是⼀个QRect,包含了x,y,width,height.其中x,y是左上⻆的坐标.
  • setGeometry(QRect)setGeometry(int x, int y, int width, int height):设置控件的位置和尺⼨.可以直接设置⼀个QRect,也可以分四个属性单独设置.

注意:move只能修改位置,但是不能修改尺寸

代码示例

通过updownleftright按钮控制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, heightQRect 对象(计算时 不包含 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)

但是在点击按钮时,打印的geometryframeGeometry则存在差异:

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

代码示例

  1. 设置窗⼝图标--绝对路径
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放进 去).

  1. 使用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 = 75false 等价于 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;");
}
相关推荐
疯狂的喵11 小时前
分布式系统监控工具
开发语言·c++·算法
敲敲千反田11 小时前
MySQL复习
数据库·mysql
水淹萌龙11 小时前
Iconify 的离线加载
开发语言·前端·javascript
SelectDB技术团队11 小时前
上市大模型企业数据基础设施的选择:MiniMax 基于阿里云 SelectDB 版,打造全球统一AI可观测中台
数据库·数据仓库·人工智能·ai·apache
进阶小白猿11 小时前
Java技术八股学习Day26
java·开发语言·学习
2301_8223827611 小时前
模板编译期排序算法
开发语言·c++·算法
余瑜鱼鱼鱼11 小时前
synchronized总结
java·开发语言
小宇的天下11 小时前
Calibre :SVRF rule file example
java·开发语言·数据库
码农水水12 小时前
大疆Java面试被问:使用Async-profiler进行CPU热点分析和火焰图解读
java·开发语言·jvm·数据结构·后端·面试·职场和发展
JSU_曾是此间年少12 小时前
ubuntu安装2026最新版Mysql(截止到1月底)
数据库·mysql