【Qt】QWidget的geometry属性

geometry,意思是“几何”。可以将geometry视为是四个属性的统称。

x:横坐标

y:纵坐标

width:宽度

height:高度

API说明

geometry()

获取到控件的位置和尺⼨. 返回结果是⼀个 QRect, 包含了 x, y, width, height. 其中 x, y 是左上⻆的坐标

setGeometry(QRect)

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

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

Rect就是“矩形”。

在Qt中针对一些几何上的概念也进行了封装。例如QPoint表示一个点,QRect表示一个矩形,这些都是属于小对象,里面的属性非常少,占用空间也小。这种小对象在C++中进行使用的时候,通常会按照值的方式来传递参数。

move只是修改位置,二setGeometry既可以修改位置,又可以修改尺寸。

例子一:使用上下左右按钮移动位置 

下面进行实际演示:

首先要注意的是,修改这些属性的时候,一定要先确认好你当前选中的是哪个控件。

设置四个按钮,分别更改名称up,left,right,down,并修改其objectName,期望通过点击这几个按钮,就能够修改target按钮的geometry。

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

#include<QDebug>

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

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


void Widget::on_pushButton_target_clicked()
{
    QRect rect = ui->pushButton_target->geometry();
    qDebug() << rect;
}

void Widget::on_pushButton_up_clicked()
{
    //获取target自身的geometry
    QRect rect = ui->pushButton_target->geometry();
    rect.setY(rect.y() - 1);
    ui->pushButton_target->setGeometry(rect);
}

void Widget::on_pushButton_down_clicked()
{
    QRect rect = ui->pushButton_target->geometry();
    rect.setY(rect.y() + 1);
    ui->pushButton_target->setGeometry(rect);
}


void Widget::on_pushButton_left_clicked()
{
    QRect rect = ui->pushButton_target->geometry();
    rect.setX(rect.x() - 1);
    ui->pushButton_target->setGeometry(rect);
}


void Widget::on_pushButton_right_clicked()
{
    QRect rect = ui->pushButton_target->geometry();
    rect.setX(rect.x() + 1);
    ui->pushButton_target->setGeometry(rect);
}

在当前代码执行的过程中,实际执行的效果是在调整左上角的位置,而左上角位置改变的同时,高度和宽度也发生了改变。

        如果只想让按钮进行平移,即其高度宽度不变,整个按钮的位置发生变化?

刚才的代码,修改的是QRect对象的x和y,这样的修改就会使QRect宽度和高度发生改变。此时不需要再修改QRect,而是通过QRect基于serGeometry第二个函数重新设置位置即可。

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

#include<QDebug>

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

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


void Widget::on_pushButton_target_clicked()
{
    QRect rect = ui->pushButton_target->geometry();
    qDebug() << rect;
}

void Widget::on_pushButton_up_clicked()
{
    //获取target自身的geometry
    QRect rect = ui->pushButton_target->geometry();
//    rect.setY(rect.y() - 1);
//    ui->pushButton_target->setGeometry(rect);
    ui->pushButton_target->setGeometry(rect.x(), rect.y() - 1, rect.width(), rect.height());
}

void Widget::on_pushButton_down_clicked()
{
    QRect rect = ui->pushButton_target->geometry();
//    rect.setY(rect.y() + 1);
//    ui->pushButton_target->setGeometry(rect);
    ui->pushButton_target->setGeometry(rect.x(), rect.y() + 1, rect.width(), rect.height());
}


void Widget::on_pushButton_left_clicked()
{
    QRect rect = ui->pushButton_target->geometry();
//    rect.setX(rect.x() - 1);
//    ui->pushButton_target->setGeometry(rect);
    ui->pushButton_target->setGeometry(rect.x() - 1, rect.y(), rect.width(), rect.height());
}


void Widget::on_pushButton_right_clicked()
{
    QRect rect = ui->pushButton_target->geometry();
//    rect.setX(rect.x() + 1);
//    ui->pushButton_target->setGeometry(rect);
    ui->pushButton_target->setGeometry(rect.x() + 1, rect.y(), rect.width(), rect.height());
}

例子二:表白神器

设置一个label,俩个按钮,需要更改这三个objectName。注意名字需要有一定命名风格。

#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_like->setText("             送你一朵小花花!");
}


void Widget::on_pushButton_reject_clicked()
{
    //点击拒绝,挪走按钮

    //首先获取到窗口的尺寸
    int width = this->geometry().width();
    int height = this->geometry().height();
    //生成随机数
    int x = rand() % (width - ui->pushButton_reject->geometry().width());
    int y = rand() % (height - ui->pushButton_reject->geometry().height());
    //根据随机数移动按钮位置
    ui->pushButton_reject->move(x, y);
}

rand()是C标准库中的函数,能够生成一个随机的整数,这个数字的范围很大。rand函数之前需要时间戳设置随机种子。在C语言中通过time可以获取到秒级时间戳(以1970年1月1日0时0分0秒为基准计算当前时刻和基准时刻的秒数/毫秒数/微秒数 之差)。

这种方式是根据点击按钮来提供信号的,但是按钮提供的信号不止有点击(一下一上),可以不使用clicked信号,换成pressed,当鼠标按下的时候触发。

#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_like->setText("             送你一朵小花花!");
}


void Widget::on_pushButton_reject_clicked()
{
    //不使用
}

void Widget::on_pushButton_reject_pressed()
{
    //点击拒绝,挪走按钮

    //首先获取到窗口的尺寸
    int width = this->geometry().width();
    int height = this->geometry().height();
    //生成随机数
    int x = rand() % (width - ui->pushButton_reject->geometry().width());
    int y = rand() % (height - ui->pushButton_reject->geometry().height());
    //根据随机数移动按钮位置
    ui->pushButton_reject->move(x, y);
}

此时就变得更快了。

WindowsFrame的影响

Windows Frame窗口框架,这是系统自带的。

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

在Qt中,关于位置尺寸,提供了很多的API:

有的API的位置信息是以Widget本体左上角为原点的(不考虑Window frame)

有的API的位置信息是以window frame左上角为原点的。

上述geometry()、setGeometry()都是不考虑window frame的。

Qt中还提供了frameGeometry()和setFrameGeometry(),这是需要考虑window frame的。

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

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

#include<QDebug>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    
    //针对widget对象来使用geometry和frameGeometry观察现象
    QRect rect1 = this->geometry();
    QRect rect2 = this->frameGeometry();
    qDebug() << rect1;
    qDebug() << rect2;
}

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

使用此代码运行程序的时候,发现此时的位置是相同的,这是因为当前代码是放到了构造函数中,此时这个Widget对象正在构造,还没有被加入到对象。

因此此时还看不到window frame的影响。

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

#include<QDebug>
#include<QPushButton>

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

    QPushButton* button = new QPushButton(this);
    button->setText("按钮");
    button->move(350,250);
    connect(button, &QPushButton::clicked, this, &Widget::handleButton);
}

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

void Widget::handleButton()
{
    //针对widget对象来使用geometry和frameGeometry观察现象
    QRect rect1 = this->geometry();
    QRect rect2 = this->frameGeometry();
    qDebug() << rect1;
    qDebug() << rect2;
}

所以,在点击按钮时, 打印的 geometry 和 frameGeometry 是存在差异的。

评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值