【Qt 学习笔记】QWidget的geometry属性及window frame的影响


  • 博客主页:Duck Bro 博客主页
  • 系列专栏:Qt 专栏
  • 关注博主,后期持续更新系列文章
  • 如果有错误感谢请大家批评指出,及时修改
  • 感谢大家点赞👍收藏⭐评论✍

QWidget的geometry属性

文章编号:Qt 学习笔记 / 16

文章目录

  • QWidget的geometry属性
    • 一、geometry属性
      • [1. 简介](#1. 简介)
      • [2. API](#2. API)
      • [3. 代码示例](#3. 代码示例)
        • [3.1 示例1:控制按钮的大小变化](#3.1 示例1:控制按钮的大小变化)
        • [3.2 示例2:控制按钮的移动](#3.2 示例2:控制按钮的移动)
        • [3.3 示例3:无法拒绝的辞职表](#3.3 示例3:无法拒绝的辞职表)
    • [二、window frame 的影响](#二、window frame 的影响)
      • [1. 影响](#1. 影响)
      • [2. 相关的API](#2. 相关的API)
      • [3. 代码示例 (geometry 和 frameGeometry 的区别)](#3. 代码示例 (geometry 和 frameGeometry 的区别))

一、geometry属性

1. 简介

geometry属性在计算机图形学中常用于描述和操作2D和3D对象的位置、大小和形状。通过geometry属性,我们可以对图形对象进行各种操作

在 Qt 中,geometry属性表示当前控件的位置和尺寸,就是四个属性的统称

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

2. API

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

提及:QPiont表示一个点 QRect表示一个矩形 这两个都属于小对象,里面的属性非常少,占用空间也小
提及:区别于move,move只能修改位置 setGeometry 可以修改位置,又可以修改尺寸

3. 代码示例

3.1 示例1:控制按钮的大小变化



文件代码:

cpp 复制代码
//widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

private slots:
    void on_pushButton_up_clicked();
    void on_pushButton_down_clicked();
    void on_pushButton_right_clicked();
    void on_pushButton_left_clicked();
private:
    Ui::Widget *ui;
};
#endif // WIDGET_H
cpp 复制代码
//widget.cpp

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
}

Widget::~Widget()
{
    delete ui;
}

//向上按钮
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_right_clicked()
{
    QRect rect= ui->pushButton_target->geometry();
    rect.setX(rect.x()+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);
}
3.2 示例2:控制按钮的移动


文件代码:

cpp 复制代码
//widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

private slots:
    void on_pushButton_up_clicked();
    void on_pushButton_down_clicked();
    void on_pushButton_right_clicked();
    void on_pushButton_left_clicked();
private:
    Ui::Widget *ui;
};
#endif // WIDGET_H
cpp 复制代码
widget.cpp

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
}

Widget::~Widget()
{
    delete ui;
}

//向上按钮
void Widget::on_pushButton_up_clicked()
{
    QRect rect= ui->pushButton_target->geometry();
//    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()
{
    QRect rect= ui->pushButton_target->geometry();
//    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_right_clicked()
{
    QRect rect= ui->pushButton_target->geometry();
//    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_left_clicked()
{
    QRect rect= ui->pushButton_target->geometry();
//    rect.setX(rect.x()-5);
//    ui->pushButton_target->setGeometry(rect);
      ui->pushButton_target->setGeometry(rect.x()-5,rect.y(),rect.width(),rect.height());
}
3.3 示例3:无法拒绝的辞职表
cpp 复制代码
//widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

private slots:


    void on_pushButton_accept_clicked();

    void on_pushButton_reject_pressed();

private:
    Ui::Widget *ui;
};
#endif // WIDGET_H
cpp 复制代码
//widget.cpp

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    srand(time(0));
}

Widget::~Widget()
{
    delete ui;
}

void Widget::on_pushButton_accept_clicked()
{
    ui->label->setText("感谢老板!!!");
}

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


}

二、window frame 的影响

window frame 窗口框架 是操作系统自带的

1. 影响

如果 widget 作为⼀个窗⼝ (带有标题栏, 最⼩化, 最⼤化, 关闭按钮), 那么在计算尺⼨和坐标的 时候就有两种算法. 包含window frame 和 不包含 window frame.

在Qt中,关于位置尺寸,提供了很多的API 有的API的位置是以Widget本体左上角为原点的不包含 window frame.有的API的位置是以window frame为左上角为原点.

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

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

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

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 对象

3. 代码示例 (geometry 和 frameGeometry 的区别)

  • 创建一个按钮,查看geometry 和 frameGeometry的返回值

执行程序, 可以看到, 构造函数中, 打印出的 geometry 和 frameGeometry 是相同的.

但是在点击按钮时, 打印的 geometry 和 frameGeometry 则存在差异.

文件代码:

cpp 复制代码
widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include<QDebug>
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;
}

Widget::~Widget()
{
    delete ui;
}


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

注意:

在构造⽅法中, Widget 刚刚创建出来, 还没有加⼊到对象树中. 此时也就不具备 Window frame.
在按钮的 slot 函数中, 由于⽤⼾点击的时候, 对象树已经构造好了, 此时 Widget 已经具备了Window frame,因此在位置和尺⼨上均出现了差异.
如果把上述代码修改成打印 pushButton 的 geometry 和 frameGeometry , 结果就是完全相 同的. 因为 pushButton 并⾮是⼀个窗⼝


相关推荐
Scott9999HH7 小时前
【IIoT流量实战】蒸汽管道阀门全关却仍有流量?用 Python 实现涡街信号 FFT 频谱分析与温压全补偿积算网关,深度拆解靠谱的涡街流量计厂家硬核技术标准
开发语言·python
2401_841495648 小时前
【操作系统】进程同步与互斥实验报告
c++·算法·操作系统·进程·并发·同步·互斥
fqbqrr8 小时前
2607C++,soui与安卓
c++·soui
码智社8 小时前
AES加密原理详解及Java实现加解密实战
java·开发语言
AI云海8 小时前
python 列表、元组、集合和字典
开发语言·python
克里斯蒂亚诺更新9 小时前
ruoyi角色权限的对应关系
笔记
萧瑟余晖9 小时前
JDK 26 新特性详解
java·开发语言
马优晨10 小时前
Freemarker 完整讲解(后端 Java 模板引擎)
java·开发语言·freemarker·freemarker 完整讲解·freemarker模板引擎
a11177611 小时前
2FA 验证码生成器(github登录验证 app)
笔记·学习
我的xiaodoujiao11 小时前
API 接口自动化测试详细图文教程学习系列32--Allure测试报告2
python·学习·测试工具·pytest