app.progress - 进度对话框 API
显示和控制进度对话框。
权限:L0 安全 — 无需声明,始终可用
整个模块只有一个入口:app.progress.create(config) 创建对话框并返回一个句柄,
之后所有操作都是句柄上的方法。
local p = app.progress.create({ title = "处理中" })
p:update(50, "已完成一半")
p:close()
句柄方法要用冒号调用(p:update(...)),不是点号。
app.progress.create(config)
创建并显示一个进度对话框。
参数:
config(table):title(string, 必需) - 对话框标题message(string) - 详细消息,默认空indeterminate(boolean) - 是否为不确定进度(默认true,显示来回滚动的条)cancellable(boolean) - 是否显示取消按钮(默认false)onCancel(function) - 用户点取消时的回调
返回值: progressHandle - 进度句柄;失败时返回 nil, error
local p, err = app.progress.create({
title = "下载文件",
message = "准备中...",
indeterminate = false,
cancellable = true,
onCancel = function()
app.log.info("下载已取消")
end
})
if not p then
app.log.error("创建进度对话框失败: " .. tostring(err))
return
end
没传 title 会直接失败——它是唯一的必需字段。
句柄方法
handle:update(value, message?)
更新进度值和消息。
参数:
value(number) - 进度值,范围 0–100(不是 0–1)message(string, 可选) - 同时更新消息文本
for i = 1, #files do
p:update(i * 100 / #files, "处理: " .. app.path.basename(files[i]))
end
调用
update()会把不确定进度切换成确定进度。 即使创建时indeterminate = true,第一次update()之后滚动条就变成按value走的实心条。 想一直保持不确定状态,就只用setMessage()别用update()。
handle:setMessage(message)
只更新消息文本,不动进度值,也不会把不确定进度切成确定进度。
参数:
message(string) - 新消息
p:setMessage("正在执行步骤 2...")
handle:isCancelled()
查询用户有没有点过取消。需要创建时 cancellable = true。
返回值: boolean
if p:isCancelled() then
p:close()
return
end
handle:close()
关闭对话框。
p:close()
两种处理取消的方式
cancellable = true 之后有两条路,按循环的形状挑:
轮询 isCancelled() —— 适合有明确循环的批处理,退出点看得见:
for i = 1, 100 do
if p:isCancelled() then break end
p:update(i, "步骤 " .. i)
end
onCancel 回调 —— 适合没有循环可插入检查的场合(等待某个异步结果时):
local cancelled = false
local p = app.progress.create({
title = "长时间操作",
cancellable = true,
onCancel = function() cancelled = true end
})
两者可以混用,但没必要——挑一个就好。
完整示例
批量处理文件
function MyPlugin:handleBatchProcess(context)
local files = context.selectedFiles
local total = #files
local p = app.progress.create({
title = "批量处理",
message = "准备中...",
indeterminate = false,
cancellable = true
})
if not p then return end
local processed = 0
for i, file in ipairs(files) do
if p:isCancelled() then break end
p:update(i * 100 / total, "处理: " .. app.path.basename(file))
self:processFile(file)
processed = processed + 1
end
p:close()
app.notification.show("完成", "处理了 " .. processed .. " 个文件")
end
不确定进度(不知道要多久)
function MyPlugin:handleSearch(context)
local p = app.progress.create({
title = "搜索中",
message = "正在搜索文件...",
indeterminate = true
})
if not p then return end
-- 全程只用 setMessage,不用 update——否则滚动条会变成实心条
p:setMessage("正在扫描子目录...")
local results = self:searchFiles()
p:close()
app.notification.show("完成", "找到 " .. #results .. " 个文件")
end
同时开多个
每次 create() 都是独立的一个对话框,互不干扰:
function MyPlugin:handleParallelDownload(context)
local urls = {"url1", "url2", "url3"}
local bars = {}
for i, url in ipairs(urls) do
bars[i] = app.progress.create({
title = "下载 " .. i,
message = "准备中...",
indeterminate = false
})
end
for pct = 1, 100 do
for _, p in ipairs(bars) do
if p then p:update(pct, "下载中... " .. pct .. "%") end
end
end
for _, p in ipairs(bars) do
if p then p:close() end
end
end