当前位置: 首页 > news >正文

Qt---Qt函数库

Qt 框架采用模块化架构,核心模块包括 Qt Core(基础功能)、Qt Widgets(桌面 UI 组件)、Qt Gui(图形相关),扩展模块涵盖网络、数据库、多线程、Qt Quick 等。所有类均以 Q 为前缀(如 QObjectQWidget),无统一命名空间,但通过模块划分功能边界。

一、核心基础模块(Qt Core)

Qt Core 是 Qt 框架的基础,提供跨平台的核心功能,不依赖图形界面,适用于控制台程序和服务端开发。

1. QCoreApplication 应用程序核心类

作为非 GUI 应用的入口点,管理应用程序的生命周期、事件循环和全局资源,GUI 应用的 QApplication 继承自此类。

  • 核心函数

    • static QCoreApplication* instance():返回应用程序实例(单例模式)。
    • int exec():启动事件循环(程序运行的核心,处理事件队列,直至 quit() 被调用)。
    • void quit():终止事件循环(使 exec() 返回 0)。
    • void exit(int returnCode):终止事件循环并指定返回码(常用于主窗口关闭时)。
    • QString applicationName() / void setApplicationName(const QString& name):获取/设置应用名称(用于窗口标题、日志等)。
    • QString applicationVersion() / void setApplicationVersion(const QString& version):获取/设置应用版本。
  • 使用场景:所有 Qt 程序必须创建 QCoreApplication 或其派生类实例,是事件循环的起点。

  • 示例代码

    #include <QCoreApplication>
    #include <QDebug>int main(int argc, char *argv[]) {QCoreApplication app(argc, argv); // 初始化应用app.setApplicationName("MyConsoleApp");app.setApplicationVersion("1.0.0");qDebug() << "Application started. Press Ctrl+C to exit.";return app.exec(); // 启动事件循环
    }
    

2. QObject 元对象基类

Qt 中几乎所有类的基类,提供信号与槽事件处理对象树管理元对象信息等核心功能,是 Qt 框架的灵魂。

  • 核心特性与函数

    • 对象树与内存管理

      • void setParent(QObject* parent):设置父对象,子对象生命周期依赖于父对象(父对象销毁时自动删除子对象)。
      • QObject* parent() const:获取父对象。
      • QList<QObject*> children() const:获取所有子对象。
      • void deleteLater():延迟删除对象(确保当前事件处理完成后再销毁,避免野指针)。
    • 元对象系统

      • const QMetaObject* metaObject() const:返回元对象(存储类的元信息,如信号、槽、属性)。
      • bool inherits(const char* className):判断是否继承自指定类(如 obj->inherits("QWidget"))。
      • QString objectName() const / void setObjectName(const QString& name):获取/设置对象名称(用于查找对象 findChild())。
    • 信号与槽相关

      • bool connect(const QObject* sender, const char* signal, const QObject* receiver, const char* slot, Qt::ConnectionType type = Qt::AutoConnection):连接信号与槽(Qt 4 风格)。
      • bool disconnect(const QObject* sender, const char* signal, const QObject* receiver, const char* slot):断开连接。
    • 事件处理

      • bool event(QEvent* e):事件处理入口(可重写以自定义事件逻辑)。
      • bool eventFilter(QObject* watched, QEvent* event):事件过滤器(拦截其他对象的事件)。
  • 使用场景:所有需要信号与槽、事件处理或对象树管理的类都应继承 QObject,并在类声明中添加 Q_OBJECT 宏(启用元对象功能)。

  • 示例代码

    #include <QObject>
    #include <QDebug>class MyObject : public QObject {Q_OBJECT // 必须添加,启用元对象功能
    public:explicit MyObject(QObject* parent = nullptr) : QObject(parent) {}signals:void valueChanged(int newValue); // 信号(仅声明,无需实现)public slots:void onValueChanged(int value) { // 槽函数qDebug() << "Value changed to:" << value;}
    };int main(int argc, char *argv[]) {QCoreApplication app(argc, argv);MyObject obj1, obj2;// 连接信号与槽:obj1的valueChanged触发obj2的onValueChangedQObject::connect(&obj1, &MyObject::valueChanged, &obj2, &MyObject::onValueChanged);emit obj1.valueChanged(42); // 发射信号,槽函数会被调用return app.exec();
    }#include "main.moc" // 若使用qmake,需包含moc生成文件
    

3. QString 字符串类

Qt 中的字符串处理类,基于 Unicode,支持动态长度、自动内存管理,提供丰富的字符串操作接口,优于 C++ 标准库的 std::string

  • 核心函数

    • 构造与转换

      • QString(const char* str):从 C 字符串构造(自动转换为 Unicode)。
      • QString::fromUtf8(const char* str):从 UTF-8 编码构造。
      • const char* toUtf8() const:转换为 UTF-8 编码的 C 字符串(返回 QByteArray)。
      • int toInt(bool* ok = nullptr, int base = 10) const:转换为整数。
      • double toDouble(bool* ok = nullptr) const:转换为浮点数。
    • 字符串操作

      • QString append(const QString& str) / QString operator+(const QString& str):拼接字符串。
      • QString replace(int position, int n, const QString& after):替换子串。
      • QString mid(int position, int n = -1) const:提取子串(从 position 开始,长度 n,默认到结尾)。
      • int indexOf(const QString& str, int from = 0, Qt::CaseSensitivity cs = Qt::CaseSensitive) const:查找子串位置。
      • bool contains(const QString& str, Qt::CaseSensitivity cs = Qt::CaseSensitive) const:判断是否包含子串。
      • QString toLower() const / QString toUpper() const:转换为小写/大写。
    • 其他常用方法

      • int length() const / bool isEmpty() const:获取长度/判断为空。
      • QString trimmed() const:去除首尾空白字符。
      • static QString number(int n, int base = 10):将数字转换为字符串。
  • 使用场景:所有字符串处理场景(UI 文本、文件路径、网络数据等),避免直接使用 char*std::string 以减少编码问题。

  • 示例代码

    #include <QString>
    #include <QDebug>int main() {QString str = "Hello, Qt!";qDebug() << "Length:" << str.length(); // 输出 9QString upper = str.toUpper();qDebug() << upper; // 输出 "HELLO, QT!"if (str.contains("Qt", Qt::CaseInsensitive)) {qDebug() << "Contains 'Qt'";}QString numStr = QString::number(123.45, 'f', 1); // 格式化为保留1位小数qDebug() << numStr; // 输出 "123.5"return 0;
    }
    

4. 容器类(QListQVectorQMap 等)

Qt 提供一系列模板容器类,替代 C++ 标准容器,优化了跨平台性能和 Qt 特性集成(如与 QVariant 兼容)。

  • QList<T>:最常用的动态数组,内部实现为数组+链表混合结构,支持快速随机访问和中间插入。

    • 核心函数:append()prepend()insert()removeAt()at()count()isEmpty()contains()
    • 示例:
      QList<int> numbers;
      numbers << 1 << 2 << 3; // 插入元素
      numbers.append(4);
      qDebug() << numbers.at(2); // 输出 3
      numbers.removeAt(0); // 移除第一个元素
      
  • QVector<T>:连续内存的动态数组,类似 std::vector,适合频繁随机访问。

    • 核心函数:resize()data()(返回原始指针)、operator[]fill()
  • QMap<Key, T>:有序键值对容器(基于红黑树),按键排序,支持范围查询。

    • 核心函数:insert(key, value)value(key, defaultValue)contains(key)remove(key)keys()values()
    • 示例:
      QMap<QString, int> scores;
      scores["Alice"] = 90;
      scores.insert("Bob", 85);
      qDebug() << scores["Alice"]; // 输出 90
      if (scores.contains("Bob")) {qDebug() << "Bob's score:" << scores.value("Bob");
      }
      
  • QHash<Key, T>:无序哈希表,查找速度快于 QMap(平均 O(1)),但不保证顺序。

5. QVariant 变体类型

用于存储任意 Qt 数据类型(如 intQStringQList 等),支持类型转换,常用于需要动态类型的场景(如 QSettings、模型视图框架)。

  • 核心函数

    • QVariant(Type type):构造指定类型的变体。
    • void setValue(const T& value):设置值(自动推断类型)。
    • T value<T>() const:获取值(若类型不匹配返回默认值)。
    • bool canConvert(Type type) const:判断是否可转换为指定类型。
    • bool convert(Type type):转换为指定类型(成功返回 true)。
  • 示例代码

    #include <QVariant>
    #include <QDebug>int main() {QVariant var(42); // 存储整数qDebug() << var.typeName(); // 输出 "int"qDebug() << var.toInt(); // 输出 42var.setValue(QString("Hello")); // 存储字符串qDebug() << var.toString(); // 输出 "Hello"if (var.canConvert<int>()) {qDebug() << "Can convert to int:" << var.toInt(); // 转换失败,返回0}return 0;
    }
    

6. QTimer 定时器类

用于触发定时事件,支持单次触发和周期性触发,基于 Qt 事件循环,精度适中(毫秒级)。

  • 核心函数

    • void start(int msec):启动定时器(每隔 msec 毫秒触发一次)。
    • void singleShot(int msec, const QObject* receiver, const char* member):静态方法,单次触发(msec 后调用槽函数)。
    • void setInterval(int msec):设置间隔时间。
    • void stop():停止定时器。
    • 信号:timeout()(定时器触发时发射)。
  • 示例代码

    #include <QCoreApplication>
    #include <QTimer>
    #include <QDebug>class TimerExample : public QObject {Q_OBJECT
    public:TimerExample(QObject* parent = nullptr) : QObject(parent) {// 创建周期性定时器auto timer = new QTimer(this);connect(timer, &QTimer::timeout, this, &TimerExample::onTimeout);timer->start(1000); // 每秒触发一次}public slots:void onTimeout() {qDebug() << "Timer triggered";}
    };int main(int argc, char *argv[]) {QCoreApplication app(argc, argv);TimerExample example;// 单次定时器:3秒后退出应用QTimer::singleShot(3000, &app, &QCoreApplication::quit);return app.exec();
    }#include "main.moc"
    

二、Qt Widgets 模块(桌面 UI 组件)

Qt Widgets 提供用于构建桌面应用的 UI 组件,基于 QWidget 类,支持传统的窗口、按钮、文本框等控件,是 Qt 最成熟的 UI 解决方案。

1. QApplication 应用程序类

继承自 QCoreApplication,用于管理 GUI 应用的资源、窗口和事件(如鼠标、键盘事件),是所有 Widgets 应用的入口。

  • 核心函数

    • static QApplication* instance():返回应用实例。
    • int exec():启动 GUI 事件循环(处理用户输入、窗口刷新等)。
    • static QWidget* activeWindow():获取当前活跃窗口。
    • static void setStyle(const QString& style):设置应用样式(如 “Fusion”、“Windows”、“Macintosh”)。
    • static QPalette palette() / void setPalette(const QPalette& palette):获取/设置全局调色板。
  • 示例代码

    #include <QApplication>
    #include <QWidget>int main(int argc, char *argv[]) {QApplication app(argc, argv);app.setApplicationName("MyFirstGUI");app.setStyle("Fusion"); // 使用跨平台的Fusion样式QWidget window; // 创建主窗口window.setWindowTitle("Hello Qt Widgets");window.resize(400, 300); // 设置窗口大小window.show(); // 显示窗口return app.exec(); // 启动事件循环
    }
    

2. QWidget 基础窗口部件类

所有 UI 控件的基类,可作为独立窗口或其他控件的子部件,提供窗口属性(大小、位置、标题)和事件处理。

  • 核心属性与函数

    • 窗口状态

      • void show() / void hide():显示/隐藏部件。
      • void setWindowTitle(const QString& title):设置窗口标题(仅顶级窗口有效)。
      • void resize(int w, int h) / void setGeometry(int x, int y, int w, int h):设置大小/位置和大小。
      • QSize sizeHint() const:返回推荐大小(布局管理器会参考此值)。
    • 样式与外观

      • void setStyleSheet(const QString& styleSheet):设置 CSS 风格的样式表(如 setStyleSheet("background-color: red;"))。
      • void setEnabled(bool enabled):设置是否启用(禁用时控件灰显,不响应事件)。
    • 布局管理

      • void setLayout(QLayout* layout):为部件设置布局管理器(自动管理子部件位置)。
  • 示例代码

    #include <QApplication>
    #include <QWidget>
    #include <QPushButton>int main(int argc, char *argv[]) {QApplication app(argc, argv);QWidget window;window.setWindowTitle("QWidget Example");window.setGeometry(100, 100, 300, 200); // 位置(100,100),大小300x200// 创建按钮作为窗口的子部件QPushButton button("Click Me", &window);button.setGeometry(100, 80, 100, 30); // 相对于父窗口的位置和大小window.show();return app.exec();
    }
    

3. 常用控件类

QPushButton 按钮控件

用于触发操作的按钮,支持文本、图标,发射 clicked() 信号。

  • 核心函数:
    • QPushButton(const QString& text, QWidget* parent = nullptr):构造带文本的按钮。
    • void setIcon(const QIcon& icon):设置图标。
    • 信号:clicked(bool checked = false)(点击时发射)、pressed()(按下时)、released()(释放时)。
QLineEdit 单行文本框

用于输入或显示单行文本,支持密码模式、输入限制等。

  • 核心函数:
    • QString text() const / void setText(const QString& text):获取/设置文本。
    • void setEchoMode(QLineEdit::EchoMode mode):设置回显模式(Normal 正常显示,Password 显示掩码)。
    • void setReadOnly(bool readOnly):设置为只读。
    • 信号:textChanged(const QString& text)(文本变化时)、returnPressed()(按下回车时)。
QTextEdit 多行文本框

支持富文本编辑,可输入多行文本、插入图片等。

  • 核心函数:
    • QString toPlainText() const / void setPlainText(const QString& text):获取/设置纯文本。
    • void setHtml(const QString& html):设置 HTML 格式文本。
    • void append(const QString& text):追加文本。
QComboBox 下拉列表

提供可选列表,支持单选,可编辑。

  • 核心函数:
    • void addItem(const QString& text) / void addItems(const QStringList& list):添加选项。
    • int currentIndex() const / void setCurrentIndex(int index):获取/设置当前选中索引。
    • QString currentText() const:获取当前选中文本。
    • 信号:currentIndexChanged(int index)currentTextChanged(const QString& text)
QCheckBox 复选框

支持勾选/取消勾选的复选框,可用于多选场景。

  • 核心函数:
    • bool isChecked() const / void setChecked(bool checked):获取/设置勾选状态。
    • 信号:toggled(bool checked)(状态变化时)。
QRadioButton 单选按钮

用于互斥选择(同一父部件或同一 QButtonGroup 中只能选中一个)。

  • 核心函数:
    • QCheckBox 类似,信号 toggled(bool checked)
    • 需配合 QButtonGroup 实现互斥:
      QButtonGroup* group = new QButtonGroup(parent);
      group->addButton(radio1, 0); // 关联按钮和ID
      group->addButton(radio2, 1);
      

4. 布局管理器(QLayout 派生类)

自动管理子部件的位置和大小,适应窗口尺寸变化,避免硬编码坐标。

QVBoxLayout 垂直布局

按垂直方向排列部件,从上到下依次放置。

QHBoxLayout 水平布局

按水平方向排列部件,从左到右依次放置。

QGridLayout 网格布局

按行列网格排列部件,支持跨行列。

核心函数(通用):
  • void addWidget(QWidget* widget, int stretch = 0, Qt::Alignment alignment = Qt::Alignment()):添加部件。

  • void addLayout(QLayout* layout, int stretch = 0):嵌套布局。

  • void setSpacing(int spacing):设置部件间距。

  • void setContentsMargins(int left, int top, int right, int bottom):设置布局边缘留白。

  • 示例代码

    #include <QApplication>
    #include <QWidget>
    #include <QVBoxLayout>
    #include <QHBoxLayout>
    #include <QPushButton>
    #include <QLineEdit>int main(int argc, char *argv[]) {QApplication app(argc, argv);QWidget window;window.setWindowTitle("Layout Example");// 创建垂直布局作为主布局QVBoxLayout* mainLayout = new QVBoxLayout(&window);// 添加文本框QLineEdit* edit = new QLineEdit();mainLayout->addWidget(edit);// 创建水平布局放置按钮QHBoxLayout* buttonLayout = new QHBoxLayout();buttonLayout->addWidget(new QPushButton("OK"));buttonLayout->addWidget(new QPushButton("Cancel"));// 将水平布局添加到主布局mainLayout->addLayout(buttonLayout);// 设置布局间距和边距mainLayout->setSpacing(10);mainLayout->setContentsMargins(20, 20, 20, 20);window.resize(300, 150);window.show();return app.exec();
    }
    

5. QMainWindow 主窗口类

提供标准主窗口结构:标题栏、菜单栏、工具栏、状态栏和中央部件,适合构建复杂应用。

  • 核心函数

    • void setCentralWidget(QWidget* widget):设置中央部件(主窗口必须有中央部件)。
    • QMenuBar* menuBar():获取菜单栏(自动创建)。
    • QToolBar* addToolBar(const QString& title):添加工具栏。
    • QStatusBar* statusBar():获取状态栏(自动创建)。
  • 示例代码

    #include <QApplication>
    #include <QMainWindow>
    #include <QMenu>
    #include <QAction>
    #include <QTextEdit>int main(int argc, char *argv[]) {QApplication app(argc, argv);QMainWindow mainWin;mainWin.setWindowTitle("QMainWindow Example");mainWin.resize(800, 600);// 设置中央部件(文本编辑区)QTextEdit* centralWidget = new QTextEdit();mainWin.setCentralWidget(centralWidget);// 创建菜单栏和菜单QMenu* fileMenu = mainWin.menuBar()->addMenu("File");// 添加菜单项QAction* newAction = fileMenu->addAction("New");QAction* openAction = fileMenu->addAction("Open");fileMenu->addSeparator(); // 添加分隔线QAction* exitAction = fileMenu->addAction("Exit");// 连接退出动作到主窗口关闭QObject::connect(exitAction, &QAction::triggered, &mainWin, &QMainWindow::close);// 添加状态栏提示newAction->setStatusTip("Create a new document");mainWin.statusBar()->showMessage("Ready");mainWin.show();return app.exec();
    }
    

6. QDialog 对话框类

用于短期交互(如输入参数、显示消息),模态(阻塞父窗口)或非模态(不阻塞)。

  • 核心函数

    • int exec():以模态方式显示(返回结果码,如 QDialog::Accepted)。
    • void show():以非模态方式显示。
    • void accept() / void reject():关闭对话框并返回对应结果码。
  • 标准对话框

    • QMessageBox:消息框(提示、警告、错误、询问),静态方法如 QMessageBox::information()QMessageBox::question()
    • QFileDialog:文件选择对话框,QFileDialog::getOpenFileName() 获取打开文件路径。
    • QInputDialog:输入对话框,QInputDialog::getText() 获取用户输入文本。
  • 示例代码

    #include <QApplication>
    #include <QMainWindow>
    #include <QPushButton>
    #include <QMessageBox>
    #include <QFileDialog>int main(int argc, char *argv[]) {QApplication app(argc, argv);QMainWindow mainWin;// 添加按钮触发对话框QPushButton* msgBtn = new QPushButton("Show Message");mainWin.setCentralWidget(msgBtn);// 连接按钮点击到消息框QObject::connect(msgBtn, &QPushButton::clicked, [&]() {// 显示询问对话框int result = QMessageBox::question(&mainWin, "Question", "Do you want to open a file?",QMessageBox::Yes | QMessageBox::No);if (result == QMessageBox::Yes) {// 显示文件选择对话框QString filePath = QFileDialog::getOpenFileName(&mainWin, "Open File","/home", "Text Files (*.txt)");if (!filePath.isEmpty()) {QMessageBox::information(&mainWin, "Selected File", "You selected: " + filePath);}}});mainWin.show();return app.exec();
    }
    

三、信号与槽机制(Qt 核心特性)

信号与槽(Signals & Slots)是 Qt 用于对象间通信的机制,替代传统回调,支持类型安全和松散耦合。

1. 基本概念

  • 信号(Signal):对象状态变化时发射的通知(如按钮被点击、文本框内容变化),仅声明,无需实现。
  • 槽(Slot):接收信号并处理的函数(可像普通函数一样调用),需实现。
  • 连接(Connection):通过 QObject::connect() 将信号与槽绑定,信号发射时槽函数自动执行。

2. 连接方式

Qt 支持多种连接类型(Qt::ConnectionType),决定槽函数的执行线程和时机:

连接类型说明
Qt::AutoConnection自动选择(默认):同线程用直接连接,跨线程用队列连接
Qt::DirectConnection直接调用:槽函数在发射信号的线程执行(同步,可能阻塞信号发射线程)
Qt::QueuedConnection队列调度:槽函数在接收者线程的事件循环中执行(异步,线程安全)
Qt::BlockingQueuedConnection阻塞队列:同队列连接,但信号发射线程会阻塞至槽函数执行完毕(跨线程)
  • 示例代码
    // Qt 5+ 新语法(类型安全,推荐)
    connect(sender, &Sender::signalName, receiver, &Receiver::slotName, Qt::QueuedConnection);// Qt 4 旧语法(字符串匹配,不推荐)
    connect(sender, SIGNAL(signalName(int)), receiver, SLOT(slotName(int)), Qt::DirectConnection);
    

3. 信号与槽的要求

  • 信号和槽的参数类型必须兼容(槽的参数可少于信号,多余参数被忽略)。
  • 信号必须声明在类的 signals 区域(无需 public/private 修饰,默认为 public)。
  • 槽可声明在 public slotsprotected slotsprivate slots 区域,行为类似对应访问权限的函数。
  • 继承 QObject 并添加 Q_OBJECT 宏的类才能使用信号与槽(需通过 moc 工具预处理)。

4. 高级用法

  • lambda 表达式作为槽:简化短逻辑处理(Qt 5.0+ 支持):

    connect(button, &QPushButton::clicked, [this]() {qDebug() << "Button clicked, count:" << ++m_count;
    });
    
  • 信号连接信号:一个信号发射时触发另一个信号:

    connect(obj1, &MyObject::valueChanged, obj2, &MyObject::valueChanged);
    
  • 断开连接:不再需要时断开,避免悬空指针:

    disconnect(sender, &Sender::signalName, receiver, &Receiver::slotName);
    

四、事件处理机制

Qt 事件处理负责响应用户输入(鼠标、键盘)、系统通知(窗口大小变化、定时器)等,通过事件对象(QEvent)传递,支持灵活的处理方式。

1. QEvent 事件基类

所有事件的基类,包含事件类型(Type)和处理状态。

  • 常用事件类型:
    • QEvent::MouseButtonPress:鼠标按下
    • QEvent::KeyPress:键盘按下
    • QEvent::Resize:窗口大小变化
    • QEvent::Timer:定时器事件
    • QEvent::Close:窗口关闭

2. 事件处理方式

重写事件处理函数

QWidget 及派生类提供特定事件的虚函数(如 mousePressEventkeyPressEvent),重写即可自定义处理。

  • 示例代码:
    #include <QApplication>
    #include <QWidget>
    #include <QMouseEvent>
    #include <QDebug>class MyWidget : public QWidget {Q_OBJECT
    protected:// 重写鼠标按下事件void mousePressEvent(QMouseEvent* event) override {if (event->button() == Qt::LeftButton) {qDebug() << "Left mouse pressed at:" << event->pos(); // 相对窗口坐标}else if (event->button() == Qt::RightButton) {qDebug() << "Right mouse pressed at:" << event->globalPos(); // 全局屏幕坐标}// 调用父类实现(确保默认行为,如窗口拖动)QWidget::mousePressEvent(event);}// 重写键盘按下事件void keyPressEvent(QKeyEvent* event) override {if (event->key() == Qt::Key_Escape) {qDebug() << "Escape key pressed, closing window";close();}QWidget::keyPressEvent(event);}
    };int main(int argc, char *argv[]) {QApplication app(argc, argv);MyWidget widget;widget.show();return app.exec();
    }#include "main.moc"
    
事件过滤器

通过 installEventFilter() 为对象安装事件过滤器,在事件到达目标对象前拦截处理。

  • 示例代码:
    #include <QApplication>
    #include <QWidget>
    #include <QPushButton>
    #include <QEvent>
    #include <QDebug>class EventFilter : public QObject {Q_OBJECT
    protected:bool eventFilter(QObject* watched, QEvent* event) override {// 拦截按钮的点击事件if (watched->inherits("QPushButton") && event->type() == QEvent::MouseButtonPress) {qDebug() << "Button click filtered!";return true; // 事件被处理,不再传递}// 其他事件交给默认处理return QObject::eventFilter(watched, event);}
    };int main(int argc, char *argv[]) {QApplication app(argc, argv);QWidget window;QPushButton button("Click Me", &window);EventFilter filter;button.installEventFilter(&filter); // 为按钮安装过滤器window.show();return app.exec();
    }#include "main.moc"
    
重写 event() 函数

所有事件都会先经过 event() 函数,可在此处分发或拦截事件(适合处理自定义事件)。

  • 示例代码:
    bool MyWidget::event(QEvent* event) {if (event->type() == QEvent::Timer) {qDebug() << "Timer event received";return true; // 处理定时器事件}// 其他事件交给父类处理return QWidget::event(event);
    }
    

五、绘图与图形(Qt Gui 模块)

Qt Gui 提供绘图功能,通过 QPainterQPaintDevice(如窗口、图片)上绘制图形、文本、图像等。

1. QPainter 绘图类

用于执行绘图操作,支持线条、矩形、椭圆、文本、图像等,需在 paintEvent() 中使用。

  • 核心函数:
    • void drawLine(int x1, int y1, int x2, int y2):绘制直线。
    • void drawRect(int x, int y, int w, int h):绘制矩形。
    • void drawEllipse(const QRect& rect):绘制椭圆(矩形内接)。
    • void drawText(int x, int y, const QString& text):绘制文本。
    • void drawPixmap(const QRect& target, const QPixmap& pixmap):绘制图像。
    • void setPen(const QPen& pen):设置画笔(线条颜色、宽度、样式)。
    • void setBrush(const QBrush& brush):设置画刷(填充颜色、纹理)。

2. QPaintEvent 绘图事件

窗口需要重绘时(如显示、大小变化)触发,必须在 paintEvent() 中创建 QPainter 进行绘图。

  • 示例代码
    #include <QApplication>
    #include <QWidget>
    #include <QPainter>
    #include <QPen>
    #include <QBrush>class DrawingWidget : public QWidget {Q_OBJECT
    protected:void paintEvent(QPaintEvent* event) override {Q_UNUSED(event); // 忽略事件参数QPainter painter(this); // 在当前窗口绘图// 绘制红色直线(宽度2px,虚线)QPen linePen(Qt::red, 2, Qt::DashLine);painter.setPen(linePen);painter.drawLine(50, 50, 250, 50);// 绘制蓝色填充矩形painter.setPen(QPen(Qt::blue)); // 蓝色边框painter.setBrush(QBrush(Qt::lightGray)); // 浅灰填充painter.drawRect(50, 80, 200, 100);// 绘制绿色椭圆painter.setPen(QPen(Qt::darkGreen));painter.setBrush(QBrush(Qt::green));painter.drawEllipse(QRect(100, 200, 100, 80));// 绘制文本painter.drawText(100, 320, "Qt Drawing Example");}
    };int main(int argc, char *argv[]) {QApplication app(argc, argv);DrawingWidget widget;widget.setWindowTitle("Drawing Example");widget.resize(300, 350);widget.show();return app.exec();
    }#include "main.moc"
    

六、网络编程(Qt Network 模块)

Qt Network 提供跨平台的网络编程接口,支持 TCP、UDP、HTTP、FTP 等协议,简化网络通信开发。

1. QNetworkAccessManager HTTP 客户端

用于发送 HTTP 请求(GET、POST 等),支持异步操作,通过信号返回响应。

  • 核心函数:

    • QNetworkReply* get(const QNetworkRequest& request):发送 GET 请求。
    • QNetworkReply* post(const QNetworkRequest& request, const QByteArray& data):发送 POST 请求。
    • 信号:finished(QNetworkReply* reply)(请求完成时)、downloadProgress(qint64 bytesReceived, qint64 bytesTotal)(下载进度)。
  • 示例代码

    #include <QApplication>
    #include <QNetworkAccessManager>
    #include <QNetworkRequest>
    #include <QNetworkReply>
    #include <QDebug>int main(int argc, char *argv[]) {QApplication app(argc, argv);QNetworkAccessManager manager;// 发送GET请求QNetworkRequest request(QUrl("https://www.qt.io"));QNetworkReply* reply = manager.get(request);// 连接请求完成信号QObject::connect(reply, &QNetworkReply::finished, [&]() {if (reply->error() == QNetworkReply::NoError) {QByteArray data = reply->readAll();qDebug() << "Response:" << data.left(500); // 输出前500字节} else {qDebug() << "Error:" << reply->errorString();}reply->deleteLater(); // 释放资源app.quit(); // 退出应用});return app.exec();
    }
    

2. TCP 通信(QTcpSocketQTcpServer

  • QTcpServer:TCP 服务器,监听端口并接受客户端连接。

  • QTcpSocket:TCP 客户端/服务器端套接字,用于数据收发。

  • 服务器示例

    #include <QCoreApplication>
    #include <QTcpServer>
    #include <QTcpSocket>
    #include <QDebug>int main(int argc, char *argv[]) {QCoreApplication app(argc, argv);QTcpServer server;// 监听本地8080端口if (!server.listen(QHostAddress::Any, 8080)) {qDebug() << "Server could not start:" << server.errorString();return 1;}qDebug() << "Server listening on port 8080...";// 连接新连接信号QObject::connect(&server, &QTcpServer::newConnection, [&]() {QTcpSocket* socket = server.nextPendingConnection();qDebug() << "New client connected:" << socket->peerAddress().toString();// 接收客户端数据QObject::connect(socket, &QTcpSocket::readyRead, [socket]() {QByteArray data = socket->readAll();qDebug() << "Received:" << data;// 回复客户端socket->write("Message received: " + data);});// 客户端断开连接时释放资源QObject::connect(socket, &QTcpSocket::disconnected, [socket]() {qDebug() << "Client disconnected";socket->deleteLater();});});return app.exec();
    }
    

七、多线程(Qt Core 模块)

Qt 提供多种多线程方案,避免 UI 线程阻塞,提升程序响应性。

1. QThread 线程类

封装线程,通过重写 run() 函数定义线程执行逻辑。

  • 核心函数:

    • void start(Priority priority = InheritPriority):启动线程(调用 run())。
    • void quit():退出线程事件循环。
    • void wait(unsigned long time = ULONG_MAX):等待线程结束。
    • 信号:started()(线程启动时)、finished()(线程结束时)。
  • 示例代码

    #include <QApplication>
    #include <QThread>
    #include <QDebug>
    #include <QPushButton>class WorkerThread : public QThread {Q_OBJECT
    protected:void run() override {qDebug() << "Worker thread ID:" << QThread::currentThreadId();// 模拟耗时操作for (int i = 0; i < 5; ++i) {msleep(1000); // 休眠1秒qDebug() << "Working..." << i;}}
    };int main(int argc, char *argv[]) {QApplication app(argc, argv);qDebug() << "Main thread ID:" << QThread::currentThreadId();QPushButton button("Start Worker");WorkerThread thread;// 点击按钮启动线程QObject::connect(&button, &QPushButton::clicked, [&]() {if (!thread.isRunning()) {thread.start();}});button.show();return app.exec();
    }#include "main.moc"
    

2. QRunnable 任务类

轻量级任务接口,配合 QThreadPool 实现线程池管理,适合短期任务。

  • 示例代码:
    #include <QCoreApplication>
    #include <QRunnable>
    #include <QThreadPool>
    #include <QDebug>class MyTask : public QRunnable {
    public:void run() override {qDebug() << "Task running in thread:" << QThread::currentThreadId();// 任务逻辑}
    };int main(int argc, char *argv[]) {QCoreApplication app(argc, argv);QThreadPool::globalInstance()->setMaxThreadCount(4); // 设置最大线程数// 提交10个任务for (int i = 0; i < 10; ++i) {QThreadPool::globalInstance()->start(new MyTask());}// 等待所有任务完成QThreadPool::globalInstance()->waitForDone();return 0;
    }
    

八、Qt 开发最佳实践

  1. 内存管理

    • 利用对象树:为动态创建的部件设置父对象,避免内存泄漏。
    • 使用 deleteLater() 而非直接 delete,确保事件处理完成后再销毁对象。
  2. 线程安全

    • 跨线程通信优先使用信号与槽(Qt::QueuedConnection),避免直接调用对象方法。
    • 共享数据需加锁(QMutex),或使用线程安全容器(QAtomicInt)。
  3. 性能优化

    • 大量数据处理放入后台线程,避免阻塞 UI 线程。
    • 使用 QStringBuilder 优化字符串拼接(% 运算符)。
    • 绘图时使用 QPainter::beginNativePainting() 结合 OpenGL 加速。
  4. 跨平台适配

    • 文件路径使用 QDirQFileInfo,避免硬编码斜杠(/\)。
    • 样式使用 QStyleSheet 而非平台特定 API,优先选择 Fusion 样式。

本文只包含常用的方法,更多内容可参考 Qt 官方文档,包括 Qt Quick(QML 界面)、Qt Multimedia(多媒体)、Qt 3D(三维图形)等高级模块。通过合理利用 Qt 的跨平台特性和模块化设计,可高效开发从简单工具到复杂应用的各类软件。

http://www.lryc.cn/news/621360.html

相关文章:

  • 深度学习-卷积神经网络CNN-膨胀卷积、可分离卷积(空间可分离、深度可分离)、分组卷积
  • 小知识点:splice与slice
  • 5.Ansible-playbook-模块介绍(知识点补充)
  • 【从零开始学习Redis】项目实战-黑马点评D1
  • Rabbitmq+STS+discovery_k8s +localpv部署排坑详解
  • 迅雷链接在线解密解析工具系统源码/本地化API/开源(源码下载)
  • TCP 连接管理:深入分析四次握手与三次挥手
  • NetLimiter:精准掌控网络流量,优化网络体验
  • vue3+leaflet案例:告警系统GIS一张图(附源码下载)
  • 新增和编辑共用弹窗模板
  • 深度解析 Vue 高阶技巧:提升工程化能力的实用方案
  • 机器人伴侣的智能升级:Deepoc具身智能模型如何重塑成人伴侣体验
  • AI驱动的智能爬虫架构与应用
  • C++中的链式操作原理与应用(三):专注于异步操作延的C++开源库 continuable
  • 开发避坑指南(26):Vue3 input输入框前置后 置元素解决方案
  • uniapp开发动态添加密码验证
  • 【力扣322】零钱兑换
  • C++ 排序指南
  • Kafka下载和安装
  • Ubuntu 22.04 远程桌面设置固定密码的方法
  • HQA-Attack: Toward High Quality Black-Box Hard-Label Adversarial Attack on Text
  • CoreShop商城框架开启多租户(3)
  • PyTorch 2025全解析:从基础到前沿,深度学习框架的技术演进与实战指南
  • ESP32入门开发·通用硬件定时器 (GPTimer)
  • C# 高并发处理方式
  • 算法题Day1
  • torchvision中数据集的使用与DataLoader 小土堆pytorch记录
  • # Vue 列表渲染详解
  • VLMs开发——基于Qwen2.5-VL 实现视觉语言模型在目标检测中的层级结构与实现方法
  • RxJava Android 创建操作符实战:从数据源到Observable