スクリーンショットを撮るプラグインを作りました。

先日紹介したツール「pyPlugger」のプラグインをもう1つ作りました。

今回作ったプラグインは、プラグインの動作オプションを設定ファイルに保存するタイプのものです。

ちなみに、今回作ったのは、かなり前に作成したscrot(スクリーンショットを撮るツール)コマンドのフロントエンドツールをプラグインとして手直ししたものです。
作成したプラグインプラグインディレクトリに置き、pyPluggerを起動すると、こんな画面になります。

Shooootボタンをクリックすると、Delay timeで指定した時間(秒)後にpyPluggerが非表示となり、スクリーンショットが保存されます。保存が終了すると、ウインドウが再度表示されます。

pyPlugger終了時に、ファイル名やディレイタイムなどの設定が保存され、次回起動時にまた読み込まれます。

とりあえず、ソースはこんな感じです。
下記のソースの最後の2つの関数が設定の保存と読み込みに感する関数です。
それらの関数はpyPlugger起動時、終了時に呼び出されます。

# -*- coding: utf-8 -*-

import sys
import os
import types

import pygtk
if sys.platform != 'win32':
    pygtk.require('2.0')
import gtk


# グローバル変数
g_fileName = '%Y-%m-%d_$wx$h.png'
g_outputDir = '~/'
g_delaySec = 0
g_selectWinOrRect = False
g_fileNameEntry = None
g_outputPathEntry = None
g_shootButton = None


def on_filename_changed(widget, data=None):
    '''
    ファイル名入力フィールドが変更された場合の処理。
    '''
    global g_fileName
    g_fileName = g_fileNameEntry.get_text()
    print 'filename modified'

def on_output_dir_changed(widget, data=None):
    '''
    出力パスが変更された場合の処理
    '''
    global g_outputDir
    g_outputDir = g_outputPathEntry.get_text()
    print 'output dir modified'
    
def on_select_output_dir(widget, event=None):
    '''
    ディレクトリ選択ダイアログを表示。
    選択されたディレクトリをテキストフィールドに設定する。
    '''
    global g_outputDir
    
    print 'output dir sel'
    chooser = gtk.FileChooserDialog('Select Output Directory',
                                    None,
                                    gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER,
                                    (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
                                     gtk.STOCK_OK, gtk.RESPONSE_OK))

    chooser.set_default_response(gtk.RESPONSE_OK)
    chooser.set_position(gtk.WIN_POS_CENTER)

    # ディレクトリ選択ダイアログを実行
    resp = chooser.run()
    if resp != gtk.RESPONSE_OK:
        chooser.destroy()
        return

    # 選択結果を入力フィールドに設定
    g_outputPathEntry.set_text(chooser.get_filename())

    # ダイアログの破棄
    chooser.destroy()    

def on_changed_delay_combo(widget, data=None):
    '''
    ディレイコンボボックスが選択された場合の処理
    '''
    global g_delaySec
    
    if widget == None:
        return
    g_delaySec = widget.get_active()
    print g_delaySec

def on_toggle_select_win_or_rect(widget, data=None):
    '''
    Select window or rectangleチェックボックスの状態
    が変わった場合に事項する処理
    '''
    global g_selectWinOrRect
    g_selectWinOrRect = widget.get_active()
    print g_selectWinOrRect
    
def on_button_shoot(widget, event=None):
    '''
    scrotのコマンド文字列を作成し、実行する。
    '''
    # 出力先のディレクトリが存在することを確認。
    # 存在しない場合には処理を中断
    global g_fileName
    global g_outputDir
    global g_delaySec
    global g_selectWinOrRect

    outdir = os.path.expanduser(g_outputDir)
    outdir = os.path.normpath(outdir)
    if os.path.isdir(outdir) == False:
        print 'no such directory:%s' % outdir
        return

    # scrotコマンドの引数の情報(リスト)を作成
    cmdArg = ['scrot']

    if len(g_fileName) > 0:
        cmdArg.append(g_fileName)

    cmdArg += ['-e',
               'mv $f %s' % outdir,
               '-d',
               str(g_delaySec)]

    # Select window or rectangleのチェックがONだったら、
    # -sオプションを追加。
    if g_selectWinOrRect:
        cmdArg.append('-s')

    # ウインドウをアイコン化する。
    wind = widget.get_toplevel()
    print wind
    if wind:
        wind.hide_all()
        
    # スクリーンショットを取る前に自身のウインドウを閉じる
    # 未処理のイベントがなくなるまで待機。
    # (ウインドウのアイコン化が完了するのを待つため)
    while gtk.events_pending():
        gtk.main_iteration()

    # スクリーンショットを取る
    rc = os.spawnvp(os.P_WAIT, 'scrot', cmdArg)

    print '== complete =='

    # ウインドウを再表示
    if wind:
        wind.show_all()

#
# プラグインプロトコル関連の関数
#
def get_author():
    '''
    プラグイン製作者名を返す
    '''
    return u'jkani4'

def get_name():
    '''
    プラグイン名称を取得
    '''
    return u'ScreenShot plugin'

def get_description():
    '''
    プラグインについての説明文を取得
    '''
    return u'スクリーンショットツールscrotのフロントエンドプラグイン。\nこのプラグインを使用するためには、scrotコマンドがインストール\nされており、コマンドへのパスが設定されている必要があります。'
    
def get_version():
    '''
    プラグインバージョン(文字列)の取得
    '''
    return u'0.5.0'

def get_widgets():
    '''
    プラグインがアクティブになった際に呼び出される関数。
    プラグインGUIを生成して返す。
    '''
    global g_fileName
    global g_outputDir
    global g_delaySec
    global g_selectWinOrRect
    global g_fileNameEntry
    global g_outputPathEntry
    global g_shootButton

    vbox = gtk.VBox()
    vbox.set_border_width(5)

    # ファイル名
    hbox = gtk.HBox()
    vbox.pack_start(hbox, False, False, 4)    
    
    label = gtk.Label('File Name :')
    hbox.pack_start(label, False, False, 2)
    label.set_size_request(100, -1)
    label.set_alignment(0.0, 0.5)

    g_fileNameEntry = gtk.Entry()
    hbox.pack_start(g_fileNameEntry, False, False, 2)
    if len(g_fileName) > 0:
        g_fileNameEntry.set_text(g_fileName)
    g_fileNameEntry.connect('changed', on_filename_changed)

    # 出力ディレクトリ
    hbox = gtk.HBox()
    vbox.pack_start(hbox, False, False, 4)
    
    label = gtk.Label('Output Directory :')
    hbox.pack_start(label, False, False, 2)
    label.set_size_request(100, -1)
    label.set_alignment(0.0, 0.5)

    g_outputPathEntry = gtk.Entry()
    hbox.pack_start(g_outputPathEntry, False, False, 2)
    if len(g_outputDir) > 0:
        g_outputPathEntry.set_text(g_outputDir)
    g_outputPathEntry.connect('changed', on_output_dir_changed)
    
    bt = gtk.Button('...')
    hbox.pack_start(bt, False, False ,2)
    bt.connect('clicked', on_select_output_dir)

    # ディレイ入力フィールド
    hbox = gtk.HBox()
    vbox.pack_start(hbox, False, False, 4)

    label = gtk.Label('Delay time :')
    hbox.pack_start(label, False, False, 2)
    label.set_size_request(100, -1)
    label.set_alignment(0.0, 0.5)

    combo = gtk.combo_box_new_text()
    hbox.pack_start(combo, False, False, 2)
    for i in range(11):
        combo.append_text(str(i)+'sec')
    combo.set_active(g_delaySec)
    combo.connect('changed', on_changed_delay_combo)

    # その他のオプション
    frame = gtk.Frame('Options')
    vbox.pack_start(frame, False, False, 4)

    optBox = gtk.VBox()
    frame.add(optBox)

    check = gtk.CheckButton('Select window or rectangle.')
    optBox.pack_start(check, False, False, 2)
    check.set_border_width(5)
    check.set_active(g_selectWinOrRect)
    check.connect('toggled', on_toggle_select_win_or_rect)

    # セパレータ
    sep = gtk.HSeparator()
    vbox.pack_start(sep, False, False, 4)

    # 実行ボタン
    g_shootButton = gtk.Button('Shoooot')
    vbox.pack_end(g_shootButton, False, False, 2)
    g_shootButton.connect('clicked', on_button_shoot)
    
    return vbox

SETTING_KEY_FILE_NAME = 'fileName'
SETTING_KEY_OUTPUT_DIR_PATH = 'outputDirPath'
SETTING_KEY_DELAY_SEC = 'delaySec'
SETTING_KEY_WIN_OR_RECT = 'selectWinOrRect'

def get_settings():
    '''
    プラグインの設定を保存する際に呼び出される関数。
    プラグインのパラメータを辞書の形で返す。
    '''
    return {SETTING_KEY_FILE_NAME: g_fileName,
            SETTING_KEY_OUTPUT_DIR_PATH: g_outputDir,
            SETTING_KEY_DELAY_SEC: g_delaySec,
            SETTING_KEY_WIN_OR_RECT: g_selectWinOrRect}

def set_settings(settings):
    '''
    プラグインの設定を復元する際に呼び出される関数。
    渡された辞書settingのデータをもとに、設定を復元する処理
    を記述する。
    '''
    global g_fileName
    global g_outputDir
    global g_delaySec
    global g_selectWinOrRect
    
    if type(settings) != types.DictType:
        print 'error. setting is not dictionary.'

    if SETTING_KEY_FILE_NAME in settings:
        g_fileName = settings[SETTING_KEY_FILE_NAME]

    if SETTING_KEY_OUTPUT_DIR_PATH in settings:
        g_outputDir = settings[SETTING_KEY_OUTPUT_DIR_PATH]

    if SETTING_KEY_DELAY_SEC in settings:
        g_delaySec = settings[SETTING_KEY_DELAY_SEC]

    if SETTING_KEY_WIN_OR_RECT in settings:
        g_selectWinOrRect = settings[SETTING_KEY_WIN_OR_RECT]

プラグインマネージャ、pyPlugger、サンプルのプラグインなど、明日にでもまとめてポケット倉庫@Wikiにアップしようと思います。