Pythonとの統合

Dragonframe 2027(現在開発中)以降、DragonframeはPython + PySide(Qt 6.11まで)をサポートします。.

インストール後 2027.01 開発ビルド, ~/Dragonframe/scripts/__init__.py に Python 初期化ファイルを作成します。
また、環境変数 DRAGONFRAME_PATH に、Python モジュールディレクトリへのパスをコロンで区切ったリストを設定することもできます。.

現時点ではインターフェースはまだ開発段階です。最終リリースまでに変更される可能性があります。.
util.executeInMainThread および util.executeInMainThreadWithResult を除き、すべての関数はメインスレッドからのみ呼び出す必要があることに注意してください。.

利用可能なモジュールとメソッドは以下のとおりです。

=== dragonframe.ui ===

Menu:
Members:

  FileMenu : The File menu.

  EditMenu : The Edit menu.

  ViewMenu : The View menu.

  SceneMenu : The Scene menu.

  CaptureMenu : The Capture menu.

  PlaybackMenu : The Playback menu.

  WindowMenu : The Window menu.

  HelpMenu : The Help menu.

  UserTopLevel1 : A top-level user menu.

  UserTopLevel2 : A top-level user menu.

  UserTopLevel3 : A top-level user menu.

  CinematographyImageContextMenu : The right-click context menu on the cinematography image.

addMenuOption:
addMenuOption(arg0: dragonframe.ui.Menu, arg1: str, arg2: object) -> None

Add a menu item to the specified menu.

    location -- Menu value indicating which menu to add the item to
    label    -- display text for the menu item
    callback -- callable invoked with no arguments when the item is selected


addMenuSeparator:
addMenuSeparator(arg0: dragonframe.ui.Menu) -> None

Add a separator line to the specified menu.

    location -- Menu value indicating which menu to add the separator to


isMenuOptionChecked:
isMenuOptionChecked(arg0: dragonframe.ui.Menu, arg1: str) -> bool

Returns if a menu item is checked.

    location -- Menu value indicating which menu to add the item to
    label    -- display text for the menu item


setMenuOptionChecked:
setMenuOptionChecked(arg0: dragonframe.ui.Menu, arg1: str, arg2: bool) -> None

Sets a menu item to be checkable and sets the current value.

    location -- Menu value indicating which menu to add the item to
    label    -- display text for the menu item
    checked  -- whether the menu item is checked


setTopLevelMenuName:
setTopLevelMenuName(arg0: dragonframe.ui.Menu, arg1: str) -> None

Set the name of a user-defined top level menu.

    location -- UserTopLevel1, UserTopLevel2, or UserTopLevel3
    label    -- display text for the menu



=== dragonframe.events ===

EventType:
Members:

  Shoot : A capture (shoot) has been initiated.

  Delete : A frame has been deleted.

  Position : The playhead position has changed.

  CaptureComplete : A single exposure capture has completed.

  FrameComplete : All exposures for the current frame have been captured.

  TestComplete : A test shot capture has completed.

  Edit : An edit operation has occurred.

  AfterAssist : An assist operation has finished.

  Exposure : The active exposure (pass) has changed.

  Bash : A bash/shell script event has fired.

  Save : The scene has been saved.

  NewTake : A new take has been created.

  CaptureFailed : A capture attempt failed.

  MocoDisconnected : The motion control rig has disconnected.

  CameraDisconnected : The camera has disconnected.

registerInterest:
registerInterest(arg0: list[dragonframe.events.EventType], arg1: object) -> None

Register a callback to be invoked when any of the given EventType values occur.

    types    -- list of EventType values to listen for
    callback -- callable invoked with the EventType when the event fires

Example::

    def on_event(event_type):
        print('event:', event_type)
    dragonframe.events.registerInterest(
        [dragonframe.events.EventType.FrameComplete], on_event)


=== dragonframe.scene ===

currentExposure:
currentExposure() -> int

Return the 1-based index of the currently active exposure (pass), or 0 if no scene is open.


currentFrame:
currentFrame() -> int

Return the 1-based index of the currently selected frame, or 0 if no scene is open.


exposureCount:
exposureCount() -> int

Return the number of exposures (passes) defined in the current scene, or 0 if no scene is open.


exposureFolder:
exposureFolder(arg0: int) -> str

Return the absolute path to the capture folder for the given exposure.

    exposure -- 1-based exposure (pass) index

Returns an empty string if no scene is open.


exposureFramePrefix:
exposureFramePrefix(arg0: int) -> str

Return the file name prefix used for captured frames of the given exposure.

    exp -- 1-based exposure index

Returns an empty string if no scene is open.


exposureName:
exposureName(arg0: int) -> str

Return the display name of the given exposure (pass).

    exp -- 1-based exposure index

Returns an empty string if no scene is open.


feedFolder:
feedFolder() -> str

Return the absolute path to the live-view feed folder, or an empty string if no scene is open.


highResFile:
highResFile(arg0: int, arg1: int, arg2: bool) -> str

Return the file path of the captured image for a given frame and exposure.

    vframe   -- 1-based virtual frame number
    exposure -- 1-based exposure (pass) index
    raw      -- if True, return the path to the raw file instead of the processed image


importAxisSetup:
importAxisSetup(arg0: str) -> None

Import a motion control axis setup file.

    fileName -- absolute path to the .dfscene file


loadMediaIntoReferences:
loadMediaIntoReferences(arg0: list[str]) -> None

Load images into the references folder.




loadMediaIntoTestShots:
loadMediaIntoTestShots(arg0: list[str]) -> None

Load images into the test shots folder.




loadReferenceLayerImage:
loadReferenceLayerImage(arg0: str) -> bool

Load a still image as the active reference layer.

    fileName -- absolute path to the image file


loadReferenceLayerImageSequence:
loadReferenceLayerImageSequence(arg0: str) -> bool

Load an image sequence as the active reference layer.

    fileName -- absolute path to the first frame of the image sequence


loadReferenceLayerMovie:
loadReferenceLayerMovie(arg0: str) -> bool

Load a movie file as the active reference layer.

    fileName -- absolute path to the movie file


loadReferenceLayerScene:
loadReferenceLayerScene(arg0: str) -> bool

Load another Dragonframe scene as the active reference layer.

    fileName -- absolute path to the .dfscene file


name:
name() -> str

Return the full name of the open scene, or an empty string if no scene is open.


namePrefix:
namePrefix() -> str

Return the name prefix used when constructing frame file names, or an empty string if no scene is open.


save:
save() -> None

Save the current scene to disk. Has no effect if no scene is open.


sceneFolder:
sceneFolder() -> str

Return the absolute path to the scene folder, or an empty string if no scene is open.


sceneName:
sceneName() -> str

Return the scene number/identifier portion of the scene name, or an empty string if no scene is open.


setCurrentExposure:
setCurrentExposure(arg0: int) -> None

Set the currently active exposure (pass).

    exp -- 1-based exposure index

Has no effect if no scene is open.


setCurrentFrame:
setCurrentFrame(arg0: int) -> None

Set the currently selected frame.

    frame -- 1-based frame index

Has no effect if no scene is open.


takeFile:
takeFile() -> str

Return the absolute path to the scene data file (.dfscene), or an empty string if no scene is open.


takeFolder:
takeFolder() -> str

Return the absolute path to the current take folder, or an empty string if no scene is open.


takeName:
takeName() -> str

Return the take number/identifier portion of the scene name, or an empty string if no scene is open.


testRefsFolder:
testRefsFolder() -> str

Return the absolute path to the test reference images folder, or an empty string if no scene is open.


testShotsFolder:
testShotsFolder() -> str

Return the absolute path to the test shots folder, or an empty string if no scene is open.


=== dragonframe.util ===

executeInMainThread:
executeInMainThread(call: object, args: object = (), kwargs: dict = {}) -> None

Executes a call on the main thread.


executeInMainThreadWithResult:
executeInMainThreadWithResult(call: object, args: object = (), kwargs: dict = {}) -> object

Executes a call on the main thread, waiting for the result.

以下は__init__.pyファイルのサンプルです。

print("Initializing Dragonframe python")

from dragonframe import ui
from dragonframe import events
from dragonframe import scene

def print_module_docs(mod):
    name = getattr(mod, '__name__', str(mod))
    print(f"\n=== {name} ===")
    for attr in sorted(dir(mod)):
        if attr.startswith('_'):
            continue
        obj = getattr(mod, attr)
        doc = getattr(obj, '__doc__', None)
        if doc:
            print(f"\n{attr}:\n{doc}")

print_module_docs(ui)
print_module_docs(events)
print_module_docs(scene)

from PySide6.QtWidgets import (QFileDialog)

def get_media(user_data: dict):
    print("get_media")
    print(f"Scene Name {scene.name()} {scene.sceneName()} {scene.takeName()}")
    fileNames, _ = QFileDialog.getOpenFileNames(None, "Get Media",
                                              "Test Python",
                                              "All Files (*);;Media Files (*.jpg,*.png,*.tiff,*.crw)", "")
    if fileNames:
        print(f"Chosen files {fileNames}")
        scene.loadMediaIntoReferences(fileNames);

def load_reference_image(user_data: dict):
    print("load_reference_image")
    print(f"Scene Name {scene.name()} {scene.sceneName()} {scene.takeName()}")
    fileName, _ = QFileDialog.getOpenFileName(None, "Load Reference Image",
                                              "Test Python",
                                              "All Files (*);;Image Files (*.jpg,*.png,*.tiff,*.crw)", "")
    if fileName:
        print(f"Chosen file {fileName}")
        scene.loadReferenceLayerImage(fileName);

def launch_image(user_data: dict):
    print("Launch image! ")
    print("Exposure: " + str(user_data["exposure"]))
    frameList = user_data["frames"];
    for frame in frameList:
        fileName = scene.highResFile(frame, user_data["exposure"], False)
        rawFileName = scene.highResFile(frame, user_data["exposure"], True)
        print(f"FRAME: {frame}, File {fileName}, Raw {rawFileName}");

ui.addMenuSeparator(ui.Menu.FileMenu);
ui.addMenuOption(ui.Menu.FileMenu, "Company|Load Reference Image", load_reference_image);

ui.addMenuOption(ui.Menu.CinematographyImageContextMenu, "My Launcher", launch_image);
ui.addMenuOption(ui.Menu.CinematographyImageContextMenu, "Import to References", get_media);

def handle_shoot(user_data: dict):
    print("Shooting! " + str(user_data["frame"]) + " " + str(user_data["exposure"]));

def handle_position(user_data: dict):
    print("POSITION: " + str(user_data["frame"]) + " " + str(user_data["exposure"]));

def handle_cc(user_data: dict):
    print("CC: " + str(user_data["frame"]) + " " + str(user_data["exposure"]));


events.registerInterest([events.EventType.Shoot], handle_shoot);
events.registerInterest([events.EventType.Position], handle_position);
events.registerInterest([events.EventType.CaptureComplete], handle_cc);