一、Qt常用控件:从入门到顺手

说实话,Qt的控件体系是我用过最舒服的GUI框架之一。你想想看,一个QPushButton就能搞定按钮,一个QLabel就能显示文字,组合起来就能搭出完整的界面。今天我就带你过一遍最常用的五个控件:QPushButton、QLabel、QLineEdit、QTextEdit、QComboBox。

这些控件,说白了就是桌面应用的"砖块"。你搭房子需要砖,做界面就需要它们。我刚开始学Qt时,就是靠这几个控件拼出了第一个能用的工具软件。

核心知识点速览

  • QPushButton:按钮,触发动作
  • QLabel:标签,显示文本或图片
  • QLineEdit:单行输入框,输入用户名密码等
  • QTextEdit:多行文本编辑器,支持富文本
  • QComboBox:下拉选择框,节省界面空间
Qt 常用控件知识体系 Qt 常用控件 QPushButton 触发动作 / 点击事件 QLabel 显示文本 / 图片 QLineEdit 单行输入 / 密码模式 QTextEdit 多行文本 / 富文本 QComboBox 下拉选择 / 节省空间 五个控件覆盖了 80% 的桌面应用交互场景 信号与槽机制让它们协同工作

二、QPushButton:最基础的交互入口

QPushButton,说白了就是那个你点一下就会触发动作的按钮。我习惯叫它"推按钮",虽然现在没人这么叫了。

2.1 基本用法

QPushButton *btn = new QPushButton("点击我", this);
btn->setGeometry(50, 50, 120, 40);

// 连接点击信号
connect(btn, &QPushButton::clicked, [=]() {
    qDebug() << "按钮被点击了!";
});

嗯,这里要注意:connect的写法有新旧两种。上面这种是Qt5推荐的写法,编译期就能检查类型安全。我以前用旧版SIGNAL/SLOT宏,经常因为拼写错误导致运行时崩溃,排查起来特别痛苦。

2.2 常用属性

属性 作用 示例
text 按钮文字 btn->setText("保存")
icon 设置图标 btn->setIcon(QIcon("save.png"))
enabled 是否可用 btn->setEnabled(false)
setFlat 扁平样式 btn->setFlat(true)

小技巧:我个人习惯在按钮文字里加快捷键,比如"保存(&S)",这样Alt+S就能触发。用户体验会好很多。

三、QLabel:不只是显示文字

QLabel,很多人觉得它就是个"静态文本标签"。其实它能干的事不少——显示图片、显示富文本、甚至作为超链接使用。

3.1 显示文本

QLabel *label = new QLabel("欢迎使用本程序", this);
label->setAlignment(Qt::AlignCenter);  // 居中显示
label->setStyleSheet("font-size: 18px; color: #333;");

3.2 显示图片

QLabel *imageLabel = new QLabel(this);
QPixmap pix(":/images/logo.png");
imageLabel->setPixmap(pix.scaled(200, 100, Qt::KeepAspectRatio));

我在项目中遇到过一个问题:直接用setPixmap不缩放,图片太大把界面撑变形了。后来养成了习惯,只要加载图片就顺手加个scaled,保持宽高比。

3.3 超链接支持

QLabel *linkLabel = new QLabel("<a href='https://qt.io'>访问Qt官网</a>", this);
linkLabel->setOpenExternalLinks(true);  // 点击自动打开浏览器

注意:setOpenExternalLinks必须设置为true,否则点击链接不会生效。我曾经调试了半天才发现是忘了这行。

四、QLineEdit:单行输入的好帮手

QLineEdit,说白了就是那个让你输入一行文字的框。用户名、密码、搜索关键词,都靠它。

4.1 基本用法

QLineEdit *edit = new QLineEdit(this);
edit->setPlaceholderText("请输入用户名");  // 占位提示
edit->setMaxLength(20);  // 限制最大长度

// 获取输入内容
QString text = edit->text();

4.2 密码模式

QLineEdit *pwdEdit = new QLineEdit(this);
pwdEdit->setEchoMode(QLineEdit::Password);  // 显示为圆点
pwdEdit->setPlaceholderText("请输入密码");

你想想看,如果不设成Password模式,密码就明文显示了,这在演示时特别尴尬。我见过有人把密码直接暴露在投影仪上……

4.3 常用信号

信号 触发时机 典型用途
textChanged 内容变化时 实时搜索、输入校验
returnPressed 按下回车时 登录确认、搜索跳转
editingFinished 失去焦点时 保存编辑结果

建议:做搜索框时,我习惯连接returnPressed信号,用户输完直接回车就能触发搜索,比点按钮快多了。

五、QTextEdit:多行文本的利器

QTextEdit和QLineEdit的区别,就像笔记本和便签纸。一个能写长篇大论,一个只能记个关键词。

5.1 基本用法

QTextEdit *textEdit = new QTextEdit(this);
textEdit->setPlainText("这是普通文本");  // 纯文本
textEdit->setHtml("<b>这是粗体</b>");   // 富文本

// 获取内容
QString plain = textEdit->toPlainText();
QString html = textEdit->toHtml();

5.2 追加内容

textEdit->append("新的一行");  // 自动换行追加
textEdit->insertPlainText("在光标处插入");

我记得做日志查看器时,用append不断追加日志行,界面流畅不卡顿。但要注意:如果日志量太大,建议限制最大行数,否则内存会爆。

5.3 只读模式

textEdit->setReadOnly(true);  // 用户不能编辑,只能看

这个在显示协议条款、日志信息时特别有用。用户能滚动查看,但不能修改内容。

六、QComboBox:下拉选择的智慧

QComboBox,说白了就是一个下拉框。当选项太多时,用它比用一排单选按钮清爽多了。

6.1 基本用法

QComboBox *combo = new QComboBox(this);
combo->addItem("选项一");
combo->addItem("选项二");
combo->addItem("选项三");

// 设置当前选中
combo->setCurrentIndex(0);

// 获取选中
int index = combo->currentIndex();
QString text = combo->currentText();

6.2 可编辑模式

combo->setEditable(true);  // 允许用户输入自定义内容
combo->setInsertPolicy(QComboBox::NoInsert);  // 不自动插入

我在项目中遇到过:用户想输入一个不在下拉列表里的值。如果设成可编辑模式,就能满足这个需求。但要注意,设成NoInsert可以防止用户乱输的内容污染下拉列表。

6.3 信号处理

connect(combo, QOverload<int>::of(&QComboBox::currentIndexChanged),
        [=](int index) {
    qDebug() << "选中了第" << index << "项";
});

重点:QComboBox有两个重载的currentIndexChanged信号,一个带int参数,一个带QString参数。用QOverload明确指定类型,避免编译歧义。

七、综合示例:一个简单的登录界面

把上面五个控件组合起来,就能做出一个像模像样的登录界面。你想想看,是不是很直观?

// 创建窗口
QWidget *window = new QWidget;
window->setWindowTitle("登录");
window->resize(300, 250);

// 用户名
QLabel *userLabel = new QLabel("用户名:", window);
userLabel->move(30, 30);
QLineEdit *userEdit = new QLineEdit(window);
userEdit->setPlaceholderText("请输入用户名");
userEdit->move(100, 30);

// 密码
QLabel *pwdLabel = new QLabel("密码:", window);
pwdLabel->move(30, 70);
QLineEdit *pwdEdit = new QLineEdit(window);
pwdEdit->setPlaceholderText("请输入密码");
pwdEdit->setEchoMode(QLineEdit::Password);
pwdEdit->move(100, 70);

// 角色选择
QLabel *roleLabel = new QLabel("角色:", window);
roleLabel->move(30, 110);
QComboBox *roleCombo = new QComboBox(window);
roleCombo->addItems({"管理员", "普通用户", "访客"});
roleCombo->move(100, 110);

// 备注
QTextEdit *noteEdit = new QTextEdit(window);
noteEdit->setPlaceholderText("备注信息(可选)");
noteEdit->setGeometry(30, 150, 240, 60);

// 登录按钮
QPushButton *loginBtn = new QPushButton("登录(&L)", window);
loginBtn->setGeometry(100, 220, 100, 30);

// 点击登录
connect(loginBtn, &QPushButton::clicked, [=]() {
    QString user = userEdit->text();
    QString pwd = pwdEdit->text();
    QString role = roleCombo->currentText();
    QString note = noteEdit->toPlainText();
    qDebug() << "登录信息:" << user << pwd << role << note;
});

window->show();

经验之谈:实际项目中,我一般会把界面布局交给QFormLayout或QGridLayout,而不是手动move。这里为了演示清晰,用了绝对定位。正式开发时,布局管理器才是正道。

八、避坑指南

最后,分享几个我踩过的坑,希望能帮你少走弯路。

  • 信号连接失败:检查控件是否被销毁了。我曾经在局部函数里new了控件,函数结束就被回收了,信号永远触发不了。
  • QLineEdit密码可见:setEchoMode要在setText之前调用,否则密码会先明文显示一瞬间。
  • QComboBox索引越界:获取currentIndex前,先检查count() > 0。空下拉框取索引会返回-1。
  • QTextEdit内存泄漏:频繁append大量文本时,记得清理。我一般限制最多10000行,超了就删掉前面的。

好了,这五个控件就讲到这里。你动手试试看,用它们拼一个自己的小工具出来,成就感会特别强。


公众号:蓝海资料掘金营,微信deep3321