Qt 控件指南与进阶技巧

Qt
3.7k 词

Qt 常用控件速查、事件系统、绘图与文件操作。

一、UI 设计两种方式

可视化设计(Qt Designer)

适合灵活性不高的项目。在 Designer 中拖拽控件,右键按钮 → “转到槽” 自动生成代码。连接指令写入 ui_xxx.h,自定义连接写在 .cpp 构造函数中。

1
2
3
4
5
MainWindow::MainWindow(QWidget *parent) : QWidget(parent), ui(new Ui::MainWindow) {
ui->setupUi(this);
// 自定义槽连接写在这里
connect(ui->okBtn, &QPushButton::clicked, this, &MainWindow::onOk);
}

代码化设计

适合需要动态创建控件的场景:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Manual : public QDialog {
Q_OBJECT
public:
explicit Manual(QWidget *parent = nullptr);
private:
QCheckBox *checkBoxUnderLine;
QRadioButton *redBot;
QPlainTextEdit *plainEdit;
QPushButton *okBot;
};

// 构造函数中创建
Manual::Manual(QWidget *parent) : QDialog(parent) {
okBot = new QPushButton("确定", this);
okBot->move(200, 300);
connect(okBot, &QPushButton::clicked, this, &QDialog::accept);
}

二、常用控件速查

控件类 说明 关键方法
QPushButton 按钮 setText(), clicked
QCheckBox 复选框 isChecked(), setChecked()
QRadioButton 单选按钮 isChecked()
QLineEdit 单行输入 text(), setText(), setPlaceholderText()
QTextEdit 多行富文本 toPlainText(), setHtml()
QPlainTextEdit 多行纯文本 toPlainText()
QComboBox 下拉框 addItem(), currentText()
QSpinBox 数字输入 value(), setRange()
QLabel 标签 setText(), setPixmap()
QSlider 滑块 value(), setRange()

容器控件

  • QGroupBox:带标题的组框
  • QTabWidget:选项卡
  • QStackedWidget:页面栈(配合 QListWidget 做侧边导航)
  • QScrollArea:滚动区域

弹簧控件(QSpacerItem)

用于布局中填充空白、控制控件间距:

1
2
3
QSpacerItem *spacer = new QSpacerItem(40, 20, 
QSizePolicy::Expanding, QSizePolicy::Minimum);
layout->addSpacerItem(spacer);

三、样式表(QSS)

类似 CSS,可以美化 Qt 界面:

1
2
3
4
5
6
7
8
9
10
11
12
13
QPushButton {
background-color: #4CAF50;
color: white;
border: none;
padding: 8px 16px;
border-radius: 4px;
}
QPushButton:hover {
background-color: #45a049;
}
QPushButton:pressed {
background-color: #3e8e41;
}

应用方式:

1
2
3
4
// 全局样式
qApp->setStyleSheet("QPushButton { color: red; }");
// 单个控件
btn->setStyleSheet("background-color: blue;");

四、事件系统

鼠标事件

1
2
3
4
5
6
7
8
void mousePressEvent(QMouseEvent *event) override {
if (event->button() == Qt::LeftButton) {
// 左键按下
}
}
void mouseMoveEvent(QMouseEvent *event) override;
void mouseReleaseEvent(QMouseEvent *event) override;
void wheelEvent(QWheelEvent *event) override;

定时器

1
2
3
4
5
6
7
8
9
10
// 方式一:QTimer
QTimer *timer = new QTimer(this);
connect(timer, &QTimer::timeout, this, &MyWidget::update);
timer->start(1000); // 每 1000ms

// 方式二:timerEvent
void timerEvent(QTimerEvent *event) override {
if (event->timerId() == m_timerId) { /* ... */ }
}
m_timerId = startTimer(1000);

事件分发与过滤器

1
2
3
4
5
6
7
8
9
10
// 事件过滤器:在目标对象之前拦截事件
bool eventFilter(QObject *obj, QEvent *event) override {
if (obj == targetWidget && event->type() == QEvent::KeyPress) {
// 处理按键
return true; // 拦截,不再传递
}
return QWidget::eventFilter(obj, event);
}
// 安装
targetWidget->installEventFilter(this);

五、绘图(QPainter)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
void paintEvent(QPaintEvent *event) override {
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing);

// 画线
painter.drawLine(10, 10, 100, 100);
// 画矩形
painter.setPen(Qt::red);
painter.setBrush(Qt::blue);
painter.drawRect(50, 50, 200, 100);
// 画文字
painter.setFont(QFont("Arial", 16));
painter.drawText(rect(), Qt::AlignCenter, "Hello Qt");
}

绘图只能在 paintEvent 中进行。触发重绘:update()(异步)或 repaint()(同步)。

六、文件操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <QFile>
#include <QFileDialog>
#include <QTextStream>

// 打开文件对话框
QString path = QFileDialog::getOpenFileName(this, "打开文件",
"/home", "文本文件 (*.txt);;所有文件 (*)");

// 读取文件
QFile file(path);
if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
QTextStream in(&file);
QString content = in.readAll();
file.close();
}

// 写入文件
QFile outFile("output.txt");
if (outFile.open(QIODevice::WriteOnly | QIODevice::Text)) {
QTextStream out(&outFile);
out << "Hello Qt!" << "\n";
outFile.close();
}