- 博客主页: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 并⾮是⼀个窗⼝