対象バージョン: BlinkGTK 1.2.5 以降
言語: 日本語 | English
BlinkGTK は GObject Introspection に対応しているため、Python から
PyGObject を使って利用できます。
このチュートリアルの完全なプログラムは、どれも BlinkGTK 1.2.5 (Chromium
156) で実行して確かめています。
blinkgtk-run python3 <ファイル> の形で (理由)以前このページに載っていたコードは、そのままでは動きません。次の 3 点を書き換えてください。
| 以前の書き方 | 1.2.5 以降の書き方 |
|---|---|
| 初期化を呼ばずにウィジェットを作る | ウィジェットを作る前に BlinkGTK.gtk_init(sys.argv[:1])
を呼ぶ |
app.run(sys.argv) |
BlinkGTK.gtk_application_run(app) の後に
BlinkGTK.gtk_shutdown() |
BlinkGtk などの別の名前空間、blink_gtk
モジュールの import |
gi.require_version("BlinkGTK", "0.1") と
from gi.repository import BlinkGTK |
app.run() で回すと、ウィンドウは出ますが Chromium
の処理が回らず、ページが読み込まれません。
# Fedora
sudo dnf install python3-gobject gtk4 blinkgtk-bin blinkgtk-bin-gir
# Debian / Ubuntu
sudo apt install python3-gi gir1.2-gtk-4.0
# BlinkGTK 本体と型情報は、ダウンロードした DEB をファイルで指定します (APT のリポジトリはありません)
sudo apt install ./libblinkgtk-0.1-0_<版>-1_amd64.deb ./gir1.2-blinkgtk-0.1_<版>-1_amd64.debBlinkGTK のパッケージを入れるためのリポジトリの設定は、インストールガイド を参照してください。
import gi
gi.require_version("Gtk", "4.0")
gi.require_version("BlinkGTK", "0.1")
from gi.repository import BlinkGTK, Gtk
print(f"GTK {Gtk.get_major_version()}.{Gtk.get_minor_version()}.{Gtk.get_micro_version()}")
print(f"BlinkGTK {BlinkGTK.gtk_get_version()} (Chromium {BlinkGTK.gtk_get_chromium_version()})")BlinkGTK.gtk_get_version() と
BlinkGTK.gtk_get_chromium_version()
は、初期化の前でも呼べます。
ここで 1.2.4 以前が表示された場合は、BlinkGTK
を更新してください。
次のプログラムを minimal.py
として保存し、blinkgtk-run python3 minimal.py
で実行します。
Python のプログラムは、必ず blinkgtk-run
を通して実行してください。 BlinkGTK (Chromium)
のメモリ割り当ての仕組みは、プロセスの最初から読み込まれている必要があります。C
のアプリは起動時に読み込みますが、Python では BlinkGTK
が後から読み込まれるため、blinkgtk-run を通さないと HTTPS
の頁を開いたときに異常終了します。blinkgtk-run は RPM・DEB
では /usr/bin/blinkgtk-run、tarball では展開した場所の
usr/bin/blinkgtk-run にあります。blinkgtk-run
は環境変数 LD_PRELOAD
を使うので、プログラムから起動する別のプログラムにも引き継がれます。
引数に URL を渡すと、そのページを開きます。
#!/usr/bin/env python3
"""最小限の BlinkGTK ブラウザ"""
import sys
import gi
gi.require_version("Gtk", "4.0")
gi.require_version("BlinkGTK", "0.1")
from gi.repository import BlinkGTK, Gtk # noqa: E402
def on_activate(app, url):
window = Gtk.ApplicationWindow(application=app, title="BlinkGTK Minimal Browser")
window.set_default_size(1024, 768)
view = BlinkGTK.WebView.new()
window.set_child(view)
window.present()
view.load_uri(url)
def main():
url = sys.argv[1] if len(sys.argv) > 1 else "https://example.com/"
# 1. BlinkGTK を初期化する (GTK のウィジェットを作る前に 1 回だけ)
ok, _argv = BlinkGTK.gtk_init(sys.argv[:1])
if not ok:
print("BlinkGTK を初期化できませんでした", file=sys.stderr)
return 1
# 2. アプリケーションを作り、BlinkGTK のメインループで回す
app = Gtk.Application(application_id="org.example.MinimalBrowser")
app.connect("activate", on_activate, url)
rc = BlinkGTK.gtk_application_run(app) # 最後のウィンドウを閉じると戻る
# 3. BlinkGTK を終了する
BlinkGTK.gtk_shutdown()
return rc
if __name__ == "__main__":
sys.exit(main())gi.require_version("Gtk", "4.0")
gi.require_version("BlinkGTK", "0.1")使うライブラリの版を明示します。from gi.repository import ...
より前に書きます。
ok, _argv = BlinkGTK.gtk_init(sys.argv[:1])BlinkGTK.WebView を作る前に、1
回だけ呼びますsys.argv[:1]
のように、プログラム名だけを渡すことをお勧めします。アプリの引数を渡すと、Chromium
のオプションとして解釈されることがありますview = BlinkGTK.WebView.new()BlinkGTK.WebView.new() でインスタンスを作ります
(BlinkGTK.WebView() ではありません)rc = BlinkGTK.gtk_application_run(app)
BlinkGTK.gtk_shutdown()BlinkGTK.gtk_application_run() は、GTK と Chromium
の両方の処理を回します。app.run() は使いませんBlinkGTK.gtk_shutdown()
を呼びますBlinkGTK.WebView は、読み込みに関わる次の 4
つのシグナルを出します。
| シグナル名 | ハンドラの引数 | 説明 |
|---|---|---|
load-changed |
(view, event: BlinkGTK.LoadEvent) |
読み込みの状態が変わった |
load-failed |
(view, error_code: int, failing_uri: str) |
読み込みが確定せずに終わった (中断など) |
title-changed |
(view) |
ページのタイトルが変わった。値は view.get_title()
で読む |
uri-changed |
(view) |
URI が変わった。値は view.get_uri() で読む |
title-changed と uri-changed
には、新しい値が引数として渡されません。
def on_load_changed(view, event):
if event == BlinkGTK.LoadEvent.FINISHED:
print(f"読み込み完了: {view.get_title()} ({view.get_uri()})")
def on_load_failed(view, error_code, failing_uri):
if failing_uri != (view.get_uri() or failing_uri):
return # iframe など、表示中のページではない失敗
if error_code == -3:
return # 中断。停止ボタンや次の読み込みで普通に起きる
print(f"読み込みが確定しませんでした: {failing_uri} (エラー番号 {error_code})")
def on_title_changed(view):
window.set_title(f"{view.get_title()} - Browser")
view.connect("load-changed", on_load_changed)
view.connect("load-failed", on_load_failed)
view.connect("title-changed", on_title_changed)| 値 | 意味 |
|---|---|
BlinkGTK.LoadEvent.STARTED |
load_uri() / load_html()
で読み込みを始めた。リンク・戻る・進む・再読み込みでは来ない |
BlinkGTK.LoadEvent.COMMITTED |
表示する文書が確定した |
BlinkGTK.LoadEvent.FINISHED |
読み込みが終わった |
BlinkGTK.LoadEvent.REDIRECTED |
将来のために予約されています。現在は送られません |
比較には数値ではなく、上の名前を使ってください。
STARTED
はすべての移動で来るわけではないため、読み込み中かどうかの判定にはプロパティ監視の
notify::is-loading を使います。
error_code は Chromium のネットワークエラーの番号です
(負の値)。-3
は中断で、停止ボタンや、読み込み中に別のページを開いたときに普通に起きますload-failed
は来ず、COMMITTED と FINISHED が来ますfailing_uri と view.get_uri()
を比べて除きますGObject のプロパティの変化は、notify::プロパティ名
シグナルで受け取れます。
ハンドラの引数は (view, pspec) です。値は
view.props.title のように読めます。
def on_title_notify(view, pspec):
print(f"タイトル: {view.props.title}")
def on_uri_notify(view, pspec):
print(f"URI: {view.props.uri}")
view.connect("notify::title", on_title_notify)
view.connect("notify::uri", on_uri_notify)| プロパティ名 | 型 | 説明 |
|---|---|---|
uri |
str |
現在の URI |
title |
str |
ページのタイトル |
zoom-level |
float |
拡大率。1.0 が 100% (読み書き可) |
is-loading |
bool |
読み込み中かどうか |
読み込み中の表示 (進み具合のバー、停止・再読み込みのボタン)
は、notify::is-loading で切り替えます。
リンク・戻る・進む・再読み込みを含むどの移動でも、読み込みの開始と終了で届きます。値は
view.is_loading() で読みます。
開始のときは続けて 2
回届くことがあるので、届いた回数ではなく値で判定してください。
def on_is_loading_changed(view, pspec):
loading = view.is_loading()
stop_button.set_sensitive(loading)
reload_button.set_sensitive(not loading)
view.connect("notify::is-loading", on_is_loading_changed)読み込みの進み具合 (0.0〜1.0) は
view.get_estimated_load_progress() で読めます。
これはプロパティではないため、変化の通知はありません。使い方は実践的な使い方の例を参照してください。
| メソッド | 説明 |
|---|---|
load_uri(uri) |
URI を開く |
reload() |
再読み込み |
stop() |
読み込みを止める |
go_back() / go_forward() |
履歴を戻る / 進む |
can_go_back() / can_go_forward() |
戻れるか / 進めるか |
#!/usr/bin/env python3
"""戻る・進む・再読み込みと URL 欄を持つブラウザ"""
import sys
import gi
gi.require_version("Gtk", "4.0")
gi.require_version("BlinkGTK", "0.1")
from gi.repository import BlinkGTK, Gtk # noqa: E402
class BrowserWithNavigation(Gtk.ApplicationWindow):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.set_default_size(1024, 768)
toolbar = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=6)
self.back_button = Gtk.Button(label="←", sensitive=False)
self.back_button.connect("clicked", lambda _b: self.webview.go_back())
toolbar.append(self.back_button)
self.forward_button = Gtk.Button(label="→", sensitive=False)
self.forward_button.connect("clicked", lambda _b: self.webview.go_forward())
toolbar.append(self.forward_button)
reload_button = Gtk.Button(label="↻")
reload_button.connect("clicked", lambda _b: self.webview.reload())
toolbar.append(reload_button)
self.url_entry = Gtk.Entry(hexpand=True)
self.url_entry.connect("activate", self.on_url_activate)
toolbar.append(self.url_entry)
self.webview = BlinkGTK.WebView.new()
self.webview.set_vexpand(True)
# 読み込みの開始と終了 (どの経路の移動でも来る) でボタンを更新する
self.webview.connect("notify::is-loading", self.on_is_loading_changed)
self.webview.connect("title-changed", self.on_title_changed)
self.webview.connect("uri-changed", self.on_uri_changed)
main_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
main_box.append(toolbar)
main_box.append(self.webview)
self.set_child(main_box)
def on_url_activate(self, entry):
url = entry.get_text().strip()
if url and "://" not in url and not url.startswith(("about:", "data:")):
url = "https://" + url
if url:
self.webview.load_uri(url)
def on_is_loading_changed(self, webview, pspec):
self.update_navigation_buttons()
def on_title_changed(self, webview):
title = webview.get_title()
self.set_title(f"{title} - Browser" if title else "Browser")
def on_uri_changed(self, webview):
self.url_entry.set_text(webview.get_uri() or "")
self.update_navigation_buttons()
def update_navigation_buttons(self):
self.back_button.set_sensitive(self.webview.can_go_back())
self.forward_button.set_sensitive(self.webview.can_go_forward())
def on_activate(app, url):
window = BrowserWithNavigation(application=app)
window.present()
window.webview.load_uri(url)
def main():
url = sys.argv[1] if len(sys.argv) > 1 else "https://example.com/"
ok, _argv = BlinkGTK.gtk_init(sys.argv[:1])
if not ok:
print("BlinkGTK を初期化できませんでした", file=sys.stderr)
return 1
app = Gtk.Application(application_id="org.example.NavigationBrowser")
app.connect("activate", on_activate, url)
rc = BlinkGTK.gtk_application_run(app)
BlinkGTK.gtk_shutdown()
return rc
if __name__ == "__main__":
sys.exit(main())戻る・進むボタンの有効・無効は、uri-changed と
notify::is-loading
で更新しています。リンクや戻る・進むによる移動でも更新されます。
#!/usr/bin/env python3
"""ヘッダーバーと読み込みの進み具合を表示するブラウザ"""
import sys
import gi
gi.require_version("Gtk", "4.0")
gi.require_version("BlinkGTK", "0.1")
from gi.repository import BlinkGTK, GLib, Gtk # noqa: E402
class ProgressBrowser(Gtk.ApplicationWindow):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.set_default_size(1200, 900)
self.set_titlebar(Gtk.HeaderBar())
self.set_title("Browser")
self.progress_bar = Gtk.ProgressBar(visible=False)
self.timer_id = 0
self.webview = BlinkGTK.WebView.new()
self.webview.set_vexpand(True)
# 読み込みの開始と終了は notify::is-loading で受け取る (リンク・戻る・再読み込みでも来る)
self.webview.connect("notify::is-loading", self.on_is_loading_changed)
self.webview.connect("notify::title", self.on_title_notify)
vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
vbox.append(self.progress_bar)
vbox.append(self.webview)
self.set_child(vbox)
def on_is_loading_changed(self, webview, pspec):
if webview.is_loading():
self.progress_bar.set_visible(True)
if self.timer_id == 0:
# 進み具合には通知が無いので、読み込み中だけ 0.1 秒ごとに読む
self.progress_bar.set_fraction(0.0)
self.timer_id = GLib.timeout_add(100, self.update_progress)
else:
self.progress_bar.set_visible(False)
if self.timer_id:
GLib.source_remove(self.timer_id)
self.timer_id = 0
print(f"読み込み終了: {webview.get_title() or '(タイトルなし)'}", flush=True)
def update_progress(self):
self.progress_bar.set_fraction(self.webview.get_estimated_load_progress())
return GLib.SOURCE_CONTINUE
def on_title_notify(self, webview, pspec):
self.set_title(webview.props.title or "Browser")
def on_activate(app, url):
window = ProgressBrowser(application=app)
window.present()
window.webview.load_uri(url)
def main():
url = sys.argv[1] if len(sys.argv) > 1 else "https://example.com/"
ok, _argv = BlinkGTK.gtk_init(sys.argv[:1])
if not ok:
print("BlinkGTK を初期化できませんでした", file=sys.stderr)
return 1
app = Gtk.Application(application_id="org.example.ProgressBrowser")
app.connect("activate", on_activate, url)
rc = BlinkGTK.gtk_application_run(app)
BlinkGTK.gtk_shutdown()
return rc
if __name__ == "__main__":
sys.exit(main())is-loading が True
になったらタイマーを始め、get_estimated_load_progress() を
0.1 秒ごとに読んでバーに反映しますis-loading が False
に戻ったらタイマーを止めます。完了・失敗・中断のどの終わり方でも
False に戻りますページの JavaScript を Python から実行して結果を受け取るメソッド
(WebKitGTK の evaluate_javascript() に当たるもの)
は、現在ありません。
ページとアプリの間でメッセージをやり取りする仕組みは アプリ統合 API
で説明しています (C の説明です)。
PyGObject がインストールされていません。
# Fedora
sudo dnf install python3-gobject
# Debian / Ubuntu
sudo apt install python3-giBlinkGTK の introspection データ (BlinkGTK-0.1.typelib)
が見つかりません。
Fedora では blinkgtk-bin-gir、Debian / Ubuntu では
gir1.2-blinkgtk-0.1 をインストールしてください。
それでも見つからない場合の確認方法は、インストールガイド のトラブルシューティングを参照してください。
app.run()
で回していないか確認してください。BlinkGTK.gtk_application_run(app)
で回す必要があります。
また、ウィジェットを作る前に BlinkGTK.gtk_init()
を呼んでいるかも確認してください。
BlinkGTK 1.2.4 以前では、Python から起動すると Chromium
の子プロセスが起動できずに終了します。
BlinkGTK.gtk_get_version() で版を確かめ、1.2.5
以降に更新してください。
以前の資料にあった名前を使っていないか確認してください。次の名前は存在しません。
| 存在しない名前 | 代わりに使うもの |
|---|---|
execute_javascript() |
ありません (JavaScript の実行について) |
set_enable_javascript() |
set_javascript_enabled() |
set_auto_load_images() |
set_images_enabled() |
set_enable_local_storage() |
set_local_storage_enabled() |
estimated-load-progress プロパティ |
get_estimated_load_progress() メソッド |
実行して確かめた完全なプログラムが examples にあります。
minimal_browser.py — 最小構成のブラウザbrowser_with_signals.py — 4 つのシグナルとボタン・URL
欄・進み具合のバーを使うブラウザcomplete_browser.py — 設定の切り替えも含むブラウザblinkgtk-run python3 minimal_browser.py https://example.com/Python から BlinkGTK を使うときの要点は次のとおりです。
BlinkGTK.gtk_init() を呼ぶBlinkGTK.gtk_application_run() で回し、終わったら
BlinkGTK.gtk_shutdown() を呼ぶtitle-changed と uri-changed
は引数なし。値は get_title() / get_uri()
で読むnotify::is-loading で切り替える次のステップ:
BlinkGTK Project | Copyright 2025 | BSD-3-Clause License