Files
work-secretfile-selfcheck/UmiOCR-data/qt_res/qml/Widgets/MissionCtrlPanel.qml

277 lines
11 KiB
QML
Raw Normal View History

// ==============================================
// =============== 任务进度控制面板 ===============
// ==============================================
import QtQuick 2.15
import QtQuick.Controls 2.15
Item {
id: missionCtrl
// 信号
signal runClicked // 点击 运行
signal pauseClicked // 点击 暂停
signal resumeClicked // 点击 恢复
signal stopClicked // 点击 停止
// 通知回调
function runFinished(allNum) { // 任务开始,传入总任务数
state_ = "run"
isWaiting = false
timer.start() // 新开始计时
msnNowNum = 0 // 刷新任务计数
msnAllNum = allNum
timer.updateNumber() // 刷新任务计数文本
}
function pauseFinished() { // 暂停
state_ = "pause"
isWaiting = false
timer.pause() // 暂停计时
timer.updateNumber() // 刷新任务计数文本
}
function resumeFinished() { // 恢复
state_ = "run"
isWaiting = false
timer.resume() // 恢复计时
timer.updateNumber() // 刷新任务计数文本
}
function stopFinished() { // 停止
state_ = "stop"
isWaiting = false
timer.pause() // 暂停计时
timer.updateNumber() // 刷新任务计数文本
}
function msnStep(step=1) { // 任务计数步进
msnNowNum += step
if(msnNowNum > msnAllNum) msnNowNum = msnAllNum
timer.updateNumber() // 刷新任务计数文本
}
// 任务状态
property string state_: "stop" // 当前状态, stop run pause
property bool isWaiting: false // 等待回调中
// 任务计数
property int msnAllNum: 0 // 总任务数
property int msnNowNum: 0 // 当前已完成任务数
clip: true
// 右:开始/暂停/停止按钮
Item {
id: ctrlRight
anchors.top: parent.top
anchors.bottom: parent.bottom
anchors.right: parent.right
// 右栏宽度
property real width_: size_.line * 8
width: width_
// 开始/暂停/恢复 按钮
Item {
id: btn1
anchors.top: parent.top
anchors.bottom: parent.bottom
anchors.left: parent.left
width: qmlapp.enabledEffect?ctrlRight.width_:(
state_==="stop"?ctrlRight.width_:ctrlRight.width_*0.5)
Button_ {
visible: state_ === "stop" && !isWaiting
anchors.fill: parent
bold_: true
bgColor_: theme.coverColor1
bgHoverColor_: theme.coverColor2
text_: qsTr("开始任务")
onClicked: {
if(isWaiting) return
isWaiting = true
Qt.callLater(runClicked)
}
}
IconButton {
visible: state_ !== "stop" || isWaiting
anchors.fill: parent
color: theme.textColor
bgColor_: theme.coverColor1
bgHoverColor_: theme.coverColor2
margins: size_.spacing
icon_: isWaiting?"wait":(state_==="run" ? "pause" : "run")
toolTip: (state_==="run" ? qsTr("暂停任务\n暂停后可以待机或休眠。\n但是关机或退出软件将会丢弃任务内容。") :
qsTr("继续任务"))
onClicked: {
if(isWaiting) return
isWaiting = true
switch(state_) {
case "run": Qt.callLater(pauseClicked); return;
case "pause": Qt.callLater(resumeClicked); return;
}
}
}
// 动画
PropertyAnimation on width { // 折叠一半
running: qmlapp.enabledEffect && state_!=="stop"
to: ctrlRight.width_*0.5
duration: 80
easing.type: Easing.InCubic
}
PropertyAnimation on width { // 展开全部
running: qmlapp.enabledEffect && state_==="stop"
to: ctrlRight.width_
duration: 80
easing.type: Easing.OutCubic
}
}
// 停止 按钮
IconButton {
id: btn2
anchors.top: parent.top
anchors.bottom: parent.bottom
anchors.right: parent.right
anchors.left: btn1.right
anchors.leftMargin: size_.smallSpacing
visible: width > 1
color: theme.noColor
bgColor_: theme.coverColor1
bgHoverColor_: theme.coverColor2
margins: size_.spacing
icon_: isWaiting?"wait":"stop"
toolTip: qsTr("终止任务\n放弃未完成的内容。")
onClicked: {
if(isWaiting) return
isWaiting = true
Qt.callLater(stopClicked)
}
}
}
// 左:文字/进度条
Item {
id: ctrlLeft
anchors.top: parent.top
anchors.bottom: parent.bottom
anchors.left: parent.left
anchors.right: ctrlRight.left
anchors.rightMargin: size_.spacing
Item {
id: ctrlLeftTop
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
height: size_.line
Row {
anchors.top: parent.top
anchors.bottom: parent.bottom
anchors.right: parent.right
spacing: size_.line
// 计时器、任务计数器
Text_ {
id: timer
text: `${strState} ${strTime} ${strNumber}`
color: timer_.running?theme.textColor:(missionCtrl.msnNowNum<missionCtrl.msnAllNum?theme.noColor:theme.yesColor)
font.pixelSize: size_.smallText
verticalAlignment: Text.AlignVCenter // 垂直居中
property string strState: "" // 状态文本, "已暂停"
property string strTime: "" // 时间文本
property string strNumber: "" // 任务数量文本, 23/100
// 新开始计时
function start() {
timer_.running = true
startStamp = getTimestamp()
runTime = pauseTime = 0
updateTime()
}
// 暂停
function pause() {
timer_.running = false
pauseStartStamp = getTimestamp()
updateTime()
}
// 恢复计时
function resume() {
timer_.running = true
const t = getTimestamp()
pauseTime += t-pauseStartStamp // 累加暂停时长
updateTime()
}
// 获取时间戳
function getTimestamp() {
return (new Date()).getTime() / 1000
}
// 刷新时间
function updateTime() {
if(runTime < 0.1) {
strTime = "" // 时间太短,不显示
return
}
let s = ""
let minutes = Math.floor(runTime / 60)
let seconds = Math.floor(runTime % 60)
if(minutes < 10) minutes = "0"+minutes
if(seconds < 10) seconds = "0"+seconds
strTime = minutes + ':' + seconds
}
// 刷新数量、显示文本
function updateNumber() {
// n="23/100" , p="已停止"
let n = `${missionCtrl.msnNowNum}/${missionCtrl.msnAllNum}`
let p = ""
// 运行中
if(missionCtrl.state_ === "run") {
if(missionCtrl.msnNowNum < missionCtrl.msnAllNum)
p = qsTr("正在运行")
else
p = qsTr("正在保存") // 所有任务处理完毕,但任务队列未返回结束
}
// 暂停中
else if(missionCtrl.state_ === "pause") {
p = qsTr("已暂停")
}
// 已停止
else if(missionCtrl.state_ === "stop") {
if(missionCtrl.msnNowNum <= 0)
n = p = ""
else if(missionCtrl.msnNowNum < missionCtrl.msnAllNum)
p = qsTr("任务停止")
else
p = qsTr("任务完成")
}
// 刷新
timer.strNumber = n
timer.strState = p
if(missionCtrl.msnAllNum > 0)
missionProgress.percent = missionCtrl.msnNowNum/missionCtrl.msnAllNum
}
property real startStamp // 开始时间戳,秒
property real pauseStartStamp // 本次暂停开始的时间戳,秒
property real pauseTime // 暂停时长,秒
property real runTime // 运行时长,秒
property bool isPause: false // 是否正在暂停
Timer {
id: timer_
interval: 100 // 更新间隔
repeat: true
running: false
onTriggered: {
// 刷新运行时长
const timestamp = timer.getTimestamp()
timer.runTime = timestamp-timer.startStamp-timer.pauseTime
timer.updateTime()
}
}
}
}
}
HProgressBar {
id: missionProgress
anchors.bottom: parent.bottom
anchors.left: parent.left
anchors.right: parent.right
anchors.bottomMargin: size_.line * 0.1
height: size_.line * 0.5
highlightColor: missionCtrl.state_==="run"?theme.yesColor:theme.coverColor4
color: theme.bgColor
percent: 0
}
}
}