type
status
date
slug
summary
tags
category
icon
password
前言
在项目开发过程中,我们常常面对多窗口页面联动或单窗口内包含多个页面容器的设计。随着需求的不断迭代,页面数量逐渐增加,页面之间的关联也变得愈发复杂,导致页面管理的难度显著提升。在这种情况下,开发新需求往往变得异常艰难,经常需要添加大量的 if else 语句来处理错误的页面跳转逻辑,这又使得页面逻辑更加混乱。如果我们不能妥善的处理,一点小小的改动,都会给我们布置了一个新的迷宫。

复杂性
在软件开发中,我们通常面临三种复杂性:业务复杂性(源于现实世界)、工具复杂性(包括开发语言、框架等)和团队(人员)复杂性。
针对多窗口页面管理,我们需要一个路由工具来简化页面跳转的操作。应对业务复杂性,我们需要对页面进行梳理,找出规律并定义合适的规则。在引入新工具和新规则对现有项目进行改造时,复杂性会急剧增加(两种工具、两中规则并行时的混乱)。因此,工具设计必须符合开发人员的直觉和习惯,规则需要足够简单且有效,并且团队需要能够轻松使用这些新的设计和规则。
示例程序
本篇博客通过一个 Qt Quick 示例程序,使用 StackView 作为容器管理页面,结合 routing 机制,遵循数据驱动显示和关注点分离的原则,提供了一个多窗口页面管理解决方式,希望读者在面对相似问题是能有所启示。



统一管理所有的页面资源
这里的路由与我们通常所讲的网络路由不一样,类别 Android 开发种 ARouter 的实现机制,示例中,路由特指基于页面的唯一标识,可以从一个页面出发,跳转到目标页面。
Qt 中可以使用枚举定义所有的页面,并且枚举值映射对应的页面资源路径。
页面跳转的管理
使用 Qt StackView 作为容器装载页面,基于 StackView 提供的 api 和其特性,对其进行封装。
借鉴 Android 中 Activity 的启动模式,页面入栈时,定义了三种模式:
- Standard,页面添加到栈顶
- SingleInstance,清空栈后添加
- SingleTask,如果栈里面已经存在目标页面,弹出其上的页面,并调用目标页面的刷新函数
当然还要支持跳转页面时传递参数、设置动画。
页面跳转规则定义
在实现了页面的统一管理和路由工具的支持后,还有一个关键步骤:定义页面跳转的规则。
需求设计人员,通常不会考虑页面之间的关联关系。面对不断堆叠的业务场景,我们需要确保无论新添加多少页面,页面与页面直之间有多少组合显示形式,我们都能应对。定义简单且有效的规则,保障我们软件的可维护性和扩展性。

- 每个页面由最近父级别的 router 所管理(一般情况下一个 StackView 容器对应一个 router 管理类)
- 页面跳转由目标页面所在最小范围的 router 执行
- 示例一:RightFirstPage → RightSecondPage,页面跳转由 HomeTwinPageRouter 执行
- 示例二:HomeFirstPage→HomeTwinContainerPage,页面跳转由 MainPageRouter 执行
- 示例三:大屏 HomeFirstPage→HomeTwinContainerPage,同时小屏 SamllFirstPage → SmallSecondPage,页面跳转由 DoubleScreenPageRouter 执行。
通过以上方法,就能让示例程序的页面管理顺利运行了!然而在实际项目中,页面结构可能更为复杂,还需要我们在实践中进一步完善和扩展工具,不断运用新的技巧来解决意想不到的问题。