第4章 深入Qt核心模块

第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() 则可手动处理挂起事件。

事件队列调度流程如下:

  1. 事件产生(用户/系统/自定义)
  2. 派发至事件队列
  3. exec() 循环中取出事件
  4. 分发给目标对象的 event() 方法

此机制保证了程序响应性与异步处理能力。

4.1.2 时间、定时器与多线程

定时器: Qt 提供 QTimer 用于周期性或单次触发操作。

QTimer *timer = new QTimer(this);
connect(timer, &QTimer::timeout, this, &MyClass::doSomething);
timer->start(1000); // 每秒触发

线程: Qt 提供跨平台的线程机制(QThread):

  1. 继承 QThread 并重写 run()
  2. 或将工作对象移至子线程执行。

示例:

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 概述

QGuiApplicationQApplication 的轻量级版本,用于图形环境但不含 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
  • 手写笔/手势:QTabletEventQGesture

示例:

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();
});

这样便实现了一个基础的客户端-服务器通信模型。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

weisonx

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值