ウィンドウ、システムトレイ、バージョン情報ダイアログでアイコンを指定(コード例)
「ウィンドウ、システムトレイ、バージョン情報ダイアログでアイコンを指定(覚え書き)」の続き。
コード例
「ウィンドウの位置とサイズを記憶し、壊さずに隠した後で再表示を行う」のコードにアイコンの処理を追加したもの。
アイコンの指定には複数の方法(メンバ関数)があるため、コメント記号の後ろに他の方法も書いているところがある。
[任意]ファイル名: iconloadtest.py
#! /usr/bin/python # -*- encoding: utf-8 -*- import sys import os try: import pygtk pygtk.require("2.0") except: pass try: import gtk except: print >> sys.stderr, "Error: PyGTK not installed" sys.exit(1) if gtk.pygtk_version < (2,10,0): errtitle = "Error" errmsg = "PyGTK 2.10.0 or later required" if gtk.pygtk_version < (2,4,0): print >> sys.stderr, errtitle + ": " + errmsg else: errdlg = gtk.MessageDialog(type=gtk.MESSAGE_ERROR, buttons = gtk.BUTTONS_OK) errdlg.set_title(errtitle) errdlg.set_markup(errmsg) errdlg.run() sys.exit(1) # XPM形式のアイコン xpm_icon = ["48 48 2 1", " c None", ". c #66C8FF", " ", " ", " .. ", " .. ", " .. ", " .... ", " .... ", " .... ", " ...... ", " ...... ", " ...... ", " ........ ", " ........ ", " ........ ", " .......... ", " .......... ", " .......... ", " ............ ", " .......................................... ", " .............................................. ", " .......................................... ", " ........................................ ", " ...................................... ", " .................................... ", " ................................ ", " .............................. ", " ............................ ", " ........................ ", " ...................... ", " .................... ", " .................... ", " .................... ", " .................... ", " ...................... ", " ...................... ", " ...................... ", " ........................ ", " ........... ........... ", " ......... ......... ", " ......... ......... ", " ....... ....... ", " ...... ...... ", " ..... ..... ", " .... .... ", " ... ... ", " . . ", " ", " ",] def url_handler(dialog, link, user_data): """ バージョン情報ダイアログのURLをクリックしたときに開く """ # xdg-openとfirefoxだけの簡易的なチェックをしている if os.system("xdg-open %s" % link) != 0: if os.system("firefox %s" % link) != 0: print "url open failed" class TestWindow(gtk.Window): """ テスト用ウィンドウ """ pos = None # 復元処理が最初だけ行われないように size = None # 分岐する関係で、Noneにしている def __init__(self, item, **args): """ ウィンドウの初期化 """ gtk.Window.__init__(self, **args) # 親クラスのコンストラクタ global xpm_icon self.item = item self.set_title("Test window") self.set_size_request(300, 180) # 最小サイズ # ファイルの場所を指定してset_icon_from_file()で開く # この場合はスクリプトと同じディレクトリにある「icon.png」 self.set_icon_from_file(os.path.join(os.path.dirname(__file__), "icon.png")) # 下は埋め込みXPMアイコンを使用する場合(色数とサイズに注意) # (set_icon()の引数はgtk.gdk.Pixbufオブジェクト) ##self.set_icon(gtk.gdk.pixbuf_new_from_xpm_data(xpm_icon)) # set_icon_name()ではアイコン名で指定 # /usr/share/icons/[使用しているアイコンテーマ名]/以下や # /usr/share/pixmaps/以下の拡張子を除いたファイル名部分を指定 ##self.set_icon_name("user-trash-full") # スクロールバーの付いたテキストビューを1つ配置 self.textview = gtk.TextView() self.sw = gtk.ScrolledWindow() self.sw.add(self.textview) self.sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) self.add(self.sw) # シグナル self.connect("delete_event", self.delete) def delete(self, widget, event): """ 閉じるボタンなどにより閉じられたときの処理 """ # 座標とサイズの記憶(2要素のタプル型) self.pos = self.get_position() # X座標とY座標 self.size = self.get_size() # 幅と高さ # メニュー項目のチェックを外す self.item.set_active(False) # 隠しつつ、Trueを返して破壊を防ぐ return self.hide_on_delete() # gtk.Widgetクラスのメンバ関数 def restore_and_show_all(self, active): """ 記憶された位置とサイズを復元して表示する """ if active == True: # gtk.CheckMenuItemのチェック状態を引数として渡している # 位置とサイズを復元してから再表示・最初は復元しない if self.pos: # 初期値はNoneにしているため、最初は復元されない (x, y) = self.pos # タプル要素の分解 self.move(x, y) # 移動 if self.size: (width, height) = self.size self.resize(width, height) # サイズ変更 self.show_all() # 再表示 else: # 既に表示されているときには隠すようにする self.emit("delete_event", None) # delete_eventを起こす class TrayMenu(gtk.Menu): """ システムトレイのメニュー """ def __init__(self, tray): gtk.Menu.__init__(self) self.tray = tray # メニュー項目(チェック形式) self.item1 = gtk.CheckMenuItem("Window") self.item1.connect("activate", self.item1_activate) self.append(self.item1) # 区切り線 self.append(gtk.SeparatorMenuItem()) # メニュー項目(バージョン情報ダイアログ) self.item2 = gtk.ImageMenuItem(stock_id=gtk.STOCK_ABOUT) self.item2.connect('activate', self.item2_activate) self.append(self.item2) # 区切り線 self.append(gtk.SeparatorMenuItem()) # 終了 self.item_quit = gtk.ImageMenuItem(stock_id=gtk.STOCK_QUIT) self.item_quit.connect('activate', self.quit_activate) self.append(self.item_quit) # このメニューを表示可能にする self.show_all() # ウィンドウを準備しておく self.win = TestWindow(item=self.item1, type=gtk.WINDOW_TOPLEVEL) def activate(self, widget): # item1を選択したことにする(チェックの状態変化 + ウィンドウ表示状態変化) self.item1.emit("activate") def item1_activate(self, widget): """ 項目item1が選択されたときの処理 """ self.win.restore_and_show_all(widget.get_active()) # widgetとself.item1は同一 def item2_activate(self, widget): """ 項目item2が選択されたときの処理 """ global xpm_icon url = "http://d.hatena.ne.jp/kakurasan/20080726/p1" gtk.about_dialog_set_url_hook(url_handler, url) # URLを開く関数の関連付け aboutdlg = gtk.AboutDialog() # ダイアログ(gtk.Windowの子クラス)のアイコンの指定方法も同様 aboutdlg.set_icon_from_file(os.path.join(os.path.dirname(__file__), "icon.png")) ##aboutdlg.set_icon(gtk.gdk.pixbuf_new_from_xpm_data(xpm_icon)) # XPM aboutdlg.set_name("Test") aboutdlg.set_copyright("(C) 2008 kakurasan") aboutdlg.set_comments("Icon test") # アプリケーションの説明など aboutdlg.set_license("Licensed under GPLv3") # 実際にはライセンス本文を入れる aboutdlg.set_wrap_license(True) # ライセンス自動折り返し aboutdlg.set_website(url) # 実際のURL aboutdlg.set_website_label(url) # URLリンクで表示される文字列 aboutdlg.set_authors(["kakurasan"]) # バージョン情報ダイアログのロゴ(set_logo()の引数)もgtk.gdk.Pixbuf ##aboutdlg.set_logo(gtk.gdk.pixbuf_new_from_xpm_data(xpm_icon)) # ファイルから読み込む場合はgtk.gdk.pixbuf_new_from_file()でPixbuf生成 aboutdlg.set_logo(gtk.gdk.pixbuf_new_from_file(os.path.join(os.path.dirname(__file__), "icon.png"))) # set_logo_icon_name()ではアイコン名で指定 ##aboutdlg.set_logo_icon_name("user-trash-full") aboutdlg.run() aboutdlg.destroy() def quit_activate(self, widget): """ 終了の項目が選択されたときの処理 """ gtk.main_quit() def show_menu(self, widget, button, time): """ メニューのポップアップを行う """ # gtk.status_icon_position_menu()でメニューをアイコンの位置に合わせる self.popup(None, None, gtk.status_icon_position_menu, button, time, self.tray) class PyGTKIconLoadTest: """ アイコン、ロゴのテスト """ def main(self): tray = gtk.StatusIcon() # PyGTK 2.10以上 menu = TrayMenu(tray) # gtk.Menuの子クラス # アイコン名による指定 ##tray.set_from_icon_name("user-trash-full") # ファイルを直接開く場合は直接その場所を指定 ##tray.set_from_file(os.path.join(os.path.dirname(__file__), "icon.png")) # XPMアイコンはコードへの埋め込みができる(ただし、色数とサイズに注意) tray.set_from_pixbuf(gtk.gdk.pixbuf_new_from_xpm_data(xpm_icon)) tray.set_tooltip("test") # マウスポインタを少し乗せたときに出る文字列 tray.connect("activate", menu.activate) # 通常クリック時の処理 tray.connect("popup-menu", menu.show_menu) # メニューを出す gtk.main() if __name__ == "__main__": app = PyGTKIconLoadTest() app.main()
この中で
os.path.join(os.path.dirname(__file__), "icon.png")
と書いている部分のアイコンは、コードと同じディレクトリに置かれたicon.pngを使用する。ファイルが存在しない場合
gobject.GError: ファイル '[スクリプトのあるディレクトリ]/icon.png' のオープンに失敗しました: そのようなファイルやディレクトリはありません
となる。
テスト用に適当に作ったアイコンを
http://cid-3f9be5b1cd4a806c.skydrive.live.com/browse.aspx/%E5%85%AC%E9%96%8B/%E3%83%86%E3%82%B9%E3%83%88%E7%94%A8%E7%B4%A0%E6%9D%90/GTK+%E3%81%AE%E3%82%A2%E3%82%A4%E3%82%B3%E3%83%B3%E6%8C%87%E5%AE%9A%E3%83%86%E3%82%B9%E3%83%88
に作成・アップロードしたが、これを使用すると、バージョン情報のダイアログでは
と表示される。上のコードでは、ここの他にウィンドウのアイコンとしてもこれを使用している。また、システムトレイでは、埋め込んだXPMのアイコン(水色の星マーク)を表示している。
関連記事:
参考URL: