Files
work-secretfile-selfcheck/UmiOCR-data/qt_res/qml/TabPages/PagesManager.qml

232 lines
8.3 KiB
QML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// ===============================================
// =============== 页面的逻辑管理器 ===============
// ===============================================
import QtQuick 2.15
import TagPageConnector 1.0 // Python页面连接器
Item {
// ========================= 【列表】 =========================
property var infoList: [
{
key: "Navigation", // 页面的唯一标识符。同时也是对应Python模块的名称。
url: "", // 页面的qml文件路径。留空时初始化为 key/key.qml
needController: false, // 为true时才需要加载对应Python模块不需要可留空
title: qsTr("新标签页"), // 页面的显示名称。
intro: "" // 页面的简介。
},
{
key: "ScreenshotOCR",
needController: true,
title: qsTr("截图OCR"),
intro: qsTr("# 截图OCR\n\n屏幕截图快捷转文字。也支持粘贴图片。")
},
{
key: "BatchOCR",
needController: true,
title: qsTr("批量OCR"),
intro: qsTr("# 批量OCR\n\n导入本地图片或文件夹批量转换文字。\n\n支持格式")
+ " `jpg, jpe, jpeg, jfif, png, webp, bmp, tif, tiff`",
},
{
key: "BatchDOC",
needController: true,
title: qsTr("批量文档"),
intro: qsTr("# 批量文档识别\n\n批量导入文档提取文字或生成双层可搜索PDF。\n\n支持格式")
+ " `pdf, xps, epub, mobi, fb2, cbz`",
},
{
key: "QRCode",
needController: true,
title: qsTr("二维码"),
intro: qsTr("# 二维码\n\n识别或生成二维码、条形码。\n\n支持协议")
+ " `Aztec, Codabar, Code128, Code39, Code93, DataBar, DataBarExpanded, DataMatrix, EAN13, EAN8, ITF, LinearCodes, MatrixCodes, MaxiCode, MicroQRCode, PDF417, QRCode, UPCA, UPCE`",
},
{
key: "GlobalConfigsPage",
title: qsTr("全局设置"),
intro: qsTr("# 全局设置\n\n调节全局设置项对所有页面生效。")
},
{
key: "About",
title: qsTr("关于"),
intro: qsTr("# 关于")
},
]
/* 存放当前已打开的页面
obj: 页面组件对象
info: 页面信息infoList中对应项的引用
infoIndex: 页面信息下标infoList中对应项的引用
*/
property var pageList: []
// Python的页面连接器手动维护单例状态
TagPageConnector { id: connector }
// ========================= 【增删改查】 =========================
// 初始化
function initListUrl() {
for(let i=infoList.length-1; i>=0; i--){
const info = infoList[i]
if(!info.url) {
info.url = `${info.key}/${info.key}.qml`
}
}
}
// 创建一个页面的组件类 comp
function getComp(infoIndex) {
const info = infoList[infoIndex]
if(info.comp) return info.comp
const url = info.url
const comp = Qt.createComponent(url)
if (comp.status === Component.Ready) { // 加载成功
infoList[infoIndex].comp = comp
return comp
} else{ // 加载失败
if (comp.status === Component.Error) { // 加载失败,提取错误信息
let str = comp.errorString()
const last = str.lastIndexOf(":")
if(last < 0) last = -1
str = str.substring(last+1).replace("\n","")
console.error(`Error${url}${str}`)
}
else{
console.error(`Error${url}`)
}
return undefined
}
}
// 创建并返回一个 infoList[infoIndex] 页面。
function newPage(infoIndex){
const info = infoList[infoIndex]
// 实例化逻辑控制器
let ctrlKey = ""
if(info.needController){
ctrlKey = connector.addPage(info.key)
if(!ctrlKey){
console.error("【Error】添加页面失败组件["+info.key+"]创建控制器失败!")
return undefined
}
}
else { // 新增一个不带控制器的简单页
ctrlKey = connector.addSimplePage(info.key)
}
// 检查组件
let comp = getComp(infoIndex)
if(!comp){
console.error("【Error】添加页面失败组件["+info.key+"]的comp无法创建")
return undefined
}
// 实例化页面,挂到巢下,写入自身参数
const obj = comp.createObject(pagesNest, {
z: -1, visible: false,
ctrlKey: ctrlKey, // Python控制器key
connector: connector, // Python控制器对象
})
// 收集并返回页面对象信息
const dic = {
obj: obj,
info: info,
infoIndex: infoIndex,
ctrlKey: ctrlKey
}
// 向控制器传入页面对象
connector.setPageQmlObj(ctrlKey, obj)
return dic
}
// 增: 在 pageList 的 index 处,插入一个 infoList[infoIndex] 页面。
function addPage(index, infoIndex){ // index=-1 代表尾部插入
// 列表添加
const dic = newPage(infoIndex)
if(dic == undefined){
return false
}
pageList.splice(index, 0, dic) // 列表添加
return true
}
// 增改: 在 pageList 的 index 处,删除该页面,改为 infoIndex 页。
function changePage(index, infoIndex){
const page = pageList[index]
// 删除旧页的python逻辑控制器
const flag = connector.delPage(page.ctrlKey)
if(!flag){
console.error("【Warning】删除页面失败控制器["+page.ctrlKey+"]删除失败!")
// return false // 暂时不管控制器删除失败
}
const dic = newPage(infoIndex)
if(dic == undefined){
return false
}
page.obj.destroy() // 旧页对象删除
pageList[index] = dic // 替换新页
return true
}
// 删: 在 pageList 的 index 处,发送关闭指令。
function closePage(index){
pageList[index].obj.closePage()
}
// 删: 在 pageList 的 index 处,删除该页面。
function delPage(index){
const page = pageList[index]
// 删除python逻辑控制器
const flag = connector.delPage(page.ctrlKey)
if(!flag){
console.error("【Warning】删除页面失败控制器["+page.ctrlKey+"]删除失败!")
// return false // 暂时不管控制器删除失败
}
page.obj.destroy() // 页对象删除
pageList.splice(index, 1) // 列表删除
return true
}
// 改: 展示 index 页。
function showPage(index){
// 遍历,将展示的页面设为可视状态,其他页面设为非可视状态
for(let i in pageList){
if(i==index){
pageList[i].obj.z = 0
pageList[i].obj.visible = true
pageList[i].obj.showPage()
}else{
pageList[i].obj.z = -1
pageList[i].obj.visible = false
}
}
}
// 改: 将一个原本在 index 的页移到 go 处。
function movePage(index, go){
var x = pageList.splice(index, 1)[0] // 删除
pageList.splice(go, 0, x) // 添加
}
// 查: 传入下标 index 列表 list 报错内容前缀 msg ,返回下标是否合法。
function isIndex(index, list, msg=""){
if(index<0 || index>=list.length){
if(msg)
console.error(msg+"下标"+index+"超出范围"+(pageList.length-1)+"")
return false
}
return true
}
// ========================= 【辅助元素】 =========================
// 页巢,作为已生成的页组件对象的父级。可挂载到可视节点下来展示。
Item {
id: pagesNest
anchors.fill: parent
}
property var pagesNest: pagesNest
}