PyGTKでシステムトレイのアイコンの隣にポップアップウィンドウを作成する(後半)
「PyGTKでシステムトレイのアイコンの隣にポップアップウィンドウを作成する(前半)」の続き。
コード例
下のコードを実行してシステムトレイに出たアイコンをクリックすると、トレイアイコンが縦並びのときには横に、横並びのときには縦に長い(比率が1:5の)ポップアップウィンドウが出て、もう一度トレイアイコンをクリックすると消える。
#! /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 is not installed" sys.exit(1) if gtk.pygtk_version < (2,10,0): errtitle = "Error" errmsg = "PyGTK >= 2.10.0 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) class TrayMenu(gtk.Menu): """ システムトレイのメニュー """ def __init__(self, tray): gtk.Menu.__init__(self) # 必須 self.tray = tray self.show = False # ウィンドウの表示フラグ # 終了 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() def activate(self, widget): """ クリックされたときの処理 """ # ウィンドウが表示されている場合は壊す if self.show == True: self.win.destroy() self.show = False else: # 表示されていない場合にウィンドウ作成 # (画面の情報, 表示領域の情報, 方向の情報) を取得 (screen, area, orientation) = self.tray.get_geometry() print "orientation:", orientation print "x:%d y:%d width:%d height:%d\n" % (area.x, area.y, area.width, area.height) # ポップアップウィンドウの作成 self.win = gtk.Window(gtk.WINDOW_POPUP) # ドックウィンドウにする場合 # self.win.set_type_hint(gtk.gdk.WINDOW_TYPE_HINT_DOCK) # システムトレイアイコンが縦方向に並ぶ場合(パネルが左右端にある場合など) if orientation == gtk.ORIENTATION_VERTICAL: # 画面右端にある場合は左に表示する # アイコンのX座標 + 幅 + (幅 x 5) # つまり「アイコンのX座標 + 幅 x (1 + 5)」を画面幅と比較 if area.x + area.width * (1 + 5) > screen.get_width(): x = area.x - area.height * 5 y = area.y width = area.width * 5 height = area.height # それ以外は右に表示する else: x = area.x + area.height y = area.y width = area.width * 5 height = area.height # システムトレイアイコンが横方向に並ぶ場合(パネルが上下端にある場合など) else: # 画面上端にある場合は下に表示する if area.y < area.height * 5: x = area.x y = area.y + area.height width = area.width height = area.height * 5 # それ以外は上に表示する else: x = area.x y = area.y - area.height * 5 width = area.width height = area.height * 5 # 上で決めたサイズと位置に調整 self.win.resize(width, height) self.win.move(x, y) # ウィンドウを表示 self.win.show_all() self.show = True def show_menu(self, widget, button, time): self.popup(None, None, gtk.status_icon_position_menu, button, time, self.tray) def quit_activate(self, widget): """ 終了 """ gtk.main_quit() class PyGTKSystrayGeometryTest: """ システムトレイのアイコンジオメトリテスト """ def main(self): tray = gtk.StatusIcon() menu = TrayMenu(tray) tray.set_from_stock(gtk.STOCK_DIALOG_INFO) tray.connect("popup-menu", menu.show_menu) tray.connect("activate", menu.activate) gtk.main() if __name__ == "__main__": app = PyGTKSystrayGeometryTest() app.main()
システムトレイアイコンの並び方向が正常に取得できない環境での例
下はシステムトレイアイコンの並び方向の情報を利用する代わりにシステムトレイアイコンのX座標を用いて、システムトレイを提供するパネル/バーが画面の左右に張り付いているときに横方向(かつ画面の内側)にウィンドウを出すようにしたもの。システムトレイアイコンの位置(X座標)によっては意図しない方向にウィンドウが出てしまうことがある。
#! /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 is not installed" sys.exit(1) if gtk.pygtk_version < (2,10,0): errtitle = "Error" errmsg = "PyGTK >= 2.10.0 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) class TrayMenu(gtk.Menu): """ システムトレイのメニュー """ def __init__(self, tray): gtk.Menu.__init__(self) # 必須 self.tray = tray self.show = False # ウィンドウの表示フラグ # 終了 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() def activate(self, widget): """ クリックされたときの処理 """ # ウィンドウが表示されている場合は壊す if self.show == True: self.win.destroy() self.show = False else: # 表示されていない場合にウィンドウ作成 # (画面の情報, 表示領域の情報, 方向の情報) を取得 (screen, area, orientation) = self.tray.get_geometry() print "x:%d y:%d width:%d height:%d\n" % (area.x, area.y, area.width, area.height) # ポップアップウィンドウの作成 self.win = gtk.Window(gtk.WINDOW_POPUP) # ドックウィンドウにする場合 # self.win.set_type_hint(gtk.gdk.WINDOW_TYPE_HINT_DOCK) if area.x + area.width * (1 + 5) > screen.get_width() or area.x < area.width: # 画面右端にある場合は左に表示する # アイコンのX座標 + 幅 + (幅 x 5) # つまり「アイコンのX座標 + 幅 x (1 + 5)」を画面幅と比較 if area.x + area.width * (1 + 5) > screen.get_width(): x = area.x - area.height * 5 y = area.y width = area.width * 5 height = area.height # それ以外は右に表示する else: x = area.x + area.height y = area.y width = area.width * 5 height = area.height # システムトレイアイコンが横方向に並ぶ場合(パネルが上下端にある場合など) else: # 画面上端にある場合は下に表示する if area.y < area.height * 5: x = area.x y = area.y + area.height width = area.width height = area.height * 5 # それ以外は上に表示する else: x = area.x y = area.y - area.height * 5 width = area.width height = area.height * 5 # 上で決めたサイズと位置に調整 self.win.resize(width, height) self.win.move(x, y) # ウィンドウを表示 self.win.show_all() self.show = True def show_menu(self, widget, button, time): self.popup(None, None, gtk.status_icon_position_menu, button, time, self.tray) def quit_activate(self, widget): """ 終了 """ gtk.main_quit() class PyGTKSystrayGeometryTest2: """ システムトレイのアイコンジオメトリテスト """ def main(self): tray = gtk.StatusIcon() menu = TrayMenu(tray) tray.set_from_stock(gtk.STOCK_DIALOG_INFO) tray.connect("popup-menu", menu.show_menu) tray.connect("activate", menu.activate) gtk.main() if __name__ == "__main__": app = PyGTKSystrayGeometryTest2() app.main()
関連記事:
- PyGTKでシステムトレイを使用してメニューを表示する
- PyGTKでシステムトレイのアイコンの隣にポップアップウィンドウを作成する(前半)
- システムトレイアイコンの並び方向に関する覚え書き(2009/2/10現在)
- システムトレイアイコンの隣のポップアップウィンドウにスライダーを表示する(前半)
- システムトレイアイコンの隣のポップアップウィンドウにスライダーを表示する(後半)
参考URL:
- PyGTK リファレンス: gtk.gdk.Screen
- PyGTK リファレンス: gtk.gdk.Rectangle
- PyGTK リファレンス: GTK Orientation Constants
使用したバージョン:
- Python 2.5.2
- PyGTK 2.13.0