GtkSourceViewを表示専用にする、その方法が分からなかったのでメモ
はいアフィ入りました〜w
というか他のGTK関連書籍は正直10年いや20年前のもので役に立たないと思われたからです。ていうか昔は盛んだったんですなぁ(´・ω・`)
まぁそれはともかく、このアフィリンクの書籍とは一切関係ない話なのですが
以下は普通の知能を持っていれば当たり前の話なのですが、GtkSourceViewに対して変更を禁止しようと思ったのですが
自分はgtksourceview read-onlyなどで延々とググり続けてしまった罠。
なにかset_read_onlyみたいなメソッドがあるのかな〜と…無いですね。*1
そしてその方法について誰も言及していない。何故か。その理由はあまりにも基本的だからだと推察します。
つまり…単にGtkのウィジェットとしてキー入力を無効化してしまえばいいだけではないか?と思いついたからです。
しかし単純にset_sensitive()でFalseにするとナビゲーションすら不能になるという。
そこで、キーボードイベントをconnectしてナビゲーションキー以外はTrueを返してバブリングを抑制。キー入力を遮断してしまうという方法を取りました。
マウスボタンも右ボタンを許すとメニューが飛び出てしまうので潰しておきます。
ただしこれだとテキスト選択してコピーが出来ないので(いや別に出来なくてもいいけど)何か自前の「コピー」だけあるメニューでも表示するとかしたほうが良いかもですね。
他にスマートな方法があるのかも知れませんが、こんな単純なことを思いつきました的な話でした。
サンプルコード
面倒くさいので、GtkSourceViewテスト用コードの全体をコピペ!
import gi
gi.require_version('Gtk', '3.0')
gi.require_version('GtkSource', '3.0')
from gi.repository import Gtk, Gdk, GtkSource, GObject, GLib, Gio
class Myclass:
allowed_keys = (
Gdk.KEY_Up,
Gdk.KEY_Left,
Gdk.KEY_Down,
Gdk.KEY_Right,
Gdk.KEY_Page_Up,
Gdk.KEY_Page_Down,
Gdk.KEY_Home,
Gdk.KEY_End,
)
def __init__(self):
self.win = Gtk.Window(Gtk.WindowType.TOPLEVEL)
self.win.set_title("title")
self.win.set_resizable(True)
self.win.show()
self.win.connect("destroy",self.destroy)
self.win.resize(1024,768)
basebox = Gtk.VBox(False,8)
basebox.show()
self.win.add(basebox)
self.basebox = basebox
source = GtkSource.View()
self.buffer = source.get_buffer()
self.lm = GtkSource.LanguageManager()
self.buffer.set_language(self.lm.get_language('python'))
source.connect("key-press-event", self.view_key_handler)
source.connect("key-release-event", self.view_key_handler)
source.connect("button-press-event", self.view_button_handler)
source.connect("button-release-event", self.view_button_handler)
filename = GtkSource.File()
filename.set_location(Gio.File.new_for_path('srcviewtest.py'))
fileloader= GtkSource.FileLoader.new(self.buffer, filename)
fileloader.load_async(GLib.PRIORITY_LOW, None, None, None, None, None)
source.set_show_line_numbers(True)
basebox.add(source)
source.show()
self.source = source
def view_key_handler(self,widget,data):
if not data.keyval in self.allowed_keys:
return True
def view_button_handler(self, widget, event):
if event.button != 1:
return True
def destroy(self, widget, data=None):
Gtk.main_quit()
def main(self):
Gtk.main()
if __name__ == '__main__':
m=Myclass()
m.main()