0
votes

Using this tutorial https://python-gtk-3-tutorial.readthedocs.io/en/latest/builder.html I have created a similar Glade GUI which has a quit button and two radio buttons A and B. I am quite confused by radio buttons.

If I use GtkButton or GtkToggleButton the rba function triggers twice, I assume it triggers both when the button becomes the active one and when it becomes the inactive one. Is that right?

I don't need anything complicated, either

  1. a function which triggers when a button is clicked, within which I can find out which one is now active, OR

  2. a function for each button which triggers only when its own button is clicked.

I also need to be able to switch which button is active, preferably without triggering the/its function.

Have I misunderstood something essential?

EDIT: After much experimentation, I have found that second bit of code works for a signal GtkToggleButton>toggled>rba. I can't get anything similar to work for the other button though!

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

    class Handler:

        def buttonQuit(self, menuitem): # quit with Quit button
            Gtk.main_quit()
        def on_window1_destroy(self, object): # close window with 0 or X
            Gtk.main_quit()

        def rba(self, menuitem):
            print('A')

    builder = Gtk.Builder()
    builder.add_from_file('test.glade')
    builder.connect_signals(Handler())
    window = builder.get_object("window1")
    window.show_all()

    Gtk.main()

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

class Handler:

    def buttonQuit(self, menuitem): # quit with Quit button
        Gtk.main_quit()
    def on_window1_destroy(self, object): # close window with 0 or X
        Gtk.main_quit()

    def rba(self, menuitem):
        print('in rba')
        print (RBA.get_active())

builder = Gtk.Builder()
builder.add_from_file('test.glade')
builder.connect_signals(Handler())
window = builder.get_object("window1")

RBA = builder.get_object('radiobuttonA')
window.show_all()

Gtk.main()

<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.18.3 -->
<interface>
  <requires lib="gtk+" version="3.12"/>
  <object class="GtkWindow" id="window1">
    <property name="can_focus">False</property>
    <property name="window_position">center</property>
    <property name="gravity">center</property>
    <property name="has_resize_grip">True</property>
    <signal name="destroy" handler="on_window1_destroy" swapped="no"/>
    <child>
      <object class="GtkBox" id="box1">
        <property name="visible">True</property>
        <property name="can_focus">False</property>
        <property name="orientation">vertical</property>
        <child>
          <object class="GtkButtonBox" id="buttonbox1">
            <property name="visible">True</property>
            <property name="can_focus">False</property>
            <property name="halign">center</property>
            <property name="valign">center</property>
            <property name="layout_style">start</property>
            <child>
              <object class="GtkRadioButton" id="radiobuttonA">
                <property name="label" translatable="yes">A</property>
                <property name="visible">True</property>
                <property name="can_focus">True</property>
                <property name="receives_default">False</property>
                <property name="halign">start</property>
                <property name="valign">center</property>
                <property name="xalign">0</property>
                <property name="active">True</property>
                <property name="draw_indicator">True</property>
              </object>
              <packing>
                <property name="expand">False</property>
                <property name="fill">False</property>
                <property name="position">0</property>
              </packing>
            </child>
            <child>
              <object class="GtkRadioButton" id="radiobuttonB">
                <property name="label" translatable="yes">B</property>
                <property name="visible">True</property>
                <property name="can_focus">True</property>
                <property name="receives_default">False</property>
                <property name="halign">start</property>
                <property name="valign">center</property>
                <property name="xalign">0</property>
                <property name="draw_indicator">True</property>
                <property name="group">radiobuttonA</property>
              </object>
              <packing>
                <property name="expand">False</property>
                <property name="fill">False</property>
                <property name="position">1</property>
              </packing>
            </child>
          </object>
          <packing>
            <property name="expand">False</property>
            <property name="fill">True</property>
            <property name="position">0</property>
          </packing>
        </child>
        <child>
          <object class="GtkButton" id="buttonQuit">
            <property name="label" translatable="yes">Quit</property>
            <property name="width_request">100</property>
            <property name="visible">True</property>
            <property name="can_focus">True</property>
            <property name="receives_default">True</property>
            <property name="halign">center</property>
            <property name="valign">center</property>
            <property name="xalign">0.56000000238418579</property>
            <property name="yalign">0.49000000953674316</property>
            <signal name="clicked" handler="buttonQuit" swapped="no"/>
          </object>
          <packing>
            <property name="expand">False</property>
            <property name="fill">True</property>
            <property name="position">1</property>
          </packing>
        </child>
      </object>
    </child>
  </object>
</interface>
2
Have you tried to connect to the toggled signal of both radiobuttons? You then have to figure out which radiobutton is active with something like radiobutton.get_active().theGtknerd
Gtknerd: See edit above.ChrisOfBristol
Sorry, I did not understand your edit. See my answer.theGtknerd

2 Answers

1
votes

This is one of the ways to set up Python + Gtk properly with the basic idea you already have. It works for me.

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

class GUI:
    def __init__ (self):
        builder = Gtk.Builder()
        builder.add_from_file('test.glade')
        builder.connect_signals(self)
        window = builder.get_object("window1")

        RBA = builder.get_object('radiobuttonA')
        RBA.connect('toggled', self.rba)
        RBB = builder.get_object('radiobuttonB')
        RBB.connect('toggled', self.rbb)
        window.show_all()

    def buttonQuit(self, menuitem): # quit with Quit button
        Gtk.main_quit()
    def on_window1_destroy(self, window): # close window with 0 or X
        Gtk.main_quit()

    def rba(self, radiobutton):
        print('in rba')
        print (radiobutton.get_active())

    def rbb(self, radiobutton):
        print('in rbb')
        print (radiobutton.get_active())

def main():

    app = GUI()
    Gtk.main()


if __name__ == "__main__":  
    sys.exit(main())
0
votes

With the code below and Glade sending 'clicked' signals, it triggers both the 'switched on' and 'switched off' functions, but only once each and I can test which is on. This will work for me. I have changed some names to 'dummy' to remind me that these don't seem to have any function that I want. Thanks gtknerd!

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

class GUI:
    def __init__ (self):
        builder = Gtk.Builder()
        builder.add_from_file('/home/chris/Debreate/test/gtknerd.glade')
        builder.connect_signals(self)
        window = builder.get_object("window1")

        dummy1 = builder.get_object('radiobuttonA')
        dummy2 = builder.get_object('radiobuttonB')
        dummy3 = builder.get_object('radiobuttonC')
        window.show_all()

    def buttonQuit(self, menuitem): # quit with Quit button
        Gtk.main_quit()
    def on_window1_destroy(self, window): # close window with 0 or X
        Gtk.main_quit()

    def rba(self, radiobuttonA):
        #print('in rba:', radiobuttonA.get_active(), radiobuttonA.get_label()) #2
        if radiobuttonA.get_active(): print('in rba:', radiobuttonA.get_label()) 

    def rbb(self, radiobuttonB):
        #print('in rbb:', radiobuttonB.get_active(), radiobuttonB.get_label()) #2
        if radiobuttonB.get_active(): print('in rbb:', radiobuttonB.get_label()) 

    def rbc(self, radiobuttonC):
        #print('in rbc:', radiobuttonC.get_active(), radiobuttonC.get_label()) #2
        if radiobuttonC.get_active(): print('in rbc:', radiobuttonC.get_label()) 

def main():
    app = GUI()
    Gtk.main()


if __name__ == "__main__":  
    sys.exit(main())