Paepoi » PyObjC Tips » その他 NSControl
その他 NSControl
最終更新日 2024.08.25
個別ページを作るまでもないものを。
NSTextField のサブクラスなので NSTextField のメソッドも利用できます。
文字列の選択に特化しているようです。
又内部の NSMenu にアクセスできますので画像付きのポップアップも利用できます。
未選択状態は用意されていないので必要な場合は自分で作る必要があります。
個別ページを作るまでもないものを。
NSComboBox
右にある逆三角形をタップするとプルダウンして選択できます。NSTextField のサブクラスなので NSTextField のメソッドも利用できます。
文字列の選択に特化しているようです。
#!/usr/bin/env python3 import AppKit, objc items = [ 'やっぱり超望遠で野鳥でしょ', 'GoPro を固定してツーリング動画', '電車だよ、わかんねえかなぁ', '靴に付いたカメラで空を見上げたい' ] class MyView(AppKit.NSView): def initWithFrame_(self, rect): objc.super(MyView, self).initWithFrame_(rect) # # NSComboBox @ NSTextField のサブクラス # 高さを厳密にしないとズレて表示されるのでこんな感じに # self.cbox = AppKit.NSComboBox.labelWithString_('何が撮りたい?') h = self.cbox.frameSize()[1] self.cbox.setFrame_(((10, 10), (200, h))) self.cbox.addItemsWithObjectValues_(items) self.addSubview_(self.cbox) # return self def isFlipped(self): # 左上を原点にする return True class MyWindow(AppKit.NSWindow): def init(self): rect = AppKit.NSMakeRect(0, 0, 220, 100) objc.super(MyWindow, self).initWithContentRect_styleMask_backing_defer_( rect, AppKit.NSTitledWindowMask | AppKit.NSClosableWindowMask | AppKit.NSResizableWindowMask | AppKit.NSMiniaturizableWindowMask, AppKit.NSBackingStoreBuffered, False) # NSView self.canvas = MyView.alloc().initWithFrame_(rect) self.contentView().addSubview_(self.canvas) # etc self.setTitle_('Sample') self.setDelegate_(self) return self def windowWillClose_(self, sender): ''' 終了時に値を書き出し 何も選択していない場合は -1 になる ''' num = self.canvas.cbox.indexOfSelectedItem() if num > -1: print(self.canvas.cbox.objectValueOfSelectedItem()) 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()) NSApp.run()
NSPopUpButton
NSCombobox と同様ですがこちらはどの部分をタップしてもプルダウンできます。又内部の NSMenu にアクセスできますので画像付きのポップアップも利用できます。
未選択状態は用意されていないので必要な場合は自分で作る必要があります。
#!/usr/bin/env python3 import AppKit, objc items = ['Apache の', 'アイコンを', '勝手に使って', 'ごめんなチャイ'] class MyView(AppKit.NSView): def initWithFrame_(self, rect): objc.super(MyView, self).initWithFrame_(rect) # # NSPopUpButton @ NSButton のサブクラス # autoenablesItems プロパティを True にしないと変化しない # self.pbtn = AppKit.NSPopUpButton.alloc().initWithFrame_pullsDown_(((10, 10), (200, 40)), False) self.pbtn.addItemsWithTitles_(items) self.pbtn.setAutoenablesItems_(True) self.addSubview_(self.pbtn) # ICON のセット for i, s in enumerate(['a.png', 'c.png', 'f.png', 'p.png']): # apache のアイコンを拝借、皆デフォルトで入っているよね? path = f'/usr/share/httpd/icons/{s}' image = AppKit.NSImage.alloc().initWithContentsOfFile_(path) menu = self.pbtn.itemArray()[i] menu.setImage_(image) # 選択した時にアクションさせる menu.setTarget_(self) menu.setAction_('onSelect:') # return self def onSelect_(self, sender): # 選択を変更するとココに来る print(sender.title()) def isFlipped(self): # 左上を原点にする return True class MyWindow(AppKit.NSWindow): def init(self): rect = AppKit.NSMakeRect(0, 0, 220, 100) objc.super(MyWindow, self).initWithContentRect_styleMask_backing_defer_( rect, AppKit.NSTitledWindowMask | AppKit.NSClosableWindowMask | AppKit.NSResizableWindowMask | AppKit.NSMiniaturizableWindowMask, AppKit.NSBackingStoreBuffered, False) # NSView self.canvas = MyView.alloc().initWithFrame_(rect) self.contentView().addSubview_(self.canvas) # etc self.setTitle_('Sample') return self 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()
NSSlider
NSSlider は名前のとおりスライダーです。#!/usr/bin/env python3 import AppKit, objc class MyView(AppKit.NSView): def initWithFrame_(self, rect): objc.super(MyView, self).initWithFrame_(rect) # # 普通に作る、初期値は 0.0〜1.0 # slider1 = AppKit.NSSlider.sliderWithTarget_action_(self, 'onSlide1:') slider1.setFrameOrigin_((10, 10)) self.addSubview_(slider1) #slider1.setSliderType_(NSSliderTypeCircular) # 使いづらい # # カスタマイズ版、メソッド名で何を指定しているか解るはず # ちなみに整数で指定しても勝手に float と解釈してくれる # slider2 = AppKit.NSSlider.sliderWithValue_minValue_maxValue_target_action_( 120, 80, 200, self, 'onSlide2:') # メモリの表示、線の数を指定 slider2.setNumberOfTickMarks_(7) # メモリ上にしか止まらないように slider2.setAllowsTickMarkValuesOnly_(True) # 配置 slider2.setFrameOrigin_((10, 40)) self.addSubview_(slider2) # # 上記の数値を表示するラベル # self.label = AppKit.NSTextField.labelWithString_('80.0') self.label.setFrameOrigin_((150, 40)) self.addSubview_(self.label) # return self def onSlide1_(self, sender): # 選択を変更するとココに来る print(sender.floatValue()) def onSlide2_(self, sender): # 選択を変更、label を変更 self.label.setStringValue_(f'{sender.floatValue()}') # はみ出さないように self.label.sizeToFit() def isFlipped(self): # 左上を原点にする return True class MyWindow(AppKit.NSWindow): def init(self): rect = AppKit.NSMakeRect(0, 0, 220, 100) objc.super(MyWindow, self).initWithContentRect_styleMask_backing_defer_( rect, AppKit.NSTitledWindowMask | AppKit.NSClosableWindowMask | AppKit.NSResizableWindowMask | AppKit.NSMiniaturizableWindowMask, AppKit.NSBackingStoreBuffered, False) # NSView self.canvas = MyView.alloc().initWithFrame_(rect) self.contentView().addSubview_(self.canvas) # etc self.setTitle_('Sample') return self 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()
NSSegmentedControl
NSSegmentedControl はボタンのグループ化を超簡単に実現してくれます。#!/usr/bin/env python3 import AppKit, objc buttons = ['ボタンの', 'グループ化は', '簡単', 'です'] class MyView(AppKit.NSView): def initWithFrame_(self, rect): objc.super(MyView, self).initWithFrame_(rect) # # システム環境設定のディスプレイとかで使われているアレ # sc = AppKit.NSSegmentedControl.segmentedControlWithLabels_trackingMode_target_action_( buttons, AppKit.NSSegmentSwitchTrackingSelectOne, self, 'onSeg:') # インデックスで選択を指定 sc.setSelectedSegment_(1) sc.setFrameOrigin_((10, 10)) self.addSubview_(sc) # return self def onSeg_(self, sender): # 選択を変更するとココに来る print(sender.selectedSegment()) def isFlipped(self): # 左上を原点にする return True class MyWindow(AppKit.NSWindow): def init(self): rect = AppKit.NSMakeRect(0, 0, 300, 100) objc.super(MyWindow, self).initWithContentRect_styleMask_backing_defer_( rect, AppKit.NSTitledWindowMask | AppKit.NSClosableWindowMask | AppKit.NSResizableWindowMask | AppKit.NSMiniaturizableWindowMask, AppKit.NSBackingStoreBuffered, False) # NSView self.canvas = MyView.alloc().initWithFrame_(rect) self.contentView().addSubview_(self.canvas) # etc self.setTitle_('Sample') return self 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.