第4章 深入Qt核心模块
Qt 是一个跨平台的 C++ 应用开发框架,其核心模块不仅提供 GUI 功能,更包括系统级能力如事件循环、线程控制、文件处理与网络通信等。本章将系统深入讲解 Qt 的四大基础模块:Core、GUI、Widgets 和 Network。
4.1 深入理解 Core 模块
4.1.1 QCoreApplication 与事件循环
QCoreApplication 是 Qt 应用程序的基础类之一,主要用于无界面的控制台应用。它的核心功能是事件循环机制。
int main(int argc, char *argv[]) {
QCoreApplication app(argc, argv);
return app.exec(); // 启动事件循环
}
事件循环通过 exec() 方法启动,QCoreApplication::processEvents() 则可手动处理挂起事件。
事件队列调度流程如下:
- 事件产生(用户/系统/自定义)
- 派发至事件队列
exec()循环中取出事件- 分发给目标对象的
event()方法
此机制保证了程序响应性与异步处理能力。
4.1.2 时间、定时器与多线程
定时器: Qt 提供 QTimer 用于周期性或单次触发操作。
QTimer *timer = new QTimer(this);
connect(timer, &QTimer::timeout, this, &MyClass::doSomething);
timer->start(1000); // 每秒触发
线程: Qt 提供跨平台的线程机制(QThread):
- 继承
QThread并重写run(); - 或将工作对象移至子线程执行。
示例:
class Worker : public QObject {
Q_OBJECT
public slots:
void process() { /* long task */ }
};
QThread *thread = new QThread;
Worker *worker = new Worker;
worker->moveToThread(thread);
connect(thread, &QThread::started, worker, &Worker::process);
thread->start();
4.1.3 Qt 文件与进程操作
文件读写: 使用 QFile, QTextStream, QDataStream
QFile file("example.txt");
if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
QTextStream in(&file);
QString content = in.readAll();
file.close();
}
进程控制: 使用 QProcess 启动外部程序
QProcess *proc = new QProcess(this);
proc->start("ping", QStringList() << "www.qt.io");
可通过 readyReadStandardOutput() 捕获输出。
4.2 深入理解 GUI 模块
4.2.1 QGuiApplication 概述
QGuiApplication 是 QApplication 的轻量级版本,用于图形环境但不含 Widgets。核心功能包括:
- 图形平台抽象
- OpenGL 渲染支持
- 屏幕、多显示器管理(
QScreen)
QGuiApplication app(argc, argv);
QWindow *window = new QWindow;
window->resize(800, 600);
window->show();
return app.exec();
4.2.2 图像处理与字体管理
图像处理: Qt 提供 QImage, QPixmap, QPainter
QImage img("photo.png");
img = img.scaled(100, 100, Qt::KeepAspectRatio);
img.save("resized.png");
字体: 通过 QFont, QFontDatabase 管理系统或自定义字体
QFont font("Courier New", 12, QFont::Bold);
label->setFont(font);
加载外部字体:
int id = QFontDatabase::addApplicationFont(":/fonts/MyFont.ttf");
QString family = QFontDatabase::applicationFontFamilies(id).at(0);
4.2.3 输入设备与平台无关接口
Qt 提供对平台无关的输入事件抽象:
- 键盘:
QKeyEvent - 鼠标:
QMouseEvent - 触控:
QTouchEvent - 手写笔/手势:
QTabletEvent、QGesture
示例:
void MyWidget::keyPressEvent(QKeyEvent *event) {
if (event->key() == Qt::Key_Escape)
close();
}
此外,GUI 模块还提供对屏幕信息(QScreen)、剪贴板(QClipboard)等系统资源的访问。
4.3 深入理解 Widgets 模块
4.3.1 QWidget 架构解析
QWidget 是所有可视控件的基类。其结构如下:
- 布局系统(
QLayout) - 事件系统(
paintEvent,mousePressEvent) - 绘图系统(
QPainter)
控件层级采用父子关系自动管理,子控件自动渲染在父控件之上。
QWidget *parent = new QWidget;
QPushButton *child = new QPushButton("Click", parent);
4.3.2 重绘事件与控件继承
重绘事件由 paintEvent() 控制,可实现自定义控件外观。
void MyWidget::paintEvent(QPaintEvent *) {
QPainter p(this);
p.setBrush(Qt::green);
p.drawEllipse(rect());
}
继承控件重写部分功能,例如自定义按钮:
class RoundButton : public QPushButton {
protected:
void paintEvent(QPaintEvent *) override {
QPainter p(this);
p.setRenderHint(QPainter::Antialiasing);
p.drawEllipse(rect());
p.drawText(rect(), Qt::AlignCenter, text());
}
};
4.3.3 自定义控件的绘制与交互
完整控件通常需要处理绘制、事件响应和属性控制。
示例:自定义色块控件
class ColorBox : public QWidget {
QColor color;
public:
void setColor(QColor c) { color = c; update(); }
protected:
void paintEvent(QPaintEvent *) override {
QPainter p(this);
p.setBrush(color);
p.drawRect(rect());
}
void mousePressEvent(QMouseEvent *) override {
emit clicked(color);
}
signals:
void clicked(QColor);
};
此控件支持用户点击并发出颜色信号。
4.4 深入理解 Network 模块
4.4.1 QTcpSocket 与 QUdpSocket 用法
TCP 客户端:
QTcpSocket *socket = new QTcpSocket;
socket->connectToHost("127.0.0.1", 1234);
socket->write("Hello Server");
UDP 通信:
QUdpSocket *udp = new QUdpSocket;
udp->writeDatagram("ping", QHostAddress("127.0.0.1"), 4567);
接收数据:
connect(udp, &QUdpSocket::readyRead, [&]() {
while (udp->hasPendingDatagrams()) {
QByteArray data;
data.resize(udp->pendingDatagramSize());
udp->readDatagram(data.data(), data.size());
qDebug() << data;
}
});
4.4.2 网络请求与 QNetworkAccessManager
QNetworkAccessManager 支持 GET/POST 等 HTTP 操作。
QNetworkAccessManager *manager = new QNetworkAccessManager;
connect(manager, &QNetworkAccessManager::finished, this, [](QNetworkReply *reply) {
qDebug() << reply->readAll();
});
manager->get(QNetworkRequest(QUrl("https://api.qt.io")));
支持表单、JSON、文件上传等多种请求格式。
4.4.3 实现本地服务器与客户端通信
TCP Server:
QTcpServer *server = new QTcpServer;
connect(server, &QTcpServer::newConnection, [&]() {
QTcpSocket *client = server->nextPendingConnection();
client->write("欢迎连接");
});
server->listen(QHostAddress::Any, 8888);
TCP Client:
QTcpSocket *client = new QTcpSocket;
client->connectToHost("127.0.0.1", 8888);
connect(client, &QTcpSocket::readyRead, [&]() {
qDebug() << "接收:" << client->readAll();
});
这样便实现了一个基础的客户端-服务器通信模型。
2617

被折叠的 条评论
为什么被折叠?



