Qt提供了很多关于获取窗体位置及显示区域大小的函数,本实例利用一个简单的显示窗体的各种位置信息,包括窗体的所在点位置、长、宽信息等。本实例的目的是分析各个有关位置信息的函数之间的区别,如x()、y()、pos()、rect()、size()、geometry()等,以及在不同的情况下应使用哪个函数来获取位置信息。实现的效果如下图所示。
在实例中,分别调用了x()、y()、frameGeometry()、pos()、geometry()、width()、height()、rect()、size()几个函数,这几个函数均是QWidget提供的。当改变对话框的大小,或移动对话框时,调用各个函数所获得的信息显示也相应地发生变化,从变化中可得知各函数之间的区别。
由于本实例的目的是为了分析各函数之间的区别并获得结论,而程序本身的实现较为简单,因此只简单介绍实现过程。
新建Qt Widgets Application,项目名称Geometry,基类QWidget。设计UI界面如下:
头文件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();
void updateLabel();
protected:
void moveEvent(QMoveEvent *event);
void resizeEvent(QResizeEvent *event);
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);
updateLabel();
}
程序初始化时调用updateLabel()函数,以获得各位置函数的信息并显示。具体代码如下:
void Widget::updateLabel()
{
QString str;
// 获得x()函数的结果并显示
ui->labX->setText(QString::number(x()));
// 获得y()函数的结果并显示
ui->labY->setText(QString::number(y()));
// 获得frameGeometry()函数的结果并显示
str=QString::number(frameGeometry().x()) ","
QString::number(frameGeometry().y()) ","
QString::number(frameGeometry().width()) ","
QString::number(frameGeometry().height());
ui->labFrameGeo->setText(str);
// 获得pos()函数的结果并显示
str=QString::number(pos().x()) ","
QString::number(pos().y());
ui->labPos->setText(str);
// 获得geometry函数的结果并显示
str=QString::number(geometry().x()) ","
QString::number(geometry().y()) ","
QString::number(geometry().width()) ","
QString::number(geometry().height());
ui->labGeo->setText(str);
// 获得width(),height()函数的结果并显示
ui->labWidth->setText(QString::number(width()));
ui->labHeight->setText(QString::number(height()));
// 获得rect()函数的结果并显示
str=QString::number(rect().x()) ","
QString::number(rect().y()) ","
QString::number(rect().width()) ","
QString::number(rect().height());
ui->labRect->setText(str);
// 获得size()函数的结果并显示
str=QString::number(size().width()) ","
QString::number(size().height());
ui->labSize->setText(str);
}
updateLabel()函数负责调用各个位置函数获得结果并显示。
重定义QWidget的moveEvent()和resizeEvent()函数,分别响应对话框的移动事件和大小调整事件,使得窗体在被移动或窗体大小发生改变时,能同步更新各函数结果的显示。具体代码如下:
void Widget::moveEvent(QMoveEvent *event)
{
updateLabel();
}
void Widget::resizeEvent(QResizeEvent *event)
{
updateLabel();
}
通过这个例子可以获得如下图所示的结论。
x()、y()和pos()函数都是获得整个窗体左上角的坐标位置。而frameGeometry()与geometry()相对应,frameGeometry()是获得整个窗体的左上顶点和长、宽值,而geometry()函数获得的是窗体内中央区域的左上顶点坐标以及长、宽值。直接调用width()和height()函数获得的是中央区域的长和宽的值。
还有两个函数rect()、size(),调用它们获得的结果也都是对于窗体的中央区域而言的, size()获得的是窗体中央区域的长、宽值,rect()与geometry()一样返回一个QRect对象。其中,两个函数获得的长、宽值是一样的,都是窗体中央区域的长、宽值,只是左上顶点的坐标值不一样,geometry()获得的左上顶点坐标是相对于父窗体而言的坐标,而rect()获得的左上顶点坐标始终为(0,0)。
因此,在实际应用中需根据情况使用正确的位置信息函数以获得准确的位置尺寸信息,尤其是在编写对位置精度要求较高的程序时,如地图浏览程序,更应注意函数的选择,避免产生不必要的误差。
在编写程序时,初始化窗体时最好不要使用setGeometry()函数,而用resize()和move()函数代替,因为使用setGeometry()会导致窗体show()之后在错误的位置上停留很短暂的一段时间,带来闪烁现象。
——————————————————
对于本文实例完整代码有需要的朋友,可关注并在评论区留言!