Paepoi » PyObjC Tips » NSView
NSView
最終更新日 2024.08.25
単体で使う場合は主に線や図形、又は画像の描写を行う場合に利用します。
ところで、AppKit の API はものすごく古臭いです。
レイアウタはありません、絶対位置と絶対サイズで配置する必要がある。
文字列のはみ出しに注意したり NSWindow のリサイズに合わせたりする必要がある。
NSWindow の contentView プロパティは NSView ですが配置しかできません。
この contentView に subView として NSView を配置していく。
nib を使う場合は NSViewController を使ってロードします。
ここでは使わないので直接配置しています。
グラフィック(デバイス)コンテキストの指定がありません。
AppKit での描写はフォーカスをロックして描写という流れなので不要なだけです。
そんなこんなで色々描写してみます。
だって普通画像を使うよね。

CGContext というものがあるので他の API を知っているなら解りやすいかも。
プリフィクスが長くなるので as を使って省略するといいでしょう。
NSView 概要
NSView は配置や描写を行う基底クラスです。単体で使う場合は主に線や図形、又は画像の描写を行う場合に利用します。
ところで、AppKit の API はものすごく古臭いです。
レイアウタはありません、絶対位置と絶対サイズで配置する必要がある。
文字列のはみ出しに注意したり NSWindow のリサイズに合わせたりする必要がある。
NSWindow の contentView プロパティは NSView ですが配置しかできません。
この contentView に subView として NSView を配置していく。
nib を使う場合は NSViewController を使ってロードします。
ここでは使わないので直接配置しています。
drawRect
drawRect というハンドラで描写しますが、他の API と何か違いますよね。グラフィック(デバイス)コンテキストの指定がありません。
AppKit での描写はフォーカスをロックして描写という流れなので不要なだけです。
そんなこんなで色々描写してみます。
#!/usr/bin/env python3
import AppKit, objc
PIC = 'umejiro3.jpg' # 手持ち画像に書き換えしてください
class MyView(AppKit.NSView):
def initWithFrame_(self, rect):
objc.super(MyView, self).initWithFrame_(rect)
return self
def drawRect_(self, rect):
# 背景の塗りつぶし
AppKit.NSColor.brownColor().set()
AppKit.NSRectFill(rect)
# 背景から 5px オフセットして枠っぽく画像
rect_img = AppKit.NSInsetRect(rect, 5, 5)
image = AppKit.NSImage.alloc().initWithContentsOfFile_(PIC)
image.drawInRect_(rect_img)
# 線
AppKit.NSColor.whiteColor().set()
path = AppKit.NSBezierPath.bezierPath()
path.setLineWidth_(10)
path.moveToPoint_((50, 100))
path.lineToPoint_((200, 200))
path.stroke()
# 文字列
bg_color = AppKit.NSColor.colorWithSRGBRed_green_blue_alpha_(0.4, 1.0, 1.0, 0.5)
text = AppKit.NSAttributedString.alloc().initWithString_attributes_(
'ウメジロー',
{
AppKit.NSForegroundColorAttributeName: AppKit.NSColor.whiteColor(),
AppKit.NSBackgroundColorAttributeName: bg_color
})
AppKit.NSColor.blueColor().set()
text.drawAtPoint_((15, 15))
#def isFlipped(self):
# # 描写原点は左下です、コレを有効にすると左上が原点になる
# return True
class MyWindow(AppKit.NSWindow):
def init(self):
rect = AppKit.NSMakeRect(0, 0, 320, 240)
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_('ウメジロー')
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()
図形は省いた。だって普通画像を使うよね。

CoreGraphics を使う
PyObjC からでも CoreGraphics を直接使えます、C 言語と同じだから面倒だけど。CGContext というものがあるので他の API を知っているなら解りやすいかも。
プリフィクスが長くなるので as を使って省略するといいでしょう。
import AppKit, objc
from Quartz import CoreGraphics as cg
class MyView(AppKit.NSView):
def initWithFrame_(self, rect):
objc.super(MyView, self).initWithFrame_(rect)
return self
def drawRect_(self, rect):
# CoreGraphics 直描写
ctx = cg.NSGraphicsContext.currentContext().CGContext()
# 背景の塗りつぶし
rgb = cg.CGColorCreateGenericRGB(0.5, 1.0, 0.7, 1)
cg.CGContextSetFillColorWithColor(ctx, rgb)
cg.CGContextFillRect(ctx, rect)
# moveto, lineto
cg.CGContextSetRGBStrokeColor(ctx, 1.0, 0, 0, 1)
cg.CGContextSetLineWidth(ctx, 10)
cg.CGContextMoveToPoint(ctx, 100.0, 100.0)
cg.CGContextAddLineToPoint(ctx, 200, 200)
# まとめることもできる
cg.CGContextAddLines(ctx, [(50, 100), (50, 200)], 2)
# 描写
cg.CGContextDrawPath(ctx, cg.kCGPathStroke)
Copyright(C) sasakima-nao All rights reserved 2002 --- 2025.