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

qt-C++笔记之继承自 QWidget和继承自QObject 并通过 getWidget() 显示窗口或控件时的区别和原理

qt-C++笔记之继承自 QWidget和继承自QObject 并通过 getWidget() 显示窗口或控件时的区别和原理

在这里插入图片描述

code review!

参考笔记
1.qt-C++笔记之父类窗口、父类控件、对象树的关系
2.qt-C++笔记之继承自 QWidget和继承自QObject 并通过 getWidget() 显示窗口或控件时的区别和原理
3.qt-C++笔记之自定义类继承自 QObjectQWidget 及开发方式详解

文章目录

  • qt-C++笔记之继承自 QWidget和继承自QObject 并通过 getWidget() 显示窗口或控件时的区别和原理
    • 1. 继承自 `QWidget` 的特点
      • 1.1.特点
      • 1.2.显示方式
    • 2. 继承自 `QObject` 的特点
      • 2.1.特点
      • 2.2.显示方式
    • 3. 两者的区别
    • 4. 使用场景对比
      • 4.1.继承自 `QWidget` 的场景
      • 4.2.继承自 `QObject` 的场景
    • 5.总结
    • 6. 继承自 `QWidget` 的完整示例
    • 7. 继承自 `QObject` 并通过 `getWidget()` 显示的完整示例

在Qt C++开发中, QWidgetQObject 是两个非常重要的基类,它们是 Qt 框架中类层次结构的核心部分。它们的功能和设计目标不同,因此在继承它们时涉及到的使用场景和实现方式也有所区别。以下是继承自 QWidget 和继承自 QObject 并通过 getWidget() 显示窗口或控件时的区别和原理。

1. 继承自 QWidget 的特点

QWidget 是 Qt 中所有可视化组件(窗口、控件等)的基类。直接从 QWidget 继承的类表示一个可见的 GUI 组件,如窗口、按钮、标签等。

1.1.特点

  • 可视化组件QWidget 自身是一个可视化的对象,可以直接显示在屏幕上。
  • 事件处理:支持 GUI 的事件处理系统(如鼠标事件、键盘事件等)。
  • 布局和绘制:可以添加子控件、设置布局,并通过重写 paintEvent 自定义绘制内容。
  • 生命周期管理:支持父子关系,父控件销毁时会自动销毁其子控件。

1.2.显示方式

继承自 QWidget 的类可以通过以下方式显示:

MyWidget *widget = new MyWidget();
widget->show(); // 直接显示

2. 继承自 QObject 的特点

QObject 是 Qt 中的基础非可视化对象的基类。继承自 QObject 的类本身不是一个可视化控件,不能直接显示在屏幕上

2.1.特点

  • 非可视化对象QObject 主要用于实现非 GUI 相关的逻辑,如数据管理、后台处理、信号槽通信等。
  • 信号与槽:支持 Qt 的信号与槽机制,用于实现组件之间的通信。
  • 生命周期管理:类似于 QWidget,它也支持父子关系,父对象销毁时会自动销毁其子对象。
  • 轻量级:相比 QWidgetQObject 更轻量级,因为它不包含 GUI 相关的功能。

2.2.显示方式

如果一个类继承自 QObject,但需要显示在屏幕上,通常会通过组合的方式将其与一个 QWidget 或子类相关联。例如,通过 getWidget() 方法返回一个实际的 QWidget 对象。

示例代码:

class MyObject : public QObject {
    Q_OBJECT
public:
    explicit MyObject(QObject *parent = nullptr) : QObject(parent) {
        widget = new QWidget(); // 创建一个 QWidget
        widget->setWindowTitle("My Object Widget");
    }

    QWidget* getWidget() const {
        return widget; // 返回实际的 QWidget
    }

private:
    QWidget *widget; // 内部组合一个 QWidget
};

显示方式:

MyObject *obj = new MyObject();
QWidget *widget = obj->getWidget();
widget->show(); // 显示实际的 QWidget

3. 两者的区别

特性继承自 QWidget继承自 QObject 并通过 getWidget() 显示
类职责表示一个可视化控件或窗口表示一个非可视化对象,通常用于逻辑和数据处理
显示方式直接调用 show() 显示通过 getWidget() 返回 QWidget 再显示
GUI 支持提供完整的 GUI 功能不直接支持 GUI 功能,需要组合一个 QWidget
复杂性更适合需要直接实现控件或窗口的场景更适合分离逻辑和界面的场景
对象关系本身可以作为父控件并管理子控件通常作为逻辑对象,实际控件通过组合实现

4. 使用场景对比

4.1.继承自 QWidget 的场景

  • 当您需要创建一个自定义控件或窗口,并且直接与用户交互时。
  • 例如:实现自定义窗口、按钮、输入框等。
class MyWidget : public QWidget {
    Q_OBJECT
public:
    explicit MyWidget(QWidget *parent = nullptr) : QWidget(parent) {
        setWindowTitle("My Custom Widget");
    }
};

4.2.继承自 QObject 的场景

  • 当您需要封装逻辑或非 GUI 相关功能,同时希望在需要时附加一个界面。
  • 例如:数据处理类、控制器类(MVC 模式中的 C)、后台服务类等。
class MyController : public QObject {
    Q_OBJECT
public:
    explicit MyController(QObject *parent = nullptr) : QObject(parent) {
        widget = new QWidget();
        widget->setWindowTitle("Controller Widget");
    }

    QWidget* getWidget() const {
        return widget;
    }

private:
    QWidget *widget;
};

这种方式将逻辑与显示解耦,便于维护和扩展。

5.总结

  1. 继承自 QWidget:用于直接实现可视化控件或窗口,简单直接。
  2. 继承自 QObject 并使用 getWidget():用于逻辑与界面分离的场景,常见于复杂系统或需要灵活扩展的应用程序。

6. 继承自 QWidget 的完整示例

在这个示例中,我们创建一个继承自 QWidget 的自定义窗口,并直接使用 show() 方法显示它。

// main.cpp
#include <QApplication>
#include <QWidget>
#include <QLabel>
#include <QVBoxLayout>

class MyWidget : public QWidget {
    Q_OBJECT
public:
    explicit MyWidget(QWidget *parent = nullptr) : QWidget(parent) {
        // 设置窗口标题
        setWindowTitle("Inherited from QWidget");

        // 创建一个布局和控件
        QVBoxLayout *layout = new QVBoxLayout(this);
        QLabel *label = new QLabel("This is a QWidget-based class!", this);

        // 将控件添加到布局中
        layout->addWidget(label);

        // 设置布局
        setLayout(layout);
    }
};

int main(int argc, char *argv[]) {
    QApplication app(argc, argv);

    // 创建 MyWidget 实例并显示
    MyWidget widget;
    widget.show();

    return app.exec();
}

运行效果

  • 一个窗口显示标题为 “Inherited from QWidget”。
  • 窗口中有一段文字:“This is a QWidget-based class!”。

7. 继承自 QObject 并通过 getWidget() 显示的完整示例

在这个示例中,我们创建一个继承自 QObject 的类,并通过组合方式内部创建一个 QWidget。通过 getWidget() 方法返回 QWidget 对象以显示窗口。

// main.cpp
#include <QApplication>
#include <QWidget>
#include <QLabel>
#include <QVBoxLayout>
#include <QObject>

class MyObject : public QObject {
    Q_OBJECT
public:
    explicit MyObject(QObject *parent = nullptr) : QObject(parent) {
        // 创建一个 QWidget 作为组合对象
        widget = new QWidget();
        widget->setWindowTitle("Inherited from QObject");

        // 创建一个布局和控件
        QVBoxLayout *layout = new QVBoxLayout(widget);
        QLabel *label = new QLabel("This is a QObject-based class with a QWidget!", widget);

        // 将控件添加到布局中
        layout->addWidget(label);

        // 设置布局
        widget->setLayout(layout);
    }

    // 返回内部的 QWidget
    QWidget* getWidget() const {
        return widget;
    }

private:
    QWidget *widget; // 内部组合的 QWidget 对象
};

int main(int argc, char *argv[]) {
    QApplication app(argc, argv);

    // 创建 MyObject 实例
    MyObject obj;

    // 获取 QWidget 并显示
    QWidget *widget = obj.getWidget();
    widget->show();

    return app.exec();
}

运行效果

  • 一个窗口显示标题为 “Inherited from QObject”。
  • 窗口中有一段文字:“This is a QObject-based class with a QWidget!”。

http://www.kler.cn/a/443133.html

相关文章:

  • 【git】-2 分支管理
  • 单例模式-如何保证全局唯一性?
  • CI/CD 流水线
  • 03_Redis基本操作
  • 计算机网络 笔记 数据链路层 2
  • YOLOv5改进 | CARAFE提高精度的上采样方法
  • 绿色浪潮,VELO Angel Glide坐垫奏响环保骑行乐章
  • VUE3 笔记总结
  • abc 384 D(子数组->前缀和) +E(bfs 扩展的时候 按照数值去扩展)
  • 【中工开发者】HarmonyOS APP打怪小游戏
  • QMainwindow的鼠标跟踪事件不触发问题
  • C/C++ 匿名namespace和有名namespace的区别
  • 面试小札:闪电五连鞭_5
  • tryhackme-Pre Security-Defensive Security Intro(防御安全简介)
  • Parcel 常用插件:增强功能与性能的最佳选择
  • ASRPRO学习笔记二之语音控制LED亮灭
  • 鸿蒙操作系统简介
  • git 怎么删除一个远程分支
  • 代理IP与生成式AI:携手共创未来
  • 操作系统里的算法
  • k8s存储卷和动态创建pv
  • GaussDB 企业版轻量化部署探索(二)
  • 准备写一个内网穿透的工具
  • Redis--高并发分布式结构
  • Blazor(.razor)+VUE+elementUI适合一起用吗
  • ArcGIS地理空间平台manager存在任意文件读取漏洞