我が comipoli はどうせ cairo に書き換えるなら Gjs 化してしまおう。
ということで以前 ClutterImage 作成が遅過ぎでお蔵入りしたソースを引っ張りだした。
ES6 仕様に書き換えをしていて yield でハマったので覚書。
#!/usr/bin/env python3 import gi gi.require_version('Gtk', '3.0') from gi.repository import Gtk, GLib class Dlg(Gtk.Dialog): def __init__(self): Gtk.Dialog.__init__(self, transient_for=None, title="Comipoli Thumbnail") self.show_all() # idle self.iter = self.iter_func() GLib.idle_add(self.iter_idle) def iter_idle(self): try: n = next(self.iter) print(n) return True except Exception as e: return False def iter_func(self): for num in range(100): yield num dlg = Dlg() dlg.run() dlg.destroy()
PyGObject
#!/usr/bin/gjs const GObject = imports.gi.GObject; const GLib = imports.gi.GLib; const Gtk = imports.gi.Gtk; var Dlg = GObject.registerClass({ GTypeName: "Dlg" }, class Dlg extends Gtk.Dialog { _init() { super._init({ transient_for: null, title: "Comipoli Thumbnail" }); this.show_all(); // idle this.iter = this.iter_func(); GLib.idle_add(GLib.PRIORITY_LOW, ()=> { let r = this.iter.next(); if (r.done) return false; print(r.value); return true; }); } * iter_func() { for (let i=0; i<100; i++) { yield i; } } }); Gtk.init(null); let dlg = new Dlg(); dlg.run(); dlg.destroy();
Gjs
g_idle_add の引数が違うことは置いておいて。
g_idle_add は何も処理を行っていない時に与えられた関数を実行し続ける関数。
false を戻さないかぎり動き続ける。
Python は例外で判別、JavaScript は next メソッドの戻り値で判別。
yield, next の使い方はまったく同じなので混乱してもーたがね。
検索すると個別で next() を呼んでいる人ばかりで困ったよ。
どう考えても yield でそんな使い方はしないと思うんですけど。
複数ファイル処理で一つ読み終わったらとっとと表示みたいな場合が主だよね。
あと JavaScript のジェネレーター関数はアスタリスクが必要。
無名関数にする手段は無いっぽい、JavaScript を筆者が使うようになった切っ掛けなのに。
でも Python には無名関数はいらないな、そんなの Python じゃない。
適材適所ってことですよ、何でもアリはコードを読み辛くするだけだ。