QWidget的geometry属性
一、geometry属性
1. 简介
geometry属性在计算机图形学中常用于描述和操作2D和3D对象的位置、大小和形状。通过geometry属性,我们可以对图形对象进行各种操作
在 Qt 中,geometry属性表示当前控件的位置和尺寸,就是四个属性的统称
x 横坐标 y 纵坐标 width 宽度 height 高度
2. API
提及:QPiont表示一个点 QRect表示一个矩形 这两个都属于小对象,里面的属性非常少,占用空间也小
提及:区别于move,move只能修改位置 setGeometry 可以修改位置,又可以修改尺寸
3. 代码示例
3.1 示例1:控制按钮的大小变化
文件代码:
//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
//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:控制按钮的移动
文件代码:
//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
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:无法拒绝的辞职表
//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
//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
3. 代码示例 (geometry 和 frameGeometry 的区别)
- 创建一个按钮,查看geometry 和 frameGeometry的返回值
执行程序, 可以看到, 构造函数中, 打印出的 geometry 和 frameGeometry 是相同的.
但是在点击按钮时, 打印的 geometry 和 frameGeometry 则存在差异.
文件代码:
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 并⾮是⼀个窗⼝