3、Qt基础控件(一):QWidget、QLabel、QPushButton、QLineEdit、QTextEdit 的使用与属性设置
好,咱们今天开始聊Qt里最基础的那几个控件。说实话,不管你做多复杂的界面,最后拆解开来,无非就是这些基础控件的组合与嵌套。我刚开始学Qt的时候,总觉得控件越多越高级,后来才发现,能把QWidget、QLabel这几个玩明白,就已经能搞定80%的界面需求了。
3.1 QWidget:一切控件的祖宗
QWidget是所有可视控件的基类。你想想看,QLabel、QPushButton,甚至QMainWindow,它们本质上都是QWidget的派生类。所以理解QWidget,就等于理解了Qt界面的底层逻辑。
我个人习惯把QWidget当作一个「空白的画布」。你可以在上面放子控件,也可以直接在上面绘图。它的核心属性其实不多,但个个都很关键:
| 属性 | 类型 | 说明 |
|---|---|---|
| geometry | QRect | 控件的位置和大小(相对于父控件) |
| minimumSize / maximumSize | QSize | 控件的尺寸限制 |
| sizePolicy | QSizePolicy | 控件在布局中的伸缩策略 |
| windowTitle | QString | 窗口标题(仅顶层窗口有效) |
| enabled | bool | 控件是否可用 |
| visible | bool | 控件是否可见 |
嗯,这里要注意一点:geometry 和 frameGeometry 是有区别的。前者是客户区的位置大小,后者包含了窗口边框。我在项目中遇到过有人用 frameGeometry 来设置子控件位置,结果怎么都对不齐,折腾了半天才发现是边框宽度在捣乱。
核心要点:QWidget的构造函数可以传一个父控件指针。所有子控件都会在父控件销毁时自动释放,不需要手动delete。这是Qt对象树机制的精髓。
// 创建一个顶层窗口
QWidget *window = new QWidget();
window->setWindowTitle("我的第一个窗口");
window->resize(400, 300);
// 创建一个带父控件的QWidget
QWidget *panel = new QWidget(window);
panel->setGeometry(10, 10, 200, 150);
panel->setStyleSheet("background-color: lightgray;");
3.2 QLabel:不只是显示文字
很多人觉得QLabel就是用来显示一行文字的,其实它的能力远不止于此。说白了,QLabel可以显示文本、图片、动画,甚至支持富文本HTML。我经常用它来做状态提示、图标展示,甚至是简单的图文混排。
QLabel的几个关键属性:
- text:显示的文本内容
- pixmap:显示的图片(设置后text会被覆盖)
- alignment:文本对齐方式(水平+垂直组合)
- wordWrap:是否自动换行
- openExternalLinks:是否允许打开外部链接
小技巧:如果你想让QLabel显示带格式的文字,直接用HTML字符串就行。比如 label->setText("<b>粗体</b> <font color='red'>红色</font>");。但要注意,这会让性能稍微下降,大量动态更新时慎用。
QLabel *label = new QLabel("Hello, Qt!", window);
label->setGeometry(10, 170, 200, 30);
label->setAlignment(Qt::AlignCenter);
label->setStyleSheet("font-size: 16px; color: blue;");
// 显示图片
QLabel *imageLabel = new QLabel(window);
QPixmap pix(":/images/icon.png");
imageLabel->setPixmap(pix.scaled(64, 64, Qt::KeepAspectRatio));
3.3 QPushButton:最常用的交互控件
按钮嘛,谁都会用。但你真的了解它的全部属性吗?我曾经在一个项目里,为了做一个「按下时变暗、松开时恢复」的效果,折腾了半小时,后来才发现QPushButton自带 autoFillBackground 和状态相关的样式表伪状态。
QPushButton的核心属性:
| 属性 | 说明 |
|---|---|
| text | 按钮上显示的文字 |
| icon | 按钮图标 |
| iconSize | 图标尺寸 |
| shortcut | 快捷键(如 Alt+F) |
| autoRepeat | 长按时是否自动重复触发 |
| default | 是否为默认按钮(回车触发) |
避坑指南:我曾经在做一个密码输入框时,把「确认」按钮设为了默认按钮。结果用户一按回车就直接提交了,连密码都没输完。后来我加了个判断:只有输入框内容合法时,才把按钮设为默认。所以 setDefault() 一定要配合业务逻辑使用。
QPushButton *btn = new QPushButton("点击我", window);
btn->setGeometry(220, 170, 100, 30);
btn->setIcon(QIcon(":/images/click.png"));
btn->setShortcut(QKeySequence("Alt+C"));
// 连接信号槽
connect(btn, &QPushButton::clicked, [=]() {
qDebug() << "按钮被点击了";
});
3.4 QLineEdit:单行文本输入
QLineEdit是单行输入框,看似简单,但它的属性设置直接影响用户体验。你想想看,一个没有占位符提示、没有输入限制的输入框,用户根本不知道要填什么。
关键属性一览:
- placeholderText:占位符文本(输入框为空时显示)
- echoMode:显示模式(Normal正常、Password密码掩码、NoEcho不显示)
- maxLength:最大输入字符数
- inputMask:输入掩码(如手机号格式)
- validator:验证器(如只能输入数字)
- clearButtonEnabled:是否显示一键清除按钮
实用经验:做登录界面时,我习惯把密码框的 echoMode 设为 Password,同时加一个「显示密码」的切换按钮。用户体验会好很多。另外,inputMask 和 validator 不要同时用,它们会互相干扰。
QLineEdit *lineEdit = new QLineEdit(window);
lineEdit->setGeometry(10, 210, 200, 30);
lineEdit->setPlaceholderText("请输入用户名...");
lineEdit->setMaxLength(20);
lineEdit->setClearButtonEnabled(true);
// 密码输入框
QLineEdit *pwdEdit = new QLineEdit(window);
pwdEdit->setGeometry(10, 250, 200, 30);
pwdEdit->setEchoMode(QLineEdit::Password);
pwdEdit->setPlaceholderText("请输入密码...");
3.5 QTextEdit:富文本编辑利器
QTextEdit和QLineEdit最大的区别是:它支持多行,而且支持富文本。说白了,你可以用它做一个简易的Word编辑器。我曾在项目中用它来做日志显示控件,配合 append() 方法,一行一行追加日志,效果非常好。
QTextEdit的核心能力:
| 功能 | 说明 |
|---|---|
| setPlainText() | 设置纯文本(覆盖原有内容) |
| setHtml() | 设置富文本HTML |
| append() | 追加文本(自动换行) |
| toPlainText() | 获取纯文本内容 |
| setReadOnly() | 设为只读模式 |
提示:如果你只是要显示日志,建议用 QPlainTextEdit 而不是 QTextEdit。前者针对纯文本做了优化,性能更好,内存占用也更低。我刚开始不知道这个区别,用QTextEdit显示大量日志,结果界面卡得不行。
QTextEdit *textEdit = new QTextEdit(window);
textEdit->setGeometry(10, 290, 300, 100);
textEdit->setPlaceholderText("在这里输入多行文本...");
textEdit->setHtml("<h3>标题</h3><p>这是<b>粗体</b>内容</p>");
// 追加内容
textEdit->append("新的一行内容");
3.6 知识体系总览
为了让你更直观地理解这些控件之间的关系,我画了一张结构图。你可以看到,所有控件都继承自QWidget,而每个控件又有自己独特的属性和用途。
这张图把今天讲的五个控件串起来了。你可以看到,QWidget在最顶层,下面分出了QLabel、QPushButton、QLineEdit和QTextEdit。每个控件都有自己专属的属性,但同时也继承了QWidget的通用属性,比如 geometry、enabled 这些。
好了,这一章的内容就到这里。这些基础控件虽然简单,但它们是构建复杂界面的基石。你花时间把它们吃透,后面学布局、学自定义控件都会轻松很多。