QT的UI开发框架

  1. 基于widgets

所有表现逻辑(UI元素的渲染+状态存储)和领域业务逻辑,都混杂在一起,适用于小工具。简单直接。

  1. 基于MVC(Model-View-Delegate)

将表现逻辑和领域业务逻辑分开,View负责展示和交互,Model负责组织数据和执行业务。当需要聚焦到表单细节时,Model-View会通过Delegate交互同步。

  1. 基于MVVM (Model-View-ViewModel)

基于QML引擎+QML脚本构建前端View,ViewModel充当沟通Model和View的桥梁,并负责存储View的状态。

知识问答:

1️⃣ 我们知道,ui 元素通常具有严格的层级从属关系,使用mvvm架构时,需要在viewmodel 中设计严格的层级从属关系吗?

直接回答:绝对不需要,而且强行对应是 MVVM 的常见误用。

UI 的层级是视觉布局树(Panel 套 GroupBox 套 Button),而 ViewModel 的层级应该是业务数据聚合树(公司套部门套员工)。两者完全解耦,原因有三:

  1. 层级来源完全不同

· UI 层级:源于界面布局需求(为了对齐、分组、滚动)。

· ViewModel 层级:源于数据结构和业务逻辑(比如订单包含订单详情列表)。

如果 UI 里加了一个无数据的装饰性分组框(GroupBox),ViewModel 绝不能为此新建一个空对象层级。

  1. 跨层级暴露会破坏封装

ViewModel 的核心职责是暴露数据(Property)和命令(Command),而不是暴露"子控件"。正确的做法是:

· UI 通过 Binding 指向 ViewModel 的某个集合属性(如 ObservableCollection<ItemVM>)。

· UI 中的 ListBox 或 Repeater 负责为这个集合的每一项生成对应的视觉元素。

这种映射是"一对多"或"多对多"的,完全不需要 ViewModel 知道自己被放在了哪个 Grid 里。

  1. 适应 UI 重构

如果设计师决定把三个并列的输入框改成 TabControl 分页,UI 层级会发生剧变。但只要 ViewModel 暴露的属性不变(CustomerName、OrderList 依然存在),你只需修改 XAML/QML 界面,ViewModel 一行代码都不用改。如果强耦合,UI 重构就会导致业务代码重写,丢失了 MVVM 最大的优势。


那 ViewModel 完全没有层级吗?

不是。ViewModel 有自己的"组合"关系,但它是业务上的父子关系:

· 父 VM 拥有 子 VM 的集合(例如 MainVM 拥有 UserControlVM 实例)。

· 这层关系源于业务逻辑的"包含关系",而不是因为子 VM 在屏幕右上角。

结论:在 MVVM 中,UI 树是"容器树",ViewModel 树是"数据源树"。两者依靠 DataContext(数据上下文) 在运行时动态绑定,完全隔离。记住:不要让 ViewModel 知道自己在屏幕上的位置,它只知道自己要处理什么数据。

2️⃣在传统ui框架中,因为ui对象和领域业务强耦合,导致业务被分散在ui对象树的各个节点,看上去好像领域业务也有层级从属关系一般,是不是非常不合理?

回答: 你说的太精准了,一针见血。 这不仅"看上去"不合理,在软件工程上属于典型的 "逻辑伪造层级" 反模式。

为了帮你把这层窗户纸彻底捅破,我从三个维度拆解这种"不合理"的根源和危害:

  1. 为什么开发者会犯这个错?(根源)

传统框架(如 MFC、WinForms 或早期的 Qt Widgets)中,UI 对象是天然的"容器"。为了获取数据,开发者会顺着 UI 树向上找(例如 this->ParentForm->DataGrid->SelectedItem)。这种"就近原则"导致业务协调逻辑(如"保存按钮点击后刷新列表")被物理上写在了按钮事件里,而协调范围又恰好发生在窗口层级。久而久之,视觉的"包含关系"就腐蚀了业务的"调用关系"。

  1. 最大的痛点:UI 重构即业务重写

假设你的业务逻辑是"用户点击保存,验证数据,写入数据库,刷新表格"。

在传统耦合代码中,这个流程被拆解为:

· Button_OnClick 写验证。

· Button_OnClick 调用 DbHelper。

· Button_OnClick 调用 Grid_Refresh。

当设计师把"保存按钮"从窗口底部拖到工具栏下拉菜单里,你不仅要改 UI,还要把这段业务逻辑代码剪切粘贴到新的事件处理函数中。这种"物理挪动"极易引发变量作用域报错,并导致业务逻辑随 UI 树震荡。

  1. MVVM 如何用"扁平化"解决?

这就是 MVVM 的杀手锏:业务逻辑必须附着于数据模型(ViewModel),而非视觉元素(View)。

· ViewModel 是"扁平"的:它里面只有一个 SaveCommand 和一个 ObservableCollection<Item>。它不关心按钮在哪,只关注"保存"这个业务含义。

· UI 树只是"投影":无论按钮在窗口底部、工具栏还是右键菜单,它们都绑定(Binding)到同一个 SaveCommand。

此时,UI 树的层级变化完全不影响业务代码的执行流。你删掉工具栏里的按钮,业务逻辑还好好躺在 ViewModel 里,其他地方的绑定依然有效。

结论:

UI 树是"物件的摆放"(平面设计),业务逻辑树是"数据的流向"(程序逻辑)。强行把前者当成后者,就像用家具的摆放位置去定义一家公司的管理架构------沙发放在窗前,不代表财务部就要听窗台的指挥。MVVM 的本质就是切断这根错误的脐带,让布局回归美学,让逻辑回归领域。

相关推荐
郝学胜-神的一滴1 小时前
Horse3D 游戏引擎研发笔记(七):Clydesdale——从流式日志到多输出订阅
c++·qt·unity·游戏引擎·图形渲染·unreal engine·opengl
丰锋ff14 小时前
基于 Qt 的智慧社区物业管理系统
开发语言·qt
程与留16 小时前
05_Qt 核心模块概览——Qt Core、Gui、Widgets、Quick 的职责划分
c++·qt
buhuizhiyuci17 小时前
【QT-百日筑基篇】修真世界摸爬滚打多年,终于黄天不负有心人,突破炼器中期——常用控件QWight的属性
开发语言·c++·qt·gui·图形化
Littlehero_12118 小时前
QT自定义控件之热换站系统(源码开源)
开发语言·qt
界面开发小八哥21 小时前
界面控件DevExpress Blazor v26.1新版亮点 - Filter Builder等功能升级
ui·界面控件·blazor·devexpress·ui开发
兰亭妙微UI设计公司1 天前
兰亭妙微UI设计:Neemo Project 企业AI项目管理后台全案运营价值解析
人工智能·ui
Quz1 天前
QML MouseArea 鼠标拖拽与滚轮缩放
qt
Quz1 天前
QML MouseArea 事件传递、自定义按钮
qt