☰
Qt 中的类是什么?保姆级详解(新手版)
2026/9/30 2:34:07 网站建设 项目流程

一句话:Qt 类本质就是 C++ 的类,只是 Qt 框架扩展了一套【QObject 对象模型】。 普通 C++ 类:只封装变量、成员函数;继承 QObject 的 Qt 类:除了普通 C++ 能力,额外拥有【信号槽、对象树自动内存管理、元对象系统】三大核心能力Qt

一、最核心根类:QObject(重中之重)

QObject = Qt 世界所有对象的祖宗基类几乎所有控件、窗口、定时器、线程类,都是它的子类(直接继承 / 间接继承)。

注意区分两个概念:

  1. 继承关系(父类 / 子类):C++ 的类继承,QWidget 继承 QObject;
  2. 对象树父子 (parent):对象实例之间的归属,用来自动管理内存,不是 C++ 继承!

✅ QObject 带来 3 个核心功能:

  1. 信号与槽(对象通信):对象之间不用硬调用函数,通过信号槽收发消息(按钮点击就是典型信号)
  2. 对象树自动内存管理(parent 机制)new 对象时传入this作为父对象;父对象销毁,自动删除全部子对象,不用手动 delete,减少内存泄漏
  3. 元对象系统(moc 工具):运行时知道类名字、函数,实现 Q_OBJECT 宏的能力

⚠️ 例外:QString、QList、QColor这类值类型类,不继承 QObject,和普通 C++ 的 string、vector 用法接近,不能写 Q_OBJECT、不能用信号槽。

二、可视化窗口核心类:QWidget(所有界面控件的基类)

QWidget继承自QObject + QPaintDevice(绘图设备)只要能在屏幕上显示出来的东西,全部是 QWidget 子类:

  • QMainWindow:主窗口(带菜单栏、状态栏,Qt 新建项目默认的窗口类)
  • QDialog:弹窗对话框(提示框、文件选择框)
  • QPushButton:按钮
  • QLabel:文本 / 图片标签
  • QLineEdit:单行输入框

简单理解:QObject 负责逻辑通信、内存管理;QWidget 额外增加界面绘制、鼠标键盘事件。

三、写一个自己的 Qt 类(完整示例,逐行解释)

新建头文件myclass.h

#ifndef MYCLASS_H #define MYCLASS_H #include <QObject> // 自定义Qt类:继承QObject class MyClass : public QObject { // 开启元对象系统,必须写,才能用信号槽 Q_OBJECT public: // 构造函数,explicit防止隐式转换;parent父对象默认nullptr explicit MyClass(QObject *parent = nullptr); // 普通成员函数,用来发射信号 void testSend(); // 信号:对外发出通知,只声明,不写函数体 signals: void msgSignal(QString text); // 槽函数:接收信号,执行业务 public: void recvSlot(QString text); }; #endif // MYCLASS_H

cpp 文件myclass.cpp

#include "myclass.h" #include <QDebug> // 构造函数:初始化列表调用父类QObject构造,传入parent MyClass::MyClass(QObject *parent) : QObject(parent) { } void MyClass::testSend() { // emit发射信号 emit msgSignal("Hello Qt类!"); } // 槽函数实现,收到信号后打印 void MyClass::recvSlot(QString text) { qDebug() << "槽收到消息:" << text; }

main.cpp

#include <QCoreApplication> #include "myclass.h" int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); MyClass obj1; // 信号发送对象 MyClass obj2; // 接收对象 // connect连接信号槽 connect(&obj1, &MyClass::msgSignal, &obj2, &MyClass::recvSlot); obj1.testSend(); // 调用函数,触发emit发射信号 return a.exec(); }

运行输出:槽收到消息:"Hello Qt类!"

四、对象树(parent 机制,新手最容易混淆)

// 创建按钮,父对象是当前窗口this QPushButton *btn = new QPushButton("测试按钮", this);

图解逻辑:

  1. btn 的 parent = this(当前窗口对象)
  2. 窗口对象会把 btn 加入自己的 children 子对象列表
  3. 关闭窗口,窗口对象销毁,自动把 btn delete,不用手动释放内存

❗重点:parent 是对象实例之间的归属关系,不是类的继承! 类比: 类的继承:人 → 学生(模板的继承) 对象树 parent:家长 → 孩子(实例的归属,家长消失孩子跟着销毁)

五、Qt 类 和 普通 C++ 类对比表

对比项普通 C++ 类继承 QObject 的 Qt 类
继承默认无父类必须继承 QObject/QWidget 等
Q_OBJECT不能写需要写,开启元对象系统
信号槽不支持支持,emit+connect
内存管理new 之后必须手动 delete设置 parent,父对象自动回收子对象
拷贝赋值支持❌禁止拷贝,不能objA=objB
运行时识别RTTI 才可以自带元对象,直接获取类名

六、新手高频踩坑

  1. 写 Q_OBJECT,忘记执行 qmake,编译报undefined reference to vtable虚表错误 解决:菜单栏【构建】→【Run qmake】再重新构建项目
  2. QObject 子类不能拷贝,不能写MyClass a = b;,只能用指针
  3. UI 控件(QPushButton、QLabel)属于 QWidget,只能在主线程操作,子线程不能直接修改界面
  4. QString/QList这些值类型不是 QObject 子类,不能写 Q_OBJECT,没有 parent,用法和 std::string 类似

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询