API
Gio
Action
-
Gio.Action is a way to expose any single task an application or widget does by a name. Classes like Gio.MenuItem and Gtk.ModelButton support properties to set an action name. These actions can be collected into a Gio.ActionGroup.
- Gio.ActionMap are interfaces implemented by Gtk.ApplicationWindow
Gtk
ActionGroup
Adjustment
-
Gtk.Adjustment is not a widget per se but is used in many widgets, including spin buttons, view ports, and children of Gtk.Range.
- page increment and page size refer to actions taken when the user presses PgUp or PgDn
Gtk.Adjustment.new(initial_value, lower_range, upper_range, step_increment, page_increment, page_size)
- page increment and page size refer to actions taken when the user presses PgUp or PgDn
Alignment
- Gtk.Alignment controls the alignment and size of its child widget.
Application
-
Subclasses of Gtk.Application encapsulate application behavior, including application startup and CLI processing. In practice it is simply a wrapper for the ApplicationWindow class which is instantiated in the
do_activate()
hook. Notably, the Application subclass provides the value for theapplication_id
kwarg passed to the Gtk.Application constructor. This value is validated, and any simple string is not silently accepted.Application must expose several important methods:
do_activate()
def do_activate(self): self.window = ApplicationWindow(application=self, title="Hello, World!") self.window.show_all() self.window.present()
do_startup()
ApplicationWindow
-
The Gtk.ApplicationWindow class is the main visible window for the application, and the only window for "single-instance" applications (which is the default). The ApplicationWindow class was introduced in GTK 3.4.
When an action has the prefix
win.
it specifies that the ApplicationWindow subclass will process the signal.
Assistant
- Gtk.Assistant widgets are used to build wizards.
Box
Builder
-
Gtk.Builder allows the use of interfaces to define widget layouts. Individual UI elements can be bound if they have an id attribute assigned.
fn main() { let app = gtk::Application::builder() .application_id("org.example.gtk-app") .build(); app.connect_activate(build_ui); app.run(); } fn build_ui(app: &Application):{ let builder = gtk::Builder::from_string(include_str!("window.ui")); let window: ApplicationWindow = builder.object("window") .expect("Error loading ApplicationWindow!"); window.set_application(Some(app)); window.show_all(); window.present(); }
class Application(Gtk.Application): def __init__(self, *args, **kwargs): super().__init__(application_id = "org.example.gtk-app") def do_activate(self): builder = Gtk.Builder.new_from_file("window.ui") self.window = builder.get_object("window") self.window.show_all() self.window.present() def run(self): super().run() Gtk.main()
CheckButton
- Gtk.CheckButtons are checkboxes.
clone
-
glib::clone! is used to facilitate passing strong or weak references into closures.
use glib; use glib_macros::clone; use std::rc::Rc; let v = Rc::new(1); let closure = clone!(@strong v => move |x| { println!("v: {}, x: {}", v, x); }); closure(2);
use glib; use glib_macros::clone; use std::rc::Rc; let u = Rc::new(2); let closure = clone!(@weak u => move |x| { println!("u: {}, x: {}", u, x); }); closure(3);
Container
- Both Gtk.ApplicationWindow and Gtk.Window classes indirectly derive from the abstract class Gtk.Container. The main purpose of a container subclass is to allow a parent widget to contain one or more child widgets, and there are two types:
Dialog
-
Gtk.Dialog provides a convenient way to prompt the user for a small amount of input. It is a widget that can be instantiated and customized in its own right as well as a parent to various subclasses.
dialog = Gtk.Dialog(title="Hello, World!", parent=parent)
Dialogs are split into two parts:
- Content area containing interactive widgets
- Action area containing buttons
These areas are both combined in a vertical Box that is assigned to the
vbox
field. The action area is packed to the end of this vbox, so thepack_start()
method is used to add widgets to the content area.Dialog boxes can be modal, meaning they prevent interaction with the main window while open, or nonmodal.
dialog = Gtk.Dialog(title="Hello, World!", parent=parent, modal=True)
dialog = Gtk.Dialog(title="Hello, World!", parent=parent, modal=False)
Gtk.MessageDialog is a subtype of Dialog meant to simplify the process of creating simple dialogs.
Buttons are added procedurally using
add_button()
, passing a display string (with support for mnemonics using_
) and a ResponseType enum (they once could be added on instantiation by passing a tuple to thebuttons
keyword argument).dialog.add_button("_OK", Gtk.ResponseType.OK)
Methods:
Entry
-
Unlike other widgets, Gtk.Entry can be instantiated without using a specific constructor.
entry = Gtk.Entry()
Default text can be provided by passing a string to the text keyword argument or with the
set_text()
setter method:entry = Gtk.Entry(text="Hello, World!")
entry.set_text("Hello, World!")
A password field can be made by concealing text by passing False to visibility or with the
set_visibility()
setter:password = Gtk.Entry(visibility=False)
password.set_visibility(False)
EventBox
-
Gtk.EventBox is a container widget that allows event handling for widgets like Gtk.Label that do not have an associated GDK window. The event box can be positioned above or below the windows of its child with
set_above_child()
(False by default.) An EventBox must also have a Gtk.EventMask enum set to specify the type of events the widget may receive. This enum is passed as a value toset_events()
.In the following example, an event handler is connected to the EventBox to handle
button_press_event
. This event handler changes the text of the Label after a double-click.import gi gi.require_version('Gtk', '3.0') from gi.repository import Gtk, Gdk class AppWindow(Gtk.ApplicationWindow): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.set_border_width(10) self.set_size_request(200, 50) eventbox = Gtk.EventBox.new() label = Gtk.Label.new("Double-Click Me!") eventbox.set_above_child(False) eventbox.connect("button_press_event", self.on_button_pressed, label) eventbox.add(label) self.add(eventbox) eventbox.set_events(Gdk.EventMask.BUTTON_PRESS_MASK) eventbox.realize() def on_button_pressed(self, eventbox, event, label): if event.type == Gdk.EventType._2BUTTON_PRESS: text = label.get_text() if text[0] == 'D': label.set_text("I Was Double-Clicked!") else: label.set_text("Double-Click Me Again!") return False class Application(Gtk.Application): def __init__(self, *args, **kwargs): super().__init__(*args, application_id="org.example.myapp", **kwargs) self.window = None def do_activate(self): if not self.window: self.window = AppWindow(application=self, title="Hello World!") self.window.show_all() self.window.present() if __name__ == "__main__": app = Application() app.run()
FileChooserDialog
-
Gtk.FileChooserDialog is one of the important subtypes of Gtk.Dialog. Like other dialogs, it is provided a title and parent window on instantiation. Additionally a FileChooserAction enum must be specified.
FileChooserActions include:
- Gtk.FileChooserAction.SAVE
- Gtk.FileChooserAction.OPEN
- Gtk.FileChooserAction.SELECT_FOLDER
- Gtk.FileChooserAction.CREATE_FOLDER
dialog = Gtk.FileChooserDialog( title="Save file as ...", parent=parent, action=FileChooserAction.SAVE )
Selected files are then retrieved using
dialog.get_filenames()
| Setter | Property | Description | | --------------------------------------------------------------------------------------------------------------------------------- | ----------------- | |
set_current_folder
| | Specify directory in filesystem where FileChooser will start | |set_current_name
| | For FileChooserAction.SAVE, suggest a filename | |set_select_multiple
|select_multiple
| For FileChooserAction.OPEN or SELECT_FOLDER, allow multiple file or folder selections |
Grid
-
Gtk.Grid allows children to be packed in a two-dimensional grid. Grids are instantiated with
new()
and widgets are laid out by callingattach()
(see Login for an example).attach()
lay out a widget providing column and row numbers followed by column and row spansgrid.attach(label, 0, 0, 1, 1)
HeaderBar
-
Gtk.HeaderBar allows the titlebar to be customized. Like other widgets, it can be configured on instantiation by providing values to keyword arguments or by using setters.
Adding to a window
HeaderBars are added with
set_titlebar()
. This is unlike other widgets which are assigned to an ApplicationWindow or Window usingpack_start()
,pack_end()
, oradd()
,class ApplicationWindow(Gtk.ApplicationWindow): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) headerbar = Gtk.HeaderBar(title=f"Hello, World!", subtitle="HeaderBar example", show_close_button=True) self.set_titlebar(headerbar)
class ApplicationWindow(Gtk.ApplicationWindow): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) headerbar = Gtk.HeaderBar() headerbar.set_title(f"Hello, World!") headerbar.set_subtitle("HeaderBar example") headerbar.set_show_close_button(True) self.set_titlebar(headerbar)
Label
-
Note that Gtk.Label sets its text with "label" and not "text" as you may expect from the corresponding setter.
label = Gtk.Label(label="Hello, World!")
label.set_text("Hello, World!")
ListBox
- Gtk.ListBox is a vertical container of Gtk.ListBoxRow children used as an alternative to TreeView when the children need to be interactive, as in a list of settings. ListBox
ListStore
-
Gtk.ListStore is one of the two major classes that serves as combination schema and database backing Gtk.TreeView, the other being Gtk.TreeStore.
It is instantiated with a sequence of data types, similar to a database schema. These can be standard Python types or GObjects (which are mapped to the Python types anyway):
import gi gi.require_version("Gtk", "3.0") from gi.repository import Gtk liststore = Gtk.ListStore((str, int, str))
import gi gi.require_version("Gtk", "3.0") from gi.repository import Gtk, GObject liststore = Gtk.ListStore((GObject.TYPE_STRING, GOBject).TYPE_INT, GObject.TYPE_STRING))
This object then exposes an
append
method which is used to add records:liststore.append(["Socrates", 350, "Athens"])
The store is then associated with the treeview with
set_model
treeview.set_model(liststore)
MenuBar
-
Gtk.MenuBar is populated with Gtk.MenuItems, corresponding to the expandable menu items (i.e. "File", "Edit", and "Help"). Gtk.Menu is actually used for the submenu, which like MenuBar is also populared with MenuItems. A Menu is attached to the MenuItem of a MenuBar by using the
set_submenu()
method on the Menu object. This setter does not have a corresponding kwarg, so all menus have to be constructed procedurally.import gi gi.require_version('Gtk', '3.0') from gi.repository import Gtk class AppWindow(Gtk.ApplicationWindow): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.set_size_request(250, -1) menubar = Gtk.MenuBar.new() self.add(menubar) file = Gtk.MenuItem.new_with_label("File") menubar.append(file) filemenu = Gtk.Menu.new() file.set_submenu(filemenu) new = Gtk.MenuItem.new_with_label("New") open = Gtk.MenuItem.new_with_label("Open") filemenu.append(new) filemenu.append(open) edit = Gtk.MenuItem.new_with_label("Edit") menubar.append(edit) editmenu = Gtk.Menu.new() edit.set_submenu(editmenu) cut = Gtk.MenuItem.new_with_label("Cut") copy = Gtk.MenuItem.new_with_label("Copy") paste = Gtk.MenuItem.new_with_label("Paste") editmenu.append(cut) editmenu.append(copy) editmenu.append(paste) help = Gtk.MenuItem.new_with_label("Help") menubar.append(help) helpmenu = Gtk.Menu.new() help.set_submenu(helpmenu) contents = Gtk.MenuItem.new_with_label("Help") about = Gtk.MenuItem.new_with_label("About") helpmenu.append(contents) helpmenu.append(about) class Application(Gtk.Application): def __init__(self, *args, **kwargs): super().__init__(*args, application_id="org.example.myapp", **kwargs) self.window = None def do_activate(self): if not self.window: self.window = AppWindow(application=self, title="Menu Bars") self.window.show_all() self.window.present() if __name__ == "__main__": app = Application() app.run()
Notebook
-
Gtk.Notebook is a layout container that organizes content into tabbed pages. It is instantiated with the
new()
method and pages are appended with theappend_page()
method, passing content and label widgets as arguments.The tab bar can be placed using
set_tab_pos()
, passing a Gtk.PositionType enumnotebook = Gtk.Notebook.new() # notebook.set_tab_pos(Gtk.PositionType.TOP)
notebook = Gtk.Notebook.new() notebook.set_tab_pos(Gtk.PositionType.RIGHT)
notebook = Gtk.Notebook.new() notebook.set_tab_pos(Gtk.PositionType.BOTTOM)
notebook = Gtk.Notebook.new() notebook.set_tab_pos(Gtk.PositionType.LEFT)
notebook = Gtk.Notebook.new() label = Gtk.Label.new("Tab title") child = Gtk.Label.new("Tab content") notebook.append_page(child, label)
The label widget is commonly Gtk.Label but can also be a Gtk.Box.
The tab bar can be made scrollable using
set_scrollable()
, passing a bool.
Scale
-
Gtk.Scale widgets are sliders, and they can be instantiated in one of two ways:
new()
passing an Adjustment objectnew_with_range(min, max, step)
passing values for minimum, maximum, and step
Scale values are stored as doubles, so integers have to be simulated by reducing the number of digits to 0 using
set_digits()
. By default, the number of digits is set to that of the step value.
ScrolledWindow
-
Gtk.ScrolledWindow is a decorator container that accepts a single child widget. Widgets that implement the Gtk.Scrollable interface have native scrolling suppport, like Gtk.TreeView, Gtk.TextView, and Gtk.Layout. Other widgets have to use Gtk.Viewport as an adaptor, and must be added to a Viewport which is then added to the ScrolledWindow.
It is instantiated with the
new()
method, optionally passing two Adjustment objects that affect horizontal and vertical scrolling behavior when stepping or paging.scrolled_win = Gtk.ScrolledWindow.new(None,None)
Statusbar
- Gtk.Statusbar (note the lowercase b ) stores a stack of messages, the topmost of which is displayed.
Before adding messages, a context identifier, a unique unsigned integer associated with a context description string, must be retrieved from the newly created Statusbar by passing a string value to
get_context_id()
. This allows messages to be categorized and pushed to separate stacks.statusbar.push(context_id, message)
Switch
-
Gtk.Switch allows a user to toggle a boolean value. Switch exposes getters and setters for both state (which is represented by the trough color) and active (switch position) properties. State is the backend to activ, and they are kept in sync.
import gi gi.require_version("Gtk", "3.0") from gi.repository import Gtk class ApplicationWindow(Gtk.ApplicationWindow): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.set_border_width(10) box_outer = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=6) listbox = Gtk.ListBox(selection_mode=Gtk.SelectionMode.NONE) row = Gtk.ListBoxRow() hbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=50) label1 = Gtk.Label(label="Automatic Date & Time", xalign=0) hbox.add(label1) self.switch = Gtk.Switch(valign=Gtk.Align.CENTER, state=False) hbox.add(self.switch) row.add(hbox) listbox.add(row) box_outer.add(listbox) self.add(box_outer) button = Gtk.Button(label="Click") button.connect("clicked", self.on_button_clicked) box_outer.add(button) def on_button_clicked(self, button): print(f"Value of get_active(): {self.switch.get_active()}") print(f"Value of get_state(): {self.switch.get_state()}") class Application(Gtk.Application): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.window = None def do_activate(self): if not self.window: self.window=ApplicationWindow(application=self) self.window.show_all() self.window.present() if __name__ == "__main__": app = Application() app.run()
TreeView
-
In order to create a tree or list in GTK, the Gtk.TreeView widget is paired with a Gtk.TreeModel interface, the most typical implementation of which is Gtk.ListStore or Gtk.TreeStore. TreeView is a complicated widget that must be constructed procedurally:
- Gtk.TreeView is instantiated. A ListStore is specified as data model and passed in as the value of the model kwarg.
The ListStore specifies the schema of the data as a collection of types.
Alternatively, the ListStore can be specified after instantiation.
treeview = Gtk.TreeView(model=Gtk.ListStore.new((str)))
treeview = Gtk.TreeView.new() treeview.set_model(Gtk.ListStore.new([str]))
- A Gtk.TreeViewColumn is created for every column in the model. These require a Gtk.CellRenderer to be defined. The TreeViewColumn is added to the treeview by calling the
append_column()
method on the treeview. The text kwarg appears to refer to the column of the data store to use for the column's values.treeview.append_column(Gtk.TreeViewColumn("Greeks", Gtk.CellRendererText.new(), text=0))
- Items are added to the ListStore procedurally using the
append()
method. Note that the method takes only a single argument, so collections like lists or tuples must be used.liststore.append(("Socrates",)) liststore.append(("Plato",)) liststore.append(("Aristotle",))
Changing the number of columns affects the types used to define the ListStore, the appended records, as well as the number of columns added to the TreeView itself.
import gi gi.require_version('Gtk', '3.0') from gi.repository import Gtk class ApplicationWindow(Gtk.ApplicationWindow): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.gen_treeview() scrolled_win = Gtk.ScrolledWindow.new(None,None) scrolled_win.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC) scrolled_win.add(self.treeview) self.add(scrolled_win) self.set_size_request(200,200) def get_liststore(self): store = Gtk.ListStore.new((str,)) store.append(("Socrates",)) store.append(("Plato",)) store.append(("Aristotle",)) return store def gen_treeview(self): self.treeview = Gtk.TreeView.new() self.treeview.set_model(self.get_liststore()) self.treeview.append_column(Gtk.TreeViewColumn("Greeks", Gtk.CellRendererText.new(), text=0)) class Application(Gtk.Application): def __init__(self): super().__init__(application_id='org.example.myapp') def do_activate(self): self.window = ApplicationWindow(application=self, title="Greeks") self.window.show_all() self.window.present() if __name__ == '__main__': app = Application() app.run()
import gi gi.require_version('Gtk', '3.0') from gi.repository import Gtk class ApplicationWindow(Gtk.ApplicationWindow): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.gen_treeview() scrolled_win = Gtk.ScrolledWindow.new(None,None) scrolled_win.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC) scrolled_win.add(self.treeview) self.add(scrolled_win) self.set_size_request(200,200) def get_liststore(self): store = Gtk.ListStore.new((str, str)) store.append(["Socrates", "Athens"]) store.append(["Plato", "Athens"]) store.append(["Aristotle", "Athens"]) return store def gen_treeview(self): self.treeview = Gtk.TreeView.new() self.treeview.set_model(self.get_liststore()) self.treeview.append_column(Gtk.TreeViewColumn("Greeks", Gtk.CellRendererText.new(), text=0)) self.treeview.append_column(Gtk.TreeViewColumn("Place of birth", Gtk.CellRendererText.new(), text=1)) class Application(Gtk.Application): def __init__(self): super().__init__(application_id='org.example.myapp') def do_activate(self): self.window = ApplicationWindow(application=self, title="Greeks") self.window.show_all() self.window.present() if __name__ == '__main__': app = Application() app.run()
The model backing a TreeView (usually a ListStore), can be retrieved with the
get_model()
method.treeview.get_model().append(('foo','bar'))
TreeView emits several signals:
row_activated
when a row is double-clicked, with the following implicit argumentwidget
refering to the emitting TreeView widget itselfpath
is a TreePath.column
is of type TreeViewcolumntreeview.connect("row_activated", self.on_row_activated, widget, path, column)
def on_row_activated(self, widget, path, column): row = path.get_indices()[0] print(f"row={path.get_indices()[0]},col={column.props.title}") print(widget.get_model()[row][:])
- Gtk.TreeView is instantiated. A ListStore is specified as data model and passed in as the value of the model kwarg.
The ListStore specifies the schema of the data as a collection of types.
TreePath
-
Gtk.TreePath is a type used to implement the rows of a TreeView. Although it prints to an integer with the print statement, it cannot be treated as one.
A path object can be passed as the index to a TreeModel like ListStore, as can an integer. The row number of a TreePath from a normal list-style TreeView can be retrieved with the
get_indices()
method.row = path.get_indices()[0] # Using TreePath object as index to model model[path][:] # Using row integer as index to model model[row][:]
Another method on TreePath,
get_depth()
always returns 1 for list-style TreeViews, but may be more useful for tree-style TreeViews.
TreeSelection
- Gtk.TreeSelection objects represent selection information for each tree view.
TreeViewColumn
- Gtk.TreeViewColumn represents a visible column in a Treeview.
Its props property exposes many associated values, including title.
A column is made sortable by calling
print(column.props.title)
set_sort_column_id()
, passing the column of the model to sort by.column.set_sort_column_id(0)
Window
- Gtk.Window