gpt4 book ai didi

objective-c - 如何强制刷新 NSTextField 标签

转载 作者:行者123 更新时间:2023-12-03 17:38:42 24 4
gpt4 key购买 nike

我想做的事情看起来很简单,但实现却让我很困惑。更改标签值后如何强制刷新标签?

我刚刚创建了一个简单的进度窗口。当主应用程序正在执行某些操作时,我会弹出进度窗口,并且我想在循环执行时更新标签和进度栏的值。

我创建了一个新的 NSWindow 和 XIB 文件,其中包含标签和进度条的导出,我正在使用以下内容加载它:

_pbWindow                           = [[ProgressBar alloc] initWithWindowNibName:@"ProgressBar"];

[_pbWindow showWindow:self];

当我打电话时:

_pbWindow.lblProgress1.stringValue = @"Doing this now...";

我无法让标签在新窗口中实际刷新。

我在这里和谷歌上搜索过,似乎找不到任何东西告诉我如何在不同的窗口中执行此操作,只有如果它在主窗口中,它就会刷新(无论如何,这一直是我的经验) )。

我想可能是因为窗口没有焦点,所以我尝试以模式方式打开它:

[[NSApplication sharedApplication] beginSheet:[_pbWindow window]
modalForWindow:[[NSApplication sharedApplication] mainWindow]
modalDelegate:_pbWindow
didEndSelector:nil
contextInfo:nil];

但仍然不起作用。

最佳答案

当您设置文本字段的 stringValue 时,文本字段会将自身标记为需要显示(-setNeedsDisplay... 方法之一)。它不会立即显示出来。稍后,在主事件循环期间,应用程序将告诉每个窗口 -displayIfNeeded,文本字段的新内容将实际绘制在屏幕上。

但是,由于您处于长时间运行的循环中,因此您不允许主事件循环运行,并且窗口没有机会在需要时显示。

一种解决方法是在更改文本字段的 stringValue 后直接调用文本字段上的 -displayIfNeeded:

_pbWindow.lblProgress1.stringValue = @"Doing this now...";
[_pbWindow.lblProgress1 displayIfNeeded];

但是,不让主事件循环运行还存在其他问题。仅解决这一问题仍然会留下其他问题。例如,您的应用程序将在事件监视器中显示为“无响应”,并且当鼠标悬停在其窗口上时,系统将显示旋转的色轮光标。您应该考虑寻找另一种方式来构建您的应用程序。

例如,您可以在主线程上将进度窗口作为模态窗口运行(使用 -[NSApplication runModalForWindow:])并在后台线程上执行工作。工作完成后,调用 -[NSApplication stopModal...] 方法或 -[NSApplication abortModal] 之一(但请阅读文档以了解在什么情况下应该使用 which,尽管在 10.9 中取消了对 -stopModal... 的一些限制)。主线程将被允许返回到主事件循环,但模式窗口将阻止用户对 UI 的其余部分执行任何在操作继续时不应该允许执行的操作。

或者,也许该操作实际上不应该垄断您的整个应用程序。也许它应该只是单一窗口的模式。在这种情况下,您可以将进度窗口显示为窗口上的一个工作表,该工作表应在操作期间禁用。使用 -[NSWindow beginSheet:completionHandler:] 开始工作表并在后台启动操作。操作完成后,在主线程上调用 -[NSWindow endSheet:...] 方法之一。

如果您在后台线程上运行工作,请务必使用 GCD 和 dispatch_get_main_queue()-performSelectorOnMainThread: 将任何会影响 GUI 的更改分流到主线程。 ...

关于objective-c - 如何强制刷新 NSTextField 标签,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28003022/

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