2、Qt基础控件(上):QWidget、QLabel、QPushButton、QLineEdit、布局管理器
各位同学,咱们今天聊聊Qt里最基础、也最常用的一批控件。说实话,不管你是做桌面工具还是工业软件,天天跟这几个家伙打交道。我刚开始学Qt那会儿,觉得控件嘛,拖上去就完事了。后来踩了不少坑才明白——基础控件用得好,项目能少加一半班。
2.1 QWidget:一切控件的祖宗
QWidget是所有用户界面对象的基类。说白了,你看到的每个按钮、标签、输入框,本质上都是一个QWidget。它定义了窗口最基本的属性:位置、大小、可见性、鼠标事件等等。
核心要点:QWidget本身就是一个空白矩形区域。你可以把它当作画布,往上堆其他控件。
我在项目中遇到过一个问题:新手喜欢直接new QWidget()当顶层窗口,结果发现没有标题栏。嗯,这里要注意——QWidget默认是无边框的。如果你想做一个标准窗口,得设置窗口标志:
QWidget *w = new QWidget();
w->setWindowTitle("我的窗口");
w->resize(400, 300);
w->show();
你想想看,如果只是做弹窗或者悬浮面板,用QWidget就对了。但要是做主窗口,我建议直接用QMainWindow,它自带菜单栏、工具栏、状态栏,省事很多。
2.2 QLabel:不只是显示文字
QLabel,标签控件。很多人觉得它就是个显示静态文本的玩意儿。其实不然。QLabel能显示富文本(HTML子集)、图片、动画,甚至可以作为链接点击的载体。
我个人习惯用QLabel来做三件事:
- 显示普通文本:setText("你好,Qt")
- 显示图片:setPixmap(QPixmap(":/images/logo.png"))
- 显示富文本:setText("<b>粗体</b> <font color='red'>红色</font>")
小技巧:想让QLabel自动换行?调用setWordWrap(true)。我当年做日志显示面板时,就靠这个省了一个自定义控件。
QLabel还有一个容易被忽略的功能——伙伴关系(buddy)。通过setBuddy(),你可以把标签和一个输入控件关联起来。用户点击标签时,焦点会自动跳到关联的控件上。这玩意儿在表单设计中特别好用。
2.3 QPushButton:最常用的交互入口
QPushButton,按钮。用户点一下,程序干一件事。就这么简单?其实里面门道不少。
按钮的核心是信号-槽机制。最常见的用法:
QPushButton *btn = new QPushButton("点击我", this);
connect(btn, &QPushButton::clicked, [=]() {
qDebug() << "按钮被点击了";
});
我曾经犯过一个低级错误:在按钮的点击槽里直接执行耗时操作,结果界面卡死了。后来才学会用QThread或者QtConcurrent来处理。记住:UI线程别干重活。
QPushButton还有一些实用设置:
- setEnabled(false):禁用按钮,灰色不可点
- setDefault(true):设为默认按钮,按Enter触发
- setIcon(QIcon(":/icons/ok.png")):加图标
- setFlat(true):扁平化风格,适合工具栏
注意:setDefault和setAutoDefault的区别。前者是窗口级别的默认按钮,后者是对话框级别的。搞混了会导致按Enter时触发错误的按钮。我调试过整整一个下午才找到这个bug。
2.4 QLineEdit:单行文本输入
QLineEdit,单行输入框。用户输入文字,程序获取内容。看起来简单,但输入验证、占位符、密码模式这些功能,让它的实用性大大提升。
常用设置:
| 方法 | 作用 | 示例 |
|---|---|---|
| setPlaceholderText() | 设置占位提示文字 | "请输入用户名" |
| setEchoMode() | 设置回显模式 | QLineEdit::Password |
| setValidator() | 设置输入验证器 | QIntValidator(0, 100) |
| setMaxLength() | 限制最大字符数 | 20 |
我建议你在做登录界面时,密码框一定要设置EchoMode为Password。另外,输入验证器能帮你省掉很多后端校验的麻烦。比如限制只能输入数字:
QLineEdit *ageEdit = new QLineEdit(this);
ageEdit->setValidator(new QIntValidator(0, 150, this));
信号方面,textChanged和textEdited的区别要搞清楚。前者在代码修改文本时也会触发,后者只响应用户输入。做搜索框时,我一般用textChanged配合QTimer做防抖处理。
2.5 布局管理器:让控件自动排好队
布局管理器是Qt界面设计的灵魂。没有它,你只能手动计算每个控件的位置和大小——窗口一缩放就乱套了。
Qt提供了三种基本布局:
- QHBoxLayout:水平排列,从左到右
- QVBoxLayout:垂直排列,从上到下
- QGridLayout:网格排列,像表格一样
举个例子,做一个简单的登录界面:
QVBoxLayout *mainLayout = new QVBoxLayout(this);
QHBoxLayout *userRow = new QHBoxLayout();
userRow->addWidget(new QLabel("用户名:"));
userRow->addWidget(new QLineEdit());
QHBoxLayout *pwdRow = new QHBoxLayout();
pwdRow->addWidget(new QLabel("密码:"));
pwdRow->addWidget(new QLineEdit());
QPushButton *loginBtn = new QPushButton("登录");
mainLayout->addLayout(userRow);
mainLayout->addLayout(pwdRow);
mainLayout->addWidget(loginBtn);
你想想看,如果不用布局管理器,窗口大小变化时,这些控件的位置得手动调整,多麻烦。
核心原则:布局管理器可以嵌套使用。外层用QVBoxLayout,内层用QHBoxLayout或QGridLayout,几乎能组合出任何你想要的界面结构。
布局管理器还有一些高级特性:
- addStretch():添加弹性空间,把控件挤到一边
- setSpacing():设置控件间距
- setContentsMargins():设置布局边距
- setAlignment():设置对齐方式
我曾经在做一个配置面板时,用了三层嵌套布局,效果非常整齐。记住:布局管理器不是摆设,它是你保持界面整洁的利器。
2.6 知识体系总览
下面这张图,帮你理清本章的知识脉络:
这张图展示了本章的核心逻辑:所有控件都继承自QWidget,然后通过布局管理器组合在一起,形成完整的用户界面。QLabel负责展示,QPushButton负责交互,QLineEdit负责输入——各司其职。
我的建议:刚开始学的时候,别急着写复杂界面。先把这几个控件的属性和信号摸透。你可以在一个空白窗口上,放一个标签、一个输入框、一个按钮,然后实现点击按钮把输入框的内容显示到标签上。这个小练习,能帮你理解80%的Qt界面编程基础。
好了,这一章的内容就到这里。记住:基础不牢,地动山摇。QWidget、QLabel、QPushButton、QLineEdit和布局管理器,是你以后所有Qt项目的基石。多练、多试、多踩坑,自然就熟了。