3年ほどバージョンアップのなかったpythonista3 ですが、先日、ついにバージョンアップがなされ、以下の機能が補強されました。

  • Python 3.10への対応。構造的なパターンマッチング、代入式の使用、その他新機能が使えるようになったほか、標準ライブラリが改善されています。詳細についてはWhat’s New in Python 3.10 を参照。

  • Python 2.7 への非対応化。Python 2.7 ベースのコードについては、レンチアイコンのメニューからバージョン3への変換ツールを呼び出し可能。

  • ショートカット機能への対応:Pythonista のスクリプトを、アプリとしてリリースすることなく、iOS上のショートカットとして動作させる事ができます。詳細は、shortcuts モジュールのドキュメントと  App Extensions and Shortcuts のページを参照して下さい。

  • 最新のテーマについてドキュメントを改善したほか、ダーク・モードに対応。サード・パーティー製のライブラリについてのコンテンツを追加しました。

  • iOS 12 以降に対応

  • iPadOS のマジックトラックパッド(やその他の入力デバイス)に対応

  • iOS 13以降のエディタでは新しいテキスト選択ジェスチャーに対応。(システム標準のテキスト・ジェスチャーに類似)

  • pandas と、その他多くの サードパーティ製モジュール を追加。旧バージョンに含まれていたサードパーティ製のライブラリの多くについて、より新しいバージョンにアップデートしました。

バクの修正:

  • エディタ使用時に上下の矢印ボタンが正しく機能しない問題を解消。

  • 「ドック・アクセサリー・パネル」ボタンが時々消えてしまう問題を解消。

 

twitter — iOS ツイッターアカウントと API アクセス

 注意)不幸なことに、このモジュールは iOS 11 以降では動作しません。基本的な API 群が iOS から削除されてしまったからです。

(日本語訳注 従って、これ以上訳しても活用される見込みもありませんので、このモジュールについてはここまでで翻訳を終了します。)

The twitter module provides access to the system-wide Twitter accounts that you have added in the iOS settings.

Note The first time you use any of the functions that access your Twitter accounts, a system-provided permission dialog will be shown. If you deny access, most functions will return empty data. If you change your mind later, you can allow access to your accounts from the Twitter section in the Settings app.

The central function of this module is request() – with it, you can access all of Twitter’s REST API which is documented in more detail here: Twitter API documentation.

If you just want to post a tweet or retrieve your timeline/mentions, you can also use one of the convenience functions (get_home_timeline(), get_mentions_timeline() or post_tweet()), which all use request() under the hood.

All API request functions require authentication via an account parameter. You can get an account by calling get_all_accounts() or get_account() (the latter allows you to get a specific account by its username).

Quick Start

Retrieving your Timeline

This example shows how to retrieve the 20 most recent tweets in the timeline of your first Twitter account:

import twitter
all_accounts = twitter.get_all_accounts()
if len(all_accounts) >= 1:
    account = all_accounts[0]
    tweets = twitter.get_home_timeline(account)
    for t in tweets:
        print(t.get('text'))
        print('=' * 40)
else:
    print('You don\'t have any Twitter accounts (or haven\'t given permission to access them).')

Using Other APIs

The previous example used a convenience function to access an often-used API without having to know its URL – but you can also access all other Twitter APIs by using the generic request() function, for example to download and show your profile image:

import twitter
import json
import urllib
import Image

all_accounts = twitter.get_all_accounts()
if len(all_accounts) >= 1:
    account = all_accounts[0]
    parameters = {'screen_name': account['username']}
    status, data = twitter.request(account, 'https://api.twitter.com/1.1/users/show.json', 'GET', parameters)
    if status == 200:
        user_info = json.loads(data)
        avatar_url = user_info['profile_image_url']
        # Get the URL for the original size:
        avatar_url = avatar_url.replace('_normal', '')
        filename, headers = urllib.urlretrieve(avatar_url)
        img = Image.open(filename)
        img.show()
    else:
        print('Could not retrieve profile image (status: %i)' % (status,))
else:
    print('You don\'t have any Twitter accounts (or haven\'t given permission to access them).')

For more information about valid URLs, methods, and parameters, please refer to the Twitter API documentation.

Functions

twitter.get_all_accounts()

Return a list of all Twitter accounts. Each account is represented as a dictionary that contains the internal account ID, and your username.

twitter.get_account(username)

Return the account with the given username if it exists, None otherwise.

twitter.request(account, url, method='GET', parameters=None)

Perform a Twitter API request on behalf of the given account. The return value is a tuple of the HTTP status code and the data that was returned (usually in JSON format).

See the Twitter API documentation for details about possible URLs, methods, and parameters.

If you want more control over the networking part, consider using get_request_headers() instead.

twitter.get_request_headers(account, url, method='GET', parameters=None)

Return appropriate authorization headers for performing a Twitter API request. The parameters are the same as for the request() function, but this function does not actually perform the request. You can use the returned dictionary to authorize a Twitter API request with your favorite HTTP library (e.g. requests or urllib).

twitter.get_favorites(account, username=None, count=20, parameters=None)

Return the favorites of the given user. If username is None, it will return the favorites of the given account (i.e. your own).

twitter.get_home_timeline(account, count=20, parameters=None)

Return a list of tweets in the timeline of the given account. In case of an error, None is returned. Each tweet in the list is represented as a dictionary.

twitter.get_mentions_timeline(account, count=20, parameters=None)

Return a list of mentions for the given account. In case of an error, None is returned. Each tweet in the list is represented as a dictionary.

twitter.post_tweet(account, text, parameters=None)

Post a tweet on behalf of the given account/user. If successful, information about the created tweet is returned as a dictionary. Note that the Twitter API doesn’t allow to post the same tweet multiple times.

twitter.search(account, query, count=20, parameters=None)

Perform a search for public tweets that contain the query, and return the list of results. Each tweet in the list is represented as a dictionary. In case of an error, None is returned.

speech — iOS 上のテキスト読上げ

 スピーチモジュールは、iOS 上の音声合成と音声認識の機能を提供します。

 注)音声認識はiOS 10以上でサポートされています。音声データは認識処理のため Apple のサーバーに送信されるため、最初に recognize() 関数を呼び出した際には自動的にシステムからのプライバシーに関する警告が表示されます。

Examples

 異なる言語での音声合成です:

import speech
import time

def finish_speaking():
    # 音声合成が終了するまでアイドリング
    while speech.is_speaking():
        time.sleep(0.1)

# アメリカ英語:
speech.say('Hello World', 'en_US')
finish_speaking()
# スペイン語:
speech.say('Hola mundo', 'es_ES')
finish_speaking()
# ドイツ語:
speech.say('Hallo Welt', 'de_DE')
finish_speaking()
# 日本語:
speech.say('世界よ、こんにちは', 'ja')
finish_speaking()

 マイクロフォンから録音したテキストの音声認識です。(sound.Recorder を使用):

import speech
import sound
import dialogs

# sound.Recorder を使って音声を録音:
recorder = sound.Recorder('speech.m4a')
recorder.record()
# 'Finish'ボタンを押すまで録音を継続:
dialogs.alert('Recording...', '', 'Finish', hide_cancel_button=True)
recorder.stop()
try:
    result = speech.recognize('speech.m4a')
    print('=== Details ===')
    print(result)
    print('=== Transcription ===')
    print(result[0][0])
except RuntimeError as e:
    print('Speech recognition failed: %s' % (e,))

関数

speech.get_synthesis_languages()

 音声合成が可能な、全ての言語/地域を示すタグのリストを返します。say() 関数に使用する、言語を示す引数を設定するのに役立ちます。

speech.get_recognition_languages()

 音声認識が可能な、全ての言語/地域を示すタグのリストを返します。recognize() 関数に使用する、言語を示す引数を設定するのに役立ちます。

speech.say(text[, language, rate])

 引数 text で与えたテキストをシステム組込の読上げ音声により読み上げます。引数 language は、例えば'en-US'(アメリカ英語)のように、BCPー47 形式の言語と地域を示すタグで指定します。引数 language を省略した場合には、システムのデフォルト言語が使用されます。

 引数 rate によりテキストの読上げ速度を指定できます。値の範囲は0.0(最も遅い)〜1.0(最も早い)で、デフォルト値は0.5です。

speech.stop()

 音声合成を終了します。

speech.is_speaking()

 音声合成を行なっている場合には True を、そうでなければ False を返します。

speech.recognize(file_path[, language])

 引数 file_path で指定された音声ファイル中の読み上げられたテキストを文字起こしします。音声ファイルは大体1分よりも長くてはいけません。マイクロフォンからの入力を音声ファイルに録音するには、sound.Recorder を使用することができます。

 引数 language は任意で追加でき、地域の指定も可能(例:‘de-DE‘(ドイツのドイツ語)や'en-US'(アメリカ英語)です。)デフォルトでは現在システムで設定されている言語になります。

 戻り値は転記できた文字のリストで、可能性(信頼性)の高いものから順に並べたものになります。

 結果として得られる転記したリストは2つの要素を含むタプルです:1.ユニコード文字列としてのフルテキスト、2.個々の要素の詳細な情報(例えば、タイムスタンプ、信頼性のレベルなど)のディクショナリー型のリストになります。

 この関数は音声認識が失敗した場合にはランタイムエラーを生じます。引数 language が無効だったりサポート外の場合には、代わりにバリューエラーが発生するほか、音声ファイルが読み込めない場合にはIOエラーが発生します。

sound — 効果音と音楽の再生

 サウンドモジュールは、iOS上で効果音を発生させたり音声ファイルを再生する関数を備えています。

 レコーダークラスを使ってマイクからの入力を音声ファイルに録音する事もできます。

 注)レコーダークラスを使用するためには、マイクへのアクセスを許可する必要があります。最初に Recorder.record() メソッドを使用する際には自動的にシステムが用意した許可ダイアログが表示されます。その際にマイクへのアクセスを許可しなかった場合でも、「設定」アプリの「プライバシー」画面でアクセスを許可することができます。

関数

sound.play_effect(name[, volume, pitch=1.0, pan=0.0, looping=False])

 引数 name で指定した効果音を発生させます。システム組込の効果音の名前のリストにはツールバーの[+]ボタンの「アセットピッカー」を使ってアクセスできます。なお、独自の効果音を使用したい場合には、効果音を保存した音声ファイルのファイルパスを指定することができます。

 再生は非同期で行われます。すなわち、音の再生が完了する前に関数は実行を終えて次のスクリプトの実行に進みます。

 戻り値は sound.Effect オブジェクトで、後で再生の設定調整や再生の途中で効果音を停止するために使うことができます。

 あまりに多くの(通常32音が限界です)効果音が既に再生されている場合、None が返されます。

sound.stop_all_effects()

 現在 play_effect() 経由で再生中の全ての効果音を停止します。

sound.stop_effect(effect)

 引数 effect で指定した効果音の再生を停止します。引数 effect には play_effect() の戻り値を使用します。

sound.set_volume(vol)

 全ての効果音についてデフォルトの音量を設定します。(0.0〜1.0の範囲で、デフォルト値は0.5)このメソッドは、既に再生が開始されている効果音には影響を与えません。

sound.set_honors_silent_switch(flag)

 音の再生中にサイレント(消音)スイッチを適用するか否かを設定します。(デフォルトではTrueです。)

エフェクトのクラス

class sound.Effect

 エフェクトのクラスは現在再生中の効果音を示します。直接的にエフェクトオブジェクトを生成することはできません。play_effect() 関数の戻り値として返されます。単純に一回きりのエフェクトの場合、play_effect() の戻り値は無視して問題ありません。一方で、再生中に音量やピッチなどの属性を調整したり、繰り返す効果を止めたりする際に役に立ちます。

エフェクトのメソッド

Effect.stop()

 効果音の再生を止めます。

エフェクトの属性

Effect.looping

 True に設定すると、Effect.stop() メソッドにより再生を停止するまで、効果音が無限に繰り返されます。

Effect.pan

 効果音のステレオ位置です。(-1=左、+1=右、0=センター)

Effect.pitch

 効果音のピッチ(再生速度)です。デフォルト値は1.0です。

Effect.position

 効果音の空間(3D)位置です。値は3要素タプル(x, y, z) です。この値はステレオ位置の Sound.pan 属性を上書きすることに注意してください。

Effect.volume

 効果音の現在の音量です。

プレイヤーのクラス

class sound.Player(file_path)

 プレイヤークラスは、音楽ファイルを簡便に再生するインターフェイスを提供します。このクラスは音楽やその他遅延を気にしない場合にお勧めします。ゲームの効果音には、play_effect() がより適切です。

プレイヤーのメソッド

Player.play()

 音声ファイルの再生を開始します。

Player.stop()

 音声ファイルの再生を止めて、再生位置をリセットします。

Player.pause()

 音声ファイルの再生を止めますが、現在の再生位置を保存します。 Stop playing audio, but keep the current playback position.

プレイヤーの属性

Player.current_time

 現在の再生位置を秒単位で表します。

Player.duration

 音声ファイルの再生所要時間です。(読取専用)

Player.finished_handler

 プレイヤーが再生を終了する際に引数なしで呼び出される関数/コーラブルです。

Player.number_of_loops

 音声ファイルの繰り返し再生回数です。-1 に設定すると永遠に繰り返します。

Player.playing

 音声ファイルを再生中(True)であるか停止中(False)であるかを示すブール値です。

Player.pan

 再生中の音声のステレオ位置です。(-1=左、+1=右、0=センター)

レコーダーのクラス

class sound.Recorder(file_path)

 レコーダークラスは、デバイスのマイクロフォンから音声ファイルを録音するための高度なメソッドを提供します。

 引数の file_path には記憶装置上に生成した音声ファイルを指定します。音声ファイルのフォーマットはファイル名の拡張子で自動的に決定されます。MPEG4 AACの場合は .m4a 、Linear PCM の場合は .wav です。MPEG4 音声ファイルは Wav ファイルよりもかなりコンパクトですが、ウェイブモジュールで生の音声データを処理したい場合には、Wav を使うことになるでしょう。

レコーダーのモジュール

Recorder.record([duration])

 マイクロフォンからの録音を開始します。オプションの引数として duration を設定すると、指定した秒数が経過すると録音は自動的に終了します。さもなければ、Recorder.stop() メソッドを用いて録音を明示的に停止させる必要があります。

Recorder.stop()

 音声の録音を終了します。

Recorder.pause()

 音声の録音を一時停止します。Recorder.record() メソッドを使えば録音を再開できます。

レコーダーの属性

Recorder.current_time

 現在録音中の経過時間です。

Recorder.recording

 現在録音しているか否かを示します。(ブール値)

Recorder.meters

 ピーク音量の現在の平均です。(読取専用)この属性にアクセスすると、自動的に追加の処理を必要とするレコーダーインスタンスを測定します。値は「平均」と「ピーク値」をキー値とするディクショナリー型です。それぞれは左チャンネルと右チャンネルの2つの値のタプルからなっています。例: {'average': (-35.3, -30.1), 'peak': (-5.2, -8.2)}.

MIDIプレイヤーのクラス

class sound.MIDIPlayer(file_path[, sound_bank_path])

 MIDIプレイヤーは、システム組込の「Merlin Silver」や、あなたがオリジナルで設定したサウンドバンクを使用したMIDIファイル(.mid)の簡易な再生を提供します。オリジナルのサウンドバンクを設定する場合には、sf2 フォーマットにする必要があります。

MIDIプレイヤーのメソッド

MIDIPlayer.play()

 再生を開始します。

MIDIPlayer.stop()

 再生を終了します。

MIDIプレイヤーの属性

MIDIPlayer.current_time

 現在の再生位置です。

MIDIPlayer.duration

 読み込んだ MIDI ファイルの所要時間です。

MIDIPlayer.rate

 再生速度です。(1.0が標準の速度です)

sound — 効果音と音楽の再生

 サウンドモジュールは、iOS上で効果音を発生させたり音声ファイルを再生する関数を備えています。

 レコーダークラスを使ってマイクからの入力を音声ファイルに録音する事もできます。

 注)レコーダークラスを使用するためには、マイクへのアクセスを許可する必要があります。最初に Recorder.record() メソッドを使用する際には自動的にシステムが用意した許可ダイアログが表示されます。その際にマイクへのアクセスを許可しなかった場合でも、「設定」アプリの「プライバシー」画面でアクセスを許可することができます。

関数

sound.play_effect(name[, volume, pitch=1.0, pan=0.0, looping=False])

 引数 name で指定した効果音を発生させます。システム組込の効果音の名前のリストにはツールバーの[+]ボタンの「アセットピッカー」を使ってアクセスできます。なお、独自の効果音を使用したい場合には、効果音を保存した音声ファイルのファイルパスを指定することができます。

 再生は非同期で行われます。すなわち、音の再生が完了する前に関数は実行を終えて次のスクリプトの実行に進みます。

 戻り値は sound.Effect オブジェクトで、後で再生の設定調整や再生の途中で効果音を停止するために使うことができます。

 あまりに多くの(通常32音が限界です)効果音が既に再生されている場合、None が返されます。

sound.stop_all_effects()

 現在 play_effect() 経由で再生中の全ての効果音を停止します。

sound.stop_effect(effect)

 引数 effect で指定した効果音の再生を停止します。引数 effect には play_effect() の戻り値を使用します。

sound.set_volume(vol)

 全ての効果音についてデフォルトの音量を設定します。(0.0〜1.0の範囲で、デフォルト値は0.5)このメソッドは、既に再生が開始されている効果音には影響を与えません。

sound.set_honors_silent_switch(flag)

 音の再生中にサイレント(消音)スイッチを適用するか否かを設定します。(デフォルトではTrueです。)

エフェクトのクラス

class sound.Effect

 エフェクトのクラスは現在再生中の効果音を示します。直接的にエフェクトオブジェクトを生成することはできません。play_effect() 関数の戻り値として返されます。単純に一回きりのエフェクトの場合、play_effect() の戻り値は無視して問題ありません。一方で、再生中に音量やピッチなどの属性を調整したり、繰り返す効果を止めたりする際に役に立ちます。

エフェクトのメソッド

Effect.stop()

 効果音の再生を止めます。

エフェクトの属性

Effect.looping

 True に設定すると、Effect.stop() メソッドにより再生を停止するまで、効果音が無限に繰り返されます。

Effect.pan

 効果音のステレオ位置です。(-1=左、+1=右、0=センター)

Effect.pitch

 効果音のピッチ(再生速度)です。デフォルト値は1.0です。

Effect.position

 効果音の空間(3D)位置です。値は3要素タプル(x, y, z) です。この値はステレオ位置の Sound.pan 属性を上書きすることに注意してください。

Effect.volume

 効果音の現在の音量です。

プレイヤーのクラス

class sound.Player(file_path)

 プレイヤークラスは、音楽ファイルを簡便に再生するインターフェイスを提供します。このクラスは音楽やその他遅延を気にしない場合にお勧めします。ゲームの効果音には、play_effect() がより適切です。

プレイヤーのメソッド

Player.play()

 音声ファイルの再生を開始します。

Player.stop()

 音声ファイルの再生を止めて、再生位置をリセットします。

Player.pause()

 音声ファイルの再生を止めますが、現在の再生位置を保存します。 Stop playing audio, but keep the current playback position.

プレイヤーの属性

Player.current_time

 現在の再生位置を秒単位で表します。

Player.duration

 音声ファイルの再生所要時間です。(読取専用)

Player.finished_handler

 プレイヤーが再生を終了する際に引数なしで呼び出される関数/コーラブルです。

Player.number_of_loops

 音声ファイルの繰り返し再生回数です。-1 に設定すると永遠に繰り返します。

Player.playing

 音声ファイルを再生中(True)であるか停止中(False)であるかを示すブール値です。

Player.pan

 再生中の音声のステレオ位置です。(-1=左、+1=右、0=センター)

レコーダーのクラス

class sound.Recorder(file_path)

 レコーダークラスは、デバイスのマイクロフォンから音声ファイルを録音するための高度なメソッドを提供します。

 引数の file_path には記憶装置上に生成した音声ファイルを指定します。音声ファイルのフォーマットはファイル名の拡張子で自動的に決定されます。MPEG4 AACの場合は .m4a 、Linear PCM の場合は .wav です。MPEG4 音声ファイルは Wav ファイルよりもかなりコンパクトですが、ウェイブモジュールで生の音声データを処理したい場合には、Wav を使うことになるでしょう。

レコーダーのモジュール

Recorder.record([duration])

 マイクロフォンからの録音を開始します。オプションの引数として duration を設定すると、指定した秒数が経過すると録音は自動的に終了します。さもなければ、Recorder.stop() メソッドを用いて録音を明示的に停止させる必要があります。

Recorder.stop()

 音声の録音を終了します。

Recorder.pause()

 音声の録音を一時停止します。Recorder.record() メソッドを使えば録音を再開できます。

レコーダーの属性

Recorder.current_time

 現在録音中の経過時間です。

Recorder.recording

 現在録音しているか否かを示します。(ブール値)

Recorder.meters

 ピーク音量の現在の平均です。(読取専用)この属性にアクセスすると、自動的に追加の処理を必要とするレコーダーインスタンスを測定します。値は「平均」と「ピーク値」をキー値とするディクショナリー型です。それぞれは左チャンネルと右チャンネルの2つの値のタプルからなっています。例: {'average': (-35.3, -30.1), 'peak': (-5.2, -8.2)}.

MIDIプレイヤーのクラス

class sound.MIDIPlayer(file_path[, sound_bank_path])

 MIDIプレイヤーは、システム組込の「Merlin Silver」や、あなたがオリジナルで設定したサウンドバンクを使用したMIDIファイル(.mid)の簡易な再生を提供します。オリジナルのサウンドバンクを設定する場合には、sf2 フォーマットにする必要があります。

MIDIプレイヤーのメソッド

MIDIPlayer.play()

 再生を開始します。

MIDIPlayer.stop()

 再生を終了します。

MIDIプレイヤーの属性

MIDIPlayer.current_time

 現在の再生位置です。

MIDIPlayer.duration

 読み込んだ MIDI ファイルの所要時間です。

MIDIPlayer.rate

 再生速度です。(1.0が標準の速度です)

shortcuts — Pythonista の URL ユーティリティー

イントロダクション

 ショートカットモジュールは、アプリを立ち上げたり、スクリプトを実行したり開いたりするのに使用できる、Pythonista の URL ユーティリティーを提供します。このモジュールを使ってショートカットアプリを立ち上げる(そしてショートカットを実行する)こともできますが、ショートカットアプリ上での「本来の」Python ショートカットのサポートは Pythonista の将来のバージョンで行う予定です。

関数

shortcuts.open_url(url)

 システムのデフォルトのURLスキームに対応したアプリを使って、引数 url で指定したURLを開きます。これは webbrowser.open() と等価ですが、メモリー使用量の面で言えばより軽く動作します。(例えばトゥデイズ・ウィジットで使う場合などにはより適しています。)

shortcuts.pythonista_url(path='', action='run', args=None, argv=None)

ファイル名や引数 path、actionやオプションで付加されたその他の引数から、pythonista3://...から始まるURLを生成します。

引数 action に設定可能な値は以下の通りです:

  • 'run' – 追加入力なしにスクリプトを実行するURLを開きます。
  • 'open' – スクリプトを編集するためにURLを開きます。
  • 'exec' – URLにソースコードとして埋め込まれたスクリプトで、URLを開くとPythonistaで見ることができます。ユーザーは実行するかどうかを選択できます。(埋め込まれたスクリプトはセキュリティ上の理由から自動的には実行されません。)

引数 path は、「このデバイス上の」ルートディレクトリからの相対パスにするか、「iCloud/」を前置きしてPythonista の iCloud 配下のディレクトリの相対パスにすることができます。

引数 args には sys.argv としてスクリプトに渡す引数の文字列を設定できます。もしくは、引数リストとして渡すために argv パラメーターを使うこともできます。

shortcuts.open_shortcuts_app(name=None, shortcut_input='')

 アップル純正のショートカットアプリを開き、引数 name で指定したショートカットを実行することができます。webbrowser.open('shortcuts://run-shortcut?name=[name]&input=shortcut_input') と等価です。

scene — 2次元のゲームとアニメーション

 scene モジュールはハードウェアアクセラレータを使用した2次元グラフィックスとアニメーションを簡単に作成する方法を提供します。特にゲーム用に最適です。

あらまし

イントロダクション

 scene を使用したスクリプトを描く際には、まず Scene の子クラスを生成する必要があります。この子クラスは、接触イベントなどに反応するコンテンツの描画に用います。子クラスを生成し、run() 関数に渡せば、実際のスクリーン上への scene の表示を行うことができます。Scene クラスには、その挙動をカスタマイズできるような様々なメソッドがあります。例えば、 Scene.setup() を呼ぶことによって、スクリーン上での表示の属性を設定できます:

from scene import *

class MyScene (Scene):
    def setup(self):
        self.background_color = 'green'

run(MyScene())

 上記の最小限の例は、Scene.setup() メソッドで画面の背景色を緑に設定するシンプルなものです。

 実際に画面上にコンテンツを加える際には、普通、Node オブジェクトを生成します。異なる種類のコンテンツには Node の異なる種類の子クラスが対応します。例えば、画像には SpriteNode 、テキストには LabelNode というように。Scene もまた Node の子クラスであり、ノードは他のノードを部品として取り込むことができます。(ツリーとか「scene graph」と呼ばれる構造になります。)ノードの一部品として他のノード取り込めることによって、複数のオブジェクトを一つの要素として一括して動かしたり回転させたりすることが可能になります。全てのノードは位置、角度、寸法、そしてα(透過度)の属性を持っています。これらの属性によりノードと、子ノードがどのように描画されるかが決まります。デフォルトの位置は画面の左下隅を表す(0,0)になっています。

 次の例では、setup() メソッドが、画面中央に宇宙船を表示する設定となるように拡張されています:

from scene import *

class MyScene (Scene):
    def setup(self):
        self.background_color = 'midnightblue'
        self.ship = SpriteNode('spc:PlayerShip1Orange')
        self.ship.position = self.size / 2
        self.add_child(self.ship)

run(MyScene())

 ここでいくつか注釈を:

  • SpriteNode の初期化に際して渡されている文字列(上記の「spc:PlayerShip1Orange」)は、システム組込み画像の名称です。 システム組込み画像は、Pythonista のエディター画面のソフトウェアキーボードの右上端にある「+」ボタンを使えば確認することができます。(訳注 外付けキーボードを使っている場合には画面右下端に「+」が表示されます)
  • 利便性を考慮し、scene モジュールのサイズや位置に関するオブジェクトは、標準的な引数を使用するようにしています。(setup() を呼び出す前に自動的に設定される) scene のサイズは、単純に2で割るとスクリーンの中心になるようになっています。サイズと画面上の点は相互に換算できるように、サイズは位置の属性として機能するような構成にしています。2つの数字からなるシンプルなタプルも使用可能です。
  • デフォルトでは、SpriteNode の位置属性は中央を指定するようになっています。状況によっては、代わりにスプライトの四隅の一つを基準にした方が便利な場合があります。anchor_point 属性を変更することで、四隅の一つを基準にするよう設定可能です。

画面へのタッチと簡単なアニメーション

 先程の例を画面へのタッチに反応するよう今一度拡張してみましょう。それには、Scene の touch_began() メソッドを上書きするだけで十分です。

from scene import *

class MyScene (Scene):
    def setup(self):
        self.background_color = 'midnightblue'
        self.ship = SpriteNode('spc:PlayerShip1Orange')
        self.ship.position = self.size / 2
        self.add_child(self.ship)

    def touch_began(self, touch):
        x, y = touch.location
        move_action = Action.move_to(x, y, 0.7, TIMING_SINODIAL)
        self.ship.run_action(move_action)

run(MyScene())

 この最後の例では Action クラスを使用しています。Action は Node の属性、今回は位置属性ですが、簡単に変更して Node を動かすことができます。タイミングモードの( TIMING_SNODAIL)で開始値と終了値の間の補完の仕方を指定します。この引数を省略した場合には、デフォルトの直線補完(ぎこちない動きになります)になります。ノードを回転させたり、大きさや透過度(アルファ)を変えたり、親ノードから消し去るものまで多くの Action メソッドがあります。Action.group() や Action.sequence() を使って複数のアクションを組み合わせたり、Action.repeat() を使って繰り返して動きを作り出すこともできます。

 touch_began() と同様、touch_moved() や touch_ended() という、タッチの開始や終了を調べるメソッドもあります。

高度なアニメーションと動きのコントロール

 Actions により scene 上のコンテンツに、簡単に使えて高機能なAPI(アプリケーション・プログラミング・インターフェイス)で動きを付けることができますが、Scene の update() メソッドで重ね書きすることによって、フレームベースの動きの変化をつけることも可能です。次の例では、この手法により、gravity() 関数を用いて、デバイスの指示に応じて宇宙船を動かします。デフォルトでは、update() メソッドは1秒間に60回呼び出されるため、Actions を用いるよりも、船の位置は直接的に動きます。

from scene import *
import sound

class MyScene (Scene):
    def setup(self):
        self.background_color = 'midnightblue'
        self.ship = SpriteNode('spc:PlayerShip1Orange')
        self.ship.position = self.size / 2
        self.add_child(self.ship)

    def update(self):
        x, y, z = gravity()
        pos = self.ship.position
        pos += (x * 15, y * 15)
        # Don't allow the ship to move beyond the screen bounds:
        pos.x = max(0, min(self.size.w, pos.x))
        pos.y = max(0, min(self.size.h, pos.y))
        self.ship.position = pos

    def touch_began(self, touch):
        laser = SpriteNode('spc:LaserBlue9', position=self.ship.position, z_position=-1, parent=self)
        laser.run_action(Action.sequence(Action.move_by(0, 1000), Action.remove()))
        sound.play_effect('arcade:Laser_1')

run(MyScene(), PORTRAIT)

 ここで使っている gravity() 関数はデバイスの向きを決める簡単なメソッドです。より緻密なコントロールをするに、代わりに motion モジュールを使うこともできます。motion でコントロールするゲームの場合、画面の縦←→横の自動切替を無視する事ができ、run()関数に引数を追加することにより画面を縦方向に固定することもできます。

 ひとつおまけに、スクリーンにタッチすると宇宙船からレーザーが撃たれるようにしました。レーザーのスプライト要素を初期設定する際に設定している z_position は、描画する順番を決める属性です。ここでは、宇宙船の先頭からレーザーが表示されないよう、-1に設定しています。画面にレーザーを書き加えたあと、2つの動作を繰り返し実行します。1つはレーザーを1000ポイント分上へ動かし、特別な方法を使って削除します。(本当の意味でのアニメーションではありませんが、アニメーションの流れの一部として使用できる方法です。)

 以上は、ごく基礎的な「あらまし」です。scene モジュールを活用すれば、もっと多くのことができます。この pythonista3 に付属の Examples フォルダーには、より進んだテクニックを学ぶのに使える完成したゲームをいくつか納めてあります。

図形

 scene の座標系では、左下隅を原点(0,0)としています。

 「あらまし」では、scene モジュールには、2次元の図形を便利に扱うためのクラス、まずはRect、Point、Sizeがあることに簡単に触れました。点とサイズは基本的に同一の数字の組合せですが、違う意味合いで使います。

 これらの幾何学的なオブジェクトは、多くの Node 属性、例えばNode.position、SpriteNode.size、Node.frame などに使用します。これらの属性に新規の値を設定する時には、Point や Size オブジェクトをわざわざ明示した形で宣言する必要はありません。タプルやリストのような2つの数字の組合せでも同じ役割を果たします。

 これらの全てのクラスは、一連のものと見なされるので、例えば、point[0]を使って Point の x 座標の値にアクセスすることができます。(一般的には、point.x を使うより便利です。)

 Vector2、Point、Size については、利便性を考えて、数学の演算子をサポートしています:

  • ベクトルとスカラー値(すなわち、数字のことです)の掛け算については、ベクトルの各要素にそれぞれ数字を掛けます。割り算についても同様です。例えば、Size(100,200)*0.5 は、Size(50,100)になります。
  • ベクトル同士の掛け算は、成分ごとに乗算を行います。例えば、Point(100,100)*(2,3) は Point(200、300)になります。
  • ベクトル同士の足し算も同様です。例えば、Point(100,100) + (20,50) は Point(120,150) になります。

 弾が当たったかどうかを調べるためには、点(Point) が 引数として渡した四角形(Rect)の中に入っているかどうかで判定できます。一つの四角形が他の四角形の中に入り込んでいるかどうかの判定には、 Rect.intersects() メソッドを使えます。(もしくは、厳密に四角形の中に入り込んでいるかを知りたい場合には、Rect.intersection()を使います。)

 Node の色に関する属性、例えば SpriteNode.color や Scene.background_color は様々な方法で設定できます。

  • HTML(ハイパー・テキスト・マークアップ・ランゲージ:ウェブページを書くのに使われる言語) で使われる、16進の色を示す文字列。例えば、'#ff0000' で「赤」を示す。
  • CSS(カスケーディング・スタイル・シート:ウェブページのスタイルを指定する言語) での色名称。例えば、'green', 'blue', 'magenta' など。
  • 赤、緑、青、そしてアルファ(不透明度)を表す0.0〜1.0の値の組合せを示す3ないし4つの数字のタプル。アルファの値はデフォルトで1.0で、完全に透けない状況を表します。
  • グレイスケールの値(0.0=黒、1.0=白)を表す0.0〜1.0の単独の数値。

 どの方法で色属性を指定しても、システム上は常に4つの数字のタプル(赤、緑、青、アルファ)に変換されて処理します。

古典的レンダリング・ループ

 上記のようなnodeによる画像処理に加えて、scene モジュールは、古いバージョンの pythonista のインターフェイスである「古典的レンダリング・ループ」もサポートしています。多くの場合、node による画像処理の方が処理速度がかなり速くなるのですが、「古典的レンダリング・ループ」は、Processing のような、同様のプログラミング環境に慣れた方にとっては、理解がしやすいかも知れません。

 このモードを使うには、Scene の子クラスを生成する必要があります。node を追加する代わりに、シンプルに draw() メソッドをオーバーライドする方法もあります。このメソッドはフレーム毎に(すなわち1秒間に60回)呼び出され、全てのフレームでコンテンツを「塗る」、モジュールレベルの塗り潰し機能を使うことができます。画面にこの方法で描かれた画像や線画は、フレーム毎に書き直され、残り続けることはありません。draw(メソッド)を呼び出す毎に、基本的に何も描かれていない画面に改めて書き始めることになります。

 古典的な OpenGL(汎用グラフィクスライブラリー)と同様に、実際の drawing 関数を呼び出す前に、塗り潰しや座標変換のようなプログラム全体に使用する条件を設定します。以下の例は回転する四角形を描くスクリプトです:

from scene import *

class MyScene (Scene):
    def draw(self):
        background('gray')
        colors = ['red', 'green', 'blue', 'yellow']
        # 画面中心に移動する:
        translate(self.size.w/2, self.size.h/2)
        for color in colors:
            # 塗り潰し色を設定する(この設定は以降の drawing コマンドに適用されます)
            fill(color)
            # 座標変換マトリクスに回転を設定する(この操作は前回設定に加えた回転になり、回転量が蓄積されます)
            rotate(-20)
            # 注:引数の座標値は、直前の「座標変換」コマンドに応じた、画面中心からの相対的な値になります
            rect(-50, -50, 100, 100)

run(MyScene())

 古いバージョンの pythonista を使ったことのある方なら、Node や Action とコンセプト的には似通った、Layre や Animation クラスにも親しみを覚えるかも知れません。これらのクラスは下位互換性のために使用可能にしていますが、Node や Action API を代わりに使うことを強くお勧めします。なぜなら、処理速度が圧倒的に改善されているためです。

 注 このモードで描画に使える関数は、scene_drawing モジュールで定義されています。これらの関数を使う必要がなければ、scene_drawing を import する必要はありません。

ui モジュールとの統合

 scene を実行するのに一番簡単な方法は、フルスクリーンで表示する run() 関数を使用することです。この方法では、ゲーム以外の画面を作る時には特に、都合が悪いことがあります。より柔軟に画面を構成するために、SceneView を明示的に生成することもできます。SceneView に表現したい画面に応じた scene 属性を設定し、ui モジュールを使い、生成した view ヒエラルキーに加えます。

 この方法は伝統的な UI エレメント(例えば、テキスト・フィールド)をゲームに付け加える際にも使えます。この目的のためには、SceneView を生成する必要はありません。シンプルに自動的に生成された view を、Scene の view 属性を適用して(もちろん、既に scene が生成されている場合のみ適用可能です)使うことができます。

 ui モジュールは、図形やテキストなどのベクターイメージをテクスチャとして使いたい場合の画像処理にも便利に使用できます。 このためには、 ui.Image でテクスチャを初期化、一般的には ui.ImageContext を使って生成します。ShapeNode とLabelNode クラスはコンテンツの画像処理にこの方法を使っています。

ゲームコントローラー

 scene モジュールは、Nimbus SteelSeries gamepad のような、MFi(Made For iPhone/iPad/iPod:アップルデバイスへの接続規格) ゲームコントローラーによるゲームコントロールをサポートしています。

 ゲームに対する外部コントローラーからの入力をサポートするのは極めて簡単です。基本的に Scene の子クラスである Scene.controller_changed() メソッドをコントローラーで発生するイベント(例えば、ボタンが押された、とか、ボタンから手が離された)に反応するように重ね書きするだけです。メソッドには2つのパラメーターがあります。コントローラーの変更される要素(例えば'button_a')を示す文字列としての「key」と、コントローラーの要素の「現在値」です。「現在値」の型は、コントローラーの要素の型によって決まります。基本的なボタンについては論理型、感圧式のトリガーは0.0〜1.0の間の浮動小数点型、dpads(十字キー) や ジョイスティックは−1.0〜1.0の間の値をもつxとyで構成される Point オブジェクトになります。

 Scene.update() メソッドやその他の方法でコントローラーの現在の状態を調べると、より便利な場合があります。このためには、モジュールレベルの get_controllers() 関数を使うことができます。この関数は、接続されているコントローラーのボタンや十字キー、ジョイスティックなどの現在の状態を示す辞書型のリストを返します。

Node クラス

シーン

class scene.Scene

 scene は Node オブジェクトを構成するノード群の大本のノードです。これらのノードは、画面上で scene を動かしたり、描画したりするコンテンツを作るのに使います。scene をフルスクリーンで表示するためには一般的に、モジュールレベルの run() 関数を呼び出します。他の UI コンテンツと共に scene を表示する場合には、SceneView を明示的に生成することもできます。

 scene は、以下の順番で、新しいフレームのコンテンツの作成処理を行います:

  1. scene の update() メソッドを呼び出す。
  2. scene の子クラスの処理を実行する。
  3. scene の did_evaluate_actions() メソッドを呼び出す。
  4. scene の全てのノードを描画し、新しいコンテンツを表示するため、画面のアップデート処理をする。

 画面にタッチした時の処理(touch_began(),touch_moved(),touch_ended()の重ね書きによって)やその他のゲームのコンテンツに反応させるため、少なくとも1つは、Scene の子クラスを生成するのが一般的です。

 Scene は EffectNode の子クラスであり、フルスクリーンの後処理的な効果として、カスタマイズした Shader を使うことが可能です。しかしながら、標準の EffectNode と異なり、scene の effect_enabled 属性をデフォルトでは False に設定されています。

Scene.setup()

 画像をスクリーン上に表示する直前に一度だけ呼び出します。画像の表示準備に使用します。この時点ではすでに画像のサイズや境界の属性は設定済みであり、これらによってコンテンツのレイアウトを規定できます。

Scene.touch_began(touch)

 このメソッドは scene の表示されている画面へのタッチが始まった時に呼び出されます。一般的に、直接的に呼び出すのではなく、Scene の子クラスの一部として実行します。

 touch オブジェクトの位置属性を調べる事で、scene の座標系の中のタッチした位置を知ることができます。同時に複数の場所がタッチされた場合にも、touch_id 属性を使えば、それぞれの場所の区別をつけることができます。

Scene.touch_moved(node, touch)

 このメソッドは、scene の画面に触った指などが動いた際に呼び出されます。一般的に、直接的に呼び出すのではなく、Scene の子クラスの一部として実行します。

 touch オブジェクトの位置属性を調べる事で、scene の座標系の中のタッチした位置を知ることができます。同時に複数の場所がタッチされた場合にも、touch_id 属性を使えば、それぞれの場所の区別をつけることができます。

Scene.touch_ended(node, touch)

 このメソッドは、scene の画面に触った指などが画面から離れた際に呼び出されます。一般的に、直接的に呼び出すのではなく、Scene の子クラスの一部として実行します。

 touch オブジェクトの位置属性を調べる事で、scene の座標系の中のタッチした位置を知ることができます。同時に複数の場所がタッチされた場合にも、touch_id 属性を使えば、それぞれの場所の区別をつけることができます。

Scene.did_change_size()

 このメソッドは、scene のサイズが変更された場合、通常は、画面が回転した場合に呼び出されます。一般的には、コンテンツを再配置するためにこのメソッドを重ね書きします。このメソッドが呼び出された際には、scene のサイズ属性は既に新しいサイズの数値になっています。

Scene.did_evaluate_actions()

 このメソッドは、子ノードのアクションの処理が終了した scene の後に呼び出されます。

Scene.update()

 scene のアクションに前もって実行する必要がある scene 特有の更新を行います。

 このメソッドは直接呼び出さないで下さい;scene が表示され、停止されていない限り、1フレームに1回呼び出されます。デフォルトでは、このメソッドは何もしません。scene の子クラスが、このメソッドを重ね書きし、scene に必要な更新を実行します。

Scene.pause()

 scene が実行されている間にホームボタンが押された場合に自動的に呼び出されます。このメソッドに重ね書きし、例えば、保持すべき状況のセーブをするようにできます。デフォルトでは、何も処理を行いません。

Scene.resume()

 ホームボタンが押されて scene がバックグラウンドに送られて中断した際に自動的に呼び出されます。デフォルトでは、何も処理を行いません。

Scene.stop()

 「X(バツ)」ボタンが押されて scene が停止した際に自動的に呼び出されます。現在の状態をセーブするためにこのメソッドを書き換えることができます。デフォルトでは、何も処理を行いません。

Scene.present_modal_scene(other_scene)

 他の scene を(他の scene を隠すような形で)最前列に表示します。画面に上書きする形でメニューを表示するのに便利です。scene が表示されている間は、全てのタッチ操作を受け付けます。

Scene.dismiss_modal_scene()

 Scene.present_modal_scene() を使って決められた形で表示された scene を閉じます。

Scene.controller_changed(key, value)

 このメソッドは接続中のゲームコントローラーの状況が変化した際に自動的に呼び出されます。例えば、ボタンが押された場合/離された場合、またはジョイスティックや十字キーの方向が変化した場合など。

 引数 key は変化を確認したいコントローラーの要素(例えば、'button_a', 'dpad', 'thumbstick_left'など)を指定する文字列です。引数 value はその要素の現在の値です。value の型はコントローラーの要素の型によって変わります。十字キーやジョイスティックのような方向を入力する要素の場合、value は Point オブジェクトになります。その他の要素の場合、浮動小数点型(感圧式のエレメントのとき)または論理型になります。

Scene の属性

scene.bounds

 原点(0,0)を持つ、画面の描画領域のサイズの長方形です。

Scene.dt

 update() を最後に呼び出してから経過した秒数です。カスタマイズしたアニメーションの進捗の計算に使用可能です。

Scene.size

 画面の描画領域のサイズです。

Scene.t

 scene がスタートしてから経過した秒数です。カスタマイズしたアニメーションの進捗の計算に使用可能です。

Scene.touches

 現在アクティブな全てのタッチの辞書型のリストです。Touch オブジェクトの touch_id 属性に対応しています。

Scene.background_color

 scene の背景色です。

 デフォルトではダークグレーです。

Scene.size

 ポイント単位(1ポイントは約0.35mm)で示した scene のサイズです。(読取専用)scene の表示サイズに対応しています。

Scene.view

 View は現在表示されている scene を表します。scene が表示されていない場合には、None となります。(読取専用)

Scene.presented_scene

 Scene.present_modal_scene() を使用して現在表示中の scene を表します。(表示している scene がない場合はNone)

Scene.presenting_scene

 Scene.present_modal_scene() を使用して表示した scene によって、さらに派生して表示された scene があれば、それを表します。(訳注 使用事例も探して検証してみたのですが、この訳が妥当かどうか不明です。)

ノード

class scene.Node([position=(0, 0), z_position=0.0, scale=1.0, x_scale=1.0, y_scale=1.0, alpha=1.0, speed=1.0, parent=None])

 Node クラスは scene の基礎的な構成要素です。基本的な Node クラスは、それ自体では何も描画しません。その主な役割は子クラスが使用する基礎的な挙動を指定することです。ノード群は全体をカスタマイズするために他のノードを構成要素にすることもできます。実際のコンテンツの描画のためには、一般的にノードの子クラスを使用します:

  • SpriteNode – 画像をスプライト(背景画面とは独立に位置を変えられる区画)上に描くノード
  • LabelNode – 文字列を表示するのに特化したスプライトノード
  • ShapeNode – ベジェ曲線に基づいた線画を表示するの特化したスプライトノード(例 円や角の丸い長方形)
  • EffectNode – カスタマイズしたシェーダー(特殊効果を与える仕組み)を使用して子ノードに効果を適用するノード

 ノード群は、view と subview の関係と同様に、ノードの樹型の階層構造の形で構成されています。ごく一般的には、ノードの樹型は、Scene ノードが幹となり、その他のコンテンツのノードが枝となる形になっています。この場合の scene ノードは各ノードの処理を繰り返します。そして、ノードの樹型の中に含まれるコンテンツを画面に表示します。

 全ての樹型構造の中にあるノードは、その子ノードに対して座標系を渡します。子ノードが樹型構造に付け加えられた後で、親ノードの座標系の中に子ノードの位置が設定されます。ノードの座標系は、x_scale, y_scale, rotation 属性を変える事で縮尺を変えたり、回転させたりすることができます。ノードの座標系の縮尺が変更されたり回転されたりすると、この変形はノード自体のコンテンツと子や孫のノードのコンテンツにも適用されます。

 Node クラスは、それ自身では描画を行いません。しかし、多くの子クラスが画像コンテンツを描画するため、Node クラスは画像に関するコンセプトであると解釈されます:

 フレームの属性は、ノードの画像コンテンツを表示する長方形を示します。この長方形は scale や rotation 属性に応じて変形します。フレームは、ノードクラスがコンテンツを表示すると空ではなくなります。それぞれのノードの子クラスはそれぞれ異なるコンテンツのサイズを持っています。いくつかの子クラスでは、スプライトノードのクラスのように、ノードのコンテンツのサイズが明示的に宣言されます。その他の子クラスでは、コンテンツサイズは他のオブジェクト属性を使って隠された形で、計算によって求められます。例えば、ラベルノードオブジェクトでは、ラベルに表示するテキストと、フォント属性によって決定されます。

 ノードの bbox はノードのフレームと全ての子ノードのフレームを包含した最も大きい長方形です。

 アルファ(不透過度)属性のようなそのたの属性は、ノードや子ノードの描画に影響を与えます。

 樹型構造の中の全てのノードは Action オブジェクトを実行し、ノードの属性を変化させることがあります。例えば、新しい座標へのスムーズな移動など。

Node.add_child(node)

 受け手の持つ子ノードのリストの最後にノードを追加します。

Node.remove_from_parent()

 親ノードからノードを削除します。

Node.remove_action(key)

 引数 key で指定した特定のアクションを終了させ、ノードから削除します。key はNode.run_action() メソッドに渡された任意の文字列です。

Node.remove_all_actions()

 全てのアクションを終了させ、ノードから削除します。

 ノードからアクションを削除すると、そのアクションが実行する残りのアニメーションはスキップされます。ただし、それ以前の変化は取り消されません。

Node.render_to_texture([crop_rect])

 このノードと子ノードのスナップショットとして表面に描画したTexture オブジェクト を生成します。

Node.point_to_scene(point)

 引数 point で指定した点を、このノードの座標系から、ノードを含む scene の座標系に変換します。ノードが scene の一部でなかった場合、ValueError が生じます。

Node.point_from_scene(point)

 引数 point で指定した点を、このノードの scene の座標系から、このノードのローカルな座標系に変換します。ノードが scene の一部でなかった場合、ValueError が生じます。

Node.run_action(action[, key])

 ノードで実行されるアクションのリストに、アクションを追加します。

 もし同じ key (任意の文字列)を使用するアクションが既に実行されている場合には、新しいアクションが追加される前に削除されます。

Node Attributes

Node.bbox

 ノードと全ての子ノードのコンテンツを含む長方形を親の座標系で算出します。

Node.alpha

 ノードのコンテンツに不透明度(アルファ)を適用します。

 Node クラスは描画はしませんが、その子クラス群の多くは描画をします。ノードや子ノードが描画する際に、それぞれのピクセル(画素)のアルファ値にはノードのアルファ属性が掛け算され、その値は0.0〜1.0の範囲に固定されています。この補正されたアルファ値は画素をフレームバッファーに溶け込ませるのに使われます。コンテンツを描画する子クラスについては、親のフレームバッファーに画素を溶け込ませるアルファ値によって、ブレンド処理が規定されます。

Node.frame

 ノードのコンテンツを含む、親の座標系の長方形です。子ノードについては無視します。(読取専用)

Node.children

 このノードの子ノードのリストです。このリストを修正しても、効果がないことにご注意下さい。代わりに、Node.add_child() や Node.remove_from_parent() を使用します。

Node.parent

 このノードの親ノードです。(読取専用)

Node.paused

 ノードや子孫ノードのアクションが処理中かどうかを判別する論理値です。

Node.position

 親ノードの座標系の中でのノードの位置(x,y)です。

Node.scene

 ノードを含むシーンノードです。(読取専用)

 ノードがシーンに埋め込まれていない場合には、値は None になります。

Node.speed

 ノードや子孫ノードにより実行される全てのアクションに適用される速度調整値です。

Node.x_scale

 ノードと子孫ノードの幅に掛け算する縮尺の値です。

 X 方向スケール値は、ノードと全ての子孫ノードの幅に影響を与えます。スケール値はどのようにノードのフレームの計算を行うか、どのように描画されるか、そして他の同様の指標に影響します。デフォルト値は1.0です。

Node.y_scale

 ノードと子孫ノードの高さに掛け算する縮尺の値です。

 Y 方向スケール値は、ノードと全ての子孫ノードの高さに影響を与えます。スケール値はどのようにノードのフレームの計算を行うか、どのように描画されるか、そして他の同様の指標に影響します。デフォルト値は1.0です。

Node.z_position

 ノードの z 方向の位置により、兄弟ノード同士の描画される順番が決まります。デフォルト値は0.0です。より大きな値のノードが、小さい値のノードの手前に描かれます。

Node.rotation

 ノードの Z 軸回りの回転を示します。(角度の単位はラジアンです)

 デフォルト値は0.0で、「回転しない」ことを表します。プラスの値は、反時計周りの回転を示します。座標系が回転された場合、ノードと子孫ノードに影響が及びます。

スプライトノード

class scene.SpriteNode([texture, position=(0, 0), z_position=0.0, scale=1.0, x_scale=1.0, y_scale=1.0, alpha=1.0, speed=1.0, parent=None, size=None, color='white', blend_mode=0])

 スプライトノードは、画像イメージや色のついた正方形、色を混ぜた画像イメージなどを描画するノードです。カスタマイズしたシェーダーによりオリジナルの描画上の効果を作り出すこともできます。

 スプライトノードを初期化する際には、テクスチャオブジェクトやシステム組込の画像の名称、画像ファイル(文字列)によりテクスチャを指定できます。

SpriteNode の属性

SpriteNode.anchor_point

 ノードの位置に対応するスプライトの位置を指定します。

 ユニットの座標系の空間の中でこの属性の値を指定します。デフォルト値は(0.5,0.5)です。この値の場合、その位置がスプライトの中央であることを示します。

SpriteNode.blend_mode

 ブレンドモードは、スプライトを親のフレームバッファに書き込む際に使用されます。

 この属性に設定可能な値は、後述する「ブレンドモード」のリストの通りです。デフォルト値は BLEND_NORMAL です。

SpriteNode.color

 スプライトの色です。

 テクスチャ属性が設定されている場合には、画像は指定した色で薄く着色されます。テクスチャ属性が None の場合には、色は、色付きの長方形を描画する際に使用されます。

SpriteNode.shader

 ストライプがカスタマイズしたシェーダーを使用して描画されるかどうかを決める属性です。

 デフォルト値は None で、スプライトの描画を普通に行うことを意味します。この属性にシェーダーが設定されている場合には、スプライトの描画にカスタマイズされたシェーダーが用いられます。

SpriteNode.size

 スプライトの縦と横のサイズで、単位はポイント(約0.35mm)です。テクスチャ属性を設定している場合には、サイズは自動的にテクスチャの寸法に設定されます。

SpriteNode.texture

 テクスチャは、スプライトの描画に使用されます。

 値が None の場合、スプライトは色属性を使用して色付きの長方形として描画されます。その他の場合には、スプライトの描画にテクスチャが使用されます。

エフェクトノード

class scene.EffectNode([position=(0, 0), z_position=0.0, scale=1.0, x_scale=1.0, y_scale=1.0, alpha=1.0, speed=1.0, parent=None])

 エフェクトノードオブジェクトは、後処理のエフェクトに適用することができます。

 新しいフレームは、常にエフェクトノードを使用して描画されます。エフェクトノードは、以下のステップのように動作します:

  • エフェクトノードは、その子ノードをプライベートのフレームバッファに描画します。
  • プライベートのフレームバッファのコンテンツを、標準のブレンドモードの一つを使って、スプライトノードと同様に、親のフレームバッファに合成します。より進んだ後処理のエフェクトをかけるため、カスタマイズしたシェーダーを使うことも可能です。

エフェクトノードの属性

EffectNode.crop_rect

 エフェクトノードの座標系の長方形で、エフェクトノードの子ノードにどれだけの範囲の描画をするかを指定します。

 デフォルトでは、エフェクトノードにより、子ノードの、これまでに描画されてきたフレーム上の長方形群のサイズと位置が自動的にきめられます。ところが、いくつかのケース、特に頻繁に子ノードのサイズが変更される場合や、子ノードのいくつかが画面上からはずれる場合には、この方法では効率が悪くなることがあります。

EffectNode.blend_mode

 ブレンドモードは、親ノードのフレームバッファにフィルターをかけた画像を描画する際に使用されます。

 この属性に設定可能な値は、後述する「ブレンドモード」のリストの通りです。デフォルト値は BLEND_NORMAL です。

EffectNode.effects_enabled

 False に設定すると、エフェクトノードは一般のノードと同様に描画されます。(シェーダー、ブレンドモード、長方形群は無視されます。)デフォルトの値は True です。

EffectNode.shader

 エフェクトノードを親ノードのフレームバッファに反映する際に呼び出される、カスタマイズされたシェーダーです。

 デフォルト値は None で、デフォルトのブレンドが実行されます。シェーダーを指定すると、画像を親ノードのフレームバッファにブレンドする際に、そのシェーダーを適用します。

ラベルノード

class scene.LabelNode(text, font=('Helvetica', 20), *args, **kwargs)

 ラベルノードは指定されたフォントを用いて、画像に文字列を描画し、自動的にテクスチャを生成することに特化した、スプライトノードの子クラスです。LabelNode.text や LabelNode.font 属性を設定すると、テクスチャは自動的にアップデートされます。

 デフォルトでは、テキストはノードの中央に配置されます。この位置については、Node.anchor_point 属性を調整することで、変更可能です。

ラベルノードの属性

LabelNode.text

 ラベルに描画する文字列です。

LabelNode.font

 ラベルに用いられるフォントです。フォント名称とフォントサイズ(ポイント単位)の2要素タプルです。

シェイプノード

class scene.ShapeNode(path=None, fill_color='white', stroke_color='clear', shadow=None, *args, **kwargs)

 シェイプノードは、ui.Path(ベクターシェイプ) を描画することに特化したスプライトノードの子クラスです。

 シェイプは塗り潰し色と輪郭線の色をカスタマイズでき、オプションで影を描画することができます。

シェイプノードの属性

ShapeNode.path

 描画しようとするシェイプを示す ui.Path オブジェクトです。ui.Path.line_width 属性により、描画されるシェイプの線の幅を指定します。

ShapeNode.fill_color

 シェイプを塗り潰す際の色です。

ShapeNode.stroke_color

 シェイプの輪郭線の色です。

ShapeNode.shadow

 色、x 方向オフセット、y 方向オフセット、半径の4要素タプルで、影の付け方を指定します。None に設定すると、影は描画されません。

その他のクラスOther Classes

シーンビュー

class scene.SceneView

 シーンビューは ui.View の子クラスで、シーンのコンテンツを描画したり、描画のループを実行したりします。

 一般的には、シーンビューを明確に生成することはありません。run() 関数を呼び出すと、シーンビューは自動的に実行されます。この方法でシーンを実行した後でビューの属性を修正する場合、この Scene.view 属性を使って、ビューにアクセスすることができます。

 デバッグのために、SceneView は画面最下端の「ステータスライン」に例外的に標準的な画面出力をするようになっています。そのため、シーンが画面全体をカバーしている場合でも、スクリプト開発中に print 文を使うことができます。

シーンビューの属性

SceneView.scene

 現在ビューの中に表示されているシーンです。この属性を設定しない場合、ビューは空になります。

SceneView.paused

 これを True に設定すると、描画ループは一時停止になります。

SceneView.frame_interval

 デフォルトでは、frame_interval は1になっており、描画ループは1秒間に60回更新されます。より大きい値に設定すると、更新頻度が下がります。例えば、2に設定すると1秒間に30フレームの更新となります。明示的にシーンビューを生成しない場合には、run() 関数への引数としてこの値を渡すこともできます。

SceneView.anti_alias

 これを True に設定すると、4倍の頻度でのサンプリングができるようになります。この時、(往々にして重要なことに)デバイスの能力を喰ってしまうので、デフォルトでは False に設定されています。

SceneView.shows_fps

 True に設定すると、デバッグのために、現在のフレームレートを画面上に表示します。

シェーダー

class scene.Shader(shader_src)

 シェーダーオブジェクトは、シェイプノードオブジェクトやエフェクトノードオブジェクトの描画時の動作をカスタマイズするのに使用可能な、OpenGL(CGライブラリー)のフラグメントシェーダーを示します。

 シェーダーのプログラミングは難しい内容であり、完全な紹介はこの文書の目的を超えてしまいますが、基本的な考え方は極めてシンプルです。本質的には、フラグメントシェーダーは直接的にGPU上で実行される、全ての画素に色の値を設定する関数/プログラムです。シェーダーはC言語によく似たGLシェーディング言語で書かれています。

 スプライトノードのデフォルトのシェーダーは基本的に、関連したテクスチャに対応する色を見つけるための、テクスチャの同等の入力(これは自動的に設定されます)のためだけに使用します。シンプルなシェーダーは、結果として生じる色の値を調整(例えば、カラーからグレースケールへの変換)したり、モーフィング効果にテクスチャを調和させたりします。

 シェーダーには2種類の入力方法があります:バリイングとユニフォームです。本質的に、バリイングが補間などをするのに対して、ユニフォームでは全ての画素/フラグメントに同一の値を与えます。バリイングの例としては、全ての画素が明確に異なる、テクスチャの座標があります。ユニフォームの例としては、スプライトのサイズや現在時刻があります。

 バリイングやユニフォームの組合せは、スプライトノードやエフェクトノードをカスタマイズしたシェーダーで描画する際に自動的に設定されます:

  • uniform float u_time – シーンのアニメーションループの現在のタイムスタンプです。
  • uniform vec2 u_sprite_size – スプライトのポイント単位のサイズです。
  • uniform float u_scale – スクリーンのスケールファクターです。(retinaディスプレイの場合は通常2.0です。)u_sprite_size を実際のスクリーンの画素に変換する際に使用できます。
  • uniform sampler2D u_texture – スプライトのテクスチャです。(エフェクトノードについては、このテクスチャは子ノードでの描画を含みます。)
  • uniform vec4 u_tint_color – スプライトのプレマルチプライド(事前乗算)する色です。 (SpriteNode.color 属性に対応しています。)
  • uniform vec4 u_fill_color – スプライトがテクスチャを持っていない場合、この属性が u_tint_color の代わりに使用されます。
  • varying vec2 v_tex_coord – 現在のテクスチャ(UV)の座標です。

 これらのユニフォームやバリイングが自動的に設定された場合でも、使用する場合にはシェーダーの中で宣言をする必要があります。

 Shader.ser_uniform() メソッドを使用してカスタマイズしたユニフォームを宣言し設定することもできます。カスタマイズしたユニフォームはテクスチャ(sampler2D)、浮動小数点、2/3/4要素のベクトル(vec2/vec3/vec4)のいずれかです。

 以下の例は、Pythonista のアイコンに興味深い「リップル」効果を与えるものです。同時に、ユニフォームを設定することで、シェーダーの挙動をどのようにアレンジできるかも示しています。このケースでは、リップル効果の中心は画面にタッチする場所に応じて変わります。:

from scene import *

ripple_shader = '''
precision highp float;
varying vec2 v_tex_coord;
// これらの uniforms は自動的に設定されます:
uniform sampler2D u_texture;
uniform float u_time;
uniform vec2 u_sprite_size;
// この uniform は画面へのタッチに応じて設定されます。:
uniform vec2 u_offset;

void main(void) {
    vec2 p = -1.0 + 2.0 * v_tex_coord + (u_offset / u_sprite_size * 2.0);
    float len = length(p);
    vec2 uv = v_tex_coord + (p/len) * 1.5 * cos(len*50.0 - u_time*10.0) * 0.03;
    gl_FragColor = texture2D(u_texture,uv);
}
'''

class MyScene (Scene):
    def setup(self):
            self.sprite = SpriteNode('test:Pythonista', parent=self)
            self.sprite.shader = Shader(ripple_shader)
            self.did_change_size()

    def did_change_size(self):
            # Center the image:
            self.sprite.position = self.size/2

    def touch_began(self, touch):
            self.set_ripple_center(touch)

    def touch_moved(self, touch):
            self.set_ripple_center(touch)

    def set_ripple_center(self, touch):
            # Center the ripple effect on the touch location by setting the `u_offset` shader uniform:
            dx, dy = self.sprite.position - touch.location
            self.sprite.shader.set_uniform('u_offset', (dx, dy))

run(MyScene())

Shader.get_uniform(name)

 引数 name で指定したユニフォームの現在の値を返します。ユニフォームの型は、float, vec2, vec3, vec4 のいずれかでなければなりません。(すなわち、sampler/texture ユニフォームはこのメソッドの対象外です)無効なユニフォームの名称の場合には、None を返します。

Shader.set_uniform(name, value)

 引数 name で指定したユニフォームに新しい値を設定します。値には、float型 か int型のシングルのユニフォームか、vec2, vec3, vec4型のベクトルのユニフォーム、またはsampler2D のテクスチャオブジェクトのユニフォームのいずれかを指定します。他の型のユニフォームには対応していません。

アクション

class scene.Action

 アクションオブジェクトは、通常ノードの属性を変更して時間の経過とともに画面を変化させます。Node.run_action() メソッドを使用してノードに付け加えることが可能です。

 異なるタイプのアクション(異なるノードの属性へのアクション)は、異なるクラスのメソッドを使用して生成します。例えば、Action.move_to() や Action.rotate_by() などです。

 一度ノードにアクションが追加されると、それ以上の変更はできませんが、 Node.remove_action() や Node.remove_all_actions() を使って削除することはできます。(この時、アニメーションは停止します。

 アクションの中には、他のアクションの挙動を変更するものがあります:

 Action.sequence() は複数の子供のアクションを持っています。一連のシーケンスの中のアクションは、その前に実行されるアクションが終了した後に開始されます。

 Action.group() も複数の子供のアクションを持っています。グループとして保存された全てのアクションは、全てが同時に実行開始されます。グループ全体は、全てのアクションが終了してから終了となります。Action.sequence() との組合せによりとても便利に使うことができます。

 Action.repeat() アクションは一つの子アクションを持ちます。子アクションが終了した後、再び実行します。

 シーケンス、グループ、リピートの3つのアクションは入れ子構造にすることができます。このアクション同士を組み合わせる機能を用いることによって、ノードに洗練された挙動を加えることができます。

 デフォルトでは、アニメーションのアクションの継続時間は0.5秒になっています。

classmethod Action.call(func[, duration])

 関数として(またはその他の呼び出し可能なオブジェクトとして)呼び出せるカスタマイズしたアクションを生成します。

 引数 duration を省略した場合、関数は1回呼び出され、他の引数を用いることはできません。

 引数 duration を使用した場合、アクションが実行され、進行中の(0.0から1.0の間の)ノードが関数に渡されます。この時、以下のスクリプトを使用することになります:

def custom_action(node, progress):
    pass # ここにノードに対する処理を記述…

classmethod Action.fade_by(alpha[, duration, timing_mode])

 ノードのアルファ値(不透明さの指標)を相対的な値で調整するアクションを生成します。

 このアクションを実行すると、Node.alpha 属性が新しい値へと連続的に変更されます。

classmethod Action.fade_to(alpha[, duration, timing_mode])

 ノードのアルファ値(不透明さの指標)を新しい値に変化させるアクションを生成します。

 このアクションを実行すると、Node.alpha 属性は新しい値に変更されます。

classmethod Action.group(actions...)

 並行してグループのアクションを動作させるアクションを生成します。

 アクションを実行すると、グループのアクションの全てが即座に開始され、並行に動作します。グループのアクションの動作時間はグループの中の最も長い時間実行されるものの動作時間と同じになります。グループの中に短い時間で終了するアクションがある場合には、グループの他のアクションが完了するまでアイドリングすることになります。この事は、一群のアクションを繰り返すようなアクションの繰り返しを設定する際に重要です。

 このメソッド を、呼び出す際に、一連のアクションを単体の引数、または例えばリスト型のような一つの連なりを示す引数を渡す事ができます。

classmethod Action.move_by(dx, dy[, duration, timing_mode])

 ノードを現在の位置から相対的位置に移動するアクションを生成します。

classmethod Action.move_to(x, y[, duration, timing_mode])

 ノードを現在の位置から新しい位置へ移動するアクションを生成します。

classmethod Action.repeat(action, repeat_count)

 引数 action を引数 repeat_count の回数だけ繰り返すアクションを生成します。引数 repeat_count が負の値の場合には、引数 action で指定されたアクションを無限に繰り返します。(もしくは明示的に削除されるまで繰り返します。)

classmethod Action.repeat_forever(action)

 引数 action で指定されたアクションを際限なく繰り返すアクションを生成します。

classmethod Action.rotate_by(radians[, duration, timing_mode])

 引数 radians で指定した相対的な角度だけノードを回転するアクションを生成します。

classmethod Action.rotate_to(radians[, duration, timing_mode])

 ノードを引数 radians で指定した絶対的な角度(時計回り)に回転させるアクションを生成します。

classmethod Action.scale_by(scale[, duration, timing_mode])

 ノードの x, y 方向の尺度を相対的な値で変更するアクションを生成します。

classmethod Action.scale_to(scale[, duration, timing_mode])

 ノードの x, y 方向の尺度を変更するアクションを生成します。

classmethod Action.scale_x_to(scale[, duration, timing_mode])

 ノードの x 方向の尺度を変更するアクションを生成します。

classmethod Action.scale_y_to(scale[, duration, timing_mode])

 ノードの y 方向の尺度を変更するアクションを生成します。

classmethod Action.set_uniform(name, value[, duration, timing_mode])

 引数で指定されたシェーダーユニフォームを新しい値へと変化させていくアクションを生成します。このアクションは、スプライトノードとエフェクトノードのオブジェクトに限定されることにご注意ください。引数 value は浮動小数点のユニフォームとしての単体の数字か、vec2, vec3, vec4 のユニフォームとしての2〜4の数字のセットである必要があります。

classmethod Action.sequence(actions...)

 連続的に実行されるアクション群を実行するアクションを生成します。

 アクションが実行される際には、一連のアクション群の最初のアクションが開始され、完了するまで実行されます。それに続くアクションは一連のアクションの全てが実行されるまで、同じ形で実行されます。一連のアクションの所要時間は、個々のアクションの所要時間の合計になります。

 一連のアクションについては、独立した引数またはリスト形式の様な1連なりの引数としてメソッドに渡す事ができます。

classmethod Action.wait(wait_duration)

 引数 wait_duration で指定した時間が経過するまでアイドリングするアクションを生成します。

 このアクションを実行すると、指定した時間待機し、そして終了します。通常は、アクション中の二つの異なるアクションの間に時間的間隔をあけるために使用されます。

Action の属性

Action.duration

 アクションの継続時間(秒単位)です。アクションの種類(例えば、グループやシーケンス)によっては、duration は無視されます。なお、アクションをノードに追加した後に duration やその他の属性を変更しても効果はないことに注意が必要です。

Action.timing_mode

 アクションを実行する際に使用されるタイミングモードです。

 この属性に設定可能な値のリストはタイミングモードの項を参照して下さい。デフォルトの値は TIMING_LINEAR です。

 アクションの種類(例えば、グループやシーケンス)によっては、タイミングモードは無視されます。なお、アクションをノードに追加した後に timing_mode やその他の属性を変更しても効果はないことに注意が必要です。

テクスチャ

class scene.Texture(image)

 テクスチャーオブジェクトはスプライトノードのオブジェクトが、そのコンテンツを描画する際に使用されます。テクスチャはGPUのメモリーに読み込まれた画像です。テクスチャは、システムに組込まれたイメージ(文字列)の名前や、ui.Image のオブジェクトを使って初期化することができます。

Texture.subtexture(rect)

 既に存在しているテクスチャ上の長方形の領域から、新しいテクスチャを生成します。返されるテクスチャオブジェクトは、同じテクスチャデータを元のテクスチャオブジェクトと共有します。すなわち、メモリー上に保管されるテクスチャデータは一つだけだという事です。

 引数 rect には、ユニット座標の一部、例えば(0, 0, 0.5, 0.5)を記述します。この場合、元のテクスチャの左下部分からテクスチャを生成することになります。

 このメソッドはスプライトシートやテクスチャアトラス(複数の画像を一枚の画像にまとめたもの)に使用できます。

Texture.filtering_mode

 フィルタリングモードはテクスチャの拡大縮小する際に使用されます。後述するテクスチャフィルタリングモードの定数リストの値を取ることができます。(デフォルト値は FILTERING_LINEAR です。)

Texture.size

 テクスチャの画素単位のサイズです。画面の拡大縮小の要素は考慮しないことに注意が必要です。

タッチ

class scene.Touch(x, y, prev_x, prev_y, touch_id)

 このクラスのインスタンスは、Scene.touch_began(), Scene.touch_moved() および Scene.touch_ended() メソッドに渡されます。シーンオブジェクトにもタッチ属性があります。(touch_id をタッチオブジェクトに対応させるディクショナリー型です。)

Touch.location

 タッチしている現在の場所をポイントオブジェクトとして示します。

Touch.prev_location

 動く前のタッチしていた場所をポイントオブジェクトとして示します。

幾何学的な型

Vector2

class scene.Vector2(x, y)

 Vector2 クラスは Point と Size の基礎となるクラスです。

 Vector(および点、サイズ)については、加算(+)、減算(ー)、乗算(*)、除算(/)の処理ができます。加算と減算は2つのベクトルが対象です。乗算と除算はベクトルまたはスカラー値(数字)にも適用できます。

 システムに組込まれている abs() 関数にベクトルを渡すと、ベクトルの長さが返されます。この方法は、特に減算と組合せることにより威力を発揮し、例えば abs(p2 - p1) のような形で2点間の距離を簡単に算出することができます。

 演算子として使うことで、ある点が長方形の中にあるかどうかの判定に使うことができます。

 多くの場合、Vector2 は2要素のタプルと同様の挙動をします。例えば、x 成分について添字表記(v[0])を使ってアクセスすることができます。Vector はイテレーションや引数のアンパック等にも対応しています。

 Vector2 の点やサイズのオブジェクトをscene モジュールの属性として使用する場合には、4つの数値(例えばリストやタプル)の連なりとして与えることもできます。

class scene.Point(x, y)

 Vector2 のサブクラスで、点を表すのに使用します。このクラスは追加のメソッドや属性を持たせることはできません。

サイズ

class scene.Size(w, h)

 Vector2 のサブクラスで、サイズを表すのに使用します。Vector2 と比べると、x, y 成分に Size.w(width) や Size.h(height) を使用してアクセスできる点だけが異なります。

長方形

class scene.Rect(x, y, w, h)

 Rect クラスは箱の境界を示したり、例えば、Node.frame 属性の様な他の長方形の値として使用されます。長方形は (x, y, w[idth], h[eight]) という形で、基準点(x, y) は長方形の左下を原点として表現されます。

 多くの場合、Rect は4要素のタプルと同様の振る舞いをします。例えば、x 成分について添字表記(r[0])を使ってアクセスすることができます。長方形はイテレーションや引数のアンパック等にも対応しています。

 Rect オブジェクトをscene モジュールの属性として使用する場合には、4つの数値(例えばリストやタプル)の連なりとして与えることもできます。

Rect.x

 長方形の左下隅の x 座標です。

Rect.y

 長方形の左下隅の y 座標です。

Rect.w

Rect.width

 長方形の幅です。

Rect.h

Rect.height

 長方形の高さです。

Rect.origin

 Point(rect.x, rect.y) と等価です。

Rect.size

 Size(rect.w, rect.h) と等価です。

Rect.min_x

 min(rect.x, rect.x + rect.w) と等価です。(長方形の左端の x 座標です。)

Rect.max_x

 max(rect.x, rect.x + rect.w) と等価です。(長方形の右端の x 座標です。)

Rect.min_y

 min(rect.y, rect.y + rect.h) と等価です。(長方形の下端の y 座標です。)

Rect.max_y

 max(rect.y, rect.y + rect.h) と等価です。(長方形の上端の y 座標です。)

Rect.center([p])

 引数なしで呼び出した場合には、長方形の中心を返します。引数に Point を渡した場合、長方形の x と y の値が調整され、長方形の新しい中心が p になります。

Rect.contains_point(p)

 引数 p で与えた点が長方形の領域内の場合には True を、その他の場合には False を返します。

Rect.contains_rect(other_rect)

 引数 other_rect で与えた長方形がこの長方形の領域に完全に入っている場合には True を、その他の場合には False を返します。

Rect.intersects(other_rect)

 この長方形が他の長方形と交わっている場合には True を、その他の場合には False を返します。

Rect.intersection(other_rect)

 この長方形と他の長方形が交差する部分の長方形を返します。

Rect.union(other_rect)

 2つの長方形を含む最小の長方形を返します。

Rect.translate(x, y)

 Rect(r.x + x, r.y + y, r.w, r.h)と等価です。

Rect.inset(top, left[, bottom, right])

 引数で与えた境界に合わせて変形した長方形を返します。bottom/right はオプションで、デフォルトでは top/left と同じ値になります。

関数

scene.gravity()

 現在の重力ベクトル(x, y, z) を返します。いずれの座標も 0.0 から 1.0 の間の値となります。特にモーションコントロールゲームで、デバイスの現在の向きを判定するのに使われます。

scene.get_screen_size()

 スクリーンのサイズを Size オブジェクトとしてポイント単位の値で返します。値はデバイスの方向に依存することに注意が必要です。x, y のどの方向が小さいか(縦表示か横表示か)を調べるには、min(get_screen_size()) を使用することができます。

scene.get_screen_scale()

 現在のデバイスの画面の縮尺を返します。retina ディスプレイでは通常、2.0または3.0で、ratina ディスプレイ以外の場合には1.0です。

scene.get_image_path(name)

 システム組込みの画像名称に対応するファイルの絶対パスを返します。

scene.run(scene, orientation=DEFAULT_ORIENTATION, frame_interval=1, anti_alias=False, show_fps=False, multi_touch=True)

 引数 scene で与えられた Scene オブジェクトを実行します。デフォルトでは、scene は現在のデバイスの向きで実行されます。引数 orientation を PORTRAIT(縦画面) または LANDSCAPE(横画面) に設定することで画面の縦横を指定し、自動回転機能を止めることができます。重要な点ですが、iOS 10 以降の iPad では、この orientation パラメーターによる指定は無効となります。画面分割と並行処理ができるアプリでは、技術的に画面の縦横を固定できないようになっているためです。

 デフォルトでは、scene の update() メソッドは1秒間に60回呼び出されます。引数 frame_interval を2に設定すると一秒間に30回、3に設定すると一秒間に20回という具合に時間当たりの呼び出し頻度を変更できます。

scene.get_controllers()

 接続中の全てのMFiゲームコントローラーの現在の状態をディクショナリ型のリストとして返します。(ゲームコントローラーの項についても参照下さい)

定数

Orientations

 以下の定数は、run() 関数の方向のパラメーターとして使われます。

scene.DEFAULT_ORIENTATION

 現在のデバイスの方向で、オートローテーションに従って、シーンを開始します。

scene.PORTRAIT

 強制的に縦画面にします。

scene.LANDSCAPE

 強制的に横画面にします。

ブレンドモード

scene.BLEND_NORMAL

 元の画像と目的の色を、元の画像のアルファ値(不透明度)を乗じてブレンドします。

scene.BLEND_ADD

 元の画像と目的の色を、加算してブレンドします。

scene.BLEND_MULTIPLY

 元の画像の色に目的の色を乗じてブレンドします。

テクスチャのフィルターモード

 以下の定数は Texture.filtering_mode 属性に使用されます。

scene.FILTERING_LINEAR

 直線的に変化するよう補間します。デフォルトのフィルターモードです。

scene.FILTERING_NEAREST

 最も近い点の色を用いて補間します。低解像度のアートワークを拡大する際に境界がシャープになるため、ピクセルアートに用いるモードとしてお勧めです。

タイミングモード

 以下の定数は、アクションオブジェクトの補間関数を設定するための timing_mode 属性に使用可能です。

scene.TIMING_LINEAR

 シンプルな直線補間です。(デフォルト値)

scene.TIMING_EASE_IN

 イースイン(ゆっくり動き出して加速していく)補間です。

scene.TIMING_EASE_IN_2

 2次のイースイン補間です。

scene.TIMING_EASE_OUT

 イースアウト(早く動いて、ゆっくりと止まる)補間です。

scene.TIMING_EASE_OUT_2

 2次のイースアウト補間です。

scene.TIMING_EASE_IN_OUT

 イースイン・イースアウト補間です。

scene.TIMING_SINODIAL

 TIMING_EASE_IN_OUTに似た、しかし幾分ゆったりした部分を減らした補間です。

scene.TIMING_ELASTIC_IN

 アニメーションの最初の部分に「ラバーバンド」効果を与えます。

scene.TIMING_ELASTIC_OUT

 アニメーションの最後の部分に「ラバーバンド」効果を与えます。

scene.TIMING_ELASTIC_IN_OUT

 アニメーションの最初と最後の部分に「ラバーバンド」効果を与えます。

scene.TIMING_BOUNCE_IN

 アニメーションの最初の部分に「バウンド」効果を与えます。

scene.TIMING_BOUNCE_OUT

 アニメーションの最後の部分に「バウンド」効果を与えます。

scene.TIMING_BOUNCE_IN_OUT

 アニメーションの最初と最後の部分に「バウンド」効果を与えます。

scene.TIMING_EASE_BACK_IN

 アニメーションの最初の部分に「行き過ぎて戻る」効果を与えます。

scene.TIMING_EASE_BACK_OUT

 アニメーションの最後の部分に「行き過ぎて戻る」効果を与えます。

scene.TIMING_EASE_BACK_IN_OUT

 アニメーションの最初と最初の部分に「行き過ぎて戻る」効果を与えます。

reminders — iOSのリマインダーデータベースへのアクセス

 reminders モジュールは、iOSのリマインダーデータベースの読込/書込のアクセスを提供します。リマインダーは Reminder クラスで扱うことができ、またリマインダーのリストは Calendar クラスで取扱います。

 (注 最初にリマインダーにアクセスする関数を使用する際には、システムの確認ダイヤログが表示されます。アクセスを拒否した場合、多くの関数は空のデータを返します。後でアクセスを許可したくなったら、設定アプリのプライバシーからリマインダーへのアクセス許可ができます。

クイックスタート

既存リマインダーの検索

 データベースにあるリマインダーを検索する場合には、シンプルに get_reminders() を呼び出します。引数 completed の設定により、リマインダーの未了/完了の状況(チェックがオフになっているか)でリストにフィルターをかけることができます:

import reminders
todo = reminders.get_reminders(completed=False)
print('やることリスト')
print('=========')
for r in todo:
    print('[ ] ' + r.title)
done = reminders.get_reminders(completed=True)
print('完了済の予定')
print('====')
for r in done:
    print('[x] ' + r.title)

新しいリマインダーを追加する

 新しいリマインダーを追加するためには、シンプルにタイトルと期日などを設定し、リマインダーオブジェクトを生成します。そして、Reminder.save() メソッドを呼び出して保存します:

import reminders
r = reminders.Reminder()
r.title = 'Pythonista からの追加項目です。'
r.save()
print('リマインダーに追加しましたよ。')

 Reminders アプリの中のリマインダーのリストは複数設定できます。これらのリストは reminders モジュールの中の Calendar オブジェクトで表現されます。特別な指定をしない場合、リマインダーはデフォルトのリストまたはカレンダーに追加されます。デフォルトとは異なるリストにリマインダーを追加するためには、シンプルにリマインダーを生成する際に、対応する Calendar オブジェクトを渡します。

 次の例はカレンダー(リスト)から「Pythonista」という名称のものを探し、見つかった場合には、「Pythonista リストの新しいリマインダーです。」という新しいリマインダ=を追加します:

import reminders
all_calendars = reminders.get_all_calendars()
for calendar in all_calendars:
    if calendar.title == 'Pythonista':
        r = reminders.Reminder(calendar)
        r.title = 'Pythonista リストの新しいリマインダーです。'
        r.save()
        break
else:
    print('"Pythonista"というカレンダー(リスト)は見つかりませんでした。')

カレンダー(リスト)の追加

 新しいカレンダー(リスト)をプログラムで作成することもできます。以下の例では Pythonista という名称のカレンダーが無い場合に、新しく Pythonista というカレンダーを作成します:

import reminders
all_calendars = reminders.get_all_calendars()
for calendar in all_calendars:
    if calendar.title == 'Pythonista':
        print('"Pythonista" というカレンダーは既に存在します。')
        break
else:
    new_calendar = reminders.Calendar()
    new_calendar.title = 'Pythonista'
    new_calendar.save()
    print('新しいカレンダーを追加しました。')

アラームの追加

 リマインダーは、実際に何かをリマインドした際、すなわち、通知を表示すると便利さを実感できます。そのためには、一つないし複数の :class:'Alarm' をリマインダーに追加する必要があります。:class:'Alarm' は指定の時間になった時、または地理的な場所への到着/出発により起動します。

 まずは日付と時刻によるアラームについて見てみましょう。次の例は、現在から25分後に通知を表示する、新しいリマインダーを追加します:

import reminders
import datetime
r = reminders.Reminder()
r.title = '休憩にしませんか?'
minutes = 25
due = datetime.datetime.now() + datetime.timedelta(minutes=minutes)
# 注:ここでは締切日時にアラームを鳴らすよう設定していますが、
# 別の日時にすることもできます。
r.due_date = due
a = reminders.Alarm()
a.date = due
r.alarms = [a]
r.save()
print(' %i 分後にリマインダーが通知をします。' % minutes)

 地理的な場所に基づいたアラームを追加するには、タイトルと緯度、経度を設定する必要があります。指定地点を中心としたアラームを出すべきエリアの半径と、そのエリアに入った時に鳴らすか、エリアから出た時に鳴らすかも指定できます:

import reminders

r = reminders.Reminder()
r.title = '自撮りしよ!'

a = reminders.Alarm()
lat, lng = 37.332224, -122.030780
radius = 500 # metres
title = '1 Infinite Loop'
a.location = (title, lat, lng, radius)
a.proximity = 'enter'
r.alarms = [a]
r.save()

Functions

reminders.get_reminders(calendar=None, completed=None)

 引数 calendar で指定した(または全ての)カレンダーから全てのリマインダーを取得します。

 引数 calendar が省略された、あるいは None の場合、全てのカレンダーの全てのリマインダーが返されます。

 引数 completed の値によって、リマインダーをフィルターにかけます:

  • None (the default): 全てのリマインダーを返します。
  • True: 完了済みの(チェックが外された)リマインダーのみを返します。
  • False: まだ完了していないリマインダーのみを返します。

reminders.get_all_calendars()

 使用できる全てのカレンダー(Clendar オブジェクト)のリストを返します。カレンダーはリマインダーのリストを示します。 Return a list of all available calendars (Calendar objects). Calendars represent lists of reminders.

reminders.get_default_calendar()

 デフォルトで新しいリマインダーとして使用されるカレンダーを返します。

reminders.get_calendar(calendar_id)

 引数 calendar_id で指定したカレンダーを返します。該当するカレンダーが見つからなかった場合には、None を返します。

reminders.delete_reminder(reminder)

 データベースからリマインダーを削除します。

 削除できた場合には、True を、できなかった場合には False を返します。

reminders.delete_calendar(calendar)

 データベースからカレンダーを削除します。

 削除できた場合には、True を、できなかった場合には False を返します。

Calendar オブジェクト

class reminders.Calendar

 カレンダーオブジェクトはリマインダーのリストを示します。全てのリマインダーは1つのカレンダーに属し、get_reminders() 関数を使用して特定のカレンダーのリマインダーを検索することができます。新しいリマインダーのためにデフォルトのカレンダーを取得するには、get_default_calendar() を使用します。全てのカレンダーはいずれも get_calendar() 関数を使用して検索できるようなIDを持っており、カレンダーの名称(タイトル)が変更されても、このIDは変更されません。

Calendar の属性

Calendar.title

 リマインダーのリストのタイトルです。(文字列、ユニコード)

Calendar.identifier

 カレンダーのIDです。(読込専用、文字列)

 この IDは、特定のカレンダーを検索することに後で使用できます。なお、カレンダーの名称(タイトル)が変更されてもIDは変更されません。

Calendar メソッド

Calendar.save()

 変更内容をデータベースに保存します。(カレンダーのメタデータのみが保存され、カレンダーに含まれているリマインダーは個別に Reminder.save() メソッドにより保存が必要です。)

Reminder オブジェクト

class reminders.Reminder([calendar])

 Reminder オブジェクトはリストの中の単体のリマインダーを意味します。リマインダーには複数のアラームオブジェクトを付属させることができます。アラームオブジェクトには、システムがリマインダーを通知する時刻や場所の属性を持っています。

 リマインダーは、常にリマインダーのリストを意味するカレンダーの構成要素です。リマインダーを初期設定する際に特定のカレンダーを指定しない場合には、デフォルトのカレンダーが使用されます。

Reminder の属性

Reminder.alarms

 リマインダーに関連づけられたアラームオブジェクトのリストです。

 (注:値は複製されます。アラームの属性を再設定しない限り、このリストの変更をしてもアラームは変更されません。)

Reminder.completed

 リマインダーが既に完了済(チェックが外されているか)を示します。(論理型)

Reminder.completion_date

 リマインダーが完了した(チェックが外された)日付を示します。完了していない場合には None となります。

Reminder.due_date

 リマインダーの締切日を示します。

 (注:締切日はアラームを設定する日とは同じではありません。リマインダーアプリに締切日が表示されても、アラームの追加をしない限り、通知を受けることはできません。アラームの追加は、リマインダーのアラーム属性を設定することによって行います。

Reminder.notes

 リマインダーに追加する注釈です。(文字列、ユニコード)

Reminder.priority

 リマインダーの優先順位です。(0=優先順位付けなし、1=優先順位最高、9=優先順位最低)

Reminder.title

 リマインダーのタイトル(名称)です。(文字列、ユニコード)

Reminder.url

 リマインダーに関連づけた URL です。

Reminder メソッド

Reminder.save()

 修正した内容をデータベースに保存します。(例 リマインダーのタイトルや完了/未了の属性を変更した場合など)

Alarm オブジェクト

class reminders.Alarm

 Alarm オブジェクトは、リマインダーに関連づけられたアラームを意味します。アラームは、指定時刻、または指定地点への進入/退出の際に起動できます。 Reminder.alarms 属性を設定することでリマインダーとアラームを関連づけることができます。

Alarm の属性

Alarm.date

 アラームが予定されている日付です。(datetime オブジェクト)

Alarm.location

 地理的位置に基づいたアラームのタイトル(名称)、緯度、経度および半径です。位置は3要素または4要素のタプルで示されます。(タイトル、緯度、経度[、半径])半径はデフォルトで100mになっています。

Alarm.proximity

 場所に応じたアラームの、到着または退出といった起動の条件を指定します。'enter'、'leave'または'none'のいずれかの値に設定します。

photos — iOS のフォトライブリーへのアクセス

 photos モジュールを使うと、iOS のフォトライブラリーに保管されたメディアへのアクセスができます。

 ライブラリーへの新しい画像ファイルの追加、既にあるコンテンツの修正、そして削除もできるようになります。

 (注 最初に photos にアクセスする関数を使う際には、iPhone/iPad に許可ダイアログが表示されます。もしアクセスを拒否した場合には、ほとんどの関数は、あたかもフォトライブラリーが空であるかのような動作をします。後でアクセスを許可したくなったら、「設定」アプリの「プライバシー」で写真へのアクセスを許可することできます。アプリの許可ダイアログは一度だけ表示されます。)

始めてみましょう

 フォトライブラリー内のメディアについて作業を始めるには、通常、少なくとも一つの Asset オブジェクトを必要とします。get_assets() 関数を使用することで、次の例のように、ライブラリーから全てのデータを取得することができます:

# 最後に撮った写真を取込み、コンソールに表示

import photos
all_assets = photos.get_assets()
last_asset = all_assets[-1]
img = last_asset.get_image()
img.show()

(訳注 上記のスクリプトは、保存されている写真の数が多い場合、写真の表示に数十秒を要することがあります。all_assets[-1]の数字を変更することで、任意の写真を表示させることができます。)

 Assets オブジェクトはデータの格納場所と種類(例 image (1536 x 2048))からなるメタデータに過ぎません。そのため、実際の画像データを得るには、上記の例のように Asset.get_image() 関数を使用しなければなりません。画像は PIL.Image オブジェクトとして返されます。代わりに ui.Image が必要な場合には、Asset.get_ui_image()を使用することになります。

 Assets は AssetCollection オブジェクトとしてまとめられています。Collections には通常のアルバムと、自動的に assets に組込まれた属性を持ったスマートアルバムの両方の形式があります。

 スマートアルバムの一種として、「スクリーンショット」アルバムがあり、 get_screenshots_album() 関数で簡単に検索することができます。次の短いスクリプトは、一番古いスクリーンショットを検索し、確認ダイアログを表示した上でライブラリーから削除します。

# 一番古いスクリーンショット画像を取得し、ライブラリーから削除

import photos
album = photos.get_screenshots_album()
screenshots = album.assets
if not screenshots:
    print('ライブラリーにスクリーンショットは無かったよ。')
else:
    oldest = screenshots[0]
    if oldest.can_delete:
        # こう書くだけで確認ダイヤログが自動的に表示されます。
        oldest.delete()
    else:
        print('一番古いスクリーンショットは消さずに残してあるよ。')

(訳注 確認ダイヤログの表示および一番古いスクリーンショットの削除は確認できていますが、print 文が実行されているか確認できていいません。(実行してもコンソールに文字が残っていない))

 編集した画像と置き換えることにより、ライブラリーの中の写真のコンテンツを修正することもできます。

 次の短いスクリプトは、「最近の項目」アルバムの最後のデータを読み込んで、グレースケール(白黒)に変換して画像を置き換えます。この編集は Photos アプリまたは Asset.revert() メソッドを使用することによって元の状態に戻すことができます:

# 最後の写真を取り込み、グレースケールに変換して差し替える

import photos
album = photos.get_recently_added_album()
last = album.assets[-1]
if last.can_edit_content:
    img = last.get_image()
    grayscale_img = img.convert('L')
    grayscale_img.save('.edit.jpg', quality=90)
    last.edit_content('.edit.jpg')
else:
    print('このデータは編集できません。')

 これまでの例では、インデックスを使って全てのデータを読み込んでいました。その他に、ユーザーに選択させるために画像のサムネイル一覧のダイアログを表示することもできます。pick_asset() 関数はデータ(または AssetCollection)のリストを取得し、選択されたデータを返します。複数選択することも可能です。引数なしで呼び出すと、「最近の項目」アルバムが表示されます:

# 複数選択可能な画像選択(イメージピッカー)ダイアログを表示し結果を表示

import photos
assets = photos.pick_asset(title='Pick some assets', multi=True)
print(assets)

関 数

photos.capture_image(camera='rear')

 標準的なカメラインターフェイスを表示し、取り込んだ PIL.Image オブジェクトの形でイメージを返します。

 デバイスにカメラが付いていない場合や、カメラインターフェイスがキャンセルされた場合には、None を返します。

 自分の写真を撮りたい場合には、引数 camera に 'front' を設定することができます。(マニュアルでのカメラ切替はいつでもできます。)

photos.get_assets(media_type='image', include_hidden=False)

 引数 media_type に指定した「image(静止画)」または「video(動画)」について、ライブラリー内にあるデータのリストを返します。デフォルトでは、隠しファイルは除いたリストになります。

photos.get_asset_with_local_id(local_id)

 引数 local_id (Asset.local_id の属性)で指定したデータをライブラリーから取得し返します。指定したデータがない場合には「IOError」が発生します。

photos.get_albums()

 フォトライブラリーの中のレギュラーアルバムのリストを返します。戻り値は AssetCollection オブジェクトのリストです。

photos.get_smart_albums()

 フォトライブラリーの中のスマートアルバムのリストを返します。戻り値は AssetCollection オブジェクトのリストです。

photos.get_moments()

 フォトライブラリーの中の全ての「モーメント」のリストを返します。「モーメント」は自動的に日付と場所でグルーピングされたデータです。戻り値は AssetCollection オブジェクトのリストです。

photos.get_favorites_album()

 「お気に入り」した全部のデータで構成されているスマートアルバムを返します。戻り値は AssetCollection オブジェクトです。

photos.get_recently_added_album()

 最近ライブラリーに追加したデータで構成されているスマートアルバムを返します。戻り値は AssetCollection オブジェクトです。

photos.get_selfies_album()

 画面側カメラで撮影したデータ(自撮り写真など)で構成されているスマートアルバムを返します。戻り値は AssetCollection オブジェクトです。

photos.get_screenshots_album()

 スクリーンショット機能で取得したデータで構成されているスマートアルバムを返します。戻り値は AssetCollection オブジェクトです。

photos.batch_delete(assets)

 フォトライブラリーから複数のデータを削除します。引数 assets は Asset オブジェクトを連ねたものでなければなりません。一つないしは複数のデータが消去不能な時には、IOError が発生し、全てのデータを削除せず残したままとします。データが削除できるかどうかについては、Asset.can_delete 属性を使って調べることができます。

photos.batch_revert(assets)

 複数のデータを、編集内容を取り消して元の状態に戻します。一つまたは複数のデータが編集不可能な場合、IOError が発生し、全てのデータを復元せずにそのままとします。データが編集できるかどうかについては、Asset.can_edit_content 属性を使って調べることができます。

photos.create_album(title)

 引数 title で与えた名前で、フォトライブラリーに新しいアルバムを生成して返します。戻り値は新しいアルバムを指し示す AssetCollection オブジェクトです。

photos.create_image_asset(image_path)

 フォトライブラリーに(例えば JPEG や PNG 形式の)引数 image_path で指定した新しい画像データを生成して返します。戻り値は新しい画像データを指し示す Asset オブジェクトです。

photos.pick_asset(assets=None, title='', multi=False)

 引数 assets で指定したサムネイル選択ダイアログを表示します。assets は Asset オブジェクトの連なり/リスト、または、単体の AssetCollection で指定します。

 引数 multi を True にした場合、ユーザーはデータを複数選択することができます。False にすると、一つのデータが選択されると画像選択ダイヤログは閉じられます。戻り値は multi が False の時は一つのデータ、True の時は Asset オブジェクトのリストになります。画像選択ダイアログがキャンセルされた場合には、None が返されます。

Asset クラス

class photos.Asset

 Asset クラスは画像とか動画といったフォトライブラリーの一つ一つのメディアごとに設定されています。Asset オブジェクトは直接初期化することはできません。get_assets() を使用するか、アルバムやスマートアルバムのAssetCollection.assets 属性 にアクセスしてライブラリーから取得する必要があります。

 Asset オブジェクトはメタデータのみを含んでいます。実際の画像データを取得する場合には、Asset.get_image() と get_image_data() メソッドを使用します。

 フォトライブラリーに新しい画像データを加えるには、create_image_asset() 関数を使用し、最初にディスクに保管した画像ファイルのパスを用意します。

Asset のメソッド

Asset.get_image(original=False)

 asset の画像データを取り込みます。そして、PIL.Image オブジェクトを返します。

 デフォルトでは、画像の最新バージョンが返されます。修正や編集なしの画像を取得するには、引数 original を True に設定して呼び出します。

Asset.get_image_data(original=False)

 asset の画像データを取り込みます。そして、io.BytesIO オブジェクトとして返します。画像データをバイト文字列として取得するために io.BytesIO.getvalue() を使用することができます。

 デフォルトでは、画像の最新バージョンが返されます。修正や編集なしの画像を取得するには、引数 original を True に設定して呼び出します。

 ファイルとして画像を保存するだけであれば、このメソッドはAsset.get_image() よりも効果的です。返された io.BytesIO は画像データのファイルタイプを決めるために使用できる追加の uti 属性を持っています。

Asset.get_ui_image(size=None, crop=False)

 asset の画像データを取得し、ui.Image オブジェクトを返します。ユーザーインターフェイスに表示するためなどに使用できます。幅と高さのペアでサイズを渡すことによって、画像のよりコンパクトなバージョンを要求することが可能です。(None を渡した場合、最も大きなバージョンを取得することになります。)

 引数 crop は、引数 size で指定した画像の縦横比に合わない時の拡大縮小の方法を指定します。True を渡すと、size で指定した通りのサイズで取得します。これは例えば、サムネイル画像を生成するのに便利な方法です。

Asset.edit_content(jpeg_path)

 asset の画像コンテンツを引数 jpeg_path で指定した JPEG ファイルに置き換えます。

 asset が編集不可能な場合、IOError が発生します。Asset.can_edit_content 属性を使って、編集可能かどうか確かめることができます。

 画像ファイルは JPEG 形式でなければならないことに注意してください。他の画像フォーマットは編集コンテンツとしてはサポートされていません。(create_image_asset() を使って新しいPNGファイルやGIFファイルを作成できるにも関わらず)

 システムは編集するかどうかの確認ダイヤログを表示します。

Asset.delete()

 フォトライブラリーから asset を削除します。

 asset が削除できない場合には、IOError が発生します。asset が削除可能かどうかは、Asset.can_delete 属性を使って確認できます。

 システムは削除するかどうかの確認ダイヤログを表示します。

 複数の asset を確認ダイヤログを表示せずに削除したい場合には、batch_delete() 関数を使います。

Asset.revert()

 asset を元の状態に戻します。

 asset が編集不能な場合には、IOError が発生します。Asset.can_edit_content 属性を使えば、asset が編集可能かどうか調べることができます。

 システムは編集に関する確認ダイアログを表示します。

 複数の asset を確認ダイヤログを表示せずに元の状態に戻したい場合には、batch_revert() 関数を使います。

Asset の属性

Asset.local_id

 (読込専用、文字列)現在のデバイス上の asset の ID です。

Asset.pixel_width

 (読込専用、数値型) asset のピクセル(画素)単位の幅です。

Asset.pixel_height

 (読込専用、数値型) asset のピクセル(画素)単位の高さです。

Asset.media_type

 (読込専用、文字列) asset のメディア型です。('image(画像)' または 'video(動画)')

Asset.media_subtypes

 (読込専用、文字列のリスト) asset のメディアのサブタイプです。(例  'photo_screenshot(スクリーンショット)', 'photo_hdr(HDR写真)'など)

Asset.creation_date

 (読書可能、日付型) asset を生成した日付です。Asset.can_edit_properties が True の時だけ書き込めます。

Asset.modification_date

 (読書可能、日付型) asset を編集した日付です。

Asset.hidden

 (読書可能、論理型) asset をライブラリーの中で非表示にするかどうかを指定します。can_edit_properties が True の時だけ書き込めます。

Asset.favorite

 (読書可能、論理型) asset が「お気に入り」になっているかどうかを示します。can_edit_properties が True の時だけ書き込めます。

Asset.duration

 (読込専用、数値型) 動画の再生時間を秒単位で示します。(画像の場合は常にゼロになります。)

Asset.location

 (読書可能、辞書型) 写真または動画を撮影した場所の地理的な位置を示します。少なくとも「緯度」と「経度」、場合によっては高度も含む辞書型になっています。can_edit_properties が True の時だけ書き込むことができます。

Asset.can_edit_content

 (読込専用、論理型) asset のコンテンツが変更可能かどうかを示します。Asset.revert() や Asset.edit_content()で使用します。

Asset.can_edit_properties

 (読込専用、論理型) asset のメタデータが変更可能かどうかを示します。Asset.favorite, Asset.hidden, Asset.creation_date, Asset.location で使用します。

Asset.can_delete

 (読込専用、論理型) asset が Asset.delete() を使って削除可能かどうかを示します。

AssetCollection のクラス

class photos.AssetCollection

 AssetCollection オブジェクトはフォトライブラリーのコレクション、すなわちアルバムとスマートアルバムを示します。「モーメント」(日付と場所で自動的にグルーピングされた写真)もまた AssetCollection オブジェクトで示されます。

 AssetCollection は直接初期化できません。その代わりに、get_albums()、get_smart_albums()、 get_moments() 関数を使ってフォトライブラリーからコレクションを取得します。いくつかの特別なスマートアルバムは、例えば、get_screenshots_album()、get_recently_added_album()、get_selfies_album() を使って、簡単にアクセスすることもできます。

 フォトライブラリーに新しいアルバムを生成するには、create_album() 関数を使います。AssetCollection.add_assets() を使って、asset を追加することができます。(または AssetCollection.remove_assets()を使って削除することができます。)

AssetCollection のメソッド

AssetCollection.delete()

 フォトライブラリーから asset collection を削除します。asset 自体は削除されません。

 asset collection が削除不能の場合、IOError が発生します。AssetCollection.can_delete 属性で削除可能かどうか確認できます。

AssetCollection.add_assets(assets)

 asset オブジェクトのリストを、このオブジェクトが示すアルバムに追加します。

 全ての asset collection の追加が許されている訳ではありません。AssetCollection.can_add_assets 属性を使えば追加可能かどうか確認できます。

AssetCollection.add_assets(assets)

 asset オブジェクトのリストを、このオブジェクトが示すアルバムから削除します。

 全ての asset collection の削除が許されている訳ではありません。AssetCollection.can_remove_assets 属性を使えば追加可能かどうか確認できます。

AssetCollection の属性

AssetCollection.assets

 (読込専用、asset オブジェクトのリスト) asset collection を構成する asset のリストです。リスト自体を直接変更してもフォトライブラリー上の collection には影響がないことに注意が必要です。追加や削除には、それぞれ、AssetCollection.add_assets() や AssetCollection.remove_assets() を使用します。

AssetCollection.local_idb

 (読込専用、文字列)現在のデバイス上の asset collection のIDです。

AssetCollection.title

 (読書可能、文字列) asset collection の(場合によっては局所的な)タイトルです。 AssetCollection.can_rename が True の時だけ書き込むことができます。

AssetCollection.type

 (読込専用、文字列) asset collection の型です。('album', 'smart_album' または 'moment').

 AssetCollection.subtype

 (読込専用、文字列) asset collection のサブタイプです。(例えば、'favorites', 'recently_added'など)

 AssetCollection.start_date

 (読込専用、日付型) asset collection の中で一番最初の asset を作成した日付です。

 AssetCollection.end_date

 (読込専用、日付型) asset collection の中で一番最後に asset を作成した日付です。

 AssetCollection.can_delete

 (読込専用、論理型) asset collection を削除できるか否かを示します。

 AssetCollection.can_add_assets

 (読込専用、論理型) AssetCollection.add_assets() を使った asset の追加が許可されているかを示します。

 AssetCollection.can_remove_assets

 (読込専用、論理型) AssetCollection.remove_assets() を使った asset の削除が許可されているかを示します。

 AssetCollection.can_rename

 (読込専用、論理型) asset collection のタイトルを変更可能か否かを示します。

使用をお勧めしない関数

 以下の関数は以前のバージョンとの互換性確保のために使用可能としていますが、新しいコードを作成する際には使用をお勧めしません。

  • get_count() – カメラロールの中の画像の数を返します。
  • get_image(image_index=-1, original=True, raw_data=False) – カメラロールの中の画像の中から1枚を返します。get_assets() を代わりに使用して下さい。
  • get_metadata(image_index=-1) – カメラロールの中の画像の EXIF やその他のメタデータをディクショナリー型で返します。asset のメタデータ属性を代わりに使用して下さい。
  • get_thumbnail(image_index=-1) – カメラロールの中の画像の小さなサムネイル画像を返します。サムネイル画像はオリジナル画像の縦横比に関係なく、正方形になっています。Asset.get_ui_image() を代わりに使用して下さい。
  • pick_image(show_albums=False, include_metadata=False, original=True, raw_data=False, multi=False) – 標準的な画像選択画面を表示し、選択した画像を返します。pick_asset() を代わりに使用して下さい。
  • save_image(image) – カメラロールに PIL イメージまたは ui.Image を保管します。create_image_asset() を代わりに使用して下さい。

objc_util — オブジェクティブC の APIs との橋渡しのユーティリティー

 objc_util モジュールは、Python からオブジェクティブC の API(Application Programming Interface:プログラムから iOS にアクセスするためのインターフェイス)群への「橋渡し」をします。

 (訳注 この項目については、私自身のオブジェクト指向の理解が不十分であることと、原文も少々乱れ気味であること、サンプルのスクリプトも動作が確認できていないことから、適切な訳になっていない可能性があります。お読みになる際には、是非、原文も併せてご確認をお願いします。)

 C言語と互換性のあるデータタイプを持つ python の関数ライブラリーである ctypes と、オブジェクティブCのランタイムライブラリーをベースに成り立っており、objc_util を使用することによって、既存のオブジェクティブCのクラスを Python から扱えるようになります。この時、Python のメソッド呼び出しをオブジェクティブCのメッセージに自動的に変換するような方法が用いられます。

  簡単な例として、次のオブジェクティブCのコードは、

UIPasteboard *pasteboard = [UIPasteboard generalPasteboard]
[pasteboard setString:@"Hello Objective-C"];

 以下の Python のコードに翻訳することができます:

from objc_util import *
UIPasteboard = ObjCClass('UIPasteboard')

pasteboard = UIPasteboard.generalPasteboard()
pasteboard.setString_('Hello Objective-C')

 (訳注 上記のスクリプトを実行しただけでは、一見、何も起こらないように見えますが、クリップボードに'Hello Objective-C'という文字列を書き込んでいます。スクリプト実行後、例えば python のエディター内の画面の任意の場所をタップして「ペースト」すると、スクリプトが実際に実行されたことが分かります。)

 Python からオブジェクティブCのAPI を呼び出す際に、オブジェクティブCで直接コードを書くのに比べて極端に多量のコードを書く必要がないことが分かります。

 このスクリプトの実行にあたり、objc_util は、Python の関数呼出しをオブジェクティブCのメッセージに変換するため、objc_msgSned() などの適切な関数呼出しを行います。また、Python の一般的な型(例えば、上記のスクリプトでの文字列だけでなく、リストやディクショナリーも)については、このメソッドを呼び出すことによって、オブジェクティブCの同等の基本的な型(NSString, NSMutableArray, NSMutableDictionary など)に変換されます。

 オブジェクティブ Cのセレクター(メソッドの内部表現)から Python のメソッドの名前への変換は、極めて単純に行えます。基本的にはコロン「:」をアンダースコア「_」に置き換えるだけです。例えば、doFoo:withBar: というセレクターは、doFoo_withBar_ というメソッドになります。(注 末尾にもアンダースコアがつくことにご注意ください)

 多くの場合、もう少し「パイソンぽい」文法を使うこともできます。例えば、オブジェクティブCのセレクター名の一部としてのキーワードとなる引数を使って:

# From: UIColor *color = [UIColor colorWithRed:1.0 green:0.0 blue:0.0 alpha:1.0]
# ...to:
UIColor = ObjCClass('UIColor')
color = UIColor.colorWithRed(1.0, green=0.0, blue=0.0, alpha=1.0)
# or even:
color = UIColor.color(red=1.0, green=0.0, blue=0.0, alpha=1.0)

 この、より自然な文法は多くの場合動作しますが、メソッド名とキーワードとなる引数の組合せによっては、オブジェクティブCのメソッド呼出しに適切に変換できない場合があります。このような場合、キーワードとなる引数を使わずに、前述のようにコロンをアンダースコアに置き換える方法で呼出し変数を記述してください。

 (注 ctypes モジュールの使用により Python がクラッシュすることがあります。オブジェクティブCのメソッドを呼び出す場合には、正しいパラメーター型を選ぶよう慎重に行ってください。)

例 1 – 画面の明るさを設定する

 この単純な例は、デバイスの画面の明るさを設定するものです:(訳注 このスクリプトは現在のところ動作が確認できていません)

from objc_util import *

# 'Import' an Objective-C class (generate a proxy for the class):
UIScreen = ObjCClass('UIScreen')

# Call a class method, this is equivalent to `[UIScreen mainScreen]` in Objective-C:
screen = UIScreen.mainScreen()

# `screen` is now an ObjCInstance that wraps an Objective-C object, and forwards messages to it.

# The following call is equivalent to `[screen setBrightness:0.6]`:
screen.setBrightness(0.6)

例 2 – Music/iPod アプリの現在の曲にアクセスする

 このコードは、現在再生中の曲のアーティスト名と曲名をコンソールに表示します。(注 純正の Music アプリにのみ対応しており、サードパーティ製の音楽再生アプリでは使用できません)(訳注 このスクリプトは現在のところ動作が確認できていません)

from objc_util import *

MPMusicPlayerController = ObjCClass('MPMusicPlayerController')
player = MPMusicPlayerController.systemMusicPlayer()
now_playing = player.nowPlayingItem()
if now_playing:
    artist = now_playing.valueForProperty_('artist')
    title = now_playing.valueForProperty_('title')
    print('Now playing: %s -- %s' % (artist, title))
else:
    print('No music playing')
Creating New Objective-C Classes

 より高度なオブジェクティブCのAPIの使い方をする場合には、ランタイムのオブジェクティブCのクラスを独自に作る必要が出てきます。この場合には、2つの方法があります:

  •  一般的に使用されているデリゲートパターンを実行する。すなわち、iOS に組み込まれたオブジェクティブCのクラスのコールバックインターフェイスを適用する方法です。
  •  カスタマイズを目的として、オブジェクティブCのクラスのサブクラスに位置付ける。一例として、-drawRect: をオーバーライド(子クラスで親クラスのメソッドを書き換えること)するための UIView のサブクラス化があります。

 これを成し遂げるために、objc_util モジュールには create_objc_class() 関数があります。この関数はオブジェクトCランタイムを新しいクラスに割り当てたり記録したりするほか、上の例の組み込まれたクラスのように使用できるObjCClass オブジェクトをラップします。

 create_objc_class() を使ってオブジェクティブCのクラスを作るには、以下の事柄が必要です:

name – 生成するクラスの名前で文字列型です。文字、数字とアンダースコア(アンダーバー)だけが使用可能で、数字から始めることはできません。実際に生成されるクラスの名前は、これとは異なることがあることに注意して下さい。なぜなら、この名前のクラスは既に存在している場合があるからです。このような場合、新しい名前が自動的に選ばれ、デフォルトで debug パラメーターは True になります。逆に debug が False の場合には、存在しているクラスが返され、他の全てのパラメーターは無視されます。

superclass – 新しいクラスが継承するオブジェクティブCのクラスを決定する ObjCClass オブジェクトです。

methods – 新しいクラスのインスタンスのメソッドを生成するのに使用される関数のリストです。Python の関数からオブジェクティブCのメソッドを生成するためには、オブジェクティブCのランタイムは追加のメタデータを必要とします。セレクターの名前、戻り値の型、引数ごとの型が必要となります。create_objc_class() は、可能な範囲でこのメタデータを引き出そうと努めます。その手順について以下に説明します。

全てのオブジェクティブCのメソッドは、オブジェクティブCから呼び出される際には隠れてしまう、少なくとも2つのパラメーターを必要とします:_self はオブジェクティブCのオブジェクトそのものを示すポインタです。(これはObjCInstance のオブジェクトをラップするものではなく、そのため必要なら別途ラップする必要があることに注意が必要です)そして、_cmdはセレクターを示すポインタです。(通常は必要ありません)これら2つの「隠された」パラメーターの名前は重要ではありません。パラメーターがObjCInstance のオブジェクトではなく、「そのままの」ポインタとしてオブジェクティブCのメソッドに渡されることにご注意ください。但し、オブジェクトのパラメーターはラップするコーディングをすることで簡単に変換することができます。例えば、obj = ObjCInstance(_self)という形で。

classmethods (optional) – クラスのメソッドがなければ、メソッドと同様です。(必要になることは稀です)

protocols (optional) – メソッドの型変換のヒントとして使用する文字列のリストです。デリゲート(またはその他の)プロトコルを実行する場合、全てのメソッドの戻り値と引数の型を確実に正しく推論できるよう、プロトコルの名前(例えば、'UITableViewDataSource')を記述する必要があります。

 以下は、(iOS の標準メールシートを表示するために使用される)MFMailComposeViewController のデリゲートとして動作する、シンプルなクラスを生成する例です。デリゲートはこのクラスの使用に必要不可欠です。なぜなら、他の方法ではメールシートを取り除くことができないためです。(メールシートの使用が終了した際にデリゲートが通知され、それによりシートが開放されます。):

# - (void)mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error
def mailComposeController_didFinishWithResult_error_(_self, _cmd, controller, result, error):
    print('Mail composer finished')
    # Wrap the controller parameter in an `ObjCInstance`, so we can send messages:
    mail_vc = ObjCInstance(controller)
    # Set delegate to nil, and release its memory:
    mail_vc.setMailComposeDelegate_(None)
    ObjCInstance(_self).release()
    # Dismiss the sheet:
    mail_vc.dismissViewControllerAnimated_completion_(True, None)

methods = [mailComposeController_didFinishWithResult_error_]
protocols = ['MFMailComposeViewControllerDelegate']
MyMailComposeDelegate = create_objc_class('MyMailComposeDelegate', NSObject, methods=methods, protocols=protocols)

@on_main_thread
def show_mail_sheet():
    MFMailComposeViewController = ObjCClass('MFMailComposeViewController')
    mail_composer = MFMailComposeViewController.alloc().init().autorelease()
    # Use our new delegate class:
    delegate = MyMailComposeDelegate.alloc().init()
    mail_composer.setMailComposeDelegate_(delegate)
    # Present the mail sheet:
    root_vc = UIApplication.sharedApplication().keyWindow().rootViewController()
    root_vc.presentViewController_animated_completion_(mail_composer, True, None)

if __name__ == '__main__':
    show_mail_sheet()

API リファレンス

 クラス

class objc_util.ObjCClass(name)

 引数 name で指定したオブジェクティブCのラッパーです。オブジェクティブCのクラスのメソッドを代理で呼び出します。

 メソッドの呼び出しは、スクリプトの動作の過程でオブジェクティブCのメッセージに変換されます。メソッドの名前の中のアンダースコアがセレクターの名前の中のコロンに置き換えられ、オブジェクティブCのランタイムの中で、セレクターと引数がよりOSに近いレベルの objc_msgSend() 関数を呼び出すことに使われてこの変換が実行されるのです。

 例えば、NSDictionary.dictionaryWithObject_forKey_(obj, key) (Python) の呼び出しは、実際のところ、[NSDictionary dictionaryWithObject:obj forKey:key] (Objective-C)に変換されます。メソッドの呼び出しがオブジェクティブCのオブジェクトを返した場合、それは ObjCInstance をラップしたことになり、呼び出しを結びつけることができます。(ObjCInstance は同様のプロキシの仕組みを使用します)

 いくつかの共通に使用されたクラスはモジュールの要素です。(最後のリストを参照)その他については、クラスの名前を使って単に「インポート」することになります。例:

UIPasteboard = ObjCClass('UIPasteboard')

class objc_util.ObjCInstance(ptr)

 オブジェクティブCのオブジェクトへのポインターのラップです;オブジェクトへメッセージを送る際のプロキシとして動作します。

 メソッドの呼び出しは、スクリプトの動作の過程でオブジェクティブCのメッセージに変換されます。メソッドの名前の中のアンダースコアがセレクターの名前の中のコロンに置き換えられ、オブジェクティブCのランタイムの中で、セレクターと引数が objc_msgSend() 関数を呼び出すことに使われてこの変換が実行されるのです。

例えば、obj.setFoo_withBar_(foo, bar) (Python) の呼び出しは、obj setFoo:foo withBar:bar] (Objective-C)に翻訳されます。メソッドの呼び出しによりオブジェクティブCのオブジェクトが返される場合には、ObjCInstance にもラップされ、言わば結びつけられることになります。

  NSObject メソッドの記述を呼び出すことで ObjCInstance は__str__ and __repr__ を実行します。

 インスタンスが標準的なオブジェクティブCの集合型(NSArray, NSDictionary, NSSet)をラップする場合、標準的なPythonの集合と多くの点で似通った動作をします。イテレート(for..in)できますし、「some_dict['key'], some_array[3]...)」のように、角括弧を使ったキーやインデックスでアイテムにアクセスすることもできます。

class objc_util.ObjCBlock(func, restype=None, argtypes=None)

 ブロックのサポートはまだ実験的なものであることにご注意ください。ブロックを必要としない API を使用する選択肢がある場合には、そちらを強くお勧めします。

 ObjCBlock はオブジェクトCメソッドに対して、blocks (“closures”)を渡して使用することができます。前述の通り、この機能は実験的であり、可能であれば、通常はブロック不要のAPIを使用すべきです。戻り値や引数がないブロックの場合、Python の関数を渡せます。そして、ObjCBlock へ自動的に変換されます。そのほかの場合には、ブロックを作る際、戻り値と引数を明確に設定する必要があります。

 引数のあるブロックの例(NSMutableArrayをカスタマイズした比較関数でソート):

from objc_util import *
cheeses = ns(['Camembert', 'Feta', 'Gorgonzola'])
print(cheeses)

def compare(_cmd, obj1_ptr, obj2_ptr):
    obj1 = ObjCInstance(obj1_ptr)
    obj2 = ObjCInstance(obj2_ptr)
    # Sort the strings by length:
    return cmp(obj1.length(), obj2.length())

# Note: The first (hidden) argument `_cmd` is the block itself, so there are three arguments instead of two.
compare_block = ObjCBlock(compare, restype=NSInteger, argtypes=[c_void_p, c_void_p, c_void_p])

sorted_cheeses = cheeses.sortedArrayUsingComparator_(compare_block)
print(sorted_cheeses)

 関 数

objc_util.autoreleasepool()

 NSAutoreleasePool のラッパーとして動作するコンテキストマネージャーです。 (オブジェクトCの @autoreleasepool {...} に似ています)

 使用例:

  with objc_util.autoreleasepool():

   # do stuff...

objc_util.create_objc_class(name, superclass=NSObject, methods=[], classmethods=[], protocols=[], debug=True)

 引数で与えられたメソッドを実行する新しい ObjCClass を生成して返します。

 セレクターの名前は関数の名前に応じて設定されます。関数の名前には、オプションとして、オブジェクティブCのクラスの名前を前につけることができます。例えば、これら2つの関数は、結果として同じセレクターの名前になります:

def MyClass_doSomething_withObject_(_self, _cmd, foo, bar):
    pass

def doSomething_withObject_(_self, _cmd, foo, bar):
    pass

 # これらの関数は両方とも 'doSomething:withObject:'というセレクターの名前になります。

 戻り値の型と引数の型を決めるため、 create_objc_class() は親クラスが同じセレクターのメソッドを持っているか確認します。同じセレクターのメソッドを持っている場合、親クラスのメソッドから型を継承します。この手法により、子クラスのメソッドにも親クラスの型を継承します。これでうまく行かない場合には、引数 protocols で渡した型が使われます。引数 protocols は文字列のリストです。例えば、 ['UIGestureRecognizerDelegate', 'UITableViewDataSource'] というような。これらの protocols は、同じセレクターのメソッドがあるか確認されます。この手法により、例えば、デリゲートプロトコルが設定されます。それとともに、これらの手法により多くの一般的な場合、型の情報が決められます。これらが上手く動作しない場合には、関数の引数として restype, argtypes, encoding を渡す事もできます。

 注 既に存在しているオブジェクティブCのクラスを使用する場合には、単純にObjCClass(name) を使ってリファレンスを取得して下さい。この関数は、新しいクラス生成します。例えば、オブジェクティブCのクラスの子クラスや、デリゲートプロトコルを設定します。

objc_util.load_framework(name)

 引数 name で指定したシステムフレームワークを読み込みます。(例えば、'SceneKit')

 得られるシステムフレームワークは、オブジェクトCのコードに相当します。[[NSBundle bundleWithPath:@"/System/Frameworks/.framework"] load]

objc_util.ns(obj)

 Python のオブジェクトを ObjC の同等のオブジェクトに変換します。すなわち、str => NSString, int/float => NSNumber, list => NSMutableArray, dict => NSMutableDictionary, bytearray => NSData, set => NSMutableSet という変換をします。リストやディクショナリー、集合型のような入れ子構造にも対応しています。既にObjCInstance のインスタンスになっているオブジェクトについては、変換せずそのまま返します。

 オブジェクティブCのメソッドがパラメーターとしてオブジェクトと推定される場合、Python オブジェクトのパラメーターは自動的にこの関数を使って変換され、例えば、Python の文字列は NSString としてオブジェクティブCのメソッドに渡すことができるようになります。

objc_util.nsurl(url_or_path)

 Python の文字列をNSURLのオブジェクトに変換します。(ObjCInstance でラップします)

 引数 url_or_path の文字列にコロン ‘:’ が含まれている場合、文字列はフルURLとして扱われ、+URLWithString: を使って NSURL に変換されます。それ以外の場合、+fileURLWithPath: を使ってファイルのURLが生成されます。

objc_util.nsdata_to_bytes(data)

 ObjCInstance でラップされた NSData オブジェクトを Python のバイト文字列に変換します。

objc_util.uiimage_to_png(img)

 ObjCInstance でラップされた UIImage オブジェクトを Python の PNG データで構成されたバイト文字列に変換します。

objc_util.on_main_thread(func)

 UIKit のメインスレッド上の関数(引数 func で指定)をデコレートする関数です。多くのオブジェクティブCの API、特に UIKit は、メインスレッドから呼び出す必要があります。一般的に、その他の関数をデコレートするために使われますが、例えば on_main_thread(my_function)(param1, param2) のように、特別にメインスレッドへの関数呼び出しを割り当てるために使用することもできます。

 以下はデコレーターの例です:

from objc_util import *

@on_main_thread
def post_notification(name):
    NSNotificationCenter = ObjCClass('NSNotificationCenter')
    center = NSNotificationCenter.defaultCenter()
    center.postNotificationName_object_(name, None)

# 全ての post_notification(...) の呼び出しは、on_the_thread で発生します。 

objc_util.sel(name)

 sel_registerName の便利なラッパーです。(Python の文字列をオブジェクティブCのセレクターに変換します)

 オブジェクティブCのクラスと構造体

 利便性を考えて、いくつかの共通して使われるオブジェクティブCのクラスや構造体は、モジュールレベルのオブジェクトとして使用可能になっています。そのため、以下のクラスと構造体については、明確にラップする必要はありません:

class objc_util.CGPoint

class objc_util.CGSize

class objc_util.CGVector

class objc_util.CGRect

class objc_util.CGAffineTransform

class objc_util.UIEdgeInsets

class objc_util.NSRange

class objc_util.NSDictionary

class objc_util.NSMutableDictionary

class objc_util.NSArray

class objc_util.NSMutableArray

class objc_util.NSSet

class objc_util.NSMutableSet

class objc_util.NSString

class objc_util.NSMutableString

class objc_util.NSData

class objc_util.NSMutableData

class objc_util.NSNumber

class objc_util.NSURL

class objc_util.NSEnumerator