条款38:通过复合塑膜出has-a或"根据某物实现"

本文通过具体的C++代码示例介绍了两种重要的设计模式:Has-A(拥有)关系和Is-Implement-In-Terms-Of(基于某个对象实现)。Has-A通过Person类拥有Address和PhoneNumber实例来展示;Is-Implement-In-Terms-Of则通过Set类基于list实现来解释。

1、has-a

Person class(类)示范了 has-a(有一个)的关系。一个 Person object(对象)has a(有一个)名字,一个地址,以及语音和传真电话号码。


2、is-implement-in-terms-of

      假设你需要一个类的模板来表现相当小的 objects(对象)的 sets,也就是说,排除重复的集合。你决定让你的新的 Set template(模板)从 list 继承。Set 的 member functions(成员函数)可以极大程度地依赖 list 和标准库的其它部分已经提供的机能,所以只要你熟悉了用 STL 编程的基本方法,实现就非常简单了。

     意思是一个 Set 对象可以 be implemented in terms of a list object(是根据一个 list 对象实现的)

<think>我们正在讨论QTreeView的分支样式设置,特别是涉及open、closed、has-children、has-siblings等状态的样式规则。这些规则使用Qt样式表(QSS)来定义树视图中分支指示器的外观。下面我将逐一解释用户提到的四个选择器组合,并讨论它们的作用和可能现的问题。 ### 1. `branch:open:has-children:!has-siblings` - **含义**:匹配处于展开状态(open)、有子节点(has-children)且没有兄弟节点(!has-siblings)的分支。 - **作用**:这种状态通常对应树中的唯一子节点(即该节点是其父节点的唯一子节点)且已展开。可以为这种情况设置特定的图标(例如一个没有竖线的展开图标)。 - **示例样式**: ```css QTreeView::branch:open:has-children:!has-siblings { image: url(branch-open-alone.png); /* 没有兄弟节点时的展开图标 */ } ``` ### 2. `branch:open:has-children:has-siblings` - **含义**:匹配处于展开状态(open)、有子节点(has-children)且有兄弟节点(has-siblings)的分支。 - **作用**:这种状态对应树中有兄弟节点且已展开的节点。通常需要显示一个带有竖线(表示有兄弟节点)的展开图标。 - **示例样式**: ```css QTreeView::branch:open:has-children:has-siblings { image: url(branch-open-with-siblings.png); /* 有兄弟节点时的展开图标 */ } ``` ### 3. `branch:has-children:!has-siblings:closed` - **含义**:匹配有子节点(has-children)、没有兄弟节点(!has-siblings)且处于折叠状态(closed)的分支。 - **作用**:这种状态对应树中唯一子节点(无兄弟节点)且处于折叠状态。可以设置一个特定的折叠图标(例如没有竖线的折叠图标)。 - **示例样式**: ```css QTreeView::branch:has-children:!has-siblings:closed { image: url(branch-closed-alone.png); /* 没有兄弟节点时的折叠图标 */ } ``` ### 4. `branch:closed:has-children:has-siblings` - **含义**:匹配处于折叠状态(closed)、有子节点(has-children)且有兄弟节点(has-siblings)的分支。 - **作用**:这种状态对应树中有兄弟节点且处于折叠状态的节点。通常需要显示一个带有竖线的折叠图标(表示有兄弟节点)。 - **示例样式**: ```css QTreeView::branch:closed:has-children:has-siblings { image: url(branch-closed-with-siblings.png); /* 有兄弟节点时的折叠图标 */ } ``` ### 注意事项和常见问题 1. **选择器优先级**: - 当多个规则匹配同一个分支时,后定义的规则会覆盖前面的规则。因此,应该按照从一般到特殊的顺序排列规则。 - 如果规则冲突,可能导致图标显示不正确。 2. **图标资源路径**: - 在指定图片URL时,使用绝对路径资源路径(如`:/images/branch-open.png`)。如果路径错误,图标将无法显示。 3. **图标尺寸和清晰度**: - 确保提供的图标尺寸适合树视图的分支指示器区域。过大的图标会被压缩,过小的图标可能不清晰。 - 建议使用SVG格式与设备像素比匹配的多分辨率PNG图标。 4. **样式继承**: - 分支指示器的样式不会继承树视图的其他样式(如背景色)。如需改变背景,需要单独设置。 5. **动态状态更新**: - 当节点展开/折叠兄弟节点被添加/删除时,样式会自动更新。但在编程中动态修改树结构后,可能需要调用`update()``style()->unpolish()`确保样式刷新。 6. **跨平台一致性**: - 不同的平台(Windows、macOS、Linux)可能有不同的分支指示器默认样式。如果希望保持一致,需要为所有状态定义样式。 ### 示例完整样式 结合用户提供的引用[1]和引用[2],一个完整的样式设置可能如下: ```css QTreeView::branch:has-siblings:!adjoins-item { border-image: url(vline.png) 0; /* 用于绘制节点之间的垂直线 */ } QTreeView::branch:has-siblings:adjoins-item { border-image: url(branch-more.png) 0; /* 有兄弟节点且相邻项的分支样式 */ } QTreeView::branch:!has-children:!has-siblings:adjoins-item { border-image: url(branch-end.png) 0; /* 没有子节点且没有兄弟节点(末尾节点) */ } /* 以下为问题中关注的四个状态 */ QTreeView::branch:has-children:!has-siblings:closed, QTreeView::branch:closed:has-children:has-siblings { border-image: none; image: url(branch-closed.png); /* 折叠状态 */ } QTreeView::branch:open:has-children:!has-siblings, QTreeView::branch:open:has-children:has-siblings { border-image: none; image: url(branch-open.png); /* 展开状态 */ } ``` ### 相关问题 §§相关问题§§ 1. 如何为QTreeView的不同层级设置不同的分支图标? 2. 当自定义分支图标后,如何调整图标与文本之间的间距? 3. 在Qt中,除了使用样式表,还有哪些方法可以自定义树视图的分支指示器? 4. 当树视图节点非常多时,自定义分支图标是否会影响性能?如何优化? </think>### QTreeView分支样式设置详解 在QTreeView中,分支样式通过伪状态选择器控制,以下是对关键状态组合的解释: #### 1. `branch:open:has-children:!has-siblings` - **含义**:匹配**已展开**、**有子节点**且**没有兄弟节点**的分支 - **作用**:用于树形结构中唯一子节点的展开状态 - **典型场景**:顶级节点独立分支的展开图标 - **示例样式**: ```css image: url(branch-open-alone.png); ``` #### 2. `branch:open:has-children:has-siblings` - **含义**:匹配**已展开**、**有子节点**且**有兄弟节点**的分支 - **作用**:处理非唯一子节点的展开状态 - **典型场景**:中间节点展开时的分支连接线 - **示例样式**: ```css image: url(branch-open-group.png); ``` #### 3. `branch:has-children:!has-siblings:closed` - **含义**:匹配**有子节点**、**没有兄弟节点**且**已折叠**的分支 - **作用**:独立节点的折叠指示器 - **典型场景**:单个子节点的折叠状态 - **示例样式**: ```css image: url(branch-closed-alone.png); ``` #### 4. `branch:closed:has-children:has-siblings` - **含义**:匹配**已折叠**、**有子节点**且**有兄弟节点**的分支 - **作用**:处理分支组中的折叠状态 - **典型场景**:多子节点树结构的折叠指示器 - **示例样式**: ```css image: url(branch-closed-group.png); ``` ### 完整分支状态系统 Qt的分支样式基于四个核心状态属性: 1. **展开状态**:`open`/`closed` 2. **子节点存在**:`has-children`/`!has-children` 3. **兄弟节点存在**:`has-siblings`/`!has-siblings` 4. **相邻关系**:`adjoins-item` 状态组合形成树形结构的完整视觉表示: ```mermaid graph TD A[根节点] --> B[分支:!has-siblings] A --> C[分支:has-siblings] B --> D[open状态] B --> E[closed状态] C --> F[open状态] C --> G[closed状态] D --> H[有子节点] D --> I[无子节点] ``` ### 常见问题及解决方案 1. **图标显示异常** - **现象**:自定义图标不显示尺寸错误 - **解决方案**: ```css QTreeView::branch { background: none; /* 清除默认背景 */ image: url(default.png); /* 设置默认图标 */ } ``` 2. **状态覆盖问题** - **现象**:特定状态样式被覆盖 - **原因**:选择器优先级冲突 - **解决方案**:按从通用到特殊的顺序排列规则 ```css /* 通用规则 */ QTreeView::branch:closed { ... } /* 特殊规则 */ QTreeView::branch:closed:has-children { ... } ``` 3. **性能问题** - **现象**:大型树结构渲染卡顿 - **优化方案**: - 使用`QPixmapCache`缓存图标 - 避免在样式表中使用高分辨率图片 - 设置`QTreeView::setUniformRowHeights(true)` 4. **样式继承问题** - **现象**:分支线颜色不匹配 - **解决方案**:显式设置所有相关属性 ```css QTreeView::branch:has-siblings:!adjoins-item { border-image: url(vline.png) 0; border-color: #333; /* 显式定义颜色 */ } ``` ### 最佳实践建议 1. **图标设计原则**: - 展开/折叠图标应有明显视觉差异 - 分支线颜色需与文本颜色协调(建议对比度至少4.5:1) - 推荐尺寸:16×16像素(支持高DPI缩放) 2. **状态检测技巧**: ```cpp // 调试用:打印节点的状态组合 qDebug() << "hasChildren:" << index.model()->hasChildren(index) << "hasSiblings:" << (index.model()->rowCount(index.parent()) > 1); ``` 3. **跨平台适配**: ```css /* Windows高DPI适配 */ @media (-webkit-device-pixel-ratio: 2) { QTreeView::branch { image: url(icon@2x.png); } } ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值