Paepoi » PyObjC Tips » NSButton
NSButton
最終更新日 2024.08.25
どんなスタイルがあるのかは作って確認したほうが早いので以下に。
どんなタイプがあるか、やはり作って確認したほうが早いので以下に。
NSMatrix と組み合わせて使います、以下サンプル。
ボタンスタイル
スタイル指定でどんな形のボタンになるかを決定します。どんなスタイルがあるのかは作って確認したほうが早いので以下に。
#!/usr/bin/env python3 # 左上基準のほうが配置が楽なので継承した NSView の上に置いています # title プロパティには 'Button' という文字列が最初から入っています import AppKit, objc STYLES = dict( Rounded = AppKit.NSBezelStyleRounded, #1 RegularSquare = AppKit.NSBezelStyleRegularSquare, #2 ShadowlessSquare = AppKit.NSBezelStyleShadowlessSquare, #6 TexturedSquare = AppKit.NSBezelStyleTexturedSquare, #8 SmallSquare = AppKit.NSBezelStyleSmallSquare, #10 TexturedRounded = AppKit.NSBezelStyleTexturedRounded, #11 RoundRect = AppKit.NSBezelStyleRoundRect, #12 Recessed = AppKit.NSBezelStyleRecessed, #13 Inline = AppKit.NSBezelStyleInline #15 ) IMGSTYLES = [ AppKit.NSBezelStyleDisclosure, #5 AppKit.NSBezelStyleCircular, #7 AppKit.NSBezelStyleHelpButton, #9 AppKit.NSBezelStyleRoundedDisclosure, #14 ] class ButtonView(AppKit.NSView): def initWithFrame_(self, rect): objc.super(ButtonView, self).initWithFrame_(rect) # y = 10 for key, style in STYLES.items(): button = AppKit.NSButton.alloc().initWithFrame_(((10, y), (200, 36))) button.setTitle_(key) button.setBezelStyle_(style) self.addSubview_(button) y += 40 for style in IMGSTYLES: button = AppKit.NSButton.alloc().initWithFrame_(((10, y), (200, 36))) button.setTitle_('') # Button という文字列が最初に入っているので消す button.setBezelStyle_(style) self.addSubview_(button) y += 40 # return self def isFlipped(self): # 左上を原点にする return True class MyWindow(AppKit.NSWindow): def init(self): rect = AppKit.NSMakeRect(0, 0, 220, 550) objc.super(MyWindow, self).initWithContentRect_styleMask_backing_defer_( rect, AppKit.NSTitledWindowMask | AppKit.NSClosableWindowMask | AppKit.NSResizableWindowMask | AppKit.NSMiniaturizableWindowMask, AppKit.NSBackingStoreBuffered, False) # NSView self.canvas = ButtonView.alloc().initWithFrame_(rect) self.contentView().addSubview_(self.canvas) # etc self.setTitle_('NSButton Styles') self.setDelegate_(self) return self def windowDidResize_(self, sender): # GTK+ や WPF のように追従してくれないので self.canvas.setFrameSize_(self.contentView().frame().size) class AppDelegate(AppKit.NSObject): wins = [] def applicationDidFinishLaunching_(self, notification): window = MyWindow.new() window.makeKeyAndOrderFront_(window) self.wins.append(window) AppKit.NSApp.activateIgnoringOtherApps_(True) def applicationSupportsSecureRestorableState_(self, app): return True class AppMenu(AppKit.NSMenu): def init(self): objc.super(AppMenu, self).init() item_app = AppKit.NSMenuItem.new() self.addItem_(item_app) menu_app = AppKit.NSMenu.new() item_app.setSubmenu_(menu_app) # quit menu item_quit = AppKit.NSMenuItem.new() item_quit.initWithTitle_action_keyEquivalent_('Quit App', 'terminate:', 'q') menu_app.addItem_(item_quit) return self AppKit.NSApplication.sharedApplication() AppKit.NSApp.setMainMenu_(AppMenu.new()) AppKit.NSApp.setDelegate_(AppDelegate.new()) AppKit.NSApp.run()
ボタンタイプ
ON|OFF ボタンやラジオボタンもすべて NSButton の type で指定して作ります。どんなタイプがあるか、やはり作って確認したほうが早いので以下に。
#!/usr/bin/env python3 import AppKit, objc STYLES = dict( # 普通のボタン、違いはわからない(昔は違いがあった?) MomentaryLight = AppKit.NSButtonTypeMomentaryLight, #0 MomentaryPushIn = AppKit.NSButtonTypeMomentaryPushIn, #7 # 押す毎に ON|OFF を切り替え、GtkToggleButton と同じ、違いはわからない PushOnPushOff = AppKit.NSButtonTypePushOnPushOff, #1 OnOff = AppKit.NSButtonTypeOnOff, #6 # ON 状態の時に違うテキストをタイトルにしたい場合に、GtkToggleButton とは違う Toggle = AppKit.NSButtonTypeToggle, #2 # GTK+ でいう GtkCheckButton、紛らわしい Switch = AppKit.NSButtonTypeSwitch, #3 # ラジオボタン、NSMatrix と組み合わせで使う Radio = AppKit.NSButtonTypeRadio, #4 # ON 状態の時に違う画像をタイトルにしたい場合 MomentaryChange = AppKit.NSButtonTypeMomentaryChange, #5 # 感圧トラックパッドの圧力を得る時に使う Accelerator = AppKit.NSButtonTypeAccelerator, #8 MultiLevelAccelerator = AppKit.NSButtonTypeMultiLevelAccelerator #9 ) class ButtonView(AppKit.NSView): def initWithFrame_(self, rect): objc.super(ButtonView, self).initWithFrame_(rect) # y = 10 for key, button_type in STYLES.items(): # メッセージハンドラは self のメソッドにする、コロンとアンダーバーに注意 button = AppKit.NSButton.buttonWithTitle_target_action_(key, self, 'onButtonClick:') button.setFrame_(((10, y), (200, 36))) button.setBezelStyle_(AppKit.NSBezelStyleRounded) button.setButtonType_(button_type) # 代替タイトル、Toggle 指定の時だけ切り替わる button.setAlternateTitle_('ON!!!') # 代替画像、MomentaryChange 指定の時だけ入れ替わる #button.setAlternateImage_(image) self.addSubview_(button) y += 40 # return self def onButtonClick_(self, sender): # ボタンクリックのハンドラ if sender.state() == AppKit.NSControlStateValueOn: print(sender.title()) # 感圧トラックパッドで Accelerator ボタン押し込み時のみ反応する tp = sender.doubleValue() if 1.0 < tp: print(tp) def isFlipped(self): # 左上を原点にする return True class MyWindow(AppKit.NSWindow): def init(self): rect = AppKit.NSMakeRect(0, 0, 220, 420) objc.super(MyWindow, self).initWithContentRect_styleMask_backing_defer_( rect, AppKit.NSTitledWindowMask | AppKit.NSClosableWindowMask | AppKit.NSResizableWindowMask | AppKit.NSMiniaturizableWindowMask, AppKit.NSBackingStoreBuffered, False) # NSView self.canvas = ButtonView.alloc().initWithFrame_(rect) self.contentView().addSubview_(self.canvas) # etc self.setTitle_('NSButton Types') self.setDelegate_(self) return self def windowDidResize_(self, sender): # GTK+ や WPF のように追従してくれないので self.canvas.setFrameSize_(self.contentView().frame().size) class AppDelegate(AppKit.NSObject): wins = [] def applicationDidFinishLaunching_(self, notification): window = MyWindow.new() window.makeKeyAndOrderFront_(window) self.wins.append(window) AppKit.NSApp.activateIgnoringOtherApps_(True) def applicationSupportsSecureRestorableState_(self, app): return True class AppMenu(AppKit.NSMenu): def init(self): objc.super(AppMenu, self).init() item_app = AppKit.NSMenuItem.new() self.addItem_(item_app) menu_app = AppKit.NSMenu.new() item_app.setSubmenu_(menu_app) # quit menu item_quit = AppKit.NSMenuItem.new() item_quit.initWithTitle_action_keyEquivalent_('Quit App', 'terminate:', 'q') menu_app.addItem_(item_quit) return self AppKit.NSApplication.sharedApplication() AppKit.NSApp.setMainMenu_(AppMenu.new()) AppKit.NSApp.setDelegate_(AppDelegate.new()) AppKit.NSApp.run()
ラジオボタン (NSMatrix)
ラジオボタンは複数の選択肢から一つを選択させるのに利用します。NSMatrix と組み合わせて使います、以下サンプル。
#!/usr/bin/env python3 import AppKit, objc CAMERAS = ['OM SYSTEM', 'Leica', 'NIKON', 'FUJIFILM'] class ButtonView(AppKit.NSView): def initWithFrame_(self, rect): objc.super(ButtonView, self).initWithFrame_(rect) # # Radio Buttons # # セルを作る cell = AppKit.NSButtonCell.new() cell.setButtonType_(AppKit.NSButtonTypeRadio) # 全体サイズでマトリクス作成 self.matrix = AppKit.NSMatrix.alloc().initWithFrame_mode_prototype_numberOfRows_numberOfColumns_( ((10, 10), (200, 20*4)), AppKit.NSRadioModeMatrix, cell, 4, 1) for n, camera in enumerate(CAMERAS): self.matrix.setCellSize_((200, 20)) self.matrix.cells()[n].setTitle_(camera) # 選択は setState 引数にゼロ以外を指定 self.matrix.setState_atRow_column_(1, 2, 0) self.addSubview_(self.matrix) # return self def isFlipped(self): # 左上を原点にする return True class MyWindow(AppKit.NSWindow): def init(self): rect = AppKit.NSMakeRect(0, 0, 220, 200) objc.super(MyWindow, self).initWithContentRect_styleMask_backing_defer_( rect, AppKit.NSTitledWindowMask | AppKit.NSClosableWindowMask | AppKit.NSResizableWindowMask | AppKit.NSMiniaturizableWindowMask, AppKit.NSBackingStoreBuffered, False) # NSView self.canvas = ButtonView.alloc().initWithFrame_(rect) self.contentView().addSubview_(self.canvas) # etc self.setTitle_('NSButton Matrix') self.setDelegate_(self) return self def windowDidResize_(self, sender): # GTK+ や WPF のように追従してくれないので self.canvas.setFrameSize_(self.contentView().frame().size) def windowWillClose_(self, sender): # 選択値はゼロベースで得る row = self.canvas.matrix.selectedRow() print(f'選択されたのは {CAMERAS[row]} です') class AppDelegate(AppKit.NSObject): wins = [] def applicationDidFinishLaunching_(self, notification): window = MyWindow.new() window.makeKeyAndOrderFront_(window) self.wins.append(window) AppKit.NSApp.activateIgnoringOtherApps_(True) def applicationSupportsSecureRestorableState_(self, app): return True class AppMenu(AppKit.NSMenu): def init(self): objc.super(AppMenu, self).init() item_app = AppKit.NSMenuItem.new() self.addItem_(item_app) menu_app = AppKit.NSMenu.new() item_app.setSubmenu_(menu_app) # quit menu item_quit = AppKit.NSMenuItem.new() item_quit.initWithTitle_action_keyEquivalent_('Quit App', 'terminate:', 'q') menu_app.addItem_(item_quit) return self AppKit.NSApplication.sharedApplication() AppKit.NSApp.setMainMenu_(AppMenu.new()) AppKit.NSApp.setDelegate_(AppDelegate.new()) AppKit.NSApp.run()
Copyright(C) sasakima-nao All rights reserved 2002 --- 2024.