Я хочу поместить анимированный индикатор выполнения в NSMenuItem
пользовательский вид.Это продемонстрировано в примере Apple MenuItemView , но он не анимируется (по крайней мере, не в 10.5, а в примере, очевидно, из 10.4).
Я попытался установить таймер, который вызываетsetNeedsDisplay:YES
, запланировано как NSEventTrackingRunLoopMode
, как говорят документы.Это работает, но только для определенного индикатора выполнения, если я изменяю значение, и только при первом открытии меню.Второй и последующие разы бар перерисовывается дважды, а затем остается замороженным.Для неопределенного индикатора выполнения полосы парикмахера никогда не оживляют.
Изменить: фрагмент кода.Я просто добавил вызов itemChanged
, который, похоже, не дал никакого эффекта.Обновление только текстового элемента работает нормально.
class AppDelegate(NSObject):
barItem = None
menuProgressBar = None
progressItem = None
def applicationDidFinishLaunching_(self, sender):
statusbar = NSStatusBar.systemStatusBar()
self.statusitem = statusbar.statusItemWithLength_(
NSSquareStatusItemLength)
self.statusitem.setHighlightMode_(True)
image = NSImage.imageNamed_("menubar.png")
self.statusitem.setImage_(image)
self.statusitem.retain()
menu = NSMenu.alloc().init()
AppDelegate.barItem = NSMenuItem.alloc(). \
initWithTitle_action_keyEquivalent_('progress', None, '')
itemView = NSView.alloc().initWithFrame_(NSMakeRect(0, 0, 50, 20))
itemView.setAutoresizingMask_(NSViewWidthSizable)
AppDelegate.menuProgressBar = \
NSProgressIndicator.alloc().initWithFrame_(NSMakeRect(16, 5, 22, 10))
AppDelegate.menuProgressBar.setAutoresizingMask_(NSViewWidthSizable)
AppDelegate.menuProgressBar.setControlSize_(NSSmallControlSize)
AppDelegate.menuProgressBar.setUsesThreadedAnimation_(True)
itemView.addSubview_(AppDelegate.menuProgressBar)
AppDelegate.menuProgressBar.setIndeterminate_(False)
AppDelegate.menuProgressBar.setMaxValue_(100)
AppDelegate.menuProgressBar.startAnimation_(self)
timer = NSTimer.timerWithTimeInterval_target_selector_userInfo_repeats_(
0.1, self,
objc.selector(self.animateProgress, signature='v@:'),
None, True)
NSRunLoop.currentRunLoop().addTimer_forMode_(
timer, NSEventTrackingRunLoopMode)
AppDelegate.barItem.setView_(itemView)
menu.addItem_(AppDelegate.barItem)
AppDelegate.progressItem = NSMenuItem.alloc(). \
initWithTitle_action_keyEquivalent_('Progress', None, '')
menu.addItem_(AppDelegate.progressItem)
self.statusitem.setMenu_(menu)
def animateProgress(self):
time = NSDate.timeIntervalSinceReferenceDate()
AppDelegate.menuProgressBar.setDoubleValue_(time%100)
AppDelegate.menuProgressBar.display()
AppDelegate.progressItem.setTitle_('Progress: %d'%(time%100))
AppDelegate.barItem.menu().itemChanged_(AppDelegate.barItem)