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