在 NSMenuItem 中使用 NSProgressIndicator

发布于 2024-10-11 12:29:39 字数 672 浏览 10 评论 0原文

我正在尝试在状态栏菜单内使用 NSProgressIndicator (不确定)。我使用 NSView 对象作为菜单项的视图,然后子视图进度指示器来显示它。但每当我尝试调用 startAnimation: 来获取进度时,什么也没有发生。当我尝试在普通 NSWindow 上做同样的事情时,它工作得很好,只是在菜单项内时不行。

我对可可和 Objective-C 都很陌生,所以我可能忽略了一些“明显”的东西,但我已经搜索了很多解决方法,但没有成功。我发现有关菜单项的一些内容在显示时无法更新,并且您需要使用无边框窗口。但我无法在任何文档中证实这一点。

编辑:

好的,现在几乎可以工作了。当使用 setUsesThreadedAnimation: 并从 MenuDelegate 的 menuWillOpen 并创建一个新线程时。该线程运行本地方法:

-(void) doWork(NSProgressIndicator*) p{
     [p startAnimation:self];
}

这将在打开菜单时随机(?)启动进度指示器。如果我直接调用 startAnimation: 而不经过 doWork: (仍然使用新线程),它永远不会工作。 setUsesThreadedAnimation: 不会让进度条为动画创建自己的线程吗?

I'm trying to use a NSProgressIndicator (indeterminate) inside of a statusbar-menu. I'm using an NSView-object as view for the menuitem, and then subviews the progress indicator to display it. But whenever i try to call the startAnimation: for the progress, nothing happens. When i try do the very same thing on a normal NSWindow it works perfectly, just not when inside a menuitem.

I'm new to both cocoa and objective-c so I might've overlooked something "obvious" but I've searched quite a bit for a workaround but without success. I found something about menuitems cant be updated while shown and that you need to use a bordeless window instead. But I have not been able to confirm this in any documentation.

Edit:

Ok, almost works now. When using the setUsesThreadedAnimation: and from a MenuDelegate's menuWillOpen and creating a new thread. This thread runs a local method:

-(void) doWork(NSProgressIndicator*) p{
     [p startAnimation:self];
}

This will start the progressindicator on a random(?) basis when opening the menu. If I call startAnimation: directly without going through doWork: (still using a new thread), it never works. Doesn't setUsesThreadedAnimation: make the progress-bar create it's own thread for the animation?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

以为你会在 2024-10-18 12:29:39

通过使用以下方法解决了这个问题:

[progressIndicator performSelector:@selector(startAnimation:)
                            withObject:self
                            afterDelay:0.0
                               inModes:[NSArray 
                       arrayWithObject:NSEventTrackingRunLoopMode]];

在 menuWillOpen: 内部,问题似乎是在进度条完成绘制之前调用 startAnimation: 。

Solved it by using:

[progressIndicator performSelector:@selector(startAnimation:)
                            withObject:self
                            afterDelay:0.0
                               inModes:[NSArray 
                       arrayWithObject:NSEventTrackingRunLoopMode]];

Inside the menuWillOpen:, the problem seems to have been calling startAnimation: before the progressbar was finished drawing itself.

梦里兽 2024-10-18 12:29:39

您如何引用视图中的 NSProgressIndicator(以及窗口中的 NSProgressIndicator)?例如,您是否有一个将 IBOutlet 连接到进度指示器的控制器类?如果您使用的是 IBOutlet,您确定它已正确连接到 nib 文件中吗?

另外,您在何时何地调用 startAnimation:? (我们需要看一些代码)。

有时可能发生的一件事是您忘记在笔尖中连接 IBOutlet。然后,当您尝试告诉对象在运行时在代码中执行某些操作时,IBOutletnil,因此您认为发送到对象的消息是事实上,一条消息被发送到nil。换句话说,它只是被忽略了,实际上看起来好像不起作用。

如果您确实拥有对 UI 对象的(可能)有效引用,那么您会看到的另一个常见问题是开发人员尝试“过早”向该对象发送消息时。一般来说,init 方法在控制器对象的生命周期中还为时过早,无法向用户界面对象发送消息 - 那些 IBOutlet 仍然是 nil.当 -awakeFromNib 被调用时,IBOutlet 应该是有效的(假设您将它们连接到 IB 中),然后您可以将消息发送到 UI 对象。

How are you referencing the NSProgressIndicator that is in the view (and the one in the window, for that matter)? For example, do you have a controller class that has IBOutlet's hooked up to the progress indicators? If you are using an IBOutlet, are you sure it's hooked up properly in the nib file?

Also, where and when are you calling startAnimation:? (We need to see some code).

One thing that can sometimes happen is that you forget to hook up an IBOutlet in the nib. Then, when you attempt to tell the object to do something in code at runtime, the IBOutlet is nil, and so what you think is a message being sent to your object is in fact, a message being sent to nil. In other words, it's just ignored, and effectively looks like it's not working.

Provided you do have a (potentially) valid reference to the UI object, the other common issue you'll see is when a developer is trying to send a message to the object at "too early" of a time. In general, init methods are too early in the controller object's lifetime to be able to send messages to user interface objects—those IBOutlet's are still nil. By the time -awakeFromNib is called, IBOutlet's should be valid (provided you hooked them up in IB) and you can then send the message to the UI object.

两个我 2024-10-18 12:29:39

您是否通过 -setUsesThreadedAnimation: 告诉它使用线程动画?

Have you told it to use threaded animation via -setUsesThreadedAnimation:?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文