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

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

システムトレイアイコンの隣のポップアップウィンドウにスライダーを表示する(後半)

PyGTKでシステムトレイアイコンの隣のポップアップウィンドウにスライダーを表示する(前半)」の続き。

値の取り出し

値はgtk.Rangeオブジェクトのメンバ関数get_value()により取り出すことができ、整数として使用したい場合はint()で整数に変換する。
実際には

scale = gtk.VScale() あるいは scale = gtk.HScale()
# シグナル(値変更時のハンドラと関連付け)
scale.connect("value_changed", self.value_changed)

シグナル「value_changed」で関連付けたハンドラ関数で

def value_changed(self, widget):
  """
  スライダーの値が変更されたときの処理
  """
  print int(widget.get_value())  # 端末に整数型として表示するだけ

このように引数のオブジェクトを用いて取り出すという形で行える。

コード例

下の例ではシステムトレイアイコンをクリックしたときに初期値50のスライダーを表示し、値をいじると端末にその都度(変更後の)値を表示するが、その値は保存していないため、アイコンを再びクリックして閉じてから再び開いてもまた初期値は50となる。

#! /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()
      # ポップアップウィンドウの作成
      self.win = gtk.Window(gtk.WINDOW_POPUP)
      # ドックウィンドウにする場合
#      self.win.set_type_hint(gtk.gdk.WINDOW_TYPE_HINT_DOCK)
      # システムトレイアイコンが縦方向に並ぶ場合(パネルが左右端にある場合など)
      if orientation == gtk.ORIENTATION_VERTICAL:
        scale = gtk.HScale()
        # 画面右端にある場合は左に表示する
        # アイコンのX座標 + 幅 + (幅 x 5)
        # つまり「アイコンのX座標 + 幅 x (1 + 5)」を画面幅と比較
        if area.x + area.width * (1 + 5) > screen.get_width():
          x      = area.x - area.height * 8
          y      = area.y
          width  = area.width * 8
          height = area.height
          scale.set_value_pos(gtk.POS_RIGHT)
        # それ以外は右に表示する
        else:
          x      = area.x + area.height
          y      = area.y
          width  = area.width * 8
          height = area.height
          scale.set_value_pos(gtk.POS_LEFT)
      # システムトレイアイコンが横方向に並ぶ場合(パネルが上下端にある場合など)
      else:
        scale = gtk.VScale()
        scale.set_inverted(True)  # 上が大きい値になるようにする
        # 画面上端にある場合は下に表示する
        if area.y < area.height * 8:
          x      = area.x
          y      = area.y + area.height
          width  = area.width
          height = area.height * 8
          scale.set_value_pos(gtk.POS_TOP)
        # それ以外は上に表示する
        else:
          x      = area.x
          y      = area.y - area.height * 8
          width  = area.width
          height = area.height * 8
          scale.set_value_pos(gtk.POS_BOTTOM)
      # スライダーの設定
      # gtk.Range
      scale.set_update_policy(gtk.UPDATE_CONTINUOUS)  # ドラッグして移動すると値を反映
      #scale.set_update_policy(gtk.UPDATE_DELAYED)  # スライダーのドラッグ中に停止するか止めると反映
      #scale.set_update_policy(gtk.UPDATE_DISCONTINUOUS)  # スライダーを止めて離してから反映
      scale.set_adjustment(gtk.Adjustment(value=50, lower=0, upper=100, step_incr=1, page_incr=5, page_size=0))
      # gtk.Scale
      scale.set_digits(0)  # 小数点以下なし
      #scale.set_draw_value(False)  # 値の表示/非表示を指定可能
      # シグナル(値変更時のハンドラと関連付け)
      scale.connect("value_changed", self.value_changed)
      # 上で決めたサイズと位置に調整
      self.win.resize(width, height)
      self.win.move(x, y)
      # スライダーを追加
      self.win.add(scale)
      # ウィンドウを表示
      self.win.show_all()
      self.show = True
  def value_changed(self, widget):
    """
    スライダーの値が変更されたときの処理
    """
    print int(widget.get_value())  # 端末に整数型として表示するだけ
  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 PyGTKSystraySliderTest:
  """
  システムトレイアイコンの隣にスライダーを表示するテスト
  """
  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 = PyGTKSystraySliderTest()
  app.main()

関連記事:

参考URL:

使用したバージョン: