gpt4 book ai didi

xcode - cocoa-applescript (Xcode) 中的平滑 UI 更改

转载 作者:行者123 更新时间:2023-12-03 17:13:31 26 4
gpt4 key购买 nike

我正在尝试编写一个简单的 Xcode cocoa-applescript 程序,该程序在文件夹的每个子文件夹上执行 bash 脚本,并在执行时显示进度条。

我有一个 NSProgressIndicator 设置为链接到 barStatus 以及一个 NSTextField 链接到 lblStatus > 显示一些信息性文本:

property barStatus : missing value
property lblStatus : missing value

这是发生主要操作的循环:

tell application "Finder" to set subfolders to every folder of folder macPath
barStatus's setIndeterminate_(false)
barStatus's setDoubleValue_(0)
barStatus's setMaxValue_(count of subfolders)

repeat with eachFolder in subfolders
set posixPath to (POSIX path of (eachFolder as text)) as text
-- set text of progress indicator text
lblStatus's setStringValue_("Resizing '" & ( do shell script "basename \"" & (posixPath) & "\" | sed \"s/^.*_//\"" ) & "'...")
delay 0.5

-- do the shell script
do shell script "bash ~/.uploader/image.sh \"" & posixPath & "\""

-- step the indicator
barStatus's incrementBy_(1)
end repeat
lblStatus's setStringValue_("Done!")

一切似乎都工作正常,但用户界面有点问题。进度条不是平滑地增加,而是在每一步上消失并显示一小会儿,然后再次消失。 lblStatus 中的文本确实可以顺利更改。

当我从循环中删除延迟时,事情就完全丢失了:在循环完成之前,不会进行任何 UI 更改(即使脚本正确运行)。因此,当循环完成时,进度条会消失并重新填充。

这是一个youtube video闪烁的用户界面。

我做错了什么?如何让xcode平滑地绘制进度条?

请注意,这是我第一次编写 Xcode 应用程序,而且我对 Applescript 的了解有些粗略。

编辑:

我发现,从菜单项(或绑定(bind)到该菜单项的组合键)调用处理相同函数的函数时,不会出现闪烁的 UI。

最佳答案

我不知道为什么进度条会隐藏起来。您是否将其可见属性绑定(bind)到可能使其隐藏的东西?

Things get totally lost when I remove the delay from the loop: no UI changes are made

一般来说,当“没有进行 UI 更改”时,这是因为应用程序在主线程上太忙,无法实时更新界面项。您的所有代码都在主线程上运行。您需要使其中一些发生在后台线程上。因此,我有 2 个建议供您尝试。

首先尝试使用进度条的方法“setUsesThreadedAnimation:”。将其添加到重复循环上方...

barStatus's setUsesThreadedAnimation_(true)

其次,如果这没有帮助,那么尝试将重复循环工作移到后台线程上(使用 NSThread 的 detachNewThreadSelector:)...但使界面更新发生在主线程上。我不知道 ApplescriptObjC 语言,所以下面的代码可能是完全错误的。你必须正确地写它,但它会告诉你这个想法......

[NSThread detachNewThreadSelector:@selector(processFolderListOnBacgroundThread_) toTarget:self withObject:subfolders];

-- this will happen on the main thread
on updateProgressBarByOne_()
barStatus's' incrementBy_(1)
end updateProgressBarByOne_

-- this will happen on the main thread
on updateStatusTextWithText_(statusText)
lblStatus's' setStringValue_(statusText)
end updateInterfaceItemsOnMainThreadWithObject_

-- this will happen on a background thread
on processFolderListOnBacgroundThread_(subFolders)
repeat with eachFolder in subfolders
set posixPath to (POSIX path of (eachFolder as text)) as text
-- set text of progress indicator text
my updateStatusTextWithText_("Resizing '" & ( do shell script "basename \"" & (posixPath) & "\" | sed \"s/^.*_//\"" ) & "'...")

-- do the shell script
do shell script "bash ~/.uploader/image.sh \"" & posixPath & "\""

-- step the indicator
my updateProgressBarByOne_()
end repeat
my updateStatusTextWithText_("Done!")
end processFolderListOnBacgroundThread_

如果您使用后台线程方法,您可能必须在后台线程工作时使界面中的按钮处于非事件状态(这样用户就无法按下它们并启动新任务)。因此,只需在调用“detachNewThreadSelector:”之前将其启用属性设置为 false,并在工作完成后再次启用它们即可。您可以通过使用另一个处理程序来启用它们并从后台线程代码的末尾调用它来完成此操作。

关于xcode - cocoa-applescript (Xcode) 中的平滑 UI 更改,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13988965/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com