基础控件
Qt Widgets 提供了丰富的桌面控件,本节介绍最常用的基础控件及其用法。
控件基础
Qt 的所有控件都继承自 QWidget,具有共同的特性:
// 所有控件共有的属性和方法
widget->setEnabled(false); // 禁用/启用
widget->setVisible(true); // 显示/隐藏
widget->setWindowTitle("Title"); // 窗口标题
widget->resize(400, 300); // 设置大小
widget->move(100, 100); // 设置位置
widget->setStyleSheet("color: red"); // 样式表
QLabel(标签)
用于显示文本或图片,是最简单的控件。
#include <QLabel>
// 文本标签
QLabel *textLabel = new QLabel("Hello Qt", this);
textLabel->setText("新文本");
textLabel->setAlignment(Qt::AlignCenter); // 居中对齐
// HTML 富文本
QLabel *htmlLabel = new QLabel(this);
htmlLabel->setText("<h1>标题</h1><p style='color:red'>红色文字</p>");
// 图片标签
QLabel *imageLabel = new QLabel(this);
imageLabel->setPixmap(QPixmap(":/images/logo.png"));
imageLabel->setScaledContents(true); // 图片自适应大小
// 动态更新文本
int count = 0;
label->setText(QString("点击次数: %1").arg(++count));
常用属性
| 方法 | 说明 |
|---|---|
setText() | 设置文本内容 |
setPixmap() | 设置图片 |
setAlignment() | 对齐方式(左/右/居中) |
setWordWrap() | 自动换行 |
setTextInteractionFlags() | 文本交互(可选中/可链接) |
QPushButton(按钮)
最常用的交互控件,响应点击事件。
#include <QPushButton>
// 创建按钮
QPushButton *button = new QPushButton("点击我", this);
// 连接点击信号
connect(button, &QPushButton::clicked, this, [=]() {
qDebug() << "按钮被点击";
});
// 设置图标
button->setIcon(QIcon(":/icons/save.png"));
button->setIconSize(QSize(32, 32));
// 设置快捷键
button->setShortcut(QKeySequence("Ctrl+S"));
// 设置样式
button->setStyleSheet(R"(
QPushButton {
background-color: #4CAF50;
color: white;
border: none;
padding: 10px 20px;
border-radius: 4px;
}
QPushButton:hover {
background-color: #45a049;
}
QPushButton:pressed {
background-color: #3d8b40;
}
QPushButton:disabled {
background-color: #cccccc;
}
)");
// 切换按钮(可勾选)
QPushButton *toggleBtn = new QPushButton("开关", this);
toggleBtn->setCheckable(true);
connect(toggleBtn, &QPushButton::toggled, this, [=](bool checked) {
qDebug() << "状态:" << (checked ? "开启" : "关闭");
});
QLineEdit(单行输入框)
用于接收用户单行文本输入。
#include <QLineEdit>
// 创建输入框
QLineEdit *lineEdit = new QLineEdit(this);
lineEdit->setPlaceholderText("请输入用户名"); // 提示文本
// 获取和设置文本
lineEdit->setText("默认值");
QString text = lineEdit->text();
// 信号连接
connect(lineEdit, &QLineEdit::textChanged, this, [=](const QString &text) {
qDebug() << "文本变化:" << text;
});
connect(lineEdit, &QLineEdit::returnPressed, this, [=]() {
qDebug() << "按下回车:" << lineEdit->text();
});
// 密码输入
QLineEdit *pwdEdit = new QLineEdit(this);
pwdEdit->setEchoMode(QLineEdit::Password); // 显示为密码
// 其他模式:Normal, NoEcho, PasswordEchoOnEdit
// 输入限制
lineEdit->setMaxLength(20); // 最大长度
lineEdit->setValidator(new QIntValidator(0, 100, this)); // 只能输入0-100的整数
lineEdit->setInputMask("0000-00-00"); // 日期格式掩码
// 自动补全
QStringList words;
words << "apple" << "application" << "banana" << "cherry";
QCompleter *completer = new QCompleter(words, this);
completer->setCaseSensitivity(Qt::CaseInsensitive);
lineEdit->setCompleter(completer);
输入验证器
// 整数验证
lineEdit->setValidator(new QIntValidator(0, 9999, this));
// 浮点数验证
lineEdit->setValidator(new QDoubleValidator(0.0, 100.0, 2, this));
// 正则表达式验证(邮箱)
QRegularExpression rx("\\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,}\\b");
lineEdit->setValidator(new QRegularExpressionValidator(rx, this));
QTextEdit(多行文本编辑)
支持多行文本、富文本编辑。
#include <QTextEdit>
// 创建文本编辑器
QTextEdit *textEdit = new QTextEdit(this);
textEdit->setPlaceholderText("请输入内容...");
// 设置和获取文本
textEdit->setPlainText("普通文本");
textEdit->setHtml("<b>粗体</b> 和 <i>斜体</i>");
QString text = textEdit->toPlainText();
QString html = textEdit->toHtml();
// 追加文本
textEdit->append("新行文本");
// 只读模式
textEdit->setReadOnly(true);
// 信号
connect(textEdit, &QTextEdit::textChanged, this, [=]() {
qDebug() << "内容变化";
});
// 设置字体
textEdit->setFont(QFont("Microsoft YaHei", 12));
// 限制输入
textEdit->setMaximumBlockCount(100); // 最多100行
QComboBox(下拉框)
提供下拉选择列表。
#include <QComboBox>
// 创建下拉框
QComboBox *comboBox = new QComboBox(this);
// 添加选项
comboBox->addItem("选项1");
comboBox->addItem("选项2");
comboBox->addItems({"选项3", "选项4", "选项5"});
// 带图标的选项
comboBox->addItem(QIcon(":/icons/user.png"), "用户");
// 设置当前选中项
comboBox->setCurrentIndex(0);
comboBox->setCurrentText("选项2");
// 获取选中项
int index = comboBox->currentIndex();
QString text = comboBox->currentText();
// 信号
connect(comboBox, QOverload<int>::of(&QComboBox::currentIndexChanged),
this, [=](int index) {
qDebug() << "选中索引:" << index;
});
// 可编辑下拉框
comboBox->setEditable(true);
comboBox->setInsertPolicy(QComboBox::InsertAtBottom);
// 用户数据
comboBox->addItem("北京", 110000); // 显示文本,存储城市代码
int cityCode = comboBox->currentData().toInt();
QCheckBox & QRadioButton(复选框和单选框)
#include <QCheckBox>
#include <QRadioButton>
#include <QButtonGroup>
// 复选框
QCheckBox *checkBox = new QCheckBox("同意协议", this);
checkBox->setChecked(true);
connect(checkBox, &QCheckBox::stateChanged, this, [=](int state) {
if (state == Qt::Checked) {
qDebug() << "已勾选";
} else if (state == Qt::Unchecked) {
qDebug() << "未勾选";
} else if (state == Qt::PartiallyChecked) {
qDebug() << "部分勾选";
}
});
// 三态复选框
checkBox->setTristate(true);
// 单选按钮(需要分组)
QButtonGroup *group = new QButtonGroup(this);
QRadioButton *radio1 = new QRadioButton("男", this);
QRadioButton *radio2 = new QRadioButton("女", this);
QRadioButton *radio3 = new QRadioButton("保密", this);
group->addButton(radio1, 1);
group->addButton(radio2, 2);
group->addButton(radio3, 3);
radio1->setChecked(true); // 默认选中
connect(group, QOverload<int>::of(&QButtonGroup::buttonClicked),
this, [=](int id) {
qDebug() << "选中:" << id;
});
QSlider & QSpinBox(滑块和数字框)
#include <QSlider>
#include <QSpinBox>
// 滑块
QSlider *slider = new QSlider(Qt::Horizontal, this);
slider->setRange(0, 100);
slider->setValue(50);
slider->setTickPosition(QSlider::TicksBelow);
slider->setTickInterval(10);
// 数字框
QSpinBox *spinBox = new QSpinBox(this);
spinBox->setRange(0, 100);
spinBox->setValue(50);
spinBox->setSuffix("%"); // 后缀
// 双向绑定
connect(slider, &QSlider::valueChanged, spinBox, &QSpinBox::setValue);
connect(spinBox, QOverload<int>::of(&QSpinBox::valueChanged),
slider, &QSlider::setValue);
// 浮点数版本
QDoubleSpinBox *doubleSpin = new QDoubleSpinBox(this);
doubleSpin->setRange(0.0, 1.0);
doubleSpin->setSingleStep(0.1);
doubleSpin->setDecimals(2);
QProgressBar(进度条)
#include <QProgressBar>
QProgressBar *progressBar = new QProgressBar(this);
progressBar->setRange(0, 100);
progressBar->setValue(50);
// 样式
progressBar->setTextVisible(true);
progressBar->setFormat("%p% (%v/%m)"); // 显示百分比和数值
// 不确定模式(加载中)
progressBar->setRange(0, 0); // 最大值设为0进入不确定模式
// 更新进度
for (int i = 0; i <= 100; i++) {
progressBar->setValue(i);
QThread::msleep(50); // 模拟工作
QCoreApplication::processEvents(); // 处理界面事件
}
布局管理
控件需要通过布局管理器来组织位置。
常用布局
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QGridLayout>
#include <QFormLayout>
// 垂直布局
QVBoxLayout *vLayout = new QVBoxLayout(this);
vLayout->addWidget(label);
vLayout->addWidget(lineEdit);
vLayout->addWidget(button);
vLayout->addStretch(); // 弹性空间,将控件推到顶部
// 水平布局
QHBoxLayout *hLayout = new QHBoxLayout();
hLayout->addWidget(okButton);
hLayout->addWidget(cancelButton);
hLayout->addStretch();
// 嵌套布局
vLayout->addLayout(hLayout);
// 网格布局
QGridLayout *grid = new QGridLayout();
grid->addWidget(new QLabel("姓名:"), 0, 0);
grid->addWidget(nameEdit, 0, 1);
grid->addWidget(new QLabel("年龄:"), 1, 0);
grid->addWidget(ageSpin, 1, 1);
grid->addWidget(new QLabel("地址:"), 2, 0);
grid->addWidget(addressEdit, 2, 1, 1, 2); // 跨2列
// 表单布局(标签-字段成对)
QFormLayout *form = new QFormLayout();
form->addRow("用户名:", usernameEdit);
form->addRow("密码:", passwordEdit);
form->addRow("邮箱:", emailEdit);
布局属性
// 边距和间距
layout->setContentsMargins(10, 10, 10, 10); // 左、上、右、下
layout->setSpacing(10); // 控件间距
// 拉伸因子
hLayout->addWidget(widget1, 1); // 拉伸因子1
hLayout->addWidget(widget2, 2); // 拉伸因子2(占更多空间)
// 对齐方式
layout->addWidget(widget, 0, Qt::AlignCenter); // 居中对齐
完整示例:登录表单
class LoginDialog : public QDialog
{
Q_OBJECT
public:
LoginDialog(QWidget *parent = nullptr) : QDialog(parent)
{
setWindowTitle("用户登录");
setFixedSize(400, 200);
// 创建控件
QLabel *userLabel = new QLabel("用户名:", this);
QLabel *pwdLabel = new QLabel("密码:", this);
QLineEdit *userEdit = new QLineEdit(this);
userEdit->setPlaceholderText("请输入用户名");
QLineEdit *pwdEdit = new QLineEdit(this);
pwdEdit->setPlaceholderText("请输入密码");
pwdEdit->setEchoMode(QLineEdit::Password);
QCheckBox *rememberCheck = new QCheckBox("记住密码", this);
QPushButton *loginBtn = new QPushButton("登录", this);
QPushButton *cancelBtn = new QPushButton("取消", this);
// 布局
QGridLayout *grid = new QGridLayout();
grid->addWidget(userLabel, 0, 0);
grid->addWidget(userEdit, 0, 1);
grid->addWidget(pwdLabel, 1, 0);
grid->addWidget(pwdEdit, 1, 1);
grid->addWidget(rememberCheck, 2, 1);
QHBoxLayout *btnLayout = new QHBoxLayout();
btnLayout->addStretch();
btnLayout->addWidget(loginBtn);
btnLayout->addWidget(cancelBtn);
QVBoxLayout *mainLayout = new QVBoxLayout(this);
mainLayout->addLayout(grid);
mainLayout->addLayout(btnLayout);
// 信号连接
connect(loginBtn, &QPushButton::clicked, this, [=]() {
QString username = userEdit->text();
QString password = pwdEdit->text();
if (username.isEmpty() || password.isEmpty()) {
QMessageBox::warning(this, "警告", "用户名和密码不能为空");
return;
}
// 执行登录...
accept(); // 关闭对话框,返回 Accepted
});
connect(cancelBtn, &QPushButton::clicked, this, &QDialog::reject);
}
};
下一步
掌握了基础控件后,继续学习 容器控件 了解分组框、标签页等组织控件的容器。