2009/01/28

PyGTKでプログラムを書いてみた

カーネルアップデートでHP Mini 1000でも音が出るようになりました
音が出ないのはFedoracubeの問題ではなかった模様です
良かった、良かった

音量を調節するのにPulseAudio Volume Controlを開くのも面倒なので
システムトレイに入るボリュームコントローラを探してみました
(GNOMEならアプレットがあるんですけどね)
しかし探し方が悪いのか見つからず、、
(ソースはあった、Fedoracubeに入れる為公式のリポジトリに欲しかった)

偶然以下のサイトを見つけて「結構簡単にできるんだなー」と思い
自分で作ってみることにしました
(肝心の操作はコマンドに任せるとしてGUIだけできればいいやって考え)
2008-07-19 - 試験運用中なLinux備忘録

と、ここまでは良かったのですが残念ながら途中で挫折
以下のコードは右クリックからPulseAudio Volume Controlを
左クリックでミュートの切り替え、それしかできません
まぁこれでいいや
やっつけ仕事で汚いけどソースコードを載せておきます
誰かGNOMEのアプレットみたいなの作ってくれないかなぁ

ってか、よく考えたら初Python、初GTK
見よう見まねでいけたしPython意外と書きやすいのかもなー

#!/usr/bin/python
# -*- encoding: utf-8 -*-

import sys, subprocess

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)

class TrayMenu(gtk.Menu):
def __init__(self, tray):
# 親クラスのコンストラクタ
gtk.Menu.__init__(self)

self.tray = tray

# PulseAudio Volume Control
self.item1 = gtk.ImageMenuItem("PulseAudio Volume Control")
self.item1.connect("activate", self.item1_activate)
self.item1.set_image(gtk.image_new_from_stock('gtk-preferences', gtk.ICON_SIZE_MENU))
self.append(self.item1)

# 区切り線(インスタンスを生成してそのまま入れている)
self.append(gtk.SeparatorMenuItem())

# 終了
self.item2 = gtk.ImageMenuItem(stock_id = gtk.STOCK_QUIT)
self.item2.connect('activate', self.item2_activate)
self.append(self.item2)

# このメニューを表示可能にする
self.show_all()

def item1_activate(self, widget):
print "PulseAudio Volume Control"
subprocess.Popen(["/usr/bin/pavucontrol"])

def item2_activate(self, widget):
print "終了"
gtk.main_quit()

def popup_menu(self, widget, button, time):
print "右クリック"
# gtk.status_icon_position_menu()でメニューをアイコンの位置に合わせる
self.popup(None, None, gtk.status_icon_position_menu, button, time, self.tray)

class PyGTKSystrayTest:
def main(self):
# PyGTK 2.10以上
tray = gtk.StatusIcon()

# gtk.Menuの子クラス
menu = TrayMenu(tray)

# 今回はgtk.STOCK_DIALOG_INFOのストックアイコンを使用
# set_from_file()やset_from_icon_name()、set_from_pixbuf()も使える
#tray.set_from_stock(gtk.STOCK_DIALOG_INFO)
self.change_tray_icon(tray)

# マウスオーバー
tray.set_tooltip("ボリュームコントロール")

# 左クリック
tray.connect("activate", self.toggle_mute)
# 右クリック
tray.connect("popup-menu", menu.popup_menu)

gtk.main()

def toggle_mute(self, widget):
print "左クリック"
amixer = subprocess.Popen(["/usr/bin/amixer"], stdout = subprocess.PIPE)
head = subprocess.Popen(["/usr/bin/head", "-n", "1"], stdin = amixer.stdout, stdout = subprocess.PIPE).communicate()[0]
control = head.split("'")[1]

if control != "":
amixer = subprocess.Popen(["/usr/bin/amixer", "get", control], stdout = subprocess.PIPE)
grep = subprocess.Popen(["/bin/grep", "-e", "\[on\]"], stdin = amixer.stdout, stdout = subprocess.PIPE).communicate()[0]

if grep == "":
print "unmute"
subprocess.Popen(["/usr/bin/amixer", "set", control, "on"], stdout = subprocess.PIPE)
self.change_tray_icon(widget)
else:
print "mute"
subprocess.Popen(["/usr/bin/amixer", "set", control, "off"], stdout = subprocess.PIPE)
self.change_tray_icon(widget)

def change_tray_icon(self, widget):
print "アイコン変更"
amixer = subprocess.Popen(["/usr/bin/amixer"], stdout = subprocess.PIPE)
head = subprocess.Popen(["/usr/bin/head", "-n", "1"], stdin = amixer.stdout, stdout = subprocess.PIPE).communicate()[0]
control = head.split("'")[1]

if control != "":
amixer = subprocess.Popen(["/usr/bin/amixer", "get", control], stdout = subprocess.PIPE)
grep = subprocess.Popen(["/bin/grep", "-e", "\[on\]"], stdin = amixer.stdout, stdout = subprocess.PIPE).communicate()[0]

if grep == "":
print "mute"
widget.set_from_stock(gtk.STOCK_MEDIA_STOP)
else:
print "unmute"
widget.set_from_stock(gtk.STOCK_MEDIA_PLAY)

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

0 件のコメント:

コメントを投稿