試験運用中なLinux備忘録・旧記事

はてなダイアリーで公開していた2007年5月-2015年3月の記事を保存しています。

PyGTKでシステムトレイのアイコンを切り換える(後半)

ここでは「PyGTKでシステムトレイのアイコンを切り換える(前半)」のメモを踏まえた上でのサンプルコードを貼り付ける。事前にPythonのコードと同じディレクトリに2つの画像ファイルを配置しておく。

イコン画像1

ファイル名: icon1.xpm

/* XPM */
static char * icon1_xpm[] = {
"48 48 2 1",
" 	c None",
".	c #33E033",
"                                                ",
"                                                ",
"                       ..                       ",
"                       ..                       ",
"                       ..                       ",
"                      ....                      ",
"                      ....                      ",
"                      ....                      ",
"                     ......                     ",
"                     ......                     ",
"                     ......                     ",
"                    ........                    ",
"                    ........                    ",
"                    ........                    ",
"                   ..........                   ",
"                   ..........                   ",
"                   ..........                   ",
"                  ............                  ",
"   ..........................................   ",
" .............................................. ",
"   ..........................................   ",
"    ........................................    ",
"     ......................................     ",
"      ....................................      ",
"        ................................        ",
"         ..............................         ",
"          ............................          ",
"            ........................            ",
"             ......................             ",
"              ....................              ",
"              ....................              ",
"              ....................              ",
"              ....................              ",
"             ......................             ",
"             ......................             ",
"             ......................             ",
"            ........................            ",
"            ...........  ...........            ",
"            .........      .........            ",
"           .........        .........           ",
"           .......            .......           ",
"           ......              ......           ",
"           .....                .....           ",
"          ....                    ....          ",
"          ...                      ...          ",
"          .                          .          ",
"                                                ",
"                                                "};

イコン画像2

6行目から最後までは上の画像データと同じで、スペース節約のため省略した。
ファイル名: icon2.xpm

/* XPM */
static char * icon2_xpm[] = {
"48 48 2 1",
" 	c None",
".	c #E03333",
(以下は上の画像と同じ)

コード

[任意]ファイル名: systrayiconchangetest.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 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.item_start = gtk.ImageMenuItem("Start")
    self.item_start.connect("activate", self.start_activate)
    self.item_start.set_image(gtk.image_new_from_stock('gtk-execute', gtk.ICON_SIZE_MENU))
    self.append(self.item_start)

    # 停止
    self.item_stop = gtk.ImageMenuItem("Stop")
    self.item_stop.connect("activate", self.stop_activate, False)
    self.item_stop.set_image(gtk.image_new_from_stock('gtk-stop', gtk.ICON_SIZE_MENU))
    self.item_stop.set_sensitive(False)
    self.append(self.item_stop)

    # 区切り線
    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()
  def start_activate(self, widget):
    """
    開始処理
    """
    # 状態変更のメンバ関数を呼ぶ
    self.tray.change_icon_state(True)
    # 停止のメニュー項目を有効にして開始のメニュー項目を無効にする
    self.item_stop.set_sensitive(True)
    self.item_start.set_sensitive(False)
  def stop_activate(self, widget, noctrl):
    """
    停止処理
    """
    # start_activate()内と逆の処理を行う
    self.tray.change_icon_state(False)
    self.item_stop.set_sensitive(False)
    self.item_start.set_sensitive(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 StatusIconWithPixbuf(gtk.StatusIcon):
  """
  アイコンのPixbufを保持したステータスアイコン (PyGTK 2.10以上)
  """
  def __init__(self):
    gtk.StatusIcon.__init__(self)  # 必須
    # 各アイコン画像を一度だけ読んでデータを保持する
    self.icon_play = gtk.gdk.pixbuf_new_from_file(os.path.dirname(__file__) + "/icon1.xpm")
    self.icon_stop = gtk.gdk.pixbuf_new_from_file(os.path.dirname(__file__) + "/icon2.xpm")
    # 起動直後は停止の状態にする
    self.change_icon_state(False)
  def change_icon_state(self, act):
    """
    ステータスアイコンのアイコン画像とツールチップを切り替え
    引数actはTrue(動作時)かFalse(停止時)を指定する
    """
    if act == True:
      self.set_from_pixbuf(self.icon_play)
      self.set_tooltip("Started")
    else:
      self.set_from_pixbuf(self.icon_stop)
      self.set_tooltip("Stopped")

class PyGTKSystrayIconChangeTest:
  """
  システムトレイのアイコン切り替えテスト
  """
  def main(self):
    tray = StatusIconWithPixbuf()
    menu = TrayMenu(tray)
    tray.connect("popup-menu", menu.show_menu)

    gtk.main()


if __name__ == "__main__":
  app = PyGTKSystrayIconChangeTest()
  app.main()

実行結果

赤い星のアイコンがシステムトレイに出るので

メニューから「Start」を選択すると緑色になり

今度は「Stop」を選択すると元に戻る。

関連記事:

参考URL:

使用したバージョン: