docs: 添加涉密文件自检工具实施计划

This commit is contained in:
2026-06-08 13:53:24 +08:00
commit 31161d9a5f
1838 changed files with 455407 additions and 0 deletions

View File

@@ -0,0 +1,105 @@
// ======================================================
// =============== 标签栏的复制器的逻辑管理 ===============
// ======================================================
/* 页面表现(布局、动画)应该在继承的子类中编写
delegate: // 子类中填入按钮组件,属性必须包含:
title: title_ // 标题
checked: checked_ // 是否选中
width: 宽
height: 高
*/
import QtQuick 2.15
import QtQuick.Controls 2.15
Repeater {
// ========================= 【属性与变量】 =========================
model: ListModel{} // 标签元素列表,初始为空
property bool isLock: false
Component.onCompleted: {
qmlapp.tab.bar = this // 逆向连接引用
}
// ========================= 【增删改查】 =========================
// 增: 在 index 处,插入一个标题为 title 的标签。
function addTab(index, title){ // index=-1 代表尾部插入
if(index<0) index=model.count // 尾部添加
else if(index>model.count){
console.error("【Error】添加标签失败下标"+index+"超出范围"+model.count+"")
return
}
model.insert(index, {
"title_": title,
"checked_": false
})
}
// 删: 在 index 处,删除该标签。
function delTab(index){
if(!isIndex(index, "【Error】删除标签失败"))
return
model.remove(index) // 删除按钮
}
// 改: 在 index 处,重设标签的 title 。
function changeTab(index, title){
if(!isIndex(index, "【Error】重命名标签失败"))
return
model.set(index, {"title_": title})
}
// 改: 选中 index 标签。
function showTab(index){
if(!isIndex(index, "【Error】选中标签失败"))
return
for(let i=0; i<model.count; i++){
itemAt(i).checked = (i==index)
// model.set(index, {"checked_": (i==index)})
}
}
// 改: 将一个原本在 index 的标签移到 go 处。
function moveTab(index, go){
if(!isIndex(index, "【Error】移动标签失败起点"))
return
if(!isIndex(go, "【Error】移动标签失败终点"))
return
model.move(index, go, 1)
}
// 改: 重置所有标签的序号
function resetIndex() {
for(let i=0, c=model.count; i<c; i++){
itemAt(i).index = i
}
}
// 查: 返回下标 index 是否合法。
function isIndex(index, msg=""){
if(index<0 || index>=model.count){
if(msg)
console.error(msg+"下标"+index+"超出范围"+(model.count-1)+"")
return false
}
return true
}
// ========================= 【创建和删除事件】 =========================
// 创建新标签时
onItemAdded: {
resetIndex() // 重设序号
}
onItemRemoved: {
resetIndex() // 重设序号
}
}

View File

@@ -0,0 +1,256 @@
// =========================================
// =============== 水平标签栏 ===============
// =========================================
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15
import "../Widgets"
RowLayout {
id: hTabBarLayout
anchors.fill: parent
spacing: 0
// 标签栏控制(左,置顶按钮)
Item {
width: size_.hTabBarHeight
Layout.fillHeight: true
// 图钉按钮
Button {
checkable: true
checked: mainWindowRoot.isMainWindowTop
onCheckedChanged: { // 双向绑定锁定标记
mainWindowRoot.isMainWindowTop = checked
qmlapp.globalConfigs.setValue("window.isMainWindowTop", checked, true)
}
anchors.fill: parent
anchors.margins: 4
contentItem: Icon_ {
icon: "pin"
anchors.fill: parent
color: parent.checked ? theme.bgColor : theme.textColor
}
background: Rectangle {
anchors.fill: parent
radius: size_.btnRadius
color: parent.checked ? theme.coverColor4 : (
parent.hovered ? theme.coverColor2 : "#00000000"
)
}
ToolTip_ {
visible: parent.hovered
text: qsTr("窗口置顶")
}
}
}
// 标签栏本体(中)
Rectangle {
id: hTabBarMain
Layout.fillWidth: true
Layout.fillHeight: true
color: "#00000000"
property int tabWidth: 200 // 标签当前宽度
// 方法:重设标签按钮宽度
function resetTabBtnWidth() {
let w = hTabBarMain.width
if(!qmlapp.tab.barIsLock) w -= tabBarControl.width // 无锁定时,减去+按钮宽度
w = w / barManager.model.count
tabWidth = Math.min(w, size_.line * 8)
}
onWidthChanged: resetTabBtnWidth() // 监听标签栏总宽度变化
// 监听改变锁定,重设宽度
property bool isLock: qmlapp.tab.barIsLock
onIsLockChanged: {
hTabBarMain.resetTabBtnWidth()
}
MouseArea { // 点击标签栏空余位置,都是添加新标签
anchors.fill: parent
onClicked: {
if(!qmlapp.tab.barIsLock)
qmlapp.tab.addNavi() // 添加导航页
}
}
// Rectangle { // 标签按钮下方的阴影
// anchors.bottom: parent.bottom
// width: parent.width
// height: size_.hTabBarHeight * 0.5
// gradient: Gradient {
// GradientStop { position: 0.0; color: "#00000000" }
// GradientStop { position: 1.0; color: theme.coverColor2 }
// }
// }
Rectangle { // 拖拽时的位置指示器
id: dragIndicator
visible: false
width: parent.tabWidth
height: size_.hTabBarHeight
gradient: Gradient { // 水平渐变
orientation: Gradient.Horizontal
GradientStop { position: 1.0; color: "#00000000" }
GradientStop { position: 0.0; color: theme.coverColor3 }
}
}
// 水平标签栏行布局
Row {
id: hTabBarMainRow
spacing: -1 // 给负的间隔,是为了让选中标签能覆盖左右两边标签的竖线
// ===== 标签按钮组 =====
BarManager {
id: barManager
// 标签元素模板
delegate: TabButton_ {
title: title_ // 标题
checked: checked_ // 初始时是否选中
index: index_ // 初始位置
width: hTabBarMain.tabWidth
}
// 事件:创建新标签时(与父类的槽同时生效)
onItemAdded: {
// 链接表现相关的槽函数
item.dragStart.connect(dragStart)
item.dragFinish.connect(dragFinish)
item.dragMoving.connect(dragMoving)
}
// 事件:按钮数量变化
onCountChanged: hTabBarMain.resetTabBtnWidth()
// ========================= 【拖拽相关】 =========================
property var intervalList: [] // 记录按钮位置区间的列表
property var originalPosList: [] // 记录按钮初始位置的列表
property int originalX // 记录本轮拖拽前,被拖拽按钮原本的位置
function dragStart(index){ // 方法:开始拖拽
// 重新记录当前所有按钮的位置
originalX = itemAt(index).x
intervalList = [-Infinity] // 下限:负无穷
originalPosList = [itemAt(0).x]
for(let i=1, c=model.count; i < c; i++){ // 按钮位置区间
const it = itemAt(i)
intervalList.push(it.x)
originalPosList.push(it.x)
}
intervalList.push(Infinity) // 上限:负无穷
dragIndicator.visible = true
}
function btnDragIndex(index){ // 函数返回当前index应该所处的序号
const dragItem = itemAt(index)
const x = dragItem.x + Math.round(dragItem.width/2) // 被拖动按钮的中心位置
let go = 0 // 应该拖放到的位置
for(const c=intervalList.length-1; go < c; go++){
if(x >= intervalList[go] && x <= intervalList[go+1]){
break;
}
}
return go;
}
function dragMoving(index, x){ // 方法:拖拽移动
let go = btnDragIndex(index) // 应该拖放到的序号
dragIndicator.x = originalPosList[go]
}
function dragFinish(index){ // 方法:结束拖拽
dragIndicator.visible = false
let go = btnDragIndex(index) // 应该拖放到的序号
if(index !== go){ // 需要移动
// model.move(index, go, 1)
qmlapp.tab.moveTabPage(index, go)
} else { // 无需移动,则回到原位
itemAt(index).x = originalX
}
resetIndex()
}
}
// 元素:控制按钮
Rectangle{
id: tabBarControl
color: "#00000000"
width: size_.hTabBarHeight
height: size_.hTabBarHeight
visible: !qmlapp.tab.barIsLock
// 添加“+”按钮
IconButton {
anchors.fill: parent
anchors.margins: 4
icon_: "add"
color: theme.textColor
onClicked: {
qmlapp.tab.addNavi() // 添加导航页
}
}
}
// 动画
add: Transition { // 添加子项
enabled: qmlapp.enabledEffect
NumberAnimation {
properties: "opacity, scale" // 透明度和大小从小到大
from: 0; to: 1.0
easing.type: Easing.OutBack // 缓动:超出反弹
duration: 300
}
}
move: Transition { // 移动子项
enabled: qmlapp.enabledEffect
NumberAnimation {
properties: "x,y"
easing.type: Easing.OutBack
duration: 300
}
}
}
}
// 标签栏控制(右,锁定按钮)
Item{
width: size_.hTabBarHeight
Layout.fillHeight: true
// 锁定“🔒︎”按钮
Button {
checkable: true
checked: qmlapp.tab.barIsLock
onCheckedChanged: { // 双向绑定锁定标记
qmlapp.tab.barIsLock = checked
qmlapp.globalConfigs.setValue("window.barIsLock", checked, true)
}
anchors.fill: parent
anchors.margins: 4
contentItem: Icon_ {
icon: "lock"
anchors.fill: parent
color: parent.checked ? theme.bgColor : theme.textColor
}
background: Rectangle {
anchors.fill: parent
radius: size_.btnRadius
color: parent.checked ? theme.coverColor4 : (
parent.hovered ? theme.coverColor2 : "#00000000"
)
}
ToolTip_ {
visible: parent.hovered
text: qsTr("锁定标签栏")
}
}
}
}

View File

@@ -0,0 +1,171 @@
// ==================================================
// =============== 水平标签栏的标签按钮 ===============
// ==================================================
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15
import QtGraphicalEffects 1.15 // 阴影
import "../Widgets"
Button {
id: btn
// 设定值
property string title: "Unknown TabBtn" // 显示的标题
property int index: -1 // 在标签栏中的序号
// 默认值
height: size_.hTabBarHeight
checkable: false // 手动控制
z: checked? 10 : 0 // 选中模式下弹到顶层
// 信号
signal dragStart(int index) // 开始拖拽的信号
signal dragFinish(int index) // 结束拖拽的信号
signal dragMoving(int index, int x) // 拖拽移动的信号
// 按钮前景
contentItem: Item {
anchors.fill: parent
RowLayout {
anchors.fill: parent
// TODO: 图标
Item {
width: size_.line*0.2 // 先占位
height: btn.height // 适应整个按钮的高度
}
// 标题
Text_ {
text: title // 外部传入的title
elide: Text.ElideRight // 隐藏超出宽度
Layout.fillWidth: true // 填充宽度
height: btn.height // 适应整个按钮的高度
color: (btn.hovered || btn.checked)?theme.textColor:theme.subTextColor
font.bold: btn.checked
}
// 关闭按钮
IconButton {
// 未锁定,且主按钮悬停或选中时才显示
visible: !qmlapp.tab.barIsLock && (btn.hovered || btn.checked)
Layout.alignment: Qt.AlignRight
Layout.rightMargin: size_.hTabBarHeight * 0.2
property real size: size_.hTabBarHeight * 0.7
implicitWidth: size
implicitHeight: size
bgColor_: "#00000000"
icon_: "no"
onClicked: {
qmlapp.tab.closeTabPage(index)
}
}
}
}
// 按钮背景
background: Rectangle {
anchors.fill: parent
color: parent.checked ? theme.bgColor : (
parent.hovered ? theme.coverColor1 : "#00000000"
)
// 侧边小条
Rectangle{
visible: !parent.parent.checked
height: size_.line
width: 1
anchors.verticalCenter: parent.verticalCenter
anchors.right: parent.right
color: theme.coverColor4
}
// 边缘阴影
layer.enabled: parent.checked
layer.effect: DropShadow {
transparentBorder: true
color: theme.coverColor3
samples: size_.hTabBarHeight
}
// 点击和拖拽处理
MouseArea {
anchors.fill: parent
acceptedButtons: Qt.LeftButton | Qt.MiddleButton
// 拖拽
drag.target: qmlapp.tab.barIsLock ? undefined : parent.parent // 动态启用、禁用拖拽
drag.axis: Drag.XAxis // 只能沿X轴
drag.threshold: 50 // 起始阈值
property bool dragActive: drag.active // 动态记录拖拽状态
property int dragX: parent.parent.x // 动态记录拖拽时整体的位置
onPressed: { // 左键按下,切换焦点
if(mouse.button === Qt.LeftButton) {
qmlapp.tab.showTabPage(index)
}
}
onClicked: { // 中键点击,删除标签
if(mouse.button === Qt.MiddleButton && !qmlapp.tab.barIsLock) {
qmlapp.tab.closeTabPage(index)
}
}
onDragActiveChanged: {
if(drag.active) { // 拖拽开始
parent.opacity = 0.6
parent.parent.y += parent.parent.height / 2
dragStart(index)
} else { // 拖拽结束
parent.opacity = 1
parent.parent.y -= parent.parent.height / 2
dragFinish(index)
}
}
onDragXChanged: {
if(drag.active) {
dragMoving(index, dragX)
}
}
}
}
// 选中时的放大动画
property bool enabledAni: false // true是允许动画
property bool runAni: false
Timer { // 计时器,保证初始化的一段时间内不允许动画
running: true
interval: 300
onTriggered: enabledAni=true
}
onCheckedChanged: {
if(enabledAni) runAni = checked
}
SequentialAnimation{ // 串行动画
running: qmlapp.enabledEffect && runAni
// 动画1放大
NumberAnimation{
target: btn
property: "scale"
to: 1.2
duration: 80
easing.type: Easing.OutCubic
}
// 动画2缩小
NumberAnimation{
target: btn
property: "scale"
to: 1
duration: 150
easing.type: Easing.InCubic
}
}
}