简体   繁体   中英

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM