Python」タグアーカイブ

iter_previous @ GTK+ 3 only

seemex を Ubuntu 11.04 で動かすテスト。
あらら色々問題が。
まず前回書いた StyleContext は GTK+ 2 では使えない。

# Toolbar Style
toolbar = self.uimanager.get_widget('/ToolBar')
toolbar.set_style(gtk.ToolbarStyle.ICONS)
try:
    style = toolbar.get_style_context()
    gtk.StyleContext.add_class(style, gtk.STYLE_CLASS_PRIMARY_TOOLBAR)
except Exception, s:
    pass # GTK+ 2

コレでいいや、GNOME 3 に合わせたいだけの処理なのだし。

AboutDialog の get_major_version() メソッドも使えなかった。
MAJOR_VERSION とかの定数はどちらでも使えるからコッチに変更しよう。

更に GtkTreeView 順番を上に移動する iter_previous もダメか。
GtkTreePath には確か prev メソッドがあったよな。

def on_item_up(self, widget, event=None):
    selection = self.custome_treeview.get_selection()
    model, it = selection.get_selected()
    p = model.get_path(it)
    if it:
        path = model.get_path(it)
        if path.prev():
            itprev = model.get_iter(path)
            model.swap(it, itprev)
            self.change()
        """ GTK+ 3
        itprev = it.copy()
        if model.iter_previous(itprev):
            model.swap(it, itprev)
            self.change()"""
    else:
        self.messagebox(MESSAGE_NON_SELECT)

せっかく簡単になったけど GTK+ 2 のままの Ubuntu を考慮しなきゃとは…

しかし Fedora の VirtualBox ose アップデートはまだか。
右 Ctrl+F でもそのまんま XGA サイズだし \ は打てないし辛い。

Fedora 15 Trash icon on your desktop

Fedora 15 x86_64 を二週間も使って何を今頃気がついた。
dconf-editor で

/org/gnome/desktop/background/show-desktop-icon
にチェックすればデスクトップに物が置けるようになるこうしておけば

/org/gnome/nautilus/desktop
以下で GNOME2 同様にデスクトップアイコンの表示切り替えができる、ついでに

/org/gnome/desktop/interface
以下でツールバー文字を消したりメニューやボタンにアイコンを付けたり。

やっぱりデスクトップには物が置けたほうが便利だ、ゴミ箱も表示できるし。
特にスクリーンショットの整理が今まで面倒だったのよね。

**********

ところでこの Gedit ツールバーのように seemex はできないのだろうか?
GNOME アプリは全部この色付きスタイルになっているので違うと気になる。

そんな時はソースコードを見れば解るはず、Eye of GNOME のサイトから FTP だ。
Eye of GNOME の「情報(A)」から普通にアクセスしてとっとと落とす。

gtk_style_context_add_class
という関数を使うようだ。
そうか Style がどうとかドキュメントにあるのはこういうことか。
今まで知らなかった、とにかく Python から利用するにはこう書けばいいようだ。

# Toolbar Style
toolbar = self.uimanager.get_widget('/ToolBar')
toolbar.set_style(gtk.ToolbarStyle.ICONS)
style = toolbar.get_style_context()
gtk.StyleContext.add_class(style, gtk.STYLE_CLASS_PRIMARY_TOOLBAR)

おぉ同じになった、こうすればいいようだ。
しかしこんなページを見つけたけどこうしなきゃダメなのかな?

“Hello World” in Python with GTK+ 3

というか PyGtk ではないので Python with GTK+ 3 と書くべきなんだろうなと。

**********

ところでアップデートしたら何故か gcc が入っていた。
/usr/include にヘッダとかも、自分で入れた覚えは無いがいつのまに。

何かにくっついてきたのだと思うけど、まあいいや。
Python のほうが便利なので気が向いたらでしか使わないと思うけどさ。

pygtk3 Variable Parameter

いきなり本題だが、GtkTreeView の並び順を変更するコードを書いていた。
以前の PyGtk では GtkTreePath が単なるタプルだったけどそうではないようだ。

GtkTreeModel
とにかく C 言語と同じように書けばいいだろう。
やってみると凄く簡単にできた、しかし…

''' old
def on_item_up(self, widget, event=None):
    selection = self.custome_treeview.get_selection()
    model, it = selection.get_selected()
    if it:
        path = model.get_path(it)
        if path[0] > 0:
            path2 = (path[0]-1, )
            itprev = model.get_iter(path2)
            if itprev:
                model.swap(it, itprev)
                self.change()
    else:
        self.messagebox(MESSAGE_NON_SELECT)
'''
# new
def on_item_up(self, widget, event=None):
    selection = self.custome_treeview.get_selection()
    model, it = selection.get_selected()
    if it:
        itprev = it.copy()
        if model.iter_previous(itprev):
            model.swap(it, itprev)
            self.change()
    else:
        self.messagebox(MESSAGE_NON_SELECT)

Python なのに戻り値で代入ではなく引数の値が直接変更されている。
model.iter_previous(itprev) が bool 値しか戻さないのでしばし悩んだ。
もしかして、とやってみたらこの結果。

こんなの ctypes の byref 以外で見たことが無い。
IronPython でさえ out だったら戻り値とまとめてタプルで戻すというのに。

てゆーか可能だったんだ。
明示的な型宣言ができない Python では問題がでないだろうか心配。

**********

それより Opera 11.11 の search.ini はどうなっているんだ?
Default Search キーの UUID を手書きで書き換えても本体に適用できない。
書き換えるとたとえ非表示にしていても Google と Yahoo が復活するんだが。
並べ替えは何も問題なく行われるのですが。
わけがわからないよ。

コンボボックスで簡単に変更できるようにしたけどまったく無意味になった。
こんなの酷いよ、あんまりだよ…

しかも Deleted を 1 にして Opera 本体機能で編集するとそのセクションが消滅する。
こんなの絶対おかしいよ。

とにかく現状では Default Search を弄くらず deleted を利用しなければ多分問題ない。
需要ゼロに等しいアプリだからこんなんでいいよね、もう少し改造と Debug をするけど。

GNOME3 の雰囲気に合わせて激シンプルへと向かっている。
バックアップ
seeme-1.9.1.tar.gz

pygtk3 pack_start

自作 PyGtk アプリを Gtk3 に切り替えしたい。
よし、まずは SeeMe for Linux だ。
現行 Opera の仕様と合わないまま放置もどうかと思うし。

名前を SeeMe for Linux という無駄に長い名前から seemex に変更。
単純に打つのが面倒なだけです、バージョンは 2.0 でいいな。

まず gtk 名前空間の変更、面倒だから変名しちゃえ。
というか大文字の名前空間ってやっぱり変だよね。

#import pygtk
#pygtk.require("2.0")
#import gtk
from gi.repository import Gtk as gtk

定数の大半が列挙体名のアトリビュートに変わっているのは以前書いた。
gtk.FILL が Gtk.AttachOptions.FILL になったのを見つけるのに苦労したぞ。

pack_start の引数は expand, fill, padding を C 同様に全部指定する必要あり。
デフォルト引数は現行方式では用意されていない、バインディング方法が違うし。

# old pack_start(child, expand=True, fill=True, padding=0)
v = Gtk.VBox()
v.pack_start(widget, True, True, 0)
#v.pack_start(widget) Error

アイコンは GdkPixbuf を作らなくてもパスで良かったのね、前から…

path = os.path.join(os.path.dirname( __file__ ), "seeme.xpm")
#self.icon = gtk.gdk.pixbuf_new_from_file(path)
#self.set_icon(self.icon)
self.set_icon_from_file(path)

でも GdkPixbuf をファイルから作らないと Y901x のボタンが利用できない。
んー cairo を使うみたいなんだけど今はよく解らない。
seeme からやりはじめて助かった…

レンダラのコールバック引数とかに user_data が入って飛んでくる。
とにかく何をやるのも C 言語で書くのと同じようにしなきゃいけなくいなった。

GtkDialog に vbox アトリビュートなんかも当然無い。
C 言語同様に get_content_area で GtkBox を得る必要あり。
PyGtk だからこそ便利だった拡張が丸ごと利用できなくなった。

他 PyGtk2 との細かい差はここから辿って見つけて。
GTK+ 3 Reference Manual

GtkAboutDialog は set_url_hook せずともリンクボタンになる。

VERSION = "1.9.0"

class SeeMe4(gtk.Window):
    #...
    def on_about(self, widget, event=None):
        url = "http://palepoli.skr.jp/"
        w = gtk.AboutDialog()
        w.set_transient_for(self)
        w.set_program_name("seemex")
        w.set_version(VERSION)
        w.set_copyright("Copyright(C) 2009-2011 sasakima-nao")
        w.set_license("GPL")
        w.set_logo(self.get_icon())
        v = "GTK+ Version {0}.{1}.{2}".format(
                gtk.get_major_version(),
                gtk.get_minor_version(),
                gtk.get_micro_version())
        w.set_comments(v)
        w.set_website(url)
        w.set_website_label(url)
        w.run()
        w.destroy()

よし、とりあえず GTK+ 3.0 なアプリになったぞ。
Ubuntu 11.04 で動かしていないけど多分 Ubuntu では GTK2 になるはずだが。
後は現行 Opera で無意味になったセパレータ指定とかを消したり色々。

バックアップ
seeme-1.9.0.tar.gz

コイツが一段落したら Windows 版をどうしよう…

v1 とある理由から Delphi でチャチャッと作成
v2 動画プレイヤー作りが嫌になった反動で無意味にコレの製作を続ける
v3 WPF で何か作りたいという理由だけで C# 化
v4 インストーラを作ってみたいという理由だけでインストーラ化
v5 IronPython で何かを作りたいという理由だけで IronPython 化
v6 自分でビルドしろ第二段にしたい理由だけで C# に戻す、かも…

Windows 版は完全に作者のおもちゃ。
いやコレを作ったから私は十年も生き残っているのは間違いないんだが。

Linux shift-jis zip file

とある ZIP を展開しようと思ったら Shift-JIS ファイル名を使っていて展開できない。
Ubuntu 日本語 Remix 付属の /usr/bin/zip なら展開できるのだけど Fedora だし。
仮想マシンの Ubuntu から頂いて、と思ったけど我が Fedora は 64bit だった…

仮想マシンな Windows XP から共有を利用して展開。
とソレだけの理由で仮想 Windows を立ち上げるのも面倒だ。
そういえば Python には zipfile モジュールがある、作ってみよう。

とりあえず日本語のドキュメントを探してみた。
13.4. zipfile ? ZIP アーカイブの処理 ? Python v2.6.2 documentation
extractall なんて便利なメソッドがあるじゃん、これは簡単そうだ。
ということで Nautilus スクリプトにしてみた。

#!/usr/bin/env python
#-*- coding:utf-8 -*-

import zipfile
import os

filenames = os.environ["NAUTILUS_SCRIPT_SELECTED_FILE_PATHS"].split("\n")

for f in filenames:
    z = zipfile.ZipFile(f)
    z.extractall()
    z.close()

こんなに単純なコードでいいみたい。
ファイル名は見事に化けてしまいますが展開だけは成功する。

そういえばパスワード付きの場合もある。
GTK+ でダイアログでも出して入力すればいいかな。

#!/usr/bin/env python
#-*- coding:utf-8 -*-

import zipfile
import os
import gtk

filenames = os.environ["NAUTILUS_SCRIPT_SELECTED_FILE_PATHS"].split("\n")

for f in filenames:
    z = zipfile.ZipFile(f)
    dlg = gtk.Dialog("password", None, 0, (gtk.STOCK_OK, gtk.RESPONSE_ACCEPT))
    def dlg_ok(self):
        dlg.response(gtk.RESPONSE_ACCEPT)
    entry = gtk.Entry()
    entry.connect("activate", dlg_ok)
    dlg.vbox.pack_start(entry)
    dlg.show_all()
    dlg.run()
    p = entry.get_text()
    dlg.destroy()
    z.extractall(pwd=p)

展開が終了するまでダイアログが閉じないのは何故だろう…
それと展開は死ぬほど遅い…

せっかく作ったけど素直に仮想 Windows から展開するとかのほうが良さそう。
まあ使いたくなる場合もあるだろうからスクリプト登録だけはしておくか。

ところで今頃気がついた。
Nautilus スクリプト位置にディレクトリを作れば入れ子にできるんだね。

まだまだ増やしても大丈夫そうだ。