Søren ONeill
Søren ONeill

Reputation: 529

I need example code for a simple python-gui script with gtk+

I'm new to Python and OOP and need a sample script to get an understanding of how the gtk.builder objects and window objects relate. I'm using gnome-builder to get started.

What I'd like is to load the gui definition from xml as produced by builder (or Glade): simple stuff really :

Window to have a button and a label. When button is clicked label is toggled as shown or hidden. However, the label (when shown) should be a continuously changing random letter.

The following code is from the Gnome builder hello world with gui changed to my needs.

main.py :

import sys
import gi

gi.require_version('Gtk', '3.0')

from gi.repository import Gtk, Gio

from .window import TestWindow


class Application(Gtk.Application):
    def __init__(self):
        super().__init__(application_id='test',
                         flags=Gio.ApplicationFlags.FLAGS_NONE)

    def do_activate(self):
        win = self.props.active_window
        if not win:
            win = TestWindow(application=self)
        win.present()


def main(version):
    app = Application()
    return app.run(sys.argv)

window.py:

from gi.repository import Gtk


@Gtk.Template(resource_path='/test/window.ui')
class TestWindow(Gtk.ApplicationWindow):
    __gtype_name__ = 'TestWindow'

    label = Gtk.Template.Child()

    def __init__(self, **kwargs):
        super().__init__(**kwargs)

window.ui:

<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.1 -->
<interface>
  <requires lib="gtk+" version="3.20"/>
  <template class="TestWindow" parent="GtkApplicationWindow">
    <property name="can_focus">False</property>
    <property name="default_width">600</property>
    <property name="default_height">300</property>
    <child type="titlebar">
      <placeholder/>
    </child>
    <child>
      <object class="GtkBox">
        <property name="visible">True</property>
        <property name="can_focus">False</property>
        <property name="orientation">vertical</property>
        <child>
          <object class="GtkLabel" id="label">
            <property name="visible">True</property>
            <property name="can_focus">False</property>
            <property name="label" translatable="yes">label</property>
          </object>
          <packing>
            <property name="expand">False</property>
            <property name="fill">True</property>
            <property name="position">0</property>
          </packing>
        </child>
        <child>
          <object class="GtkButton" id="button">
            <property name="label" translatable="yes">button</property>
            <property name="visible">True</property>
            <property name="can_focus">True</property>
            <property name="receives_default">True</property>
          </object>
          <packing>
            <property name="expand">False</property>
            <property name="fill">True</property>
            <property name="position">1</property>
          </packing>
        </child>
        <child>
          <placeholder/>
        </child>
      </object>
    </child>
  </template>
</interface>

Upvotes: 2

Views: 1947

Answers (2)

BlueManCZ
BlueManCZ

Reputation: 436

You can find the example code here:

https://pygobject.readthedocs.io/en/latest/guide/gtk_template.html

Connecting signals with handlers is even easier with Gtk.Template than @joshua-bell says in another answer. You don't need the .connect() function anymore.

All you need to do is create a GUI object with a signal as follows:

<object class="GtkButton">
    <property name="label">Hello world button</property>
    <property name="visible">True</property>
    <property name="can-focus">True</property>
    <property name="receives-default">True</property>
    <signal name="clicked" handler="button_click" swapped="no"/>
</object>

and use @Gtk.Template.Callback decorator to define handler for this signal:

@Gtk.Template(resource_path='/path/to/window.ui')
class AppWindow(Gtk.ApplicationWindow):
    __gtype_name__ = 'AppWindow'

    def __init__(self, **kwargs):
        super().__init__(**kwargs)

    @Gtk.Template.Callback('button_click')
    def button_click(self, *args):
        print('Hello world!')

Upvotes: 0

Josh Bell
Josh Bell

Reputation: 31

I am assuming you are using Gnome builder to build your application. In order to connect a handler to a button you should add a <signal name="clicked" handler="handler_name" /> to the button.

http://www.learningpython.com/2006/05/07/creating-a-gui-using-pygtk-and-glade/

This is a link to a tutorial for using pygtk with glade which is mostly applicable to the framework you are working with

This is a block of code from my window.py file which connects the VisitFaq button to it's handler

@Gtk.Template(resource_path='/edu/umich/help/window.ui')
class HelpWindow(Gtk.ApplicationWindow):
    __gtype_name__ = 'HelpWindow'
    VisitFaq = Gtk.Template.Child()
    ChatButton = Gtk.Template.Child()
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.ChatButton.connect('clicked', self.start_chat)


    def start_chat(self):

Here is how VisitFaq looks in the ui file

<object class="GtkButton" id="VisitFaq">
                    <property name="label" translatable="yes">Visit the FAQ</property>
                    <property name="name">FaqButton</property>
                    <property name="visible">True</property>
                    <property name="can_focus">True</property>
                    <property name="receives_default">True</property>
                    <signal name="clicked" handler="visit_faq" />
                  </object>

Upvotes: 1

Related Questions