【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 的核心机制
-
主要有三大核心机制(围绕信号与槽的展开):元对象系统,属性系统,信号与槽(最核心)
-
元对象系统(提供信号与槽机制,属性系统…)
Qt的元对象系统(meta-object)提供了用于内部对象通讯的信号与槽(signals & slots)机制
,运行时类型信息,以及动态属性系统(dynamic property system)。 -
元对象编译器MOC
-
属性系统
属性系统特性可以用于任何Qt支持的编译器与架构。它基于元对象系统(Meta-Object System),这套系统同时也提供信号与槽机制用于对象间通讯
。 -
信号与槽
信号与槽用于对象之间的通讯。信号与槽机制是Qt的核心特性。在Qt中,使用了信号与槽机制代替了回调机制。信号将会在特定的事件出现时被发出。Qt的控件预定义了很多信号,当然我们也可以继承这些控件以定义自己的子类,然后添加自己的信号。槽是在响应特定信号时会被调用的方法。Qt的控件存在很多预定义的槽,但通常的做法是继承控件以生成自己的子类,然后添加自己的槽,这样我们就可以自行处理感兴趣的信号。
-
-
其他核心机制: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 容器类,并说明它们的特点及使用场景:
QtWidgets.QStackedWidget
:QStackedWidget
是一个弹出式窗口容器,用于在一组窗口之间切换。它支持标签、标题、最小化和最大化按钮,以及内容滚动。它的特点是可以弹出新窗口,并在窗口之间切换,常用于布局多个子窗口,以及在主窗口中显示多个子窗口。QtWidgets.QVBoxLayout
:QVBoxLayout
是垂直布局容器,用于在子组件之间布局。它支持垂直布局、水平和垂直布局,特点是可以嵌套子组件,并控制子组件的大小和位置。它常用于布局文本框、按钮、标签等组件,以及在主窗口中添加子窗口。QtWidgets.QHBoxLayout
:QHBoxLayout
是水平布局容器,用于在子组件之间布局。它支持水平布局、垂直布局和水平垂直布局,特点是可以嵌套子组件,并控制子组件的大小和位置。它常用于布局下拉框、列表框等组件,以及在主窗口中添加子窗口。QtWidgets.QFormLayout
:QFormLayout
是表单布局容器,用于布局表单组件,例如文本框、下拉框和按钮。它支持垂直布局、水平布局和表单布局,特点是可以添加表单控件,并控制它们的大小和位置。它常用于布局表单数据,例如用户注册或登录窗口。QtWidgets.QGridLayout
:QGridLayout
是网格布局容器,用于在水平或垂直方向上布局多个组件。它支持组件对齐、组件大小调整和组件重叠,特点是可以控制组件的位置和大小,适用于布局多个组件的大型 GUI 应用程序。QtWidgets.QGroupBox
:QGroupBox
是一个群组框容器,用于创建群组框,可以在其中添加子窗口和组件。它的特点是可以添加子窗口,并控制子窗口的大小和位置。它常用于布局多个组件,例如菜单栏或状态栏。QtWidgets.QFrame
:QFrame
是边界框容器,用于创建边界框,可以包含文本、按钮和其他组件。它的特点是可以添加其他容器组件,并控制组件的大小和位置。它常用于布局文本、按钮和其他小型组件,例如按钮组或标签组。QtWidgets.Q Banner
:QBanner
是一个广告条容器,用于在应用程序中显示广告或信息。它的特点是可以显示文本、图像或其他媒体,并支持动画效果。它常用于在应用程序中添加广告或重要信息。QtWidgets.QListWidget
:QListWidget
是一个列表容器,用于显示列表中的项。它支持选中、拖动和删除操作,特点是可以添加、删除和修改项。它常用于显示数据列表,例如文件列表或用户列表。QtWidgets.QTreeView
:QTreeView
是树形结构容器,用于显示树形结构中的项。它支持拖动和删除操作,特点是可以添加、删除和修改项。它常用于显示数据树形结构,例如文件系统或数据库。
综上所述,这些容器类都有各自特点和使用场景,可以根据实际需要选择合适的容器类来组织和管理 GUI 应用程序中的数据和情感。
1. 事件/机制
QT 的事件 定义/来源/接收者/传递?
-
定义
Qt 事件是一个 QEvent 对象,用于描述程序内部或外部发生的动作,任意的 QObject 对象都具有事件处理的能力 -
意义
-
来源
Qt中事件的来源有两个:程序外部和内部。- 程序外部:多数情况下来自操作系统,可以通过bool QEvent::spontaneous() const函数来获知,返回true,事件发生在应用程序之外(系统事件),否则返回false。
- 程序内部:系统自动发生,比如计时器事件(timerEvent)。
-
接收者
事件由QObject类来接收,是Qt对象模型的核心,所有需要处理的事件类都必须继承QObject。 -
GUI 应用程序的事件处理方式
- Qt 事件产生后立即分发到 QWidget 对象
- QWidget 中的 event(QEvent*) 进行事件处理
- event() 根据事件的类型调用不同的事件处理函数
- 在事件处理函数中发送 Qt 中预定义的信号
- 调用信号关联的槽函数
-
事件的传递过程
信号与事件的区别
首先,我们需要了解一下相关的定义。
- 信号槽:
signal
由具体对象发出,然后会马上交给由connect
函数连接的slot
进行处理。 - 事件: Qt 使用一个事件队列对所有发出的事件进行维护,当新的事件产生时,会被追加到事件队列的尾部,前一个事件完成后,取出后面的事件进行处理。但是,必要的时候,Qt 的事件也是可以不进入事件队列,而是直接处理的。并且,事件还可以使用“事件过滤器”进行过滤。
信号与事件的区别主要可以概述为:
- 处理对象不同
事件由具体对象进行处理,信号由具体对象主动产生。改写事件处理函数可能导致程序行为发生改变,信号是否存在对应的槽函数不会改变程序行为,一般而言,信号在具体的事件处理函数中产生。 - 使用的机制和原理不同
- 事件类似于 Windows 里的消息,它的发出者一般是窗口系统。相对信号和槽机制,它 比较“底层”,它同时支持异步和同步的通信机制,一个事件产生时将被放到事件队列 里,然后我们就可以继续执行该事件 “后面”的代码。事件的机制是非阻塞的。
- 信号和槽机制相对而言比较“高层”,它的发出者一般是对象。从本质上看,它类似 于传统的回调机制,是不支持异步调用的。
- 使用场合和时机不同
一般情况下:- 在“使用”窗口部件时,我们经常需要使用信号,并且会遵循信号与槽的机制;
- 在“实现”窗口部件时,我们就不得不考虑如何处理事件了。
举个例子,当使用 QPushButton 时,我们对于它的 clicked()信号往往更为关注,而很少关心促成发射该信号的底层的鼠标或者键盘事件。但是,如果要实现一个类似于 QPushButton 的类,我们就需要编写一定的处理鼠标和键盘事件的代码,而且在必要的时候,仍然需要发射和接收 clicked()信号。
QT 的事件机制是什么?
- 事件机制:事件会经过:事件产生 ->事件派发 -> 事件过滤->事件分发->事件处理五个阶段。Qt 窗口中对于产生的一系列事件都有默认的处理动作,如果有特殊需求就需要在合适的阶段重写事件的处理动作。
- 当事件产生之后,Qt 使用用应用程序对象调用 notify() 函数将事件发送到指定的窗口
- 事件在发送过程中可以通过事件过滤器进行过滤,默认不对任何产生的事件进行过滤。
- 当事件发送到指定窗口之后,窗口的事件分发器会对收到的事件进行分类.
- 事件分发器会将分类之后的事件(鼠标事件、键盘事件、绘图事件…)分发给对应的事件处理器函数进行处理,每个事件处理器函数都有默认的处理动作,也可以重写这些事件处理器函数。
💡 当发生事件,比如点击鼠标或键盘,就会产生一个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的所有事件。
-
过滤传递中的事件,主要分为两步:
- 给要被过滤事件的类对象安装事件过滤器
组件通过installEventFilter()
函数安装事件过滤器
- 事件过滤器在组件之前接收到事件
- 事件过滤器能够决定是否将事件转发到组件对象
- 在要进行事件过滤的类中(filterObj 参数对应的类)重写从QObject类继承的虚函数eventFilter()。
- 给要被过滤事件的类对象安装事件过滤器
💡 注意:事件过滤器和被安装过滤器的组件必须在同一线程,否则,过滤器将不起作用。另外,如果在安装过滤器之后,这两个组件到了不同的线程,那么,只有等到二者重新回到同一线程的时候过滤器才会有效。
QT事件机过滤器使用的三种方法及注意事项
- 三种方法
- 父窗口类通过重写eventFilter方法来监听子控件的相关事件进行处理。
使用这种方式的好处是不需要通过重写控件的方式获取某些事件,对于安装了事件过滤器的对象,他们所有的事件都会经过这个事件过滤器,所以就可以直接在父窗口中进行监测。比如某个窗口中有个QLabel对象,我们想要监听他的鼠标点击事件,那我们就需要继承QLabel类,然后重写mousePressEvent事件,如果有其他类型的控件也需要获取某个事件,那是不是都需要继续控件并重写某个事件了,所以我们通过事件过滤器就可以很方便获取某个对象的某个事件。 - 专门的事件过滤器类,对特定的对象/特定的事件进行处理。
事件过滤器类只需对当前安装的对象进行处理,无需关心其他操作,且一个事件过滤器类可以被多个对象使用,例如Qt文档中的按键过滤示例,KeyPressEater类中的eventFilter过滤了所有的键盘按下事件,只要安装此事件过滤器的控件,都接收不到键盘按键按下的事件,这种就是对某个通用的事件进行过滤,可以进行多次复用。 - 给QApplication安装事件过滤器,达到全局事件监听的效果。
在notify方法下发事件的时候,QApplication对象可以拿到第一控制权,对某些事件优先进行处理,比如全局的快捷键操作。
- 父窗口类通过重写eventFilter方法来监听子控件的相关事件进行处理。
- 注意点:
- 事件过滤器可以安装在任何继承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
码字不易,可能当中存在某些字体错误(笔者我没有发现),如果有错误,欢迎大家指正。🤗
相关文章:
【QT八股文】系列之篇章1 | QT的基础知识及事件/机制
【QT八股文】系列之篇章1 | QT的基础知识及事件/机制 前言0. 基础Qt/PyQt5介绍/关联Qt的优缺点(为什么要用qt来做界面)Qt 的核心机制请简要介绍一下Qt中的主窗口(MainWindow)类,它有哪些重要的函数和成员变量ÿ…...
SpringBoot 3 集成Hive 3
前提条件: 运行环境:Hadoop 3.* Hive 3.* MySQL 8 ,如果还未安装相关环境,请参考:Hive 一文读懂 Centos7 安装Hadoop3 单机版本(伪分布式版本) SpringBoot 2 集成Hive 3 pom.xml <?xml ver…...
STL中优先队列的模拟实现与仿函数的介绍
文章目录 仿函数优先队列的模拟实现 仿函数 上回我们说到,优先队列的实现需要用到仿函数的特性 让我们再回到这里 这里我们发现他传入的用于比较的东西竟然是一个类模板,而不是我们所见到的函数 我们可以先创建一个类,用于比较大小 struc…...
LeetCode刷题--- 目标和
个人主页:元清加油_【C】,【C语言】,【数据结构与算法】-CSDN博客 个人专栏 力扣递归算法题 http://t.csdnimg.cn/yUl2I 【C】 http://t.csdnimg.cn/6AbpV 数据结构与算法 http://t.csdnimg.cn/hKh2l 前言:这个专栏主要讲述递归递归、搜…...
【.NET Core】反射(Reflection)详解(二)
【.NET Core】反射(Reflection)详解(二) 文章目录 【.NET Core】反射(Reflection)详解(二)一、概述二、Type类2.1 Type对象表示哪些类型2.2 获取Type及其关联对象类型的方式2.3 Type…...
【错误记录/js】保存octet-stream为文件后数据错乱
目录 说在前面场景解决方式其他 说在前面 后端:go、gin浏览器:Microsoft Edge 120.0.2210.77 (正式版本) (64 位) 场景 前端通过点击按钮来下载一些文件,但是文件内容是一些非文件形式存储的二进制数据。 后端代码 r : gin.Default()r.Stat…...
sql_lab之sqli中的post注入
Post注入 用burpsuit抓包去做 Post第一关:(gxa5) 1.判断是否存在注入 username1or 11 #&password123&submit%E7%99%BB%E5%BD%95 有回显 username1or 12 #&password123&submit%E7%99%BB%E5%BD%95 没有回显 则证明存在sq…...
智能优化算法应用:基于白冠鸡算法3D无线传感器网络(WSN)覆盖优化 - 附代码
智能优化算法应用:基于白冠鸡算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用:基于白冠鸡算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.白冠鸡算法4.实验参数设定5.算法结果6.参考文…...
DETR++: Taming Your Multi-Scale Detection Transformer论文解读
文章目录 前言一、摘要二、引言三、相关研究四、模型方法1、Removing the Encoder方法2、Multi-Head方法3、Shifted Windows方法4、Bi-directional Feature Pyramid方法5、DETR方法 五、实验结果总结 前言 今天查看了一篇DETR论文,本想网络上找博客大概浏览一下&am…...
高级数据结构 <二叉搜索树>
本文已收录至《数据结构(C/C语言)》专栏! 作者:ARMCSKGT 目录 前言正文二叉搜索树的概念二叉搜索树的基本功能实现二叉搜索树的基本框架插入节点删除节点查找函数中序遍历函数析构函数和销毁函数(后序遍历销毁)拷贝构造和赋值重载(前序遍历创建)其他函数…...
蚂蚁集团5大开源项目获开放原子 “2023快速成长开源项目”
12月16日,在开放原子开源基金会主办的“2023开放原子开发者大会”上,蚂蚁集团主导开源的图数据库TuGraph、时序数据库CeresDB、隐私计算框架隐语SecretFlow、前端框架OpenSumi、数据域大模型开源框架DB-GPT入选“2023快速成长开源项目”。 (图…...
SpringBoot+JaywayJsonPath实现Json数据的DSL(按照指定节点表达式解析json获取指定数据)
场景 若依前后端分离版手把手教你本地搭建环境并运行项目: 若依前后端分离版手把手教你本地搭建环境并运行项目_前后端分离项目本地运行-CSDN博客 在上面搭建SpringBoot项目的基础上,并且在项目中引入fastjson、hutool等所需依赖后。 Jayway JsonPat…...
气压计LPS28DFW开发(2)----水压检测
气压计LPS28DFW开发.2--水压检测 概述视频教学样品申请完整代码下载水压计算设置速率和分辨率轮询读取数据测试结果 概述 本文将介绍如何使用 LPS28DFW 传感器来读取的压强数据,来估算水下深度,可以利用液体静压的原理。 最近在弄ST和瑞萨RA的课程&…...
设计模式之-装饰模式,快速掌握装饰模式,通俗易懂的讲解装饰模式以及它的使用场景
系列文章目录 设计模式之-6大设计原则简单易懂的理解以及它们的适用场景和代码示列 设计模式之-单列设计模式,5种单例设计模式使用场景以及它们的优缺点 设计模式之-3种常见的工厂模式简单工厂模式、工厂方法模式和抽象工厂模式,每一种模式的概念、使用…...
计算机网络个人小结
不同层的数据报的名称 应用层: data TCP层: segment IP 层: packet MAC层: frame MTU vs MSS: MTU:一个网络包的最大长度,以太网中一般为 1500 字节。 https://www.xiaolincoding.com/network/1_base/how_os_deal_network_package.html#linux-%E7%BD%91…...
酒店网站搭建的作用是什么
线上已经成为各行业商家增长破局的必要手段,传统酒店行业因信息扩展度不够,导致品牌难以传播、无法实现用户对酒店所有信息全面知悉,也无法实现在线预约及其它赋能用户消费的路径。 面对获客转化难题,很多酒店商家通过建立自营商…...
俄罗斯联邦税务局遭乌克兰入侵,数据库和副本被清空,政府数据安全不容忽视
俄罗斯联邦税务局遭乌克兰入侵,数据库和副本被清空,政府数据安全不容忽视 据相关报道,2023年12月12日,乌克兰国防情报局(GUR)称其成功入侵了俄罗斯联邦税务局(FNS)系统,并清除了该机构的数据库和…...
WPF组合控件TreeView+DataGrid之TreeView封装
(关注博主后,在“粉丝专栏”,可免费阅读此文) wpf的功能非常强大,很多控件都是原生的,但是要使用TreeViewDataGrid的组合,就需要我们自己去封装实现。 我们需要的效果如图所示&#x…...
redisson 哨兵模式配置
背景:项目redis由集群改为哨兵模式,漏洞扫描未授权访问漏洞(CNVD-2019-21763),要求对redis哨兵也设置密码,redisson依赖版本为3.11.5 spring-boot版本为2.1.13。 redisson依赖升级 <dependency>&l…...
免费的ChatGPT分享
免费的ChatGPT 以下是一些免费的ChatGPT平台和工具: 零声教学AI助手 零声教育内部使用的ChatGPT,提供智能对话和问题解答功能。 Ora.ai 一个可以自定义的AI聊天机器人,可以根据个人需求进行定制和训练。 ChatGPT 人工智能聊天机器人&a…...
C语言—每日选择题—Day54
指针相关博客 打响指针的第一枪:指针家族-CSDN博客 深入理解:指针变量的解引用 与 加法运算-CSDN博客 第一题 1. 存在int类型变量x,y,z,其对应值为x0x59,y0x39,z0x6E,则x * y z的值…...
先进制造身份治理现状洞察:从手动运维迈向自动化身份治理时代
在新一轮科技革命和产业变革的推动下,制造业正面临绿色化、智能化、服务化和定制化发展趋势。为顺应新技术革命及工业发展模式变化趋势,传统工业化理论需要进行修正和创新。其中,对工业化水平的判断标准从以三次产业比重标准为主回归到工业技…...
【密码学引论】密码协议
定义:两个或者两个以上参与者为了完成某一特定任务而采取的一系列执行步骤密码协议:Kerberos、IPSec、SSL、SET算法是低层次上的概念,而协议是高层次上的概念,协议建立在算法的基础上。所有密码协议都容易受中间人攻击,…...
利用快手的用户数据和精准营销提升电商平台用户转化率和销售额
一、快手用户数据的价值 快手作为国内领先的短视频平台,拥有庞大的用户群体和丰富的用户行为数据。这些数据包括用户的观看习惯、互动行为、兴趣偏好等,对于电商平台来说具有极高的商业价值。通过分析这些数据,电商平台可以深入了解用户需求…...
Linux根目录下默认目录作用
在Linux操作系统中,根目录(/)下的默认目录一般用于不同用途的文件存放和系统管理。以下是一些常见的默认目录及其用途: /bin:该目录存放系统的基本命令和可执行文件,如ls、cp、mv等。这些命令可供系统用户…...
国产Type-C接口逻辑协议芯片:Type-C显示器芯片方案
产品介绍 双Type-C盲插选型: LDR6282 PD3.0认证协议芯片,USB-IF TID号:212 支持iic,USB转UART,CC升级方式,多年市场验证,显示器市场出货量,显示器大厂采用兼容性NO.1。采用QFN32 5*…...
uniapp如何原生app-云打包
首先第一步,需要大家在HBuilder X中找到一个项目,然后呢在找到上面的发行选项 发行->原生App-云打包 选择完该选中的直接大包就ok。 大包完毕后呢,会出现一个apk包,这是后将这个包拖动发给随便一个人就行了。 然后接收到的那…...
分布式编译distcc
工程代码编译速度太慢,决定采用分布式编译来提高编译速度. distcc ,请参考https://www.distcc.org/ 安装 我用的distcc的版本是distcc-3.2rc1, 下载源码,安装步骤如下: ./autogen.sh ./configure --disable-Werror --prefix/…...
Elasticsearch常见面试题
文章目录 1.简单介绍下ES?2.简单介绍当前可以下载的ES稳定版本?3.安装ES前需要安装哪种软件?4.请介绍启动ES服务的步骤?5.ES中的倒排索引是什么?6. ES是如何实现master选举的?7. 如何解决ES集群的脑裂问题8…...
solidity 重入漏洞
目录 1. 重入漏洞的原理 2. 重入漏洞的场景 2.1 msg.sender.call 转账 2.2 修饰器中调用地址可控的函数 1. 重入漏洞的原理 重入漏洞产生的条件: 合约之间可以进行相互间的外部调用 恶意合约 B 调用了合约 A 中的 public funcA 函数,在函数 funcA…...
直接IP做网站/企业网站seo
前言:对于动态路由协议的***,向来是***关注的目标,OSPF协议作为园区网络中较为常见的路由协议,其配置的安全性和重要性自然不言而喻。如何有效防御OSPF的安全隐患,更多的网管往往将目标投向了路由器自身安全࿰…...
网站建设业务文案/推广普通话手抄报图片大全
如下图 :报 Caused by: java.lang.IllegalStateException: SpringJUnit4ClassRunner requires JUnit 4.12 or higher. 有道翻译一下:告诉我们junit测试jar依赖包版本太低了 然后我去查看一下自己的项目pom文件的依赖 发现是4.11版本,于是修改…...
asp网站代码/百度网址大全
1、中文与英文数字混合使用,排版有规范写作中,我们经常遇到以下中文与英文、数字混用的情况。我自学python编程,是在xue.cn上进行的。时耗方面,基础功仅需50多小时,加上很多实战,包括初步运用pandas和爬虫处…...
域名购买 网站建设/抖音seo优化怎么做
上文介绍了如何自定义注解,本篇主要介绍如何使用注解 自定义注解 package com.example.annotaion;import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation…...
有口碑的企业网站建设/app开发公司推荐
原文:http://coolketang.com/staticCoding/5a99105017d009003597a964.html 1. 本节课将为您演示,集合控件在故事板中的使用。首先打开之前创建的单视图项目。 2. 然后打开故事板文件。 3. 点击控件库垂直滚动条,定位集合控件所在的位置。 4. …...
58同城网络营销靠谱吗/优化疫情防控 这些措施你应该知道
内核是操作系统最基础也是最重要的部分。下图为 RT-Thread 内核架构图,内核处于硬件层之上,内核部分包括内核库、实时内核实现。 内核库是为了保证内核能够独立运行的一套小型的类似 C 库的函数实现子集。 这部分根据编译器的不同自带 C 库的情况也会有…...