GtkSourceViewを表示専用にする、その方法が分からなかったのでメモ
- 作者: ToshioCP
- 発売日: 2017/06/06
- メディア: Kindle版
- この商品を含むブログを見る
はいアフィ入りました〜w
というか他のGTK関連書籍は正直10年いや20年前のもので役に立たないと思われたからです。ていうか昔は盛んだったんですなぁ(´・ω・`)
まぁそれはともかく、このアフィリンクの書籍とは一切関係ない話なのですが
以下は普通の知能を持っていれば当たり前の話なのですが、GtkSourceViewに対して変更を禁止しようと思ったのですが 自分はgtksourceview read-onlyなどで延々とググり続けてしまった罠。 なにかset_read_onlyみたいなメソッドがあるのかな〜と…無いですね。*1
そしてその方法について誰も言及していない。何故か。その理由はあまりにも基本的だからだと推察します。
つまり…単にGtkのウィジェットとしてキー入力を無効化してしまえばいいだけではないか?と思いついたからです。
しかし単純にset_sensitive()でFalseにするとナビゲーションすら不能になるという。 そこで、キーボードイベントをconnectしてナビゲーションキー以外はTrueを返してバブリングを抑制。キー入力を遮断してしまうという方法を取りました。
マウスボタンも右ボタンを許すとメニューが飛び出てしまうので潰しておきます。 ただしこれだとテキスト選択してコピーが出来ないので(いや別に出来なくてもいいけど)何か自前の「コピー」だけあるメニューでも表示するとかしたほうが良いかもですね。
他にスマートな方法があるのかも知れませんが、こんな単純なことを思いつきました的な話でした。
サンプルコード
面倒くさいので、GtkSourceViewテスト用コードの全体をコピペ!
#!/usr/bin/env python # -*- coding: UTF-8 -*- import gi gi.require_version('Gtk', '3.0') gi.require_version('GtkSource', '3.0') from gi.repository import Gtk, Gdk, GtkSource, GObject, GLib, Gio # For reference of GtkSourceView(but 4.0): # https://lazka.github.io/pgi-docs/GtkSource-4/classes.html 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) # widgets baseically added this self.basebox basebox = Gtk.VBox(False,8) basebox.show() self.win.add(basebox) self.basebox = basebox # Building: # You need `from gi.repository import GtkSource`, `GLib` and `Gio` # Coding: # Buffer : You need buffer for actual text contents. # The source-view is only `view`, actually you must use # buffer to load or set file type or something like that. # it can be get from source.get_buffer() (empty one) # or, create from GtkSource.Buffer(). # # LanguageManager : To specify the `programming language` for `buffer`. # # FileLoader: To load file into buffer. Need GLib module to set priority # when use async load. # Also Gio for File (filename) object. # source = GtkSource.View() self.buffer = source.get_buffer() # Use Language Manager, to set language (i.e. file type) to buffer. self.lm = GtkSource.LanguageManager() self.buffer.set_language(self.lm.get_language('python')) # Set readonly # To make view read-only, prohibit all key inputs except for navigation keys. 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) # Load text contents # FileLoader does not accept string filename. use GtkSource.File object. filename = GtkSource.File() filename.set_location(Gio.File.new_for_path('srcviewtest.py')) # This Needs Gio module. fileloader= GtkSource.FileLoader.new(self.buffer, filename) # Not use constructor, use this class method. 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 # Prohibit bubbling def view_button_handler(self, widget, event): if event.button != 1: return True # Prohibit bubbling def destroy(self, widget, data=None): Gtk.main_quit() def main(self): Gtk.main() if __name__ == '__main__': m=Myclass() m.main()
*1:もしあるのなら教えて欲しいガチで…割と困っています