【QT八股文】系列之篇章1 | QT的基础知识及事件/机制

【QT八股文】系列之篇章1 | QT的基础知识及事件/机制

  • 前言
  • 0. 基础
    • Qt/PyQt5介绍/关联
    • Qt的优缺点(为什么要用qt来做界面)
    • Qt 的核心机制
    • 请简要介绍一下Qt中的主窗口(MainWindow)类,它有哪些重要的函数和成员变量?
    • Qt中的常用容器类(偏数据类),并说明它们的特点和使用场景。
    • PyQt5中的常用容器类(偏布局类),并说明它们的特点及使用场景。
  • 1. 事件/机制
    • QT 的事件 定义/来源/接收者/传递?
    • 信号与事件的区别
    • QT 的事件机制是什么?
    • QT事件机过滤器是什么
    • QT事件机过滤器使用的三种方法及注意事项
    • QT 的事件循环?
    • QT程序是事件驱动的(如何理解)
    • 常见的QT事件类型?
    • QT事件机制有几种级别的事件过滤
    • QT/PYQT5模型/视图机制?(采用的是MVD设计模式,类似于MVC)
    • QT中模型/视图机制与Vue模型/视图机制的区别?
  • 下篇笔记链接
  • 说明

前言

笔者:xiaobai_Ry(CSDN)
笔记时间:2022年某个未知时间点😂

原创文章,未经同意请勿转载

之前说过要share QT的八股文(原创),maybe有小伙伴之前看过我的这篇笔记博客?
在这里插入图片描述先来看看之前的笔记概况吧,最近打算清理一下之前的知识存货啦啦啦(PS:给自己的年度目标还没有达标,所以最近疯狂码字系列了😂)
在这里插入图片描述终于我来更新了!!!这里我同样不喜欢在一篇博文中放太长的内容所以这里我同样分成章节来share啦。今天(2023/12/21)先来更新第一篇章吧。
在这里插入图片描述
【第一篇章主要内容】
作为第一篇章主要是基础定义及QT中重要的事件机制啦

原创文章,未经同意请勿转载

0. 基础

Qt/PyQt5介绍/关联

  • Qt 是一个跨平台的C++的 GUI 应用程序开发框架,可以适用于绝大多数操作系统和设备,包括Windows、Linux 和 macOS 等桌面设备,Android、IOS、WP等移动设备、MCU等。可以支持GUI程序和非GUI程序(如控制台工具和服务器)等的开发,是完全面向对象的框架,容易扩展,并且允许真正的组件编程。
  • PyQt5 是 Qt 的一个 Python 绑定库,它允许开发人员使用 Python 语言编写 Qt 应用程序。它支持 Windows、Linux 和 macOS 等平台,并且是一个非常流行的 Python 库,被广泛应用于 GUI 应用程序开发。

Qt的优缺点(为什么要用qt来做界面)

  • 优点: 1. 跨平台,几乎支持所有平台;2. 接口简单,文档详细;3. 简化了回调函数,采用信号与槽机制,开发效率高
  • 缺点:Qt 作为一个软件平台,比较庞大、臃肿,容易出现程序崩溃现象。

开发时,笔者也会发现开发环境,实验环境及生产环境下程序的运行效率真的还有比较多的差别,尤其是在打包没有设置好的情况下。而且随着系统的规模及复杂程度这种现象也越明显。

Qt 的核心机制

  1. 主要有三大核心机制(围绕信号与槽的展开):元对象系统,属性系统,信号与槽(最核心)

    • 元对象系统(提供信号与槽机制,属性系统…)
      Qt的元对象系统(meta-object)提供了用于内部对象通讯的信号与槽(signals & slots)机制,运行时类型信息,以及动态属性系统(dynamic property system)。

    • 元对象编译器MOC

    • 属性系统
      属性系统特性可以用于任何Qt支持的编译器与架构。它基于元对象系统(Meta-Object System),这套系统同时也提供信号与槽机制用于对象间通讯

    • 信号与槽
      信号与槽用于对象之间的通讯。信号与槽机制是Qt的核心特性。

      在Qt中,使用了信号与槽机制代替了回调机制。信号将会在特定的事件出现时被发出。Qt的控件预定义了很多信号,当然我们也可以继承这些控件以定义自己的子类,然后添加自己的信号。槽是在响应特定信号时会被调用的方法。Qt的控件存在很多预定义的槽,但通常的做法是继承控件以生成自己的子类,然后添加自己的槽,这样我们就可以自行处理感兴趣的信号。

  2. 其他核心机制:GUI界面管理机制(窗口管理器和布局管理器),事件处理机制,数据库支持….

    • 窗口布局管理器:Qt 使用布局/窗口管理器来实现 GUI 应用程序的布局。
    • 事件处理机制:Qt 的事件处理机制允许开发人员处理用户交互事件,如鼠标点击、键盘按键等。Qt 提供了一组事件处理函数,可以方便地处理各种事件。
    • Qt 数据库支持:Qt 提供了对数据库的支持,开发人员可以使用 Qt 提供的数据库 API 来连接和操作各种数据库,如 MySQL、PostgreSQL 和 Oracle 等。

请简要介绍一下Qt中的主窗口(MainWindow)类,它有哪些重要的函数和成员变量?

Qt中的主窗口(MainWindow)类是一种特殊的窗口类,它通常用于构建程序的主窗口。主窗口类继承自QWidget类,因此可以使用QWidget类中的函数和成员变量,同时还具有一些特殊的函数和成员变量。其中:

  • 最常用的函数是setCentralWidget()函数,用于设置主窗口的中心控件;
  • 还有menuBar()函数和statusBar()函数,用于设置菜单栏和状态栏等。

常用的成员变量包括:

  • centralWidget成员变量,表示主窗口的中心控件;
  • menuBar成员变量,表示菜单栏;QtWidgets.QMenuBar()
  • 侧工具栏QtWidgets.QSidebar
  • 底部工具栏QtWidgets.QBottomBar
  • 顶部工具栏QtWidgets.QToolBar(window)
  • statusBar成员变量,表示状态栏。

Qt中的常用容器类(偏数据类),并说明它们的特点和使用场景。

  • QVector:基于数组实现的动态数组容器类,支持快速的随机访问和尾部插入操作。适合于需要频繁随机访问的情况。
  • QList:基于双向链表实现的容器类,支持高效的插入和删除操作。适合于需要频繁插入和删除元素的情况。
  • QLinkedList:基于双向链表实现的容器类,支持高效的插入和删除操作,但不支持随机访问。适合于需要频繁插入和删除元素,但不需要随机访问的情况。
  • QSet:基于哈希表实现的集合容器类,支持高效的查找和插入操作,不允许重复元素。适合于需要快速查找元素,且不需要重复元素的情况。
  • QMap:基于红黑树实现的映射容器类,支持高效的查找和插入操作,键值对按照键的大小有序排列。适合于需要按键进行排序和快速查找的情况。
  • QHash:基于哈希表实现的映射容器类,支持高效的查找和插入操作,键值对无序存储。适合于需要快速查找键值对,且不需要按键排序的情况。
  • QStringList:基于QString实现的字符串列表容器类,支持高效的字符串操作,如拼接、查找、替换等。适合于处理字符串列表的情况。
  • QByteArray:基于char数组实现的字节数组容器类,支持高效的二进制数据读写操作。适合于处理二进制数据的情况。

PyQt5中的常用容器类(偏布局类),并说明它们的特点及使用场景。

在 PyQt5 中,有许多常用的容器类可以用来组织和管理 GUI 应用程序中的数据和情感。以下是一些常用的 PyQt5 容器类,并说明它们的特点及使用场景:

  1. QtWidgets.QStackedWidget: QStackedWidget 是一个弹出式窗口容器,用于在一组窗口之间切换。它支持标签、标题、最小化和最大化按钮,以及内容滚动。它的特点是可以弹出新窗口,并在窗口之间切换,常用于布局多个子窗口,以及在主窗口中显示多个子窗口。
  2. QtWidgets.QVBoxLayout: QVBoxLayout 是垂直布局容器,用于在子组件之间布局。它支持垂直布局、水平和垂直布局,特点是可以嵌套子组件,并控制子组件的大小和位置。它常用于布局文本框、按钮、标签等组件,以及在主窗口中添加子窗口。
  3. QtWidgets.QHBoxLayout: QHBoxLayout 是水平布局容器,用于在子组件之间布局。它支持水平布局、垂直布局和水平垂直布局,特点是可以嵌套子组件,并控制子组件的大小和位置。它常用于布局下拉框、列表框等组件,以及在主窗口中添加子窗口。
  4. QtWidgets.QFormLayout: QFormLayout 是表单布局容器,用于布局表单组件,例如文本框、下拉框和按钮。它支持垂直布局、水平布局和表单布局,特点是可以添加表单控件,并控制它们的大小和位置。它常用于布局表单数据,例如用户注册或登录窗口。
  5. QtWidgets.QGridLayout: QGridLayout 是网格布局容器,用于在水平或垂直方向上布局多个组件。它支持组件对齐、组件大小调整和组件重叠,特点是可以控制组件的位置和大小,适用于布局多个组件的大型 GUI 应用程序。
  6. QtWidgets.QGroupBox: QGroupBox 是一个群组框容器,用于创建群组框,可以在其中添加子窗口和组件。它的特点是可以添加子窗口,并控制子窗口的大小和位置。它常用于布局多个组件,例如菜单栏或状态栏。
  7. QtWidgets.QFrame: QFrame 是边界框容器,用于创建边界框,可以包含文本、按钮和其他组件。它的特点是可以添加其他容器组件,并控制组件的大小和位置。它常用于布局文本、按钮和其他小型组件,例如按钮组或标签组。
  8. QtWidgets.Q Banner: QBanner 是一个广告条容器,用于在应用程序中显示广告或信息。它的特点是可以显示文本、图像或其他媒体,并支持动画效果。它常用于在应用程序中添加广告或重要信息。
  9. QtWidgets.QListWidget: QListWidget 是一个列表容器,用于显示列表中的项。它支持选中、拖动和删除操作,特点是可以添加、删除和修改项。它常用于显示数据列表,例如文件列表或用户列表。
  10. QtWidgets.QTreeView: QTreeView 是树形结构容器,用于显示树形结构中的项。它支持拖动和删除操作,特点是可以添加、删除和修改项。它常用于显示数据树形结构,例如文件系统或数据库。

综上所述,这些容器类都有各自特点和使用场景,可以根据实际需要选择合适的容器类来组织和管理 GUI 应用程序中的数据和情感。

1. 事件/机制

QT 的事件 定义/来源/接收者/传递?

  • 定义
    Qt 事件是一个 QEvent 对象,用于描述程序内部或外部发生的动作,任意的 QObject 对象都具有事件处理的能力

  • 意义
    在这里插入图片描述

  • 来源
    Qt中事件的来源有两个:程序外部和内部。

    • 程序外部:多数情况下来自操作系统,可以通过bool QEvent::spontaneous() const函数来获知,返回true,事件发生在应用程序之外(系统事件),否则返回false。
    • 程序内部:系统自动发生,比如计时器事件(timerEvent)。
  • 接收者
    事件由QObject类来接收,是Qt对象模型的核心,所有需要处理的事件类都必须继承QObject。

  • GUI 应用程序的事件处理方式
    在这里插入图片描述

    1. Qt 事件产生后立即分发到 QWidget 对象
    2. QWidget 中的 event(QEvent*) 进行事件处理
    3. event() 根据事件的类型调用不同的事件处理函数
    4. 在事件处理函数中发送 Qt 中预定义的信号
    5. 调用信号关联的槽函数
  • 事件的传递过程
    在这里插入图片描述

信号与事件的区别

首先,我们需要了解一下相关的定义。

  • 信号槽:signal由具体对象发出,然后会马上交给由connect函数连接的 slot进行处理。
  • 事件: Qt 使用一个事件队列对所有发出的事件进行维护,当新的事件产生时,会被追加到事件队列的尾部,前一个事件完成后,取出后面的事件进行处理。但是,必要的时候,Qt 的事件也是可以不进入事件队列,而是直接处理的。并且,事件还可以使用“事件过滤器”进行过滤。

信号与事件的区别主要可以概述为:

  1. 处理对象不同
    事件由具体对象进行处理,信号由具体对象主动产生。改写事件处理函数可能导致程序行为发生改变,信号是否存在对应的槽函数不会改变程序行为,一般而言,信号在具体的事件处理函数中产生。
  2. 使用的机制和原理不同
    1. 事件类似于 Windows 里的消息,它的发出者一般是窗口系统。相对信号和槽机制,它 比较“底层”,它同时支持异步和同步的通信机制,一个事件产生时将被放到事件队列 里,然后我们就可以继续执行该事件 “后面”的代码。事件的机制是非阻塞的。
    2. 信号和槽机制相对而言比较“高层”,它的发出者一般是对象。从本质上看,它类似 于传统的回调机制,是不支持异步调用的。
  3. 使用场合和时机不同
    一般情况下:
    • 在“使用”窗口部件时,我们经常需要使用信号,并且会遵循信号与槽的机制;
    • 在“实现”窗口部件时,我们就不得不考虑如何处理事件了。

举个例子,当使用 QPushButton 时,我们对于它的 clicked()信号往往更为关注,而很少关心促成发射该信号的底层的鼠标或者键盘事件。但是,如果要实现一个类似于 QPushButton 的类,我们就需要编写一定的处理鼠标和键盘事件的代码,而且在必要的时候,仍然需要发射和接收 clicked()信号。

QT 的事件机制是什么?

  • 事件机制:事件会经过:事件产生 ->事件派发 -> 事件过滤->事件分发->事件处理五个阶段。Qt 窗口中对于产生的一系列事件都有默认的处理动作,如果有特殊需求就需要在合适的阶段重写事件的处理动作。
    在这里插入图片描述
  1. 当事件产生之后,Qt 使用用应用程序对象调用 notify() 函数将事件发送到指定的窗口
  2. 事件在发送过程中可以通过事件过滤器进行过滤,默认不对任何产生的事件进行过滤。
  3. 当事件发送到指定窗口之后,窗口的事件分发器会对收到的事件进行分类.
  4. 事件分发器会将分类之后的事件(鼠标事件、键盘事件、绘图事件…)分发给对应的事件处理器函数进行处理,每个事件处理器函数都有默认的处理动作,也可以重写这些事件处理器函数。

💡 当发生事件,比如点击鼠标或键盘,就会产生一个QEvent对象,这里注意QT中所有的事件类都继承于QEvent,这个QEvent对象会传给当前组件的event函数,如果没有事件过滤器,则该函数会按照事件对象的类型发送到特定的xxxEvent事件处理函数中进行处理。

  • 事件处理顺序:
    首先QCoreApplication::exec()开启了事件循环,一直到QCoreApplication::exit()被调用才终止,所以说事件循环是伴随着Qt程序的整个运行周期,事件被分发到事件队列中,当队列中有事件时会不停的将事件发送给QObject对象,队列为空时就阻塞,以下为处理顺序。
    在这里插入图片描述
    • sendEvent:使用notify()函数直接将事件发送给接收者,发送事件时不会删除该事件,通常是在栈上面创建事件,它是同步事件。
    • postEvent:将事件添加到事件队列中,并立即返回;事件必须在堆上分配,因为提交事件队列将获得事件的所有权,并在提交后删除它。在事件发布后访问该事件是不安全的,它是异步事件。
      在这里插入图片描述
  • 事件机制流程:产生事件,事件派发,事件接收者处理,事件转发
    在这里插入图片描述

QT事件机过滤器是什么

  • 定义
    除了使用事件分发器来过滤 Qt 窗口中产生的事件,还可以通过事件过滤器过滤相关的事件。当 Qt 的事件通过应用程序对象发送给相关窗口之后,窗口接收到数据之前这个期间可对事件进行过滤,过滤掉的事件就不能被继续处理了。事件过滤器可以对其它组件接收到的事件进行监控。QObject 有一个 eventFilter () 函数,用于建立事件过滤器。

  • 作用
    实际上,事件过滤器并不只是过滤事件,也可以对事件进行捕捉、并做出相应的处理操作。对象A只有安装了对象B的事件过滤器,才会在对象B的eventFilter方法中进行监控对象A的所有事件。
    在这里插入图片描述

  • 过滤传递中的事件,主要分为两步:

    1. 给要被过滤事件的类对象安装事件过滤器
      组件通过 installEventFilter() 函数安装事件过滤器
      在这里插入图片描述
    • 事件过滤器在组件之前接收到事件
    • 事件过滤器能够决定是否将事件转发到组件对象
    1. 在要进行事件过滤的类中(filterObj 参数对应的类)重写从QObject类继承的虚函数eventFilter()。

💡 注意:事件过滤器和被安装过滤器的组件必须在同一线程,否则,过滤器将不起作用。另外,如果在安装过滤器之后,这两个组件到了不同的线程,那么,只有等到二者重新回到同一线程的时候过滤器才会有效。

QT事件机过滤器使用的三种方法及注意事项

  • 三种方法
    • 父窗口类通过重写eventFilter方法来监听子控件的相关事件进行处理。
      使用这种方式的好处是不需要通过重写控件的方式获取某些事件,对于安装了事件过滤器的对象,他们所有的事件都会经过这个事件过滤器,所以就可以直接在父窗口中进行监测。比如某个窗口中有个QLabel对象,我们想要监听他的鼠标点击事件,那我们就需要继承QLabel类,然后重写mousePressEvent事件,如果有其他类型的控件也需要获取某个事件,那是不是都需要继续控件并重写某个事件了,所以我们通过事件过滤器就可以很方便获取某个对象的某个事件。
    • 专门的事件过滤器类,对特定的对象/特定的事件进行处理。
      事件过滤器类只需对当前安装的对象进行处理,无需关心其他操作,且一个事件过滤器类可以被多个对象使用,例如Qt文档中的按键过滤示例,KeyPressEater类中的eventFilter过滤了所有的键盘按下事件,只要安装此事件过滤器的控件,都接收不到键盘按键按下的事件,这种就是对某个通用的事件进行过滤,可以进行多次复用。
    • 给QApplication安装事件过滤器,达到全局事件监听的效果。
      在notify方法下发事件的时候,QApplication对象可以拿到第一控制权,对某些事件优先进行处理,比如全局的快捷键操作。
  • 注意点:
    • 事件过滤器可以安装在任何继承QObject的对象上,也可以安装在QApplication对象上(全局事件过滤器);
    • 事件过滤器(eventFilter方法)返回值为true,表示将当前事件进行过滤,不会发送到对象本身;如果返回false,表示对当前事件不做任何处理,会通过event()方法将事件分发给原来的对象。如果不知道怎么处理或者返回什么,那就返回父类的eventFilter方法(类似 return QObject::eventFilter(watched, event));
    • 一个对象可以安装多个事件过滤器(也就是一个对象的事件可以被多个对象进行监控/处理/过滤), 并且最先安装的事件过滤器是最后被调用的,类似于栈的操作,先进后出;
    • 一个事件过滤器可以被多个对象安装,但是如果在事件过滤器(eventFilter方法)中把该对象删除了, 一定要将返回值设为true。否则 Qt会将事件继续分发给这个对象,从而导致程序崩溃。

QT 的事件循环?

  • 定义:Qt事件循环:从队列中不断取出消息、处理消息的过程。
    • 事件循环:事件是一个类对象,具有特定的类型,多数情况下是被分发到一个队列中(事件队列),当队列中有事件时就不停地将队列中的事件发送给QObject对象,当队列为空时,就阻塞地等待事件。
      在这里插入图片描述

    • 事件循环首先是一个无限“循环”,程序在exec()里面无限循环,能让跟在exec()后面的代码得不到运行机会,直至程序从exec()跳出。从exec()跳出时,事件循环即被终止。QEventLoop::quit()能够终止事件循环。

    • 首先QCoreApplication::exec()开启了事件循环,一直到QCoreApplication::exit()被调用才终止,所以说事件循环是伴随着Qt程序的整个运行周期,事件被分发到事件队列中,当队列中有事件时会不停的将事件发送给QObject对象,队列为空时就阻塞

  • 类型:
    事件循环一般用exec()函数开启。QApplicaion::exec()、QMessageBox::exec()都是事件循环。其中前者又被称为主事件循环。

QT程序是事件驱动的(如何理解)

Qt将系统产生的信号(软件中断)转换成Qt事件,并且将事件封装成类,所有的事件类都是由QEvent派生的,事件的产生和处理就是Qt程序的主轴,且伴随整个程序的运行周期。因此说Qt是事件驱动的。

常见的QT事件类型?

  • 键盘事件: 按键按下和松开 Key Press Event, Key Release Event
  • 鼠标事件: 鼠标移动,鼠标按键的按下和松开,鼠标进入事件,鼠标离开事件… Mouse Motion Event, Mouse Click Event,Mouse Right Click Event,Mouse Position Event
  • 拖放事件: 用鼠标进行拖放 Dragging Event
  • 滚轮事件: 鼠标滚轮滚动
  • 绘屏事件: 重绘屏幕的某些部分 定时事件: 定时器到时
  • 焦点事件: 键盘焦点移动 进入和离开事件: 鼠标移入widget之内,或是移出 Focus Change Event
  • 移动事件: widget的位置改变
  • 大小改变事件: widget的大小改变
  • 显示和隐藏事件: widget显示和隐藏
  • 窗口事件: 窗口是否为当前窗口,窗口关闭等

QT事件机制有几种级别的事件过滤

根据对Qt事件机制的分析, 我们可以得到5种级别的事件过滤,处理办法. 以功能从弱到强, 排列如下:
1)重写特定事件处理函数.
最常见的事件处理办法就是重载象mousePressEvent(), keyPressEvent(), paintEvent() 这样的特定事件处理函数.

2)重写event()函数.
通过重载event()函数,我们可以在事件被特定的事件处理函数处理之前(象keyPressEvent())处理它. 比如, 当我们想改变tab键的默认动作时,一般要重载这个函数. 在处理一些不常见的事件(比如:LayoutDirectionChange)时,evnet()也很有用,因为这些函数没有相应的特定事件处理函数. 当我们重载event()函数时, 需要调用父类的event()函数来处理我们不需要处理或是不清楚如何处理的事件.

3) 在Qt对象上安装事件过滤器
安装事件过滤器有两个步骤: (假设要用A来监视过滤B的事件)
首先调用B的installEventFilter( const QOject *obj ), 以A的指针作为参数. 这样所有发往B的事件都将先由A的eventFilter()处理.
然后, A要重载QObject::eventFilter()函数, 在eventFilter() 中书写对事件进行处理的代码.

4) 给QAppliction对象安装事件过滤器.
一旦我们给qApp(每个程序中唯一的QApplication对象)装上过滤器,那么所有的事件在发往任何其他的过滤器时,都要先经过当前这个 eventFilter(). 在debug的时候,这个办法就非常有用, 也常常被用来处理失效了的widget的鼠标事件,通常这些事件会被QApplication::notify()丢掉. ( 在QApplication::notify() 中, 是先调用qApp的过滤器, 再对事件进行分析, 以决定是否合并或丢弃)

5) 继承QApplication类,并重写notify()函数.
Qt 是用QApplication::notify()函数来分发事件的.想要在任何事件过滤器查看任何事件之前先得到这些事件,重载这个函数是唯一的办法. 通常来说事件过滤器更好用一些, 因为不需要去继承QApplication类. 而且可以给QApplication对象安装任意个数的事件。

QT/PYQT5模型/视图机制?(采用的是MVD设计模式,类似于MVC)

QT中的模型/视图(Model/View)架构是一种用于管理和显示数据的模型。在很多书中,QT的视图模型经常被叫做MVC,其实QT中的MVC并不叫MVC,而是叫“MVD”,Qt中没有Controller的说法,而是使用了另外一种抽象: Delegate (委托) ,其行为和传统的MVC是相同的。

模型视图委托(MVD)是PyQt中特有的设计模式,类似MVC设计模式,将MVC设计模式中的Controller当做MVD中的Delegate,两者的概念基本相同。不同的是委托不是独立存在,而是包含在视图里面。

模型视图委托设计模式中,模型负责存储和管理数据;视图负责显示数据,其中界面的框架和基础信息是视图负责,具体数据的显示是委托负责;委托不仅仅负责数据的显示,还有一个重要的功能是负责数据的编辑,如在视图中双击就可以编辑数据。

其中:
在这里插入图片描述在这里插入图片描述
在这里插入图片描述在这里插入图片描述

  • 模型
    数据的存储一般是列表,表格和树,不同的存储方式有不同的操作和管理方法,为了适应这种差异性,PyQt中提供了一种统一的操作方法,如下图所示:
    在这里插入图片描述

  • 委托
    委托被封装在视图里面,主要是负责数据的显示和编辑功能。

    • 数据的编辑主要涉及的方法:
      • createEditor 在双击进入编辑时,创建编辑器,如创建QLineEdit,QTextEdit
      • updateEditorGeometry 设置编辑器显示的位置和大小
      • setEditorData 更新数据到视图
      • setModeData 通过索引更新数据到模型
        如果需要修改编辑时操作数据的方式,就需要重写上述方法。
    • 视图主要是负责显示,其中涉及的方法:
      • paint 负责绘制
      • editorEvent 负责处理事件
        如果要实现自定义视图显示,需要重写paint方法,在paint方法中绘制需要显示的控件,然后在editorEvent方法中处理事件,更新数据。

QT中模型/视图机制与Vue模型/视图机制的区别?

在这里插入图片描述

  • 相似点: 在 Qt 和 Vue 中,视图模型 (View Model) 是一种将数据和界面分离的机制。其中,模型都负责存储和管理数据,视图负责显示数据,而视图模型则负责将数据转换为界面上的元素,并将其呈现给用户。
  • 区别: 但QT采用的视图模型设计模式为MVD,而Vue中采用的是MVVM。因此,在QT中视图模型与数据模型之间是相关的,而在Vue中,View 和 Model 之间并没有直接的联系,而是通过ViewModel进行交互,Model 和 ViewModel 之间的交互是双向的, 因此View 数据的变化会同步到Model中,而Model 数据的变化也会立即反应到View 上。
    • QT采用的视图模型设计模式为MVD,而Vue中采用的是MVVM
    • QT中视图模型与数据模型之间是相关的,而在Vue中,View 和 Model 之间并没有直接的联系
    • QT中View和Model不是双向数据绑定的,而MVVM是双向数据绑定
  • 区别详细:
    • 在 Qt 中,视图模型通常使用 QProxyModel 来实现。运行机制中还会用到QModelIndex。QModelIndex 是用于表示数据模型中的索引的类,QProxyModel 是一个代理模型,它使用一个数据模型来呈现界面。开发者可以使用 QProxyModel 来创建自定义的视图模型,以适应不同的应用程序需求。在 Qt 中,视图模型通常与应用程序的数据模型相关联,数据模型中存储着应用程序的数据,而视图模型负责将数据转换为界面上的像素并将其呈现给用户。
    • 在 Vue 中,视图模型通常使用组件 (Component) 来实现。组件是 Vue 中的最小可重用单元,它们包含数据和事件处理程序。Vue 通过将组件组合在一起来构建应用程序的界面,每个组件都拥有自己的数据模型和界面呈现逻辑。开发者可以使用 Vue 的指令和计算属性来自定义组件,并将它们组合在一起来构建应用程序的界面。
    • 虽然 Qt 和 Vue 的视图模型有一些相似之处,但它们也有一些不同之处。在 Qt 中,视图模型是与数据模型相关的,而在 Vue 中,组件是与数据模型无关的。此外,在 Qt 中,视图模型中的视图对象是 QProxyModel 的实例,而在 Vue 中,组件是 Vue 实例的实例。

下篇笔记链接

下篇笔记链接:【待更新】
下篇笔记主要内容:【待更新】

说明

原创文章,未经同意请勿转载
作者:xiaobai_Ry
码字不易,可能当中存在某些字体错误(笔者我没有发现),如果有错误,欢迎大家指正。🤗

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/241092.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【ArduinoOTA无线(OTA)更新的EASY指南】

【ArduinoOTA无线(OTA)更新的EASY指南】 1. 前言2. 了解 ESP32 的 ArduinoOTA3. 无线更新案例4. ArduinoOTA入门5. 安装必备组件6. 设置硬件7. ESP32 OTA 的最低代码8. 按照我们的流程学习Arduino编程➜9. 这对OTA来说非常重要10. 通过无线方式将草图上传…

携手河南恩坤德,共创养殖新篇章

在这个充满机遇与挑战的时代,养殖业正在经历一场前所未有的变革。作为养殖户,您需要一个能够与您共同应对变革、共创未来的合作伙伴。河南恩坤德农业正是这样一个值得信赖的伙伴,我们携手共创养殖新篇章。 河南恩坤德农业以客户需求为导向&am…

Ai图片处理

Ai也可以直接导入PS文件,只不过需要进行一个相关的选择,一般来说是将图层转化为对象 第二个为图层拼合为单个图像(不常用) 第三个则是将隐藏的图片也进行显示 如果你觉得图片的信息的过少好想插入其他的图片,可以选择…

【mongoose】 Model.create() no longer accepts a callback 报错解决

在最新版的 mongoose 操作 MongoDB 数据库的时候,当我们插入一条数据时候,会报错 :Model.create() no longer accepts a callback,看了很多文章都说是,版本太高,都妥协选择了降低回旧版本,但我就…

消息队列之关于如何实现延时队列

一、延时队列的应用 1.1 什么是延时队列? 顾名思义:首先它要具有队列的特性,再给它附加一个延迟消费队列消息的功能,也就是说可以指定队列中的消息在哪个时间点被消费。 延时队列在项目中的应用还是比较多的,尤其像…

【matlab】绘制竖状单组渐变柱状图

【matlab】绘制竖状单组渐变柱状图 % matlab绘制渐变柱状图 clear;clc;close all; x1:100; a[]; for i1:length(x) if mod(i,2)0 i-i; end a[a i]; end close all; b0.8; for nm3:69 cmapload([‘D:\m…

机器学习笔记 - Swish激活函数的定义和优势

一、Swish激活函数简述 首先,Swish 是像 ReLU、sigmoid 和 tanh 一样的非线性函数,使神经网络能够对输入和输出之间的复杂关系进行建模。非线性函数对于深度学习的工作至关重要,因为它们能够捕获和表示复杂的模式。 与 ReLU 等其他常用激活函数相比,Swish 具有独特的形状。…

C# 判断两个时间段是否重叠

public static bool IsOverlap(DateTime startTime1, DateTime endTime1, DateTime startTime2, DateTime endTime2){// 判断两个时间段是否有重叠return !(endTime1 < startTime2 || startTime1 > endTime2);//根据德摩根定律&#xff0c;等效为&#xff1a;endTime1 &g…

leetcode 268. 丢失的数字(优质解法)

链接&#xff1a;268. 丢失的数字 代码: class Solution {public int missingNumber(int[] nums) {int result0;for(int i0;i<nums.length;i){result^i;}for(int i0;i<nums.length;i){result^nums[i];}return result;} } 题解&#xff1a; 本题是比较简单的题&#xff…

天文观测与计算机技术:粉丝的视角

天文观测与计算机技术&#xff1a;粉丝的视角 在浩瀚无垠的宇宙中&#xff0c;每一颗星星都像是神秘的密码&#xff0c;等待我们去破译。作为天文观测的粉丝&#xff0c;我深知每一个美丽的星图背后都离不开计算机技术的支持。在这篇文章中&#xff0c;我将分享我对天文观测与…

ei论文会被scopus检索吗

scopus数据库能检索的专业范围是比较广泛的&#xff0c;涵盖了医学&#xff0c;地球环境科学&#xff0c;化学&#xff0c;数学&#xff0c;工程学&#xff0c;物理&#xff0c;生物科学等领域&#xff0c;也收录了很多会议论文&#xff0c;那么ei论文被其检索吗?其实严格说来…

最小二乘法简介

最小二乘法简介 1、背景描述2、最小二乘法2.1、最小二乘准则2.2、最小二乘法 3、最小二乘法与线性回归3.1、最小二乘法与线性回归3.2、最小二乘法与最大似然估计 4、正态分布&#xff08;高斯分布&#xff09; 1、背景描述 在工程应用中&#xff0c;我们通常会用一组观测数据去…

基于javaWeb的高校后勤报修系统的设计与实现论文

基于JavaWeb的高校后勤报修系统的设计与实现 摘 要 当下&#xff0c;正处于信息化的时代&#xff0c;许多行业顺应时代的变化&#xff0c;结合使用计算机技术向数字化、信息化建设迈进。以前学校对于后勤报修信息的管理和控制&#xff0c;采用人工登记的方式保存相关数据&…

如何查看内存卡使用记录-查看的设备有:U盘、移动硬盘、MP3、SD卡等-供大家学习研究参考

主要功能 USB Viewer&#xff08;USB移动存储设备使用记录查看器&#xff09;可用于查看本机的USB移动存储设备使用记录。可查看的设备有&#xff1a;U盘、移动硬盘、MP3、SD卡……等。   可用于兵器、航空、航天、政府、军队等对保密要求较高的单位&#xff0c;可在计算机保…

快手ID商品详情API:电商的新机遇

快手ID商品详情API&#xff1a;电商的新机遇 随着互联网的普及和科技的飞速发展&#xff0c;短视频已经成为人们日常生活中不可或缺的一部分。作为国内领先的短视频平台&#xff0c;快手一直致力于为用户提供优质的内容和服务。近年来&#xff0c;快手推出了ID商品详情API&…

Jmeter实现性能测试--高频率(高吞吐量)

高频率场景通常涉及系统需要在极短时间内处理大量请求或事件。这些场景可能要求系统在短时间内执行多次操作&#xff0c;例如高频率的数据更新、传感器数据采集、金融交易、实时监控等。以下是一些高频率场景的示例&#xff1a; 金融交易&#xff1a; 高频交易系统需要在极短时…

银河麒麟v10 二进制安装包 安装mysql 8.35

银河麒麟v10 二进制安装包 安装mysql 8.35 1、卸载mariadb2、下载Mysql安装包3、安装Mysql 8.353.1、安装依赖包3.2、安装Mysql3.3、安装后配置 1、卸载mariadb 由于银河麒麟v10系统默认安装了mariadb 会与Mysql相冲突&#xff0c;因此首先需要卸载系统自带的mariadb 查看系统…

一个简单的获取显示器长宽和显示器分辨的代码

最近在做大屏显示&#xff0c;在现显示的时候有些显示器是不规则的&#xff0c;投到大屏上显示效果不好&#xff0c;可以直接获取显示器的分辨率&#xff0c;本地调整好&#xff0c;再直接部署。 <!DOCTYPE html> <html lang"en"> <head><meta …

Java LocalDateTime转Json报错处理

在项目中LocalDateTime 进行json转换时&#xff0c;抛出序列化异常&#xff0c;查找解决方案&#xff0c;记录下来&#xff0c;方便备查。 报错信息 Caused by: com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Java 8 date/time type java.time.LocalDateT…

HarmonyOS的装饰器之BuilderParam 理解

BuilderParam 装饰器 使用时间&#xff1a;当定义了一个子组件&#xff0c;并且子组件的build()中有一个布局在不同的父组件&#xff0c;实现效果不一样的时候&#xff0c;可以在子组件中用这个BuilderParam装饰器&#xff0c; 在父组件用Builder 装饰器进行实现&#xff0c;然…