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

もっと詳しい描写に関しては以下がすごく参考になる。
Cocoa Dev Central: Cocoa Graphics with Quartz
Cocoa Dev Central: Cocoa Graphics with Quartz II
日本人のページはどれもイマイチ、細切ればかり。
CGContext というものがあるので他の API を知っているなら解りやすいかも。
C 言語と同じだから面倒だけど。
NSView 概要
NSView は配置や描写を行う基底クラスです。単体で使う場合は主に線や図形、又は画像の描写を行う場合に利用します。
ところで、AppKit の API はものすごく古臭いです。
レイアウタはありません、絶対位置と絶対サイズで配置する必要がある。
文字列のはみ出しに注意したり NSWindow のリサイズに合わせたりする必要がある。
NSWindow の contentView プロパティは NSView ですが配置しかできません。
この contentView に subView として NSView を配置していく。
nib を使う場合は NSViewController を使ってロードします。
ここでは使わないので直接配置しています。
drawRect
drawRect というハンドラで描写しますが、他の API と何か違いますよね。グラフィック(デバイス)コンテキストの指定がありません。
AppKit での描写はフォーカスをロックして描写という流れなので不要なだけです。
そんなこんなで色々描写してみます。
#!/usr/bin/env python3 from AppKit import * PIC = '五条川.jpg' # 手持ち画像に書き換えしてください RECT = ((0, 0), (320, 240)) wins = [] class MyView(NSView): def initWithFrame_(self, rect): objc.super(MyView, self).initWithFrame_(rect) return self def drawRect_(self, rect): # 背景の塗りつぶし NSColor.darkGrayColor().set() NSRectFill(rect) # 背景から 5px オフセットして枠っぽく NSColor.brownColor().set() rect1 = NSInsetRect(rect, 5, 5) NSRectFill(rect1) # 線 NSColor.whiteColor().set() path = NSBezierPath.bezierPath() path.setLineWidth_(10) path.moveToPoint_((50, 100)) path.lineToPoint_((200, 200)) path.stroke() # 文字列 bg_color = NSColor.colorWithSRGBRed_green_blue_alpha_(0.4, 1.0, 1.0, 0.5) text = NSAttributedString.alloc().initWithString_attributes_( '描写原点は左下です', { NSForegroundColorAttributeName: NSColor.whiteColor(), NSBackgroundColorAttributeName: bg_color }) NSColor.blueColor().set() text.drawAtPoint_((15, 15)) # 画像 image = NSImage.alloc().initWithContentsOfFile_(PIC) image.drawInRect_(((200, 50), (90, 120))) #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_('NSView Test') self.setDelegate_(self) # NSView self.canvas = MyView.alloc().initWithFrame_(RECT) self.contentView().addSubview_(self.canvas) # return self def windowDidResize_(self, sender): # GTK+ や WPF のように追従してくれないので self.canvas.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()図形は省いた。
だって普通画像を使うよね。

もっと詳しい描写に関しては以下がすごく参考になる。
Cocoa Dev Central: Cocoa Graphics with Quartz
Cocoa Dev Central: Cocoa Graphics with Quartz II
日本人のページはどれもイマイチ、細切ればかり。
CoreGraphics を使う
PyObjC からでも CoreGraphics を直接使えます。CGContext というものがあるので他の API を知っているなら解りやすいかも。
C 言語と同じだから面倒だけど。
from AppKit import * from Quartz.CoreGraphics import * # 必須 class MyView(NSView): def initWithFrame_(self, rect): objc.super(MyView, self).initWithFrame_(rect) return self def drawRect_(self, rect): # CoreGraphics 直描写 ctx = NSGraphicsContext.currentContext().CGContext() # 背景の塗りつぶし rgb = CGColorCreateGenericRGB(0.5, 1.0, 0.7, 1) CGContextSetFillColorWithColor(ctx, rgb) CGContextFillRect(ctx, rect) # moveto, lineto CGContextSetRGBStrokeColor(ctx, 1.0, 0, 0, 1) CGContextSetLineWidth(ctx, 10) CGContextMoveToPoint(ctx, 100.0, 100.0) CGContextAddLineToPoint(ctx, 200, 200) # まとめることもできる CGContextAddLines(ctx, [(50, 100), (50, 200)], 2) # 描写 CGContextDrawPath(ctx, kCGPathStroke)
Copyright(C) sasakima-nao All rights reserved 2002 --- 2023.