Programming」カテゴリーアーカイブ

NotifyIcon to use from IronPython

IronPython スクリプトを快適に使いたい。
version 2.6 から Python モジュールも同梱になり更に便利になった。
そして .NET Framework のパワーがほぼ全てスクリプトのみで記述できる。
別途 SDK のインストールは不要、exe へのコンパイルも不要、言うことなし。

しかし欠点がある、初期化、つまり初回起動が遅すぎることである。
ならばタスクトレイに常駐させてしまえ!

MSDN: ContextMenu クラス (System.Windows.Forms)
MSDN: NotifyIcon クラス (System.Windows.Forms)
チュートリアル : Windows フォームの動的なコンテキスト メニューの作成

システムトレイ(タスクトレイ)にアイコンを表示するには? ? @IT
起動時にタスクトレイのアイコンのみを表示するには? ? @IT

なんかを参考に作ってみた、WindowsForm に頼るしか方法が無いみたい。
これじゃ当分 Microsoft はこの名前空間を外すことはできないな。

self.menu.MenuItems.Add("Exit", EventHandler(self.on_exit))

とする必要は無いみたい、PyGtk と同様に簡単に書けるのが IronPython の魅力。

しかし WindowsForm の Application クラスはインスタンスを作成しなくてもいいんだね。
WPF ばかりやっていたからチト調子が狂う。

ということでやってみた例。

notify_icon.pyw

# -*- coding: UTF-8 -*-

import clr

clr.AddReferenceByPartialName("System.Windows.Forms")
clr.AddReferenceByPartialName("System.Drawing")

from System import *
from System.IO import *
from System.Windows import *
from System.Windows.Forms import *
from System.Drawing import *

class NfIcon():
    """
        Task Tray Icon
    """
    def __init__(self):
        """
            Initialization
        """
        self.path = Path.GetDirectoryName(__file__)
        # create menu
        self.menu = ContextMenu()
        self.menu.MenuItems.Add("NotePad", self.on_notepad)
        self.menu.MenuItems.Add("Clipboard", self.on_clipboard)
        self.menu.MenuItems.Add("External file Execute", self.on_extern)
        self.menu.MenuItems.Add("-")
        self.menu.MenuItems.Add("Exit", self.on_exit)
        # create tray icon
        # Not inherit. this class is Sealed
        self.icon = NotifyIcon()
        self.icon.ContextMenu = self.menu
        self.icon.Icon = Icon(self.path + "\\icon.ico")
        self.icon.Text = "Description Text"
        self.icon.Visible = True

    def on_notepad(self, sender, e):
        """
            case Lancher
        """
        try:
            import os
            os.system("notepad.exe")
        except Exception, e:
            MessageBox.Show(e.Message)

    def on_clipboard(self, sender, e):
        """
            case Clipboard and Beep
        """
        try:
            Clipboard.SetText("Clipboard Text")
            Media.SystemSounds.Beep.Play()
        except Exception, e:
            MessageBox.Show(e.Message)

    def on_extern(self, sender, e):
        """
            case External file Execute
        """
        try:
            import extern
        except Exception, e:
            MessageBox.Show(e.Message)

    def on_exit(self, sender, e):
        """
            bye
        """
        self.icon.Visible = False
        Application.Exit()

if __name__ == "__main__":
    # Not Application.Run(NfIcon())
    NfIcon()
    Application.Run()

extern.py

# -*- coding: UTF-8 -*-

import clr

clr.AddReferenceByPartialName("System.Windows.Forms")

from System.Windows.Forms import *

MessageBox.Show("this File is extern.py")

ヘタクソな icon を同梱して zip にまとめたのも置いておくね。

notify_icon.zip

で、ipyw(64).exe にて notify_icon.pyw を起動させると常駐する。
アイコンを右クリックするとメニューが出るので選択すればよい。

常駐しているので初期化が必要なくなり高速にスクリプトを実行できる。
スタートアップに登録すれば簡単に使えるね、関連付けしない人は bat を作ればいい。

後は動的なスクリプト読み込みができるようにすれば理想的。
とはいえコレなら追記するのも簡単なのでそんな仕組みは不要かなとも思う。

ということで久々に書いた具体的アプリケーションコードにて本年を終わります。

Double.NaN

びっくりした事

あれ?C# って Double ならモロに 0 で除算してもコンパイルエラーにならないんだ。
clr なら同じかなと思って IronPython で為してみたけど実行エラーが出るだけだった。
てか文法が合っているなら普通の Python でもこの強引なコードで読み取りは通るんだね。

def check():
    print 0/0
input("wait: ")
check()

C# も為してみようと思ったけど仮想 Vista を立ち上げるのが面倒なので mono でやってみる。
Mandriva One GNOME は gcc がデフォでは入っていないくせに gmcs はしっかりあるんだよね。
ま、最近の GNOME なら全部入っているだろうけど。

ということで

Console.WriteLine(0/0);

だと mono でもしっかりコンパイルエラーになります、忠実に再現しているのね。

Double.NaN フィールド (System)

コレも当然動く。
こういうのって便利なのだろうか?普通に例外を吐くだけのほうが楽だと思うのだが。

プログラミングの良さげな Q&A サイトめっけ

最近 PyGtk ネタを書いていないので。
ちと海外を探していて良さげな Q&A サイトを見つけた。
プログラミング系全般を扱っているがタグで分けているので解りやすい。

Stack Overflow

Python だけで現在 15,000 もあるし PyGtk だけをタグから探すことも可能。

Hottest ‘pygtk’ Questions – Stack Overflow

全体的に Windows 環境でのことが多いのは当然だよと。
ついでにソコを見ていて見つけたんだが。

GNOME

busybox.py のコードに衝撃!こんなことができたんだ。

busybox

それと pygtk-docs.tar.gz を展開すればローカルでドキュメントが見られる。
今まで Web で全部読んでいたから軽い local で観覧できるのは嬉しいよ。
実は Fedora ならデフォルトで DevHelp にコレは入っているんだけーが…

local_manual

ところで pygoo って何?と思ったので探してみたけど

pygoo – Project Hosting on Google Code

利用したい人っているのかなぁ…
標準オブジェクトを継承して自分で拡張できなきゃ小物すら作れないと思うんだが。
上記の busybox.py を見て本当にそう思う。

Own class library to use from IronPython

IronPython を日本で検索すると C# から IronPython を使う方法ばかりだ。
GTK+ における PyGtk のように皆が使ってくれるだろうとか考えているのかな?
Windows ユーザーがそんなことをするとでも思って…(略
Windows 用オンラインソフト作者をやれば解るって…

よし。
逆に C# で作った自作クラスライブラリを IronPython から使う方法でもやるか。
需要が微妙であるのは気にしない、どうしてもそうしたい場合もあるヤン!

とりあえず Visual Studio でテキトーなクラスライブラリを作る。

using System;

namespace ClassLibrary1
{
    public class Class1
    {
        public static bool ChangeText(out string s)
        {
            s = "Change";
            return true;
        }
    }
}

classlibrary_build

意図的に out を利用している。
IronPython で ref や out を利用するにはこう書く解説も兼ねている。
下記サイトが色々と参考になることを書いてくれてているよと。

Dark Corners of IronPython

んでソレをコードと同一ディレクトリに置く。
肝心なコード。

# -*- coding: UTF-8 -*-

import clr
clr.AddReference("ClassLibrary1")
import ClassLibrary1

result, value = ClassLibrary1.Class1.ChangeText()
print result
print value

cs_lib.zip

cs_lib_py

という感じで利用できます。
サードパーティ製や自作のライブラリが使いたい場合にコレでなんとかなると思う。

IronPython 2.6 Final

知らない間に IronPython 2.6 が Final になっていた。

IronPython

試してみたけど RC3 と違いが解らない。
msi 版に含まれる Python Module も RC3 と同じみたいだし。
つか

# -*- coding: UTF-8 -*-

# python Module
import os
import zipfile

# .NET Framework
import System

dir_path = r"C:\Users\sasakima-nao\Documents\_temp"
filename = r"mpl_u160_x64.zip"

path_a = os.path.join(dir_path, filename)
print path_a
print os.path.exists(path_a)

path_b = System.IO.Path.Combine(dir_path, filename)
print path_b

zip = zipfile.ZipFile(path_b)
for f in zip.namelist():
    System.Console.WriteLine(f)

ironpython26test

Module 同梱になったのおかげでどっちでも良くなったのが少し変な気分。
どちらで書くか迷う、Python らしくないとか言う人が出るかもね。