Home > Gtk3, PyGObject, python > PyGObject: Gtk.TextView

PyGObject: Gtk.TextView

13 Aprile 2020

torna all’indice appunti

HeadBar

Il Gtk.HeaderBar è simile ad un Gtk.Box orizzontale, permette infatti di posizionare children all’inizio o alla fine.
In aggiunta permette di avere un titolo da visualizzare, tale titolo sarà centrato sulla larghezza del box.
Dal momento che GTK+ supporta le decorazioni lato Client, un oggetto Gtk.HeaderBar può essere utilizzato
al posto della title bar (che è renderizzata dal Window Manager).
Una Gtk.HeaderBar dà anche l’accesso ai controlli della window, come il close button e i window menu.

Le properties principali sono:

Name Type Flags Short Description
custom-title Gtk.Widget r/w Il title widget personalizzato da visualizzare
decoration-layout str r/w il layout per le decorazioni della window
decoration-layout-set bool r/w Se la property “decoration-layout” è stata settata
has-subtitle bool r/w/en Se riserva spazio per un sottotitolo
show-close-button bool r/w/en Se deve visualizzare le decorazioni della window (es. close button)
spacing int r/w/en La quantità di spazio tra i children
subtitle str r/w Il sottotitolo da visualizzare
title str r/w Il titolo da visualizzare

Metodi

Oltre ai soliti getter e setter relativi alle properties dell’oggetto Gtk.HeaderBar, i principali metodi sono:

new()

Crea un nuovo widget Gtk.HeaderBar

get_custom_title()

Ritorna il title widget personalizzato dell’header, o None se non ne è stato settato nessuno esplicitamente.

get_decoration_layout()

Ritorna una stringa che rappresenta il decoration layout dell’header settato con il metodo Gtk.HeaderBar.set_decoration_layout().

get_has_subtitle()

Ritorna True se l’headerbar riserva spazio per un sottotitolo

get_show_close_button()

Ritorna True se nell’headerbar sono visualizzate le window decorations, ad esempio il window close button.

get_subtitle()

Ritorna il sottotitolo della headerbar, o None se non è stato settato alcun sottotitolo esplicitamente.

get_title()

Ritorna il titolo della headerbar, o None se non è stato settato alcun titolo esplicitamente.

pack_end(child)

Aggiunge un child alla headerbar partendo dalla fine (come per il Gtk.Box).
I parametri sono:
child: il widget child (Gtk.Widget) da aggiungere alla headerbar;

pack_start(child)
Aggiunge un child alla headerbar partendo dall’inizio (come per il Gtk.Box).
I parametri sono:
child: il widget child (Gtk.Widget) da aggiungere alla headerbar;

set_custom_title(title_widget)

Aggiunge un titolo personalizzato alla headerbar. Questo sostituisce l’eventuale titolo settato con il metodo Gtk.HeaderBar.set_title().
I parametri sono:
title_widget: il widget title (Gtk.Widget) da utilizzare come titolo;

set_decoration_layout(layout)

Setta il decoration layout per la headerbar, sovrascrivendo il Gtk.Setting “gtk-decoration-layout” (ad esempio non vogliamo buttons sulla destra).
Il formato della stringa è dato dai nomi dei buttons, separati da comma (virgola) e colon (due punti “:”) che separa ciò
che deve essere visualizzato a sinistra, da quello che deve essere visualizzato a destra.
Ad esempio “menu:minimize,maximize,close” significa che a sinistra avremo un menu, mentre a destra i buttons minimize, maximize
e close.
I parametri sono:
layout: la stringa che rappresenta il decoration layout, o None per togliere il layout;

set_has_subtitle(setting)

Serve per riservare o meno lo spazio nella headerbar, per un sottotitolo.
I parametri sono:
setting: True per riservare spazio al sottotitolo, altrimenti False;

set_show_close_button(setting)

Setta se questa headerbar debba visualizzare, o meno, le standard window decorations, che includono i buttons close, maximize e minimize.
I parametri sono:
setting: True per visualizzare le standard window decorations, altrimenti False;

set_subtitle(subtitle)

Setta il sottotitolo della Gtk.HeaderBar. Notare che la HeaderBar, di default, riserva un’area per il sottotitolo, anche se al metodo viene passato
None. Se non vogliamo un’area dedicata dobbiamo settare la property “has-subtitle” a False.
I parametri sono:
subtitle: la stringa che indica il sottotitolo da visualizzare, o None;

set_title(title)

Setta il titolo della Gtk.HeaderBar.
I parametri sono:
title: la stringa che indica il titolo da visualizzare, o None;

Di seguito un codice di esempio:

import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, Pango


class SearchDialog(Gtk.Dialog):
    def __init__(self, parent):
        super().__init__("Search", parent)
        self.add_buttons(Gtk.STOCK_FIND, Gtk.ResponseType.OK,
                         Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL)
        box = self.get_content_area()
        box.add(Gtk.Label(label="Inserisci il testo da cercare"))
        self.entry = Gtk.Entry.new()
        box.add(self.entry)
        self.show_all()


class GWindow(Gtk.Window):
    def __init__(self):
        super().__init__(title="TextView Example")
        self.text_view = None
        self.text_buffer = None
        self.tag_bold = None
        self.tag_italic = None
        self.tag_underline = None
        self.tag_found = None
        self.grid = Gtk.Grid()

        self.set_default_size(500, 400)
        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
        button_bold = Gtk.ToolButton()
        button_bold.set_icon_name("format-text-bold-symbolic")
        toolbar.insert(button_bold, 0)
        # Button Italic
        button_italic = Gtk.ToolButton()
        button_italic.set_icon_name("format-text-italic-symbolic")
        toolbar.insert(button_italic, 1)
        # Button underline
        button_underline = Gtk.ToolButton()
        button_underline.set_icon_name("format-text-underline-symbolic")
        toolbar.insert(button_underline, 2)

        toolbar.insert(Gtk.SeparatorToolItem(), 3)

        # RadioButton justify left
        radio_j_left = Gtk.RadioToolButton()
        radio_j_left.set_icon_name("format-justify-left-symbolic")
        toolbar.insert(radio_j_left, 4)
        # RadioButton justify center
        radio_j_center = Gtk.RadioToolButton.new_from_widget(radio_j_left)
        radio_j_center.set_icon_name("format-justify-center-symbolic")
        toolbar.insert(radio_j_center, 5)
        # RadioButton justify right
        radio_j_right = Gtk.RadioToolButton.new_from_widget(radio_j_left)
        radio_j_right.set_icon_name("format-justify-right-symbolic")
        toolbar.insert(radio_j_right, 6)
        # RadioButton justify fill
        radio_j_fill = Gtk.RadioToolButton.new_from_widget(radio_j_left)
        radio_j_fill.set_icon_name("format-justify-fill-symbolic")
        toolbar.insert(radio_j_fill, 7)

        toolbar.insert(Gtk.SeparatorToolItem(), 8)

        button_clear = Gtk.ToolButton()
        button_clear.set_icon_name("edit-clear-symbolic")
        toolbar.insert(button_clear, 9)

        toolbar.insert(Gtk.SeparatorToolItem(), 10)

        button_search = Gtk.ToolButton()
        button_search.set_icon_name("system-search-symbolic")
        toolbar.insert(button_search, 11)

        # Bindings
        # I Tags vengono creati nel metodo costruttore del textview
        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)
        radio_j_left.connect("toggled", self.on_justify_toggled,
                             Gtk.Justification.LEFT)
        radio_j_center.connect("toggled", self.on_justify_toggled,
                               Gtk.Justification.CENTER)
        radio_j_right.connect("toggled", self.on_justify_toggled,
                              Gtk.Justification.RIGHT)
        radio_j_fill.connect("toggled", self.on_justify_toggled,
                             Gtk.Justification.FILL)
        button_clear.connect("clicked", self.on_clear_clicked)
        button_search.connect("clicked", self.on_search_clicked)

    def create_textview(self):
        scrolled_win = Gtk.ScrolledWindow()
        scrolled_win.set_hexpand(True)
        scrolled_win.set_vexpand(True)
        self.grid.attach(scrolled_win, 0, 1, 3, 1)
        # Text View
        self.text_view = Gtk.TextView()
        self.text_buffer = self.text_view.get_buffer()
        self.text_buffer.set_text("Lorem ipsum dolor sit amet, consectetur "
                                  "adipiscing elit, sed do eiusmod tempor "
                                  "incididunt ut labore et dolore magna aliqua."
                                  "Ut enim ad minim veniam, quis nostrud "
                                  "exercitation ullamco laboris (...)")
        scrolled_win.add(self.text_view)
        # Tags
        self.tag_bold = self.text_buffer.create_tag(tag_name="bold",
                                                    weight=Pango.Weight.BOLD)
        self.tag_italic = self.text_buffer.create_tag(tag_name="italic",
                                                      style=Pango.Style.ITALIC)
        self.tag_underline = self.text_buffer.create_tag(
            tag_name="underline", underline=Pango.Underline.SINGLE)
        self.tag_found = self.text_buffer.create_tag(tag_name="found",
                                                     background="yellow")

    def create_buttons(self):
        check_editable = Gtk.CheckButton(label="Editable")
        check_editable.set_active(True)
        self.grid.attach(check_editable, 0, 2, 1, 1)

        check_cursor = Gtk.CheckButton(label="Cursor Visible")
        check_cursor.set_active(True)
        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)

        # Bindings
        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)
        check_editable.connect("toggled", self.on_editable_toggled)
        check_editable.connect("toggled", self.on_cursor_toggled)

    def on_button_clicked(self, widget, tag):
        bounds = self.text_buffer.get_selection_bounds()
        if len(bounds) != 0:
            start, end = bounds
            self.text_buffer.apply_tag(tag, start, end)

    def on_clear_clicked(self, widget):
        start = self.text_buffer.get_start_iter()
        end = self.text_buffer.get_end_iter()
        self.text_buffer.remove_all_tags(start, end)

    def on_editable_toggled(self, widget):
        self.text_view.set_editable(widget.get_active())

    def on_cursor_toggled(self, widget):
        self.text_view.set_cursor_visible(widget.get_active())

    def on_wrap_toggled(self, widget, mode):
        self.text_view.set_wrap_mode(mode)

    def on_justify_toggled(self, widget, justification):
        self.text_view.set_justification(justification)

    def on_search_clicked(self, widget):
        dialog = SearchDialog(parent=self)
        response = dialog.run()
        if response == Gtk.ResponseType.OK:
            cursor_mark = self.text_buffer.get_insert()
            start = self.text_buffer.get_iter_at_mark(cursor_mark)
            if start.get_offset() == self.text_buffer.get_char_count():
                start = self.text_buffer.get_start_iter()

            self.search_and_mark(dialog.entry.get_text(), start)

        dialog.destroy()

    def search_and_mark(self, text, start):
        end = self.text_buffer.get_end_iter()
        match = start.forward_search(text, 0, end)

        if match is not None:
            match_start, match_end = match
            self.text_buffer.apply_tag(self.tag_found, match_start, match_end)
            self.search_and_mark(text, match_end)


if __name__ == "__main__":
    win = GWindow()
    win.connect("destroy", Gtk.main_quit)
    win.show_all()
    Gtk.main()

link di riferimento:

torna all’indice degli appunti
Gtk3 HeaderBar

Categorie:Gtk3, PyGObject, python Tag: , ,
I commenti sono chiusi.