Paepoi

Paepoi » PyGObject Tips » GLib(PyGObject) Tips

GLib(PyGObject) Tips

# 最終更新日 2019.07.14

Python2 関連の削除、いくつかの整理、短く読みやすいコード(のつもり)に書き換え
文字列をシングルクォートに統一、及び fstring 化(python 3.6 以降)を行いました

ユーザーディレクトリ
#!/usr/bin/env python3

# ~/.config/user-dirs.dirs で指定されたディレクトリ名を出力

from gi.repository import GLib

user_directory = dict(
    Desktop = GLib.UserDirectory.DIRECTORY_DESKTOP,
    Documents = GLib.UserDirectory.DIRECTORY_DOCUMENTS,
    Download = GLib.UserDirectory.DIRECTORY_DOWNLOAD,
    Music = GLib.UserDirectory.DIRECTORY_MUSIC,
    Pictures = GLib.UserDirectory.DIRECTORY_PICTURES,
    Public = GLib.UserDirectory.DIRECTORY_PUBLIC_SHARE,
    Templates = GLib.UserDirectory.DIRECTORY_TEMPLATES,
    Videos = GLib.UserDirectory.DIRECTORY_VIDEOS )

for key, value in user_directory.items():
    print(f'{key}: {GLib.get_user_special_dir(value)}')

システムディレクトリ
#!/usr/bin/env python3

# 参照
# http://developer.gnome.org/glib/stable/glib-Miscellaneous-Utility-Functions.html

from gi.repository import GLib

s = GLib.get_current_dir()
print(f'現在のカレントディレクトリは {s} です')

s = GLib.get_home_dir()
print(f'貴方のホームディレクトリは {s} です')

''' その他
get_system_config_dirs
get_system_data_dirs
get_tmp_dir
get_user_cache_dir
get_user_config_dir
get_user_data_dir
get_user_name
get_user_runtime_dir
'''

環境変数
#!/usr/bin/env python3

# UNIX 系では子プロセスへの変数渡しに環境変数がよく使われます

from gi.repository import GLib

# 環境変数のセット、存在していた場合上書きするかを第三引数で指定
GLib.setenv('HOGE', 'ほげ', False)
# 環境変数の取り出し
print(GLib.getenv('HOGE'))

# 一覧
for key in GLib.listenv():
    print(f'{key}: {GLib.getenv(key)}')

ファイル名リストの数値優先ソート
#!/usr/bin/env python3

from gi.repository import GLib
import functools

l = [
'40.txt',
'200.txt',
'001.txt',
'2.txt',
'03.txt',
'123456.txt']

def sort_func(str1, str2):
    cmpstr1 = GLib.utf8_collate_key_for_filename(str1, -1)
    cmpstr2 = GLib.utf8_collate_key_for_filename(str2, -1)
    if cmpstr1 < cmpstr2:
        return -1
    return 1

l.sort(key=functools.cmp_to_key(sort_func))
for s in l:
    print(s)

''' output
001.txt
2.txt
03.txt
40.txt
200.txt
123456.txt
'''

コマンドの実行、コマンド出力を得る
#! /usr/bin/env python3

from gi.repository import GLib

# コマンド出力不要なら
GLib.spawn_command_line_async('gnome-terminal')

# output にstdout、error に stderr が入る
# Python3 では出力結果がバイナリなのでデコードが必要
# 下記で ls -z 等の存在しないオプションにしてみよう
# 存在しないコマンドでは例外になるので注意
result, output, error, status = GLib.spawn_command_line_sync('ls -l')
if status == 0:
    print(output.decode("utf-8"))
else:
    print(f'stderr\n{error.decode("utf-8")}')

ファイル名ユーティリティ
#!/usr/bin/env python3

# Python なら os.path、又は Gio からも一部可能です
# 実装で一番最適と思われる手段は自身で選んでください

from gi.repository import GLib

s = '/home/suzuki/バイク/かっこいい.png'

# ディレクトリ名
print(GLib.path_get_dirname(s))
# ファイル名のみ
print(GLib.path_get_basename(s))
# 絶対パスチェック
print(GLib.path_is_absolute(s))
# URI に変換
hostname = 'MACBOOK' # ホスト名(サーバー名)不要なら None でいい)
uri =(GLib.filename_to_uri(s, hostname))
print(uri)
# パス名に戻す
path, host = GLib.filename_from_uri(uri)
print(path)
print(host)
# フルパス作成(区切り文字の有無を自動調節)
print(GLib.build_filenamev(['/home/suzuki/', '/バイク', 'かっこいい.jpg']))

バイナリファイルの読み書き
#! /usr/bin/env python3

from gi.repository import GLib

# 刀.jpg という画像を用意して試してください
# Gio を使ったほうがいいけど単純なものなら GLib だけでできる

result, contents = GLib.file_get_contents('刀.jpg')
if result:
    GLib.file_set_contents('カッコイイ.jpg', contents)

テキストファイルの読み書き
#!/usr/bin/env python3

from gi.repository import GLib

TEXT = '書き込み及び読み込みができない場合は\n例外が発生します'

# Write
try:
    # Python3 文字列は UCS-4 なので UTF-8 に encode する
    utf8str = TEXT.encode('utf-8')
    result = GLib.file_set_contents('write.txt', utf8str)
    if result:
        print('Write Success')
except Exception as e:
    print(f'Error @ {e}')

# Read
try:
    result, contents = GLib.file_get_contents('write.txt')
    if result:
        # 上記のとおりなので decode する必要あり
        ucs4str = contents.decode('utf-8')
        print(ucs4str)
except Exception as e:
    print(f'Error @ {e}')

test コマンド
#!/usr/bin/env python3

from gi.repository import GLib

# ディレクトリでは無いか(シンボリックリンク含む)
print(GLib.file_test('hoge.py', GLib.FileTest.IS_REGULAR))
# シンボリックリンクか
print(GLib.file_test('hoge.py', GLib.FileTest.IS_SYMLINK))
# ディレクトリか
print(GLib.file_test('hoge.py', GLib.FileTest.IS_DIR))
# 実行可能ファイルか
print(GLib.file_test('hoge.py', GLib.FileTest.IS_EXECUTABLE))
# 存在確認
print(GLib.file_test('hoge.py', GLib.FileTest.EXISTS))

タイマー
#!/usr/bin/env python3

# g_timeout_add 処理を行うには mainloop が必要

from gi.repository import GLib

class CountDown():
    def __init__(self):
        self.count = 10
        GLib.timeout_add(1000, self.on_timer)
        self.mainloop = GLib.MainLoop()
        self.mainloop.run()

    def on_timer(self):
        self.count -= 1
        print(self.count)
        if self.count == 0:
            self.mainloop.quit()
            return False
        return True

CountDown()

日付けと時刻
#!/usr/bin/env python3

# GTK+ でデジタル時計を作ってみます

import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, GLib

class DigitalWatch(Gtk.Window):
    def __init__(self):
        Gtk.Window.__init__(self)
        self.label = Gtk.Label()
        self.on_timer() # 初期化
        self.add(self.label)
        self.connect('delete-event', Gtk.main_quit)
        self.show_all()
        GLib.timeout_add(1000, self.on_timer)

    def on_timer(self):
        date_time = GLib.DateTime.new_now_local()
        text = date_time.format('%Y年%m月%d日\n%H時%M分%S秒')
        self.label.set_text(text)
        return True

DigitalWatch()
Gtk.main()

文字コード(cp932, utf8)変換
#!/usr/bin/env python3

'''
    g_file_get_contents で得られるのはバイナリ
    つまり CP932 のままなのでそのまま decode を呼べる
    というか Python 標準機能のほうが簡単ですが...

    f = open(sys.argv[1], encoding='cp932')
    print(f.read())
    f.close()
'''

import sys
from gi.repository import GLib

try:
    result, contents = GLib.file_get_contents(sys.argv[1])
    if result:
        try:
            str932 = contents.decode('cp932')
            print(str932)
        except Exception as e:
            print(f'ConvertError: {e}')
except Exception as e:
    print(f'FileError: {e}')
Copyright(C) sasakima-nao All rights reserved 2002 --- 2020.