Paepoi » PyObjC Tips » その他 NSControl
その他 NSControl
最終更新日 2019.05.19
個別ページを作るまでもないものを。
NSTextField のサブクラスなので NSTextField のメソッドも利用できます。
文字列の選択に特化しているようです。

又内部の NSMenu にアクセスできますので画像付きのポップアップも利用できます。
未選択状態は用意されていないので必要な場合は自分で作る必要があります。



個別ページを作るまでもないものを。
NSComboBox
右にある逆三角形をタップするとプルダウンして選択できます。NSTextField のサブクラスなので NSTextField のメソッドも利用できます。
文字列の選択に特化しているようです。
#!/usr/bin/env python3 from AppKit import * RECT = ((0, 0), (220, 100)) wins = [] items = ['白襟', '襟カバー', '巨大な襟', '中パー'] class MyView(NSView): def initWithFrame_(self, rect): objc.super(MyView, self).initWithFrame_(rect) # # NSComboBox @ NSTextField のサブクラス # 高さを厳密にしないとズレて表示されるのでこんな感じに # self.cbox = 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(NSWindow): def init(self): objc.super(MyWindow, self).initWithContentRect_styleMask_backing_defer_( RECT, NSTitledWindowMask | NSClosableWindowMask | NSResizableWindowMask | NSMiniaturizableWindowMask, NSBackingStoreBuffered, False) self.center() self.setTitle_('NSComboBox') self.setDelegate_(self) # View self._view = MyView.alloc().initWithFrame_(RECT) self.contentView().addSubview_(self._view) # return self def windowWillClose_(self, sender): # # 終了時に値を書き出し # 何も選択していない場合は -1 になる # num = self._view.cbox.indexOfSelectedItem() if num > -1: print(f'貴方は{items[num]}が好き') # 下記でもいい #print(f'貴方は{self._view.cbox.objectValueOfSelectedItem()}が好き') 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()

NSPopUpButton
NSCombobox と同様ですがこちらはどの部分をタップしてもプルダウンできます。又内部の NSMenu にアクセスできますので画像付きのポップアップも利用できます。
未選択状態は用意されていないので必要な場合は自分で作る必要があります。
#!/usr/bin/env python3 from AppKit import * RECT = ((0, 0), (220, 100)) wins = [] items = ['Apache の', 'アイコンを', '勝手に使って', 'ごめんなチャイ'] class MyView(NSView): def initWithFrame_(self, rect): objc.super(MyView, self).initWithFrame_(rect) # # NSPopUpButton @ NSButton のサブクラス # autoenablesItems プロパティを True にしないと変化しない # self.pbtn = 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 = 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(NSWindow): def init(self): objc.super(MyWindow, self).initWithContentRect_styleMask_backing_defer_( RECT, NSTitledWindowMask | NSClosableWindowMask | NSResizableWindowMask | NSMiniaturizableWindowMask, NSBackingStoreBuffered, False) self.center() self.setTitle_('NSPopUpButton') self.setDelegate_(self) # View self._view = MyView.alloc().initWithFrame_(RECT) self.contentView().addSubview_(self._view) # return self def windowWillClose_(self, sender): # 終了時に値を書き出し print(self._view.pbtn.title()) # index ならこう得る #num = self._view.pbtn.indexOfSelectedItem() 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()

NSSlider
NSSlider は名前のとおりスライダーです。#!/usr/bin/env python3 from AppKit import * RECT = ((0, 0), (220, 100)) wins = [] class MyView(NSView): def initWithFrame_(self, rect): objc.super(MyView, self).initWithFrame_(rect) # # 普通に作る、初期値は 0.0〜1.0 # slider1 = NSSlider.sliderWithTarget_action_(self, 'onSlide1:') slider1.setFrameOrigin_((10, 10)) self.addSubview_(slider1) #slider1.setSliderType_(NSSliderTypeCircular) # 使いづらい # # カスタマイズ版、メソッド名で何を指定しているか解るはず # ちなみに整数で指定しても勝手に float と解釈してくれる # slider2 = 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 = 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(NSWindow): def init(self): objc.super(MyWindow, self).initWithContentRect_styleMask_backing_defer_( RECT, NSTitledWindowMask | NSClosableWindowMask | NSResizableWindowMask | NSMiniaturizableWindowMask, NSBackingStoreBuffered, False) self.center() self.setTitle_('NSSlider') #self.setDelegate_(self) # View self._view = MyView.alloc().initWithFrame_(RECT) self.contentView().addSubview_(self._view) # return self 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()

NSSegmentedControl
NSSegmentedControl はボタンのグループ化を超簡単に実現してくれます。#!/usr/bin/env python3 from AppKit import * RECT = ((0, 0), (300, 100)) wins = [] buttons = ['ボタンの', 'グループ化は', '簡単', 'です'] class MyView(NSView): def initWithFrame_(self, rect): objc.super(MyView, self).initWithFrame_(rect) # # システム環境設定のディスプレイとかで使われているアレ # sc = NSSegmentedControl.segmentedControlWithLabels_trackingMode_target_action_( buttons, NSSegmentSwitchTrackingSelectOne, self, 'onSeg:') # インデックスで選択を指定 sc.setSelectedSegment_(1) sc.setFrameOrigin_((10, 10)) self.addSubview_(sc) # return self def onSeg_(self, sender): # 選択を変更するとココに来る print(sender.selectedSegment()) #print(sender.intValue()) 実はコレと同じ 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_('NSSegmentedControl') #self.setDelegate_(self) # View self._view = MyView.alloc().initWithFrame_(RECT) self.contentView().addSubview_(self._view) # return self 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 --- 2023.