2、绝对定位布局:使用 setGeometry 固定控件位置

各位同学,今天我们来聊聊 Qt 里最「原始」的一种布局方式——绝对定位。

说白了,就是用手工给每个控件指定坐标和大小。你让它坐哪儿,它就坐哪儿,绝不乱跑。

我刚学 Qt 那会儿,觉得这玩意儿太方便了。拖几个按钮,调调位置,界面就出来了。但后来踩了不少坑……嗯,咱们慢慢聊。

2.1 什么是绝对定位?

绝对定位,就是通过 setGeometry(x, y, width, height) 方法,直接设置控件在父窗口中的位置和尺寸。

四个参数的含义:

  • x, y:控件左上角相对于父窗口的坐标
  • width, height:控件的宽度和高度

举个例子:

QPushButton *btn = new QPushButton("登录", this);
btn->setGeometry(100, 200, 80, 30);

这行代码的意思是:在父窗口的 (100, 200) 位置,放一个宽 80、高 30 的按钮。

小技巧: 坐标原点在父窗口的左上角。x 向右为正,y 向下为正。这个和数学里的坐标系不太一样,刚上手容易搞反。

2.2 一个简单的登录界面示例

咱们直接上手写个登录界面。我习惯用绝对定位来做这种固定样式的 demo。

#include <QApplication>
#include <QWidget>
#include <QLabel>
#include <QLineEdit>
#include <QPushButton>

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    QWidget window;
    window.setWindowTitle("登录界面 - 绝对定位示例");
    window.resize(400, 300);

    // 用户名标签
    QLabel *userLabel = new QLabel("用户名:", &window);
    userLabel->setGeometry(50, 60, 80, 25);

    // 用户名输入框
    QLineEdit *userEdit = new QLineEdit(&window);
    userEdit->setGeometry(140, 60, 180, 25);

    // 密码标签
    QLabel *pwdLabel = new QLabel("密  码:", &window);
    pwdLabel->setGeometry(50, 110, 80, 25);

    // 密码输入框
    QLineEdit *pwdEdit = new QLineEdit(&window);
    pwdEdit->setGeometry(140, 110, 180, 25);
    pwdEdit->setEchoMode(QLineEdit::Password);

    // 登录按钮
    QPushButton *loginBtn = new QPushButton("登录", &window);
    loginBtn->setGeometry(120, 180, 80, 30);

    // 取消按钮
    QPushButton *cancelBtn = new QPushButton("取消", &window);
    cancelBtn->setGeometry(220, 180, 80, 30);

    window.show();
    return app.exec();
}

这段代码跑起来,你会看到一个登录窗口。两个标签、两个输入框、两个按钮,位置都是硬编码的。

核心要点: 每个控件都调用了 setGeometry,手动指定了坐标和大小。窗口缩放时,这些控件纹丝不动。

2.3 绝对定位的优缺点

咱们客观聊聊这玩意儿的利弊。我在项目里用过不少次,有甜头也有苦头。

优点 缺点
简单直观,新手友好 窗口缩放时控件不会自适应
完全控制每个控件的位置 不同分辨率下界面可能错位
适合固定尺寸的对话框 修改布局需要重新计算坐标
调试时容易定位问题 国际化时文本长度变化会导致重叠

优点方面:

  • 写起来快,不用学布局管理器那一套
  • 适合做原型验证,快速出效果
  • 对于固定尺寸的弹窗,绝对定位完全够用

缺点方面:

  • 窗口一拉伸,界面就崩了。控件不会跟着变大或移动
  • 换不同 DPI 的屏幕,坐标可能全乱套
  • 后期维护改布局,得一个个改坐标,非常痛苦
避坑指南: 我曾经在一个项目中用绝对定位做了整个主界面。后来客户要求支持高分辨率屏幕……嗯,那两周我每天都在改坐标。从那以后,主界面我再也不敢用绝对定位了。

2.4 什么时候该用绝对定位?

你可能会问:那这玩意儿是不是一无是处?

也不是。我个人觉得,以下场景用绝对定位反而更合适:

  • 固定大小的对话框:比如「关于」弹窗、设置向导中的固定步骤页
  • 自定义绘制控件:比如画板、图表控件内部,需要精确控制子元素位置
  • 游戏界面:游戏里的 HUD、按钮位置通常是固定的
  • 快速原型:先验证功能,后面再换成布局管理器

说白了,如果你确定窗口大小不会变,或者你愿意承担维护成本,那绝对定位完全可以用。

2.5 本章知识体系

下面这张图,帮你理清绝对定位的核心逻辑:

绝对定位布局 setGeometry(x, y, w, h) 坐标原点:父窗口左上角 单位:像素 优点:简单、精确 缺点:不响应缩放 缺点:维护成本高 适用场景:固定尺寸对话框、原型验证

2.6 小结

绝对定位是 Qt 布局中最基础的方式。它简单、直接,但缺乏弹性。

我个人建议:小工具、固定弹窗可以用绝对定位;主界面、可缩放窗口,还是老老实实用布局管理器。

下一章咱们会聊水平布局和垂直布局,那才是真正让界面「活起来」的东西。

课后练习: 试着用绝对定位做一个计算器界面,包含数字按钮 0-9 和加减乘除运算符。看看当窗口拉伸时,按钮会不会乱跑?

可可精品资料库