Dustin
Dustin

Reputation: 6307

Python/Glade/PyGTK - Not detecting handler correctly

I've been attempting to debug this all morning but can't seem to find the solution. I have a simple Glade/PyGTK script with three check boxes and a submit button. I've been trying to make sure I have a proper handler setup for gtk.main_quit with Glade GTKObject's Destroy Signal, but even after setting up correctly in Glade, my Python script doesn't detect the handler, hangs the application, and returns this error.

E:\Projects\DED\test.py:34: RuntimeWarning: missing handler 'on_MainWindow_destroy'
  self.builder.connect_signals(self)

I've tried changing the the handlers name, and even completely restarting the script from scratch to see where I went wrong. I can't seem to find it. Any help is appreciated! Thanks in advance.

Python Script:

import sys
try:
    import pygtk
    pygtk.require("2.0")
except:
    pass
try:
    import gtk
    import gtk.glade
except:
    sys.exit(1)


class GladeTest:

    def __init__(self):

        #Set the Glade file
        filename = "gui.glade"
        self.builder = gtk.Builder()
        self.builder.add_from_file(filename)
        self.builder.connect_signals(self)

        #Create our dictionay and connect it
        dic = { "btnSubmit_clicked" : self.btnSubmit_clicked,
        "on_MainWindow_destroy" : self.Destroy }

    def btnSubmit_clicked(self, widget):
        chkbt_chrome = self.builder.get_object("chkboxDropbox")
        print "ACTIVE--",chkbt_chrome.get_active()


    def Destroy(self, obj):
        gtk.main_quit() #make the program quit



if __name__ == "__main__":
    GladeTest()
    gtk.main()

print "All Done"

Glade File (gui.glade):

<?xml version="1.0" encoding="UTF-8"?>
<interface>
  <requires lib="gtk+" version="2.24"/>
  <!-- interface-naming-policy project-wide -->
  <object class="GtkWindow" id="MainWindow">
    <property name="visible">True</property>
    <property name="can_focus">False</property>
    <property name="title" translatable="yes">MainWindow</property>
    <property name="resizable">False</property>
    <property name="window_position">center</property>
    <signal name="destroy" handler="on_MainWindow_destroy" swapped="no"/>
    <child>
      <object class="GtkVBox" id="vbox1">
        <property name="visible">True</property>
        <property name="can_focus">False</property>
        <child>
          <object class="GtkLabel" id="label1">
            <property name="visible">True</property>
            <property name="can_focus">False</property>
            <property name="label" translatable="yes">Downloader</property>
            <attributes>
              <attribute name="style" value="normal"/>
              <attribute name="size" value="300"/>
            </attributes>
          </object>
          <packing>
            <property name="expand">False</property>
            <property name="fill">True</property>
            <property name="position">0</property>
          </packing>
        </child>
        <child>
          <object class="GtkCheckButton" id="chkboxDropbox">
            <property name="label" translatable="yes">Dropbox</property>
            <property name="visible">True</property>
            <property name="can_focus">True</property>
            <property name="receives_default">False</property>
            <property name="use_action_appearance">False</property>
            <property name="draw_indicator">True</property>
          </object>
          <packing>
            <property name="expand">False</property>
            <property name="fill">True</property>
            <property name="position">1</property>
          </packing>
        </child>
        <child>
          <object class="GtkCheckButton" id="chkboxPython">
            <property name="label" translatable="yes">Python</property>
            <property name="visible">True</property>
            <property name="can_focus">True</property>
            <property name="receives_default">False</property>
            <property name="use_action_appearance">False</property>
            <property name="draw_indicator">True</property>
          </object>
          <packing>
            <property name="expand">False</property>
            <property name="fill">True</property>
            <property name="position">2</property>
          </packing>
        </child>
        <child>
          <object class="GtkCheckButton" id="chkboxChrome">
            <property name="label" translatable="yes">Google Chrome</property>
            <property name="visible">True</property>
            <property name="can_focus">True</property>
            <property name="receives_default">False</property>
            <property name="use_action_appearance">False</property>
            <property name="draw_indicator">True</property>
          </object>
          <packing>
            <property name="expand">False</property>
            <property name="fill">True</property>
            <property name="position">3</property>
          </packing>
        </child>
        <child>
          <object class="GtkButton" id="btnSubmit">
            <property name="label" translatable="yes">Download/Run</property>
            <property name="visible">True</property>
            <property name="can_focus">True</property>
            <property name="receives_default">True</property>
            <property name="use_action_appearance">False</property>
            <signal name="clicked" handler="btnSubmit_clicked" swapped="no"/>
          </object>
          <packing>
            <property name="expand">False</property>
            <property name="fill">True</property>
            <property name="position">4</property>
          </packing>
        </child>
      </object>
    </child>
  </object>
</interface>

Upvotes: 2

Views: 2231

Answers (3)

M Grosskopf
M Grosskopf

Reputation: 1

The same happened to me. The problem disapear when i separated the init() part from the show() part. Maybe gtk / python need the initialisation to be done to fully detect the class functions.

   class MyApp():
     ...
     def __init__(self):
        try:
            builder = gtk.Builder()
            builder.add_from_file("carte.glade")
        except:
            self.error_message("Failed to load UI XML file: carte.glade")
            sys.exit(1)

       # connect signals
        builder.connect_signals(self)        

     def main(self):
        self.window.show()
        gtk.main()

Upvotes: 0

ptomato
ptomato

Reputation: 57880

Create your dictionary dic before the connect_signals() call and then say

self.builder.connect_signals(dic)

The first argument to connect_signals() has to be a dictionary or mapping of handler names to handlers. A common idiom in PyGTK is to pass self as this dictionary, since a class is automatically also a dictionary of function names mapped to functions. However, for this to work, the functions in your class have to have the same names as the handlers in the Glade file, as root45 points out. If you don't want to or can't give them the same names, then use a dictionary.

Upvotes: 0

Kris Harper
Kris Harper

Reputation: 5862

I don't really understand what you're doing with your signal dictionary. You say #Create our dictionary and connect it, but you never seem to 'connect' it.

If you just change them name self.Destroy to self.on_MainWindow_destroy it works fine for me.

The builder.connect_signals method looks for signals in the glade file and matches them functions of the same name in your script. I don't know of any way to do this with a dictionary, but if there is, you don't seem to have implemented it.

Upvotes: 2

Related Questions