Paepoi

Paepoi » PyObjC Tips » NSTextField

NSTextField

最終更新日 2019.05.12

Label と Entry
AppKit に NSLabel みたいなラベル専用ウイジェットはありません。
ラベルと一行エディットはすべて NSTextField でまかないます。

initWithFrame を使いサイズ指定で作る他に labelWithString 等も使えます。
こちらだと文字列サイズピッタリの大きさで作成されるようです。

#!/usr/bin/env python3

from AppKit import *

RECT = ((0, 0), (220, 220))
wins = []

class MyView(NSView):
    def initWithFrame_(self, rect):
        objc.super(MyView, self).initWithFrame_(rect)
        # 通常の NSControl として
        tf0 = NSTextField.alloc().initWithFrame_(NSMakeRect(10, 10, 200, 25))
        tf0.setDrawsBackground_(False)
        tf0.setEditable_(False)
        tf0.setSelectable_(False)
        tf0.setStringValue_('initWithFrame')
        tf0.setAlignment_(NSTextAlignmentCenter)
        self.addSubview_(tf0)
        # 普通のラベル (GtkLabel)
        tf1 = NSTextField.labelWithString_('labelWithString')
        tf1.setFrameOrigin_((10, 40))
        self.addSubview_(tf1)
        # 選択可能なラベル
        tf2 = NSTextField.wrappingLabelWithString_('wrappingLabelWithString')
        tf2.setFrameOrigin_((10, 70))
        self.addSubview_(tf2)
        # 装飾付き
        bg_color = NSColor.colorWithSRGBRed_green_blue_alpha_(0.4, 1.0, 1.0, 0.5)
        astr = NSAttributedString.alloc().initWithString_attributes_(
            'labelWithAttributedString',
            {
                NSForegroundColorAttributeName: NSColor.redColor(),
                NSBackgroundColorAttributeName: bg_color
            })
        tf3 = NSTextField.labelWithAttributedString_(astr)
        tf3.setFrameOrigin_((10, 100))
        self.addSubview_(tf3)
        # 書き換え可能 (GtkEntry)
        tf4 = NSTextField.textFieldWithString_('textFieldWithString')
        tf4.setFrame_(((10, 130), (200, 25)))
        self.addSubview_(tf4)
        # 文字が表示されないアレ
        tf5 = NSSecureTextField.textFieldWithString_('password')
        tf5.setFrame_(((10, 160), (200, 25)))
        self.addSubview_(tf5)
        # 検索
        tf6 = NSSearchField.alloc().initWithFrame_(((10, 190), (200, 25)))
        tf6.setPlaceholderString_('検索')
        self.addSubview_(tf6)
        #
        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_('NSTextField')
        self.setDelegate_(self)
        # ButtonView
        self._view = MyView.alloc().initWithFrame_(RECT)
        self.contentView().addSubview_(self._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()

img/nslabel.png

文字列変更メッセージ
TextField 文字列変更の監視は textDidChange をオーバーライドします。
親 View や Window のメソッドにアクセスするには下記のようにします。
#!/usr/bin/env python3

'''
    変更すると同じ文字列を下とタイトルバーにコピーするサンプル
'''

from AppKit import *

RECT = ((0, 0), (220, 100))
wins = []

class MyEdit(NSTextField):
    def textDidChange_(self, notification):
        # NSText なので string property から
        s = notification.object().string()
        # superview Property で親 View にアクセス
        self.superview().setString_(s)
        # window Property で親 Window にアクセス
        self.window().setTitle_(s)

class MyView(NSView):
    def initWithFrame_(self, rect):
        objc.super(MyView, self).initWithFrame_(rect)
        # 書き換え可能 (GtkEntry)
        tf = MyEdit.textFieldWithString_('')
        tf.setFrame_(((10, 10), (200, 25)))
        self.addSubview_(tf)
        # 普通のラベル (GtkLabel)
        self.tf1 = NSTextField.labelWithString_('labelWithString')
        self.tf1.setFrameOrigin_((10, 40))
        self.addSubview_(self.tf1)
        #
        return self

    def setString_(self, s):
        # 最初の長さ以上にはならない
        self.tf1.setStringValue_(s)

    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_('NSTextField')
        self.setDelegate_(self)
        # ButtonView
        self._view = MyView.alloc().initWithFrame_(RECT)
        self.contentView().addSubview_(self._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()

img/nstextfield.png

Copyright(C) sasakima-nao All rights reserved 2002 --- 2020.