第七章:Qt 实践
在深入了解 Qt 框架的各个模块之后,本章将通过几个实际案例,展示如何将 Qt 的强大功能应用于真实项目开发中。我们将结合界面设计、信号与槽机制、网络通信和数据处理等内容,探索 Qt 在桌面应用程序开发中的实际应用。
7.1 案例一:简单的文本编辑器
7.1.1 项目目标
构建一个支持文本编辑、保存和打开文件的简易文本编辑器,学习 QMainWindow
、菜单栏和文件操作的使用。
7.1.2 主要功能
- 打开文件: 通过文件对话框选择文件并加载内容。
- 保存文件: 将编辑内容写入到文件。
- 编辑功能: 提供基本的文本编辑功能。
7.1.3 核心代码
#include <QApplication>
#include <QMainWindow>
#include <QTextEdit>
#include <QMenuBar>
#include <QFileDialog>
#include <QMessageBox>
#include <QFile>
#include <QTextStream>class TextEditor : public QMainWindow {Q_OBJECT
private:QTextEdit *editor;public:TextEditor() {editor = new QTextEdit(this);setCentralWidget(editor);QMenu *fileMenu = menuBar()->addMenu("File");QAction *openAction = fileMenu->addAction("Open");QAction *saveAction = fileMenu->addAction("Save");QAction *exitAction = fileMenu->addAction("Exit");connect(openAction, &QAction::triggered, this, &TextEditor::openFile);connect(saveAction, &QAction::triggered, this, &TextEditor::saveFile);connect(exitAction, &QAction::triggered, this, &QMainWindow::close);}private slots:void openFile() {QString fileName = QFileDialog::getOpenFileName(this, "Open File");if (fileName.isEmpty()) return;QFile file(fileName);if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {QMessageBox::warning(this, "Error", "Could not open file");return;}QTextStream in(&file);editor->setText(in.readAll());file.close();}void saveFile() {QString fileName = QFileDialog::getSaveFileName(this, "Save File");if (fileName.isEmpty()) return;QFile file(fileName);if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {QMessageBox::warning(this, "Error", "Could not save file");return;}QTextStream out(&file);out << editor->toPlainText();file.close();}
};int main(int argc, char *argv[]) {QApplication app(argc, argv);TextEditor editor;editor.setWindowTitle("Simple Text Editor");editor.resize(800, 600);editor.show();return app.exec();
}
7.1.4 功能亮点
- 使用
QTextEdit
提供文本编辑功能。 - 文件打开和保存通过
QFileDialog
和QFile
实现。 - 菜单栏通过
QMenuBar
和QAction
构建。
7.2 案例二:网络聊天应用
7.2.1 项目目标
构建一个局域网内实时聊天应用,学习使用 QTcpServer
和 QTcpSocket
进行通信。
7.2.2 主要功能
- 服务器端: 接收并转发客户端消息。
- 客户端: 连接服务器并发送消息。
7.2.3 核心代码
服务器端
#include <QApplication>
#include <QTcpServer>
#include <QTcpSocket>
#include <QDebug>class ChatServer : public QTcpServer {Q_OBJECT
private:QList<QTcpSocket *> clients;protected:void incomingConnection(qintptr socketDescriptor) override {QTcpSocket *client = new QTcpSocket(this);client->setSocketDescriptor(socketDescriptor);clients << client;connect(client, &QTcpSocket::readyRead, [=]() {QByteArray data = client->readAll();for (QTcpSocket *other : clients) {if (other != client) other->write(data);}});connect(client, &QTcpSocket::disconnected, [=]() {clients.removeAll(client);client->deleteLater();});}
};int main(int argc, char *argv[]) {QApplication app(argc, argv);ChatServer server;if (server.listen(QHostAddress::Any, 12345)) {qDebug() << "Server is running on port 12345";} else {qDebug() << "Server failed to start";}return app.exec();
}
客户端
#include <QApplication>
#include <QTcpSocket>
#include <QVBoxLayout>
#include <QLineEdit>
#include <QTextBrowser>
#include <QPushButton>class ChatClient : public QWidget {Q_OBJECT
private:QTcpSocket *socket;QTextBrowser *chatDisplay;QLineEdit *messageInput;public:ChatClient() {socket = new QTcpSocket(this);chatDisplay = new QTextBrowser(this);messageInput = new QLineEdit(this);QPushButton *sendButton = new QPushButton("Send", this);QVBoxLayout *layout = new QVBoxLayout(this);layout->addWidget(chatDisplay);layout->addWidget(messageInput);layout->addWidget(sendButton);connect(sendButton, &QPushButton::clicked, this, &ChatClient::sendMessage);connect(socket, &QTcpSocket::readyRead, this, &ChatClient::receiveMessage);socket->connectToHost("127.0.0.1", 12345);}private slots:void sendMessage() {QString message = messageInput->text();if (!message.isEmpty()) {socket->write(message.toUtf8());messageInput->clear();}}void receiveMessage() {QByteArray data = socket->readAll();chatDisplay->append(QString::fromUtf8(data));}
};int main(int argc, char *argv[]) {QApplication app(argc, argv);ChatClient client;client.setWindowTitle("Chat Client");client.resize(400, 300);client.show();return app.exec();
}
7.2.4 功能亮点
- 服务器端管理多个客户端连接,支持消息广播。
- 客户端实现简单的聊天界面,通过信号槽实现消息收发。
7.3 案例三:图片浏览器
7.3.1 项目目标
开发一个简单的图片浏览器,支持加载本地图片文件并显示,学习 QGraphicsView
的使用。
7.3.2 核心代码
#include <QApplication>
#include <QGraphicsView>
#include <QGraphicsScene>
#include <QGraphicsPixmapItem>
#include <QFileDialog>
#include <QPushButton>
#include <QVBoxLayout>
#include <QWidget>class ImageViewer : public QWidget {Q_OBJECT
private:QGraphicsView *view;QGraphicsScene *scene;public:ImageViewer() {view = new QGraphicsView(this);scene = new QGraphicsScene(this);view->setScene(scene);QPushButton *loadButton = new QPushButton("Load Image", this);QVBoxLayout *layout = new QVBoxLayout(this);layout->addWidget(view);layout->addWidget(loadButton);connect(loadButton, &QPushButton::clicked, this, &ImageViewer::loadImage);}private slots:void loadImage() {QString fileName = QFileDialog::getOpenFileName(this, "Open Image", "", "Images (*.png *.jpg *.bmp)");if (!fileName.isEmpty()) {scene->clear();QPixmap pixmap(fileName);scene->addPixmap(pixmap);view->fitInView(scene->itemsBoundingRect(), Qt::KeepAspectRatio);}}
};int main(int argc, char *argv[]) {QApplication app(argc, argv);ImageViewer viewer;viewer.setWindowTitle("Image Viewer");viewer.resize(800, 600);viewer.show();return app.exec();
}
7.3.3 功能亮点
- 使用
QGraphicsView
和QGraphicsScene
显示图片。 - 提供简单的文件加载功能。
7.4 小结
本章通过多个案例展示了 Qt 在实际开发中的应用,包括文本编辑器、网络聊天应用和图片浏览器。这些项目涵盖了 Qt 的多个模块和技术,帮助开发者将理论知识转化为实践能力。