diff --git a/ViperBTests/ViperQtProject/App/main.vp b/ViperBTests/ViperQtProject/App/main.vp index 090202c..662b055 100644 --- a/ViperBTests/ViperQtProject/App/main.vp +++ b/ViperBTests/ViperQtProject/App/main.vp @@ -5,7 +5,7 @@ # → 步骤3 安装选项 → 步骤4 安装进度 → 步骤5 完成 # # 完善功能: -# - 许可协议页:多份协议文件(QComboBox 切换)+ "我接受" 勾选后才可继续 +# - 许可协议页:4 份协议逐份查看、逐份勾选同意(下一步才放下一份,不可跳过) # - 组件选择:QTreeWidget 树状图分组 + 勾选实时统计(数量 / 磁盘占用) # - 安装选项(独立页):发布渠道 QComboBox + 安装目录 + 快捷方式/PATH/桌面图标 # - 安装进度:进度条 + 阶段文案 + 实时日志(QPlainTextEdit) @@ -42,7 +42,7 @@ finish_summary_ptr: t.CPtr = None timer_ptr: t.CPtr = None tree_ptr: t.CPtr = None license_box_ptr: t.CPtr = None -license_sel_ptr: t.CPtr = None +eula_name_ptr: t.CPtr = None agree_cb_ptr: t.CPtr = None license_next_ptr: t.CPtr = None channel_ptr: t.CPtr = None @@ -57,6 +57,8 @@ progress_val: int = 0 comp_count: int = 0 install_path: str = "C:/Program Files/Viper6" channel_name: str = "稳定版(Stable)" +eula_idx: int = 0 +eula_agreed: int = 0 # ============================================================ @@ -81,6 +83,12 @@ privacy_text: str = "隐私政策\n\n本安装向导为本地演示程序,在 credits_text: str = "商标与版权声明\n\nViper、Viper 徽标与相关名称是 Viper Software Foundation 及其关联方的商标。\n\n本演示程序界面设计参考了行业通用安装向导的交互范式,仅用于功能与技术展示,不构成对任何第三方安装程序视觉风格的授权主张。\n\n本软件版权归 Viper Software Foundation 所有,保留一切权利。\n\n版本信息:Viper 6.0.1 · 2026" +# EULA 文档名(显示序号用) +doc_name0: str = "Viper 6.0 最终用户许可协议" +doc_name1: str = "第三方开源组件许可声明" +doc_name2: str = "隐私政策" +doc_name3: str = "商标与版权声明" + # 发布渠道文本 channel_stable: str = "稳定版(Stable)" channel_preview: str = "预览版(Preview)" @@ -113,30 +121,68 @@ def GotoStep(step: int): # 步骤0:欢迎页 # ============================================================ def OnNext(slot_id: int, data: t.CPtr): + EnterEulaPage() GotoStep(1) # ============================================================ -# 步骤1:许可协议 +# 步骤1:许可协议(逐份查看 + 逐份同意) # ============================================================ -def OnLicenseDocChanged(slot_id: int, data: t.CPtr): - """QComboBox 切换多份协议文件""" - idx: int = vqt6.vqt6_qcombobox_current_index(license_sel_ptr) +def ShowEulaDoc(idx: int): + """显示第 idx 份协议,并回填该协议的已同意状态""" txt: str = license_text - if idx == 1: txt = oss_text - elif idx == 2: txt = privacy_text - elif idx == 3: txt = credits_text + name: str = doc_name0 + if idx == 1: + txt = oss_text + name = doc_name1 + elif idx == 2: + txt = privacy_text + name = doc_name2 + elif idx == 3: + txt = credits_text + name = doc_name3 + # 标题(x/4 · 协议名) + buf: bytes = stdlib.malloc(128) + viperlib.snprintf(buf, 128, "%d/4 · %s", idx + 1, name) + vqt6.vqt6_qlabel_set_text_utf8(eula_name_ptr, buf) + stdlib.free(buf) + # 正文 vqt6.vqt6_qplaintextedit_set_plain_text_utf8(license_box_ptr, txt) + # 回填该协议已同意状态 + agreed: int = (eula_agreed >> idx) & 1 + vqt6.vqt6_qcheckbox_set_checked(agree_cb_ptr, agreed) + vqt6.vqt6_qwidget_set_enabled(license_next_ptr, agreed) + + +def EnterEulaPage(): + """进入许可页:全部已同意则停在末份,否则续接当前进度""" + global eula_idx + if eula_agreed == 15: + ShowEulaDoc(3) + else: + ShowEulaDoc(eula_idx) def OnLicenseToggled(slot_id: int, data: t.CPtr): - """勾选"我接受"后启用下一步""" + """勾选当前协议后才允许下一步""" checked: int = vqt6.vqt6_qcheckbox_is_checked(agree_cb_ptr) vqt6.vqt6_qwidget_set_enabled(license_next_ptr, checked) def OnLicenseNext(slot_id: int, data: t.CPtr): - GotoStep(2) + """逐份同意:点下一步才放下一份;末份同意后进入组件选择""" + global eula_idx, eula_agreed + idx: int = eula_idx + if idx < 0 or idx > 3: + GotoStep(2) + return + if vqt6.vqt6_qcheckbox_is_checked(agree_cb_ptr) != 0: + eula_agreed = eula_agreed | (1 << idx) + if idx >= 3: + GotoStep(2) + else: + eula_idx = idx + 1 + ShowEulaDoc(eula_idx) def OnLicenseBack(slot_id: int, data: t.CPtr): @@ -147,6 +193,7 @@ def OnLicenseBack(slot_id: int, data: t.CPtr): # 步骤2:组件选择(树状图) # ============================================================ def OnBack(slot_id: int, data: t.CPtr): + EnterEulaPage() GotoStep(1) @@ -175,11 +222,6 @@ def OnCompToggled(slot_id: int, data: t.CPtr): UpdateCompInfo() -def OnTreeItemClicked(slot_id: int, data: t.CPtr): - """点击带子节点的行 → 展开/折叠""" - vqt6.qtree_click_toggle(tree_ptr) - - # ============================================================ # 步骤3:安装选项(独立页) # ============================================================ @@ -260,7 +302,7 @@ def main() -> int: global nav0_ptr, nav1_ptr, nav2_ptr, nav3_ptr, nav4_ptr, nav5_ptr global progress_ptr, progress_status_ptr, log_ptr, path_label_ptr global summary_ptr, disk_ptr, finish_summary_ptr, timer_ptr - global tree_ptr, license_box_ptr, license_sel_ptr + global tree_ptr, license_box_ptr, eula_name_ptr global agree_cb_ptr, license_next_ptr, install_btn_ptr global channel_ptr, opt0_ptr, opt1_ptr, opt2_ptr @@ -358,7 +400,7 @@ def main() -> int: stack.addWidget(page0._ptr) - # ---------- 页1:许可协议(多文件) ---------- + # ---------- 页1:许可协议(逐份同意) ---------- page1 = vqt6.QWidget() p1 = vqt6.QVBoxLayout(page1) p1.setContentsMargins(36, 32, 36, 24) @@ -368,19 +410,10 @@ def main() -> int: vqt6.vqt6_qwidget_set_stylesheet_utf8(lh._ptr, "font-size: 22px; color: #ffffff; font-weight: bold;") p1.addWidget(lh._ptr) - doc_row = vqt6.QHBoxLayout() - p1.addLayout(doc_row._ptr) - doc_lb = vqt6.QLabel("协议文件:") - doc_row.addWidget(doc_lb._ptr) - lic_sel = vqt6.QComboBox() - lic_sel.addItem("Viper 6.0 最终用户许可协议") - lic_sel.addItem("第三方开源组件许可声明") - lic_sel.addItem("隐私政策") - lic_sel.addItem("商标与版权声明") - doc_row.addWidget(lic_sel._ptr) - doc_row.addStretch(1) - license_sel_ptr = t.CPtr(lic_sel._ptr) - lic_sel.currentIndexChanged(OnLicenseDocChanged, 0) + eula_name = vqt6.QLabel("1/4 · Viper 6.0 最终用户许可协议") + vqt6.vqt6_qwidget_set_stylesheet_utf8(eula_name._ptr, "font-size: 13px; color: #9cdcfe;") + p1.addWidget(eula_name._ptr) + eula_name_ptr = t.CPtr(eula_name._ptr) license_box = vqt6.QPlainTextEdit() license_box.setPlainText(license_text) @@ -388,7 +421,7 @@ def main() -> int: p1.addWidget(license_box._ptr) license_box_ptr = t.CPtr(license_box._ptr) - agree_cb = vqt6.QCheckBox("我接受许可协议中的条款") + agree_cb = vqt6.QCheckBox("我接受上述协议条款") p1.addWidget(agree_cb._ptr) agree_cb_ptr = t.CPtr(agree_cb._ptr) agree_cb.toggled(OnLicenseToggled, 0) @@ -463,7 +496,6 @@ def main() -> int: tree.expandAll() tree.itemChanged(OnCompToggled, 0) - tree.itemClicked(OnTreeItemClicked, 0) summary = vqt6.QLabel("已选择 3 个组件") vqt6.vqt6_qwidget_set_stylesheet_utf8(summary._ptr, "font-size: 13px; color: #9cdcfe;") @@ -475,8 +507,6 @@ def main() -> int: p2.addWidget(disk._ptr) disk_ptr = t.CPtr(disk._ptr) - p2.addStretch(1) - btn_row2 = vqt6.QHBoxLayout() p2.addLayout(btn_row2._ptr) btn_row2.addStretch(1)