2

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>
5
  • 1
    python gtk has some reasonable tutorials that you can check out to put together what you need. python-gtk-3-tutorial.readthedocs.io/en/latest/… Commented May 6, 2019 at 18:32
  • What exactly is not "example code" enough with the code you've shown? Commented May 6, 2019 at 18:33
  • thanks jonyfries -- i'll look at those right away Commented May 6, 2019 at 19:08
  • mkrieger1: The code above does not reference an on-clicked signal from the gui button and I'm having trouble figuring out where it should go ... and more fundamentally why it should go where it should go ... my brain hasn't really 'clicked' into OOP way of thinking, i guess. Commented May 6, 2019 at 19:14
  • Thanks for posting the question. I had the very same problem. The example code above does not show how to connect signals. Took me hours to find this information. Commented Dec 30, 2019 at 19:51

2 Answers 2

1

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>
Sign up to request clarification or add additional context in comments.

Comments

0

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!')

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.