L’oggetto Gtk.TextView
può essere utilizzato per visualizzare e modificare testo, anche in grande quantità, utilizzando Gtk.TextBuffer
.
Serve? Probabilmente no. Almeno non a me, per quanto posso prevedere.
Però c’è. Allora facciamo come ho fatto per il visualizzatore di icone, anzi un ulteriore passo verso l’abisso e l’abominio. Riproduco solo l’esempio, preso da qui.
Dalla mia ho un paio di giustificazioni (quasi):
- problemi di salute (intesi come carenza della stessa);
- scadenze in arrivo (Lubit, Yupp (segretissimo questo, per adesso));
- il corso di Ruby, elementare ma il linguaggio comincia a piacermi;
- altre cose in sospeso.
#!/usr/bin/python3 # tem.py from gi.repository import Gtk, Pango class SearchDialog(Gtk.Dialog): def __init__(self, parent): Gtk.Dialog.__init__(self, "Search", parent, Gtk.DialogFlags.MODAL, buttons=( Gtk.STOCK_FIND, Gtk.ResponseType.OK, Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL)) box = self.get_content_area() label = Gtk.Label("Insert text you want to search for:") box.add(label) self.entry = Gtk.Entry() box.add(self.entry) self.show_all() class TextViewWindow(Gtk.Window): def __init__(self): Gtk.Window.__init__(self, title="TextView Example") self.set_default_size(-1, 350) self.grid = Gtk.Grid() self.add(self.grid) self.create_textview() self.create_toolbar() self.create_buttons() def create_toolbar(self): toolbar = Gtk.Toolbar() self.grid.attach(toolbar, 0, 0, 3, 1) button_bold = Gtk.ToolButton.new_from_stock(Gtk.STOCK_BOLD) toolbar.insert(button_bold, 0) button_italic = Gtk.ToolButton.new_from_stock(Gtk.STOCK_ITALIC) toolbar.insert(button_italic, 1) button_underline = Gtk.ToolButton.new_from_stock(Gtk.STOCK_UNDERLINE) toolbar.insert(button_underline, 2) button_bold.connect("clicked", self.on_button_clicked, self.tag_bold) button_italic.connect("clicked", self.on_button_clicked, self.tag_italic) button_underline.connect("clicked", self.on_button_clicked, self.tag_underline) toolbar.insert(Gtk.SeparatorToolItem(), 3) radio_justifyleft = Gtk.RadioToolButton() radio_justifyleft.set_stock_id(Gtk.STOCK_JUSTIFY_LEFT) toolbar.insert(radio_justifyleft, 4) radio_justifycenter = Gtk.RadioToolButton.new_with_stock_from_widget( radio_justifyleft, Gtk.STOCK_JUSTIFY_CENTER) toolbar.insert(radio_justifycenter, 5) radio_justifyright = Gtk.RadioToolButton.new_with_stock_from_widget( radio_justifyleft, Gtk.STOCK_JUSTIFY_RIGHT) toolbar.insert(radio_justifyright, 6) radio_justifyfill = Gtk.RadioToolButton.new_with_stock_from_widget( radio_justifyleft, Gtk.STOCK_JUSTIFY_FILL) toolbar.insert(radio_justifyfill, 7) radio_justifyleft.connect("toggled", self.on_justify_toggled, Gtk.Justification.LEFT) radio_justifycenter.connect("toggled", self.on_justify_toggled, Gtk.Justification.CENTER) radio_justifyright.connect("toggled", self.on_justify_toggled, Gtk.Justification.RIGHT) radio_justifyfill.connect("toggled", self.on_justify_toggled, Gtk.Justification.FILL) toolbar.insert(Gtk.SeparatorToolItem(), 8) button_clear = Gtk.ToolButton.new_from_stock(Gtk.STOCK_CLEAR) button_clear.connect("clicked", self.on_clear_clicked) toolbar.insert(button_clear, 9) toolbar.insert(Gtk.SeparatorToolItem(), 10) button_search = Gtk.ToolButton.new_from_stock(Gtk.STOCK_FIND) button_search.connect("clicked", self.on_search_clicked) toolbar.insert(button_search, 11) def create_textview(self): scrolledwindow = Gtk.ScrolledWindow() scrolledwindow.set_hexpand(True) scrolledwindow.set_vexpand(True) self.grid.attach(scrolledwindow, 0, 1, 3, 1) self.textview = Gtk.TextView() self.textbuffer = self.textview.get_buffer() self.textbuffer.set_text("This is some text inside of a Gtk.TextView. " + "Select text and click one of the buttons 'bold', 'italic', " + "or 'underline' to modify the text accordingly.") scrolledwindow.add(self.textview) self.tag_bold = self.textbuffer.create_tag("bold", weight=Pango.Weight.BOLD) self.tag_italic = self.textbuffer.create_tag("italic", style=Pango.Style.ITALIC) self.tag_underline = self.textbuffer.create_tag("underline", underline=Pango.Underline.SINGLE) self.tag_found = self.textbuffer.create_tag("found", background="yellow") def create_buttons(self): check_editable = Gtk.CheckButton("Editable") check_editable.set_active(True) check_editable.connect("toggled", self.on_editable_toggled) self.grid.attach(check_editable, 0, 2, 1, 1) check_cursor = Gtk.CheckButton("Cursor Visible") check_cursor.set_active(True) check_editable.connect("toggled", self.on_cursor_toggled) self.grid.attach_next_to(check_cursor, check_editable, Gtk.PositionType.RIGHT, 1, 1) radio_wrapnone = Gtk.RadioButton.new_with_label_from_widget(None, "No Wrapping") self.grid.attach(radio_wrapnone, 0, 3, 1, 1) radio_wrapchar = Gtk.RadioButton.new_with_label_from_widget( radio_wrapnone, "Character Wrapping") self.grid.attach_next_to(radio_wrapchar, radio_wrapnone, Gtk.PositionType.RIGHT, 1, 1) radio_wrapword = Gtk.RadioButton.new_with_label_from_widget( radio_wrapnone, "Word Wrapping") self.grid.attach_next_to(radio_wrapword, radio_wrapchar, Gtk.PositionType.RIGHT, 1, 1) radio_wrapnone.connect("toggled", self.on_wrap_toggled, Gtk.WrapMode.NONE) radio_wrapchar.connect("toggled", self.on_wrap_toggled, Gtk.WrapMode.CHAR) radio_wrapword.connect("toggled", self.on_wrap_toggled, Gtk.WrapMode.WORD) def on_button_clicked(self, widget, tag): bounds = self.textbuffer.get_selection_bounds() if len(bounds) != 0: start, end = bounds self.textbuffer.apply_tag(tag, start, end) def on_clear_clicked(self, widget): start = self.textbuffer.get_start_iter() end = self.textbuffer.get_end_iter() self.textbuffer.remove_all_tags(start, end) def on_editable_toggled(self, widget): self.textview.set_editable(widget.get_active()) def on_cursor_toggled(self, widget): self.textview.set_cursor_visible(widget.get_active()) def on_wrap_toggled(self, widget, mode): self.textview.set_wrap_mode(mode) def on_justify_toggled(self, widget, justification): self.textview.set_justification(justification) def on_search_clicked(self, widget): dialog = SearchDialog(self) response = dialog.run() if response == Gtk.ResponseType.OK: cursor_mark = self.textbuffer.get_insert() start = self.textbuffer.get_iter_at_mark(cursor_mark) if start.get_offset() == self.textbuffer.get_char_count(): start = self.textbuffer.get_start_iter() self.search_and_mark(dialog.entry.get_text(), start) dialog.destroy() def search_and_mark(self, text, start): end = self.textbuffer.get_end_iter() match = start.forward_search(text, 0, end) if match != None: match_start, match_end = match self.textbuffer.apply_tag(self.tag_found, match_start, match_end) self.search_and_mark(text, match_end) win = TextViewWindow() win.connect("delete-event", Gtk.main_quit) win.show_all() Gtk.main()
Dal prossimo post si torna alla normalità, sono cose che mi serviranno. Forse 🙄