当前位置: 首页 > news >正文

【Qt开发】常用控件(三) -> geometry

目录

1 -> 控件的位置和尺寸

2 -> 相关 API

3 -> 代码示例

3.1 -> 控制按钮的位置

3.2 -> 表白程序


1 -> 控件的位置和尺寸

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

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

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

对于 Qt 的坐标系,使用的是 “左手坐标系”,其中坐标系的原点是当前元素的父元素的左上角。

API说明
geometry()获取到控件的位置和尺寸,返回结果是一个 QRect,包含了x,y,width,height。其中x,y 是左上角的坐标

setGeometry(QRect)

setGeometry(int x, int y, int widrh, int height)

设置控件的位置和尺寸,可以直接设置一个 QRect,也可以分四个属性单独设置

2 -> 相关 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 对象

通过观察可以发现,其实这里的 API 有 frameGeometry 和 geometry 两个就足够完成所有需求了。为什么还要提供那么多功能重复的 API 呢?

这就涉及到 Qt API 的设计理念了:尽量符合人的直觉。

举个例子感受 geometry 和 frameGeometry 的区别

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

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

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

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

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

注意:

在构造方法中,Widget 刚刚创建出来,还没有加入到对象树中,此时也就不具备 Window frame。

在按钮的 slot 函数中,由于用户点击的时候,对象树已经构造好了,此时 Widget 已经具备了 Window frame,因此在位置和尺寸上均出现了差异。

如果把上述代码修改成打印 pushButton 的 geometry 和 frameGeometry,结果就是完全相同的。因为 pushButton 并非是一个窗口。

3 -> 代码示例

3.1 -> 控制按钮的位置

1. 在界面上拖动五个按钮

五个按钮的 objectName 分别是 pushButton_target,pushButton_up,pushButton_down,pushButton_left,pushButton_right。

五个按钮的初始位置和大小自行设计。

2. 在 widget.cpp 中编写四个按钮的 slot 函数

 修改QRect对象的x和y,使QRect的高度宽度发生变化
void Widget::on_pushButton_up_clicked()
{// 获取到target本身的geometryQRect rect = ui->pushButton_target->geometry();qDebug() << rect;rect.setY(rect.y() - 5);ui->pushButton_target->setGeometry(rect);
}void Widget::on_pushButton_down_clicked()
{// 获取到target本身的geometryQRect rect = ui->pushButton_target->geometry();qDebug() << rect;rect.setY(rect.y() + 5);ui->pushButton_target->setGeometry(rect);
}void Widget::on_pushButton_left_clicked()
{// 获取到target本身的geometryQRect rect = ui->pushButton_target->geometry();qDebug() << rect;rect.setX(rect.x() - 5);ui->pushButton_target->setGeometry(rect);
}void Widget::on_pushButton_right_clicked()
{// 获取到target本身的geometryQRect rect = ui->pushButton_target->geometry();qDebug() << rect;rect.setX(rect.x() + 5);ui->pushButton_target->setGeometry(rect);
}

运行程序可以看到,按下下方的按钮,就会控制 target 的左上角的位置。对应的按钮整个尺寸也会发生改变。

上述代码中是直接设置的 QRect 中的 x,y。实际上 QRect 内部是存储了左上和右下两个点的坐标,再通过这两个点的坐标差值计算长宽。

单纯修改左上坐标就会引起整个矩形的长宽发生改变。

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

// 平移target
void Widget::on_pushButton_up_clicked()
{// 获取到target本身的geometryQRect rect = ui->pushButton_target->geometry();qDebug() << rect;
//    rect.setY(rect.y() - 5);
//    ui->pushButton_target->setGeometry(rect);ui->pushButton_target->setGeometry(rect.x(), rect.y()-5, rect.width(), rect.height());}void Widget::on_pushButton_down_clicked()
{// 获取到target本身的geometryQRect rect = ui->pushButton_target->geometry();qDebug() << rect;
//    rect.setY(rect.y() + 5);
//    ui->pushButton_target->setGeometry(rect);ui->pushButton_target->setGeometry(rect.x(), rect.y() + 5, rect.width(), rect.height());}void Widget::on_pushButton_left_clicked()
{// 获取到target本身的geometryQRect rect = ui->pushButton_target->geometry();qDebug() << rect;
//    rect.setX(rect.x() - 5);
//    ui->pushButton_target->setGeometry(rect);ui->pushButton_target->setGeometry(rect.x() - 5, rect.y(), rect.width(), rect.height());}void Widget::on_pushButton_right_clicked()
{// 获取到target本身的geometryQRect rect = ui->pushButton_target->geometry();qDebug() << rect;
//    rect.setX(rect.x() + 5);
//    ui->pushButton_target->setGeometry(rect);ui->pushButton_target->setGeometry(rect.x() + 5, rect.y(), rect.width(), rect.height());}

3.2 -> 表白程序

1. 往界面上拖拽两个按钮和一个 Label。

Label 的 objectName 为 pushButton_true 和 pushButton_false,label 的 objectName 为 label

2. 在 widget.cpp 中添加 slot 函数

void Widget::on_pushButton_true_clicked()
{ui->label->setText("好耶么么(*  ̄3)(ε ̄ *)");
}void Widget::on_pushButton_false_clicked()
{// 如果点击,就把按钮挪走// 可以通过随机数,来确定按钮新的位置int width = this->geometry().width();int height = this->geometry().height();// 重新生成按钮位置// 使用rand函数之前要设置随机种子int x = rand() % width;int y = rand() % height;// 移动按钮位置ui->pushButton_false->move(x, y);
}

运行程序可以看到,当点击 “否” 时,按钮就跑了。

上述代码使用的是 pressed,鼠标按下事件。如果使用 mouseMoveEvent,只要鼠标移动过来,按钮就跑了。

window frame 的影响

如果 widget 作为一个窗口(带有标题栏、最小化、最大化、关闭按钮),那么在计算尺寸和坐标的时候就有两种算法,包含 window frame 和不包含 window frame。

其中 x(),y(),frameGeometry(),pos(),move() 都是按照包含 window frame 的方式来计算的。

其中 geometry(),width(),height(),rect(),size() 则是按照不包含 window frame 的方式来计算的。

如果一个不是作为窗口的 widget,上述两类方式得到的结果是一致的。


感谢各位大佬支持!!!

互三啦!!!

http://www.dtcms.com/a/328827.html

相关文章:

  • 重生之我在公司写前端 | “博灵语音通知终端” | 登录页面
  • Swift 实战:从数据流到不重叠区间的高效转换
  • 《书写范式》——代码如诗,诗娟代码(Python)(附精巧“九九表”生成代码)
  • 《Linux基础知识-2》
  • 【2025】Datawhale AI夏令营-多模态RAG-Task3笔记-解决方案进阶
  • HGDB的分区表实现SQL Server的分区视图
  • 邀您参与 “直通乌镇” Spring AI Alibaba 开源竞技挑战赛!
  • 2025 最应避免的摄影陷阱以及解决方案
  • 八月补丁星期二:微软修复 111 个漏洞
  • String里常用的方法
  • Vue项目生产环境性能优化实战指南
  • 服务器查看 GPU 占用情况的方法
  • mac环境下安装git并配置密钥等
  • 搜索引擎核心机制解析
  • RabbitMQ面试精讲 Day 21:Spring AMQP核心组件详解
  • 详解Windows(二十)——恶意软件清除
  • CV 医学影像分类、分割、目标检测,之【腹腔多器官语义分割】项目拆解
  • 1.4.2 嵌入(embedding)模式:让人工智能大模型为你的产品或业务助力
  • 大模型微调【1】之入门
  • 实践基地授牌:重庆五一职院与成都影像产业园强实训
  • Coze Studio 概览(十)--文档处理详细分析
  • CW32L011电机开发板控制教程
  • C++ 面向对象四大特性:面试深度解析
  • 一个接口多个实现类,如何动态调用
  • 神经网络的核心组件解析:从理论到实践
  • ARM 实操 流水灯 按键控制 day53
  • Django REST Framework视图
  • HarmonyOS NDK的JavaScript/TypeScript与C++交互机制
  • Flask vs Django:微框架与一站式对决
  • web安全开发,在线%射击比赛管理%系统开发demo,基于html,css,jquery,python,django,三层mysql数据库