'Newbie Glade user confounded by radio buttons

I have a Glade GTK Gui which is meant to be a Front End for a CLI program I wrote a couple of years ago.

There are a number of fields for the user to fill in. These will be theoretically processed when the user presses "Submit", like in HTML. (Otherwise, they could press "Quit Without Saving")

I can actually glean the GtkEntry fields and use their content. But I am fuddled with the radio buttons. In the GUI, I can't seem to press the button at all, and I have no idea how to get the content they are meant to convey.

I am including a program that is designed to do little more than show the GUI and try to test its features.

I am including this program and the glade file in its XML form.


#!/usr/bin/env python

import gi

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

from gi.repository import Gtk

import sys

builder = Gtk.Builder()

class GUI:

    def __init__ (self):
        builder.add_from_file('EntryForm.glade')
        builder.connect_signals(self)
        window = builder.get_object("window1")
        window.show_all()
        
    def onSubmitButton(self, button):
        idir = builder.get_object('inputdir')
        result = idir.get_property('text')
        print(f'inputdir = {result}')
        odir = builder.get_object("outputdir")
        result2 = odir.get_property("text")
        print(f'outputdir = {result2}')
        builder.get_objects()
        builder.get_object('radiobuttons')
        x = radiobuttons.get_label()
        print (f'radiobutton select is {x}')

    def onDestroy(self, menuitem): 
        Gtk.main_quit()
        
    def on_window1_destroy(self, window): # close window with 0 or X
        Gtk.main_quit()

        
def main():

    app = GUI()
    Gtk.main()

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

and, as promised, the .glade file.

<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.38.2 -->
<interface>
  <requires lib="gtk+" version="3.24"/>
  <object class="GtkWindow" id="window1">
    <property name="name">GtkWindow</property>
    <property name="can-focus">True</property>
    <property name="window-position">center-always</property>
    <property name="default-width">380</property>
    <property name="default-height">200</property>
    <property name="destroy-with-parent">True</property>
    <property name="type-hint">dialog</property>
    <property name="gravity">north-east</property>
    <signal name="destroy" handler="onDestroy" swapped="no"/>
    <child>
      <!-- n-columns=2 n-rows=7 -->
      <object class="GtkGrid">
        <property name="visible">True</property>
        <property name="can-focus">True</property>
        <child>
          <object class="GtkLabel">
            <property name="name">label1</property>
            <property name="visible">True</property>
            <property name="can-focus">False</property>
            <property name="margin-left">3</property>
            <property name="margin-right">3</property>
            <property name="margin-start">3</property>
            <property name="margin-end">3</property>
            <property name="margin-top">3</property>
            <property name="margin-bottom">3</property>
            <property name="label" translatable="yes">Scripts Search - Enter Parameters</property>
            <property name="justify">fill</property>
            <attributes>
              <attribute name="font-desc" value="Serif 12"/>
              <attribute name="style" value="normal"/>
              <attribute name="weight" value="normal"/>
              <attribute name="variant" value="normal"/>
              <attribute name="stretch" value="normal"/>
              <attribute name="scale" value="1"/>
            </attributes>
            <signal name="destroy" handler="gtk-destroy" swapped="no"/>
          </object>
          <packing>
            <property name="left-attach">0</property>
            <property name="top-attach">0</property>
            <property name="width">2</property>
          </packing>
        </child>
        <child>
          <object class="GtkLabel" id="GtkWindow">
            <property name="name">GtkWindow</property>
            <property name="visible">True</property>
            <property name="can-focus">True</property>
            <property name="label" translatable="yes">
</property>
            <property name="justify">center</property>
          </object>
          <packing>
            <property name="left-attach">1</property>
            <property name="top-attach">0</property>
          </packing>
        </child>
        <child>
          <object class="GtkLabel">
            <property name="visible">True</property>
            <property name="can-focus">True</property>
            <property name="label" translatable="yes">Directory to search:</property>
            <property name="justify">right</property>
          </object>
          <packing>
            <property name="left-attach">0</property>
            <property name="top-attach">1</property>
          </packing>
        </child>
        <child>
          <object class="GtkLabel">
            <property name="visible">True</property>
            <property name="can-focus">True</property>
            <property name="label" translatable="yes">Direcotry for output:</property>
            <property name="justify">right</property>
          </object>
          <packing>
            <property name="left-attach">0</property>
            <property name="top-attach">2</property>
          </packing>
        </child>
        <child>
          <object class="GtkLabel">
            <property name="visible">True</property>
            <property name="can-focus">True</property>
            <property name="label" translatable="yes">Sort by:</property>
            <property name="justify">right</property>
          </object>
          <packing>
            <property name="left-attach">0</property>
            <property name="top-attach">3</property>
          </packing>
        </child>
        <child>
          <object class="GtkLabel">
            <property name="visible">True</property>
            <property name="can-focus">True</property>
            <property name="label" translatable="yes">Printed Report?  (y/n):</property>
            <property name="justify">right</property>
          </object>
          <packing>
            <property name="left-attach">0</property>
            <property name="top-attach">4</property>
          </packing>
        </child>
        <child>
          <object class="GtkLabel">
            <property name="visible">True</property>
            <property name="can-focus">True</property>
            <property name="label" translatable="yes">Verbose? (y/n):</property>
            <property name="justify">right</property>
          </object>
          <packing>
            <property name="left-attach">0</property>
            <property name="top-attach">5</property>
          </packing>
        </child>
        <child>
          <object class="GtkEntry" id="inputdir">
            <property name="visible">True</property>
            <property name="can-focus">True</property>
            <property name="text" translatable="yes">/usr/bin</property>
          </object>
          <packing>
            <property name="left-attach">1</property>
            <property name="top-attach">1</property>
          </packing>
        </child>
        <child>
          <object class="GtkEntry" id="outputdir">
            <property name="name">outputdir</property>
            <property name="visible">True</property>
            <property name="can-focus">True</property>
            <property name="text">/home/baz/misc/scripts</property>
            <signal name="destroy" handler="onDestroy" swapped="no"/>
          </object>
          <packing>
            <property name="left-attach">1</property>
            <property name="top-attach">2</property>
          </packing>
        </child>
        <child>
          <object class="GtkButtonBox" id="inputdi">
            <property name="name">inputdir</property>
            <property name="visible">True</property>
            <property name="can-focus">True</property>
            <property name="layout-style">start</property>
            <signal name="destroy" handler="onDestroy" swapped="no"/>
            <child>
              <placeholder/>
            </child>
          </object>
          <packing>
            <property name="left-attach">1</property>
            <property name="top-attach">1</property>
          </packing>
        </child>
        <child>
          <!-- n-columns=3 n-rows=1 -->
          <object class="GtkGrid" id="radiobutton">
            <property name="name">radiobutton</property>
            <property name="visible">True</property>
            <property name="can-focus">False</property>
            <child>
              <object class="GtkRadioButton" id="NameButton">
                <property name="label" translatable="yes">Name      </property>
                <property name="name">NameButton</property>
                <property name="visible">True</property>
                <property name="can-focus">True</property>
                <property name="receives-default">True</property>
                <property name="draw-indicator">True</property>
                <!-- signal name="toggled" handler="on_NameButton_toggled" swapped="no"/-->
              </object>
              <packing>
                <property name="left-attach">0</property>
                <property name="top-attach">0</property>
              </packing>
            </child>
            <child>
              <object class="GtkRadioButton" id="SizeButton">
                <property name="label" translatable="yes">Size      </property>
                <property name="name">SizeButton</property>
                <property name="visible">True</property>
                <property name="can-focus">True</property>
                <property name="receives-default">False</property>
                <property name="draw-indicator">True</property>
              </object>
              <packing>
                <property name="left-attach">1</property>
                <property name="top-attach">0</property>
              </packing>
            </child>
            <child>
              <object class="GtkRadioButton" id="TypeButton">
                <property name="label" translatable="yes">Type  </property>
                <property name="name">TypeButton</property>
                <property name="visible">True</property>
                <property name="can-focus">True</property>
                <property name="receives-default">False</property>
                <property name="draw-indicator">True</property>
                </object>
              <packing>
                <property name="left-attach">2</property>
                <property name="top-attach">0</property>
              </packing>
            </child>
          </object>
          <packing>
            <property name="left-attach">1</property>
            <property name="top-attach">3</property>
          </packing>
        </child>
        <child>          <!-- n-columns=2 n-rows=1 -->
          <object class="GtkGrid">
            <property name="visible">True</property>
            <property name="can-focus">False</property>
            <child>
              <object class="GtkRadioButton" id="ReportY">
                <property name="label" translatable="yes">Y             </property>
                <property name="name">ReportY</property>
                <property name="visible">True</property>
                <property name="can-focus">True</property>
                <property name="receives-default">False</property>
                <property name="active">True</property>
                <property name="draw-indicator">True</property>
              </object>
              <packing>
                <property name="left-attach">0</property>
                <property name="top-attach">0</property>
              </packing>
            </child>
            <child>
              <object class="GtkRadioButton" id="ReportN">
                <property name="label" translatable="yes">N            </property>
                <property name="name">ReportN</property>
                <property name="visible">True</property>
                <property name="can-focus">True</property>
                <property name="receives-default">False</property>
                <property name="active">True</property>
                <property name="draw-indicator">True</property>
              </object>
              <packing>
                <property name="left-attach">1</property>
                <property name="top-attach">0</property>
              </packing>
            </child>
          </object>
          <packing>
            <property name="left-attach">1</property>
            <property name="top-attach">4</property>
          </packing>
        </child>
        <child>
          <!-- n-columns=2 n-rows=1 -->
          <object class="GtkGrid">
            <property name="visible">True</property>
            <property name="can-focus">False</property>
            <child>
              <object class="GtkRadioButton" id="VerboseY">
                <property name="label" translatable="yes">Y             </property>
                <property name="name">VerboseY</property>
                <property name="visible">True</property>
                <property name="can-focus">True</property>
                <property name="receives-default">False</property>
                <property name="active">True</property>
                <property name="draw-indicator">True</property>
              </object>
              <packing>
                <property name="left-attach">0</property>
                <property name="top-attach">0</property>
              </packing>
            </child>
            <child>
              <object class="GtkRadioButton" id="VerboseN">
                <property name="label" translatable="yes">N             </property >
                <property name="name">VerboseN</property>
                <property name="visible">True</property>
                <property name="can-focus">True</property>
                <property name="receives-default">False</property>
                <property name="active">True</property>
                <property name="draw-indicator">True</property>
              </object>
              <packing>
                <property name="left-attach">1</property>
                <property name="top-attach">0</property>
              </packing>
            </child>
          </object>
          <packing>
            <property name="left-attach">1</property>
            <property name="top-attach">5</property>
          </packing>
        </child>
        <child>
          <object class="GtkButton" id="SubmitButton">
            <property name="label" translatable="yes">Submit</property>
            <property name="name">SubmitButton</property>
            <property name="visible">True</property>
            <property name="can-focus">True</property>
            <property name="receives-default">True</property>
            <signal name="clicked" handler="onSubmitButton" swapped="no"/>
            <signal name="destroy" handler="onDestroy" swapped="no"/>
            <signal name="pressed" handler="onSubmitButton" swapped="no"/>
          </object>
          <packing>
            <property name="left-attach">0</property>
            <property name="top-attach">6</property>
          </packing>
        </child>
        <child>
          <object class="GtkButton" id="QuitButton">
            <property name="label" translatable="yes">Quit Without Saving</property>
            <property name="name">QuitButton</property>
            <property name="visible">True</property>
            <property name="can-focus">True</property>
            <property name="receives-default">True</property>
            <signal name="clicked" handler="onDestroy" swapped="no"/>
            <signal name="pressed" handler="onDestroy" swapped="no"/>
          </object>
          <packing>
            <property name="left-attach">1</property>
            <property name="top-attach">6</property>
          </packing>
        </child>
      </object>
    </child>
  </object>
</interface>

I don't expect anyone to pore over the source code, but I would at least appreciate some pointers on radio buttons, particularly how to obtain their contents.

Thanks,

Bryan



Solution 1:[1]

In .glade you define RadioButton with id="NameButton" so you need

name_button = builder.get_object('NameButton')

print( name_button.get_active() )

But problem is that every RadioButton is treated as separated group and when group has only one button then it is always True.

Buttons should be in groups. Second and third RadioButton should have property group with ID of first RadioButton

<property name="group">NameButton</property>

like

            <child>
              <object class="GtkRadioButton" id="NameButton">
                # ...
              </object>
            </child>

            <child>
              <object class="GtkRadioButton" id="SizeButton">
                # ...
                <property name="group">NameButton</property>
              </object>
            </child>

            <child>
              <object class="GtkRadioButton" id="TypeButton">
                # ...
                <property name="group">NameButton</property>
              </object>
            </child>

So you have to change code in XML.


Full working code with changes in .py and .glade

#!/usr/bin/env python

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

builder = Gtk.Builder()

class GUI:

    def __init__ (self):
        builder.add_from_file('EntryForm.glade')
        builder.connect_signals(self)
        window = builder.get_object("window1")
        window.show_all()
        
    def onSubmitButton(self, button):
        inputdir = builder.get_object('inputdir').get_property('text')
        print(f'inputdir = {inputdir}')
        
        outputdir = builder.get_object("outputdir").get_property("text")
        print(f'outputdir = {outputdir}')
        
        name_button = builder.get_object('NameButton')
        #print('[NameButton] active:', name_button.get_active())
        #print('[NameButton] group :', name_button.get_group())
        for item in name_button.get_group():
            print(item.get_name(), item.get_active())

        report_button = builder.get_object('ReportY')
        for item in report_button.get_group():
            print(item.get_name(), item.get_active())

        verbose_button = builder.get_object('VerboseY')
        for item in verbose_button.get_group():
            print(item.get_name(), item.get_active())
        
    def onDestroy(self, menuitem): 
        Gtk.main_quit()

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

if __name__ == "__main__":  
    sys.exit(main())
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.38.2 -->
<interface>
  <requires lib="gtk+" version="3.24"/>
  <object class="GtkWindow" id="window1">
    <property name="name">GtkWindow</property>
    <property name="can-focus">True</property>
    <property name="window-position">center-always</property>
    <property name="default-width">380</property>
    <property name="default-height">200</property>
    <property name="destroy-with-parent">True</property>
    <property name="type-hint">dialog</property>
    <property name="gravity">north-east</property>
    <signal name="destroy" handler="onDestroy" swapped="no"/>
    <child>
      <!-- n-columns=2 n-rows=7 -->
      <object class="GtkGrid">
        <property name="visible">True</property>
        <property name="can-focus">True</property>
        <child>
          <object class="GtkLabel">
            <property name="name">label1</property>
            <property name="visible">True</property>
            <property name="can-focus">False</property>
            <property name="margin-left">3</property>
            <property name="margin-right">3</property>
            <property name="margin-start">3</property>
            <property name="margin-end">3</property>
            <property name="margin-top">3</property>
            <property name="margin-bottom">3</property>
            <property name="label" translatable="yes">Scripts Search - Enter Parameters</property>
            <property name="justify">fill</property>
            <attributes>
              <attribute name="font-desc" value="Serif 12"/>
              <attribute name="style" value="normal"/>
              <attribute name="weight" value="normal"/>
              <attribute name="variant" value="normal"/>
              <attribute name="stretch" value="normal"/>
              <attribute name="scale" value="1"/>
            </attributes>
            <signal name="destroy" handler="onDestroy" swapped="no"/>
          </object>
          <packing>
            <property name="left-attach">0</property>
            <property name="top-attach">0</property>
            <property name="width">2</property>
          </packing>
        </child>
        <child>
          <object class="GtkLabel" id="GtkWindow">
            <property name="name">GtkWindow</property>
            <property name="visible">True</property>
            <property name="can-focus">True</property>
            <property name="label" translatable="yes">
</property>
            <property name="justify">center</property>
          </object>
          <packing>
            <property name="left-attach">1</property>
            <property name="top-attach">0</property>
          </packing>
        </child>
        <child>
          <object class="GtkLabel">
            <property name="visible">True</property>
            <property name="can-focus">True</property>
            <property name="label" translatable="yes">Directory to search:</property>
            <property name="justify">right</property>
          </object>
          <packing>
            <property name="left-attach">0</property>
            <property name="top-attach">1</property>
          </packing>
        </child>
        <child>
          <object class="GtkLabel">
            <property name="visible">True</property>
            <property name="can-focus">True</property>
            <property name="label" translatable="yes">Direcotry for output:</property>
            <property name="justify">right</property>
          </object>
          <packing>
            <property name="left-attach">0</property>
            <property name="top-attach">2</property>
          </packing>
        </child>
        <child>
          <object class="GtkLabel">
            <property name="visible">True</property>
            <property name="can-focus">True</property>
            <property name="label" translatable="yes">Sort by:</property>
            <property name="justify">right</property>
          </object>
          <packing>
            <property name="left-attach">0</property>
            <property name="top-attach">3</property>
          </packing>
        </child>
        <child>
          <object class="GtkLabel">
            <property name="visible">True</property>
            <property name="can-focus">True</property>
            <property name="label" translatable="yes">Printed Report?  (y/n):</property>
            <property name="justify">right</property>
          </object>
          <packing>
            <property name="left-attach">0</property>
            <property name="top-attach">4</property>
          </packing>
        </child>
        <child>
          <object class="GtkLabel">
            <property name="visible">True</property>
            <property name="can-focus">True</property>
            <property name="label" translatable="yes">Verbose? (y/n):</property>
            <property name="justify">right</property>
          </object>
          <packing>
            <property name="left-attach">0</property>
            <property name="top-attach">5</property>
          </packing>
        </child>
        <child>
          <object class="GtkEntry" id="inputdir">
            <property name="visible">True</property>
            <property name="can-focus">True</property>
            <property name="text" translatable="yes">/usr/bin</property>
          </object>
          <packing>
            <property name="left-attach">1</property>
            <property name="top-attach">1</property>
          </packing>
        </child>
        <child>
          <object class="GtkEntry" id="outputdir">
            <property name="name">outputdir</property>
            <property name="visible">True</property>
            <property name="can-focus">True</property>
            <property name="text">/home/baz/misc/scripts</property>
            <signal name="destroy" handler="onDestroy" swapped="no"/>
          </object>
          <packing>
            <property name="left-attach">1</property>
            <property name="top-attach">2</property>
          </packing>
        </child>
        <child>
          <object class="GtkButtonBox" id="inputdi">
            <property name="name">inputdir</property>
            <property name="visible">True</property>
            <property name="can-focus">True</property>
            <property name="layout-style">start</property>
            <signal name="destroy" handler="onDestroy" swapped="no"/>
            <child>
              <placeholder/>
            </child>
          </object>
          <packing>
            <property name="left-attach">1</property>
            <property name="top-attach">1</property>
          </packing>
        </child>
        <child>
          <!-- n-columns=3 n-rows=1 -->
          <object class="GtkGrid" id="radiobutton">
            <property name="name">radiobutton</property>
            <property name="visible">True</property>
            <property name="can-focus">True</property>
            <child>
              <object class="GtkRadioButton" id="NameButton">
                <property name="label" translatable="yes">Name      </property>
                <property name="name">NameButton</property>
                <property name="active">True</property>
                <property name="visible">True</property>
                <property name="can-focus">True</property>
                <property name="receives-default">True</property>
                <property name="draw-indicator">True</property>
              </object>
              <packing>
                <property name="left-attach">0</property>
                <property name="top-attach">0</property>
              </packing>
            </child>
            <child>
              <object class="GtkRadioButton" id="SizeButton">
                <property name="label" translatable="yes">Size      </property>
                <property name="name">SizeButton</property>
                <property name="visible">True</property>
                <property name="can-focus">True</property>
                <property name="receives-default">False</property>
                <property name="draw-indicator">True</property>
                <property name="group">NameButton</property>
              </object>
              <packing>
                <property name="left-attach">1</property>
                <property name="top-attach">0</property>
              </packing>
            </child>
            <child>
              <object class="GtkRadioButton" id="TypeButton">
                <property name="label" translatable="yes">Type  </property>
                <property name="name">TypeButton</property>
                <property name="visible">True</property>
                <property name="can-focus">True</property>
                <property name="receives-default">False</property>
                <property name="draw-indicator">True</property>
                <property name="group">NameButton</property>
                </object>
              <packing>
                <property name="left-attach">2</property>
                <property name="top-attach">0</property>
              </packing>
            </child>
          </object>
          <packing>
            <property name="left-attach">1</property>
            <property name="top-attach">3</property>
          </packing>
        </child>
        <child>          <!-- n-columns=2 n-rows=1 -->
          <object class="GtkGrid">
            <property name="visible">True</property>
            <property name="can-focus">False</property>
            <child>
              <object class="GtkRadioButton" id="ReportY">
                <property name="label" translatable="yes">Y             </property>
                <property name="name">ReportY</property>
                <property name="visible">True</property>
                <property name="can-focus">True</property>
                <property name="receives-default">False</property>
                <property name="active">True</property>
                <property name="draw-indicator">True</property>
              </object>
              <packing>
                <property name="left-attach">0</property>
                <property name="top-attach">0</property>
              </packing>
            </child>
            <child>
              <object class="GtkRadioButton" id="ReportN">
                <property name="label" translatable="yes">N            </property>
                <property name="name">ReportN</property>
                <property name="visible">True</property>
                <property name="can-focus">True</property>
                <property name="receives-default">False</property>
                <property name="active">True</property>
                <property name="draw-indicator">True</property>
                <property name="group">ReportY</property>
              </object>
              <packing>
                <property name="left-attach">1</property>
                <property name="top-attach">0</property>
              </packing>
            </child>
          </object>
          <packing>
            <property name="left-attach">1</property>
            <property name="top-attach">4</property>
          </packing>
        </child>
        <child>
          <!-- n-columns=2 n-rows=1 -->
          <object class="GtkGrid">
            <property name="visible">True</property>
            <property name="can-focus">False</property>
            <child>
              <object class="GtkRadioButton" id="VerboseY">
                <property name="label" translatable="yes">Y             </property>
                <property name="name">VerboseY</property>
                <property name="visible">True</property>
                <property name="can-focus">True</property>
                <property name="receives-default">False</property>
                <property name="active">True</property>
                <property name="draw-indicator">True</property>
              </object>
              <packing>
                <property name="left-attach">0</property>
                <property name="top-attach">0</property>
              </packing>
            </child>
            <child>
              <object class="GtkRadioButton" id="VerboseN">
                <property name="label" translatable="yes">N             </property >
                <property name="name">VerboseN</property>
                <property name="visible">True</property>
                <property name="can-focus">True</property>
                <property name="receives-default">False</property>
                <property name="active">True</property>
                <property name="draw-indicator">True</property>
                <property name="group">VerboseY</property>
              </object>
              <packing>
                <property name="left-attach">1</property>
                <property name="top-attach">0</property>
              </packing>
            </child>
          </object>
          <packing>
            <property name="left-attach">1</property>
            <property name="top-attach">5</property>
          </packing>
        </child>
        <child>
          <object class="GtkButton" id="SubmitButton">
            <property name="label" translatable="yes">Submit</property>
            <property name="name">SubmitButton</property>
            <property name="visible">True</property>
            <property name="can-focus">True</property>
            <property name="receives-default">True</property>
            <signal name="clicked" handler="onSubmitButton" swapped="no"/>
            <signal name="destroy" handler="onDestroy" swapped="no"/>
          </object>
          <packing>
            <property name="left-attach">0</property>
            <property name="top-attach">6</property>
          </packing>
        </child>
        <child>
          <object class="GtkButton" id="QuitButton">
            <property name="label" translatable="yes">Quit Without Saving</property>
            <property name="name">QuitButton</property>
            <property name="visible">True</property>
            <property name="can-focus">True</property>
            <property name="receives-default">True</property>
            <signal name="clicked" handler="onDestroy" swapped="no"/>
          </object>
          <packing>
            <property name="left-attach">1</property>
            <property name="top-attach">6</property>
          </packing>
        </child>
      </object>
    </child>
  </object>
</interface>

Example result:

inputdir = /usr/bin
outputdir = /home/baz/misc/scripts
TypeButton False
SizeButton False
NameButton True
ReportN False
ReportY True
VerboseN False
VerboseY True

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1