GTK+ Forums

Discussion forum for GTK+ and Programming. Ask questions, troubleshoot problems, view and post example code, or express your opinions.
It is currently Mon Oct 20, 2014 9:15 pm

All times are UTC




Post new topic Reply to topic  [ 2 posts ] 
Author Message
 Post subject: Problems with gtk.Builder and connect_signals (Python)
PostPosted: Mon Jul 14, 2008 1:27 pm 
Offline

Joined: Fri Jul 11, 2008 4:34 pm
Posts: 3
Hello,
(First of all, I want to apologize for any bad English.)

I am developing a GTK+ app with Glade 3 and Python. I read Micah Carrick's blog entries (which helped a lot) and decided to use Gtk Builder instead of libglade.
The code consists of 4 classes:
- The App class, in which the builder object is created. It also connects the signals and shows the main window.
- The BaseWindowWrapper class, which is a base class for initializing a window.
- The MainWindowWrapper class, which is derived from BaseWindowWrapper. This is the startup window.
- The PreferencesWindowWrapper class, which is also derived from BaseWindowWrapper. This window is shown when the user clicks the Edit-Preferences menu item.

Code:
import pygtk
pygtk.require('2.0')
import gtk

class BaseWindowWrapper:
    def __init__(self, builder, name):       
        self.builder = builder
        self.window = self.builder.get_object(name)     

class PreferencesWindowWrapper(BaseWindowWrapper):
    def __init__(self, builder, name):
        BaseWindowWrapper.__init__(self, builder, name)
        self.window.connect("delete-event", self.delete_event, self)

    def delete_event(self, dialog, event, app):
        self.window.hide()
        return True

    def on_buttonClose_clicked(self, widget, data=None):   
        self.window.hide()

class MainWindowWrapper(BaseWindowWrapper):
    def __init__(self, builder, name):
        BaseWindowWrapper.__init__(self, builder, name)
             
        self.preferencesWindow = PreferencesWindowWrapper(builder, "PreferencesWindow")       
       
    def on_menuEditPreferences_activate(self, widget, data=None):
        self.preferencesWindow.window.show()             
       
    def on_MainWindow_destroy(self, widget, data=None):       
        gtk.main_quit()

class App:
    def __init__(self):
        self.builder = gtk.Builder()
        self.builder.add_from_file("ui.ui")
   
        self.mainWindow = MainWindowWrapper(self.builder, "MainWindow")

        signals = { "on_menuEditPreferences_activate": self.mainWindow.on_menuEditPreferences_activate,
                    "on_MainWindow_destroy" : self.mainWindow.on_MainWindow_destroy,
                    "on_buttonClose_clicked": self.mainWindow.preferencesWindow.on_buttonClose_clicked }               
        self.builder.connect_signals(signals)
             
    # Run main application window
    def main(self):       
        self.mainWindow.window.show()
        gtk.main()
   
if __name__ == "__main__":
    app = App()
    app.main()


The code works, but I think it is rather complicated. The thing that disturbs me most is the connect_signals line. I would like to put it into the two window classes like this (lines 5 and 18):
Code:
class PreferencesWindowWrapper(BaseWindowWrapper):
    def __init__(self, builder, name):
        BaseWindowWrapper.__init__(self, builder, name)
        self.builder.connect_signals(self) # This should connect the on_buttonClose_clicked method
        self.window.connect("delete-event", self.delete_event, self)

    def delete_event(self, dialog, event, app):
        self.window.hide()
        return True

    def on_buttonClose_clicked(self, widget, data=None):   
        self.window.hide()

class MainWindowWrapper(BaseWindowWrapper):
    def __init__(self, builder, name):
        BaseWindowWrapper.__init__(self, builder, name)
        self.builder.connect_signals(self) # This should connect the on_menuEditPreferences_activate method and all other methods, which connect_signals finds in this class
        self.preferencesWindow = PreferencesWindowWrapper(builder, "PreferencesWindow") 


Doing it this way, only the signals of the MainWindow class are connected. The on_buttonClose_clicked method of the PreferencesWindow class is never executed, although I specified self.builder.connect_signals(self) (line 5). If I put the on_buttonClose_clicked method into the MainWindow class everything works fine, but then I do not have to create an extra class...
So it seems that the connecting is only done once. Or am I'm doing something completely wrong? Should I rather use libglade?

Thanks in advance for looking through this and best regards,
benny

The glade file:
Code:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
<!--Generated with glade3 3.4.5 on Mon Jul 14 15:30:38 2008 -->
<glade-interface>
  <widget class="GtkWindow" id="MainWindow">
    <signal name="destroy" handler="on_MainWindow_destroy"/>
    <child>
      <widget class="GtkVBox" id="vbox2">
        <property name="visible">True</property>
        <child>
          <widget class="GtkMenuBar" id="menubar1">
            <property name="visible">True</property>
            <child>
              <widget class="GtkMenuItem" id="menuitem1">
                <property name="visible">True</property>
                <property name="label" translatable="yes">_Datei</property>
                <property name="use_underline">True</property>
                <child>
                  <widget class="GtkMenu" id="menu1">
                    <property name="visible">True</property>
                    <child>
                      <widget class="GtkImageMenuItem" id="imagemenuitem1">
                        <property name="visible">True</property>
                        <property name="label" translatable="yes">gtk-new</property>
                        <property name="use_underline">True</property>
                        <property name="use_stock">True</property>
                      </widget>
                    </child>
                    <child>
                      <widget class="GtkImageMenuItem" id="imagemenuitem2">
                        <property name="visible">True</property>
                        <property name="label" translatable="yes">gtk-open</property>
                        <property name="use_underline">True</property>
                        <property name="use_stock">True</property>
                      </widget>
                    </child>
                    <child>
                      <widget class="GtkImageMenuItem" id="imagemenuitem3">
                        <property name="visible">True</property>
                        <property name="label" translatable="yes">gtk-save</property>
                        <property name="use_underline">True</property>
                        <property name="use_stock">True</property>
                      </widget>
                    </child>
                    <child>
                      <widget class="GtkImageMenuItem" id="imagemenuitem4">
                        <property name="visible">True</property>
                        <property name="label" translatable="yes">gtk-save-as</property>
                        <property name="use_underline">True</property>
                        <property name="use_stock">True</property>
                      </widget>
                    </child>
                    <child>
                      <widget class="GtkSeparatorMenuItem" id="separatormenuitem1">
                        <property name="visible">True</property>
                      </widget>
                    </child>
                    <child>
                      <widget class="GtkImageMenuItem" id="imagemenuitem5">
                        <property name="visible">True</property>
                        <property name="label" translatable="yes">gtk-quit</property>
                        <property name="use_underline">True</property>
                        <property name="use_stock">True</property>
                      </widget>
                    </child>
                  </widget>
                </child>
              </widget>
            </child>
            <child>
              <widget class="GtkMenuItem" id="menuitem2">
                <property name="visible">True</property>
                <property name="label" translatable="yes">_Bearbeiten</property>
                <property name="use_underline">True</property>
                <child>
                  <widget class="GtkMenu" id="menu2">
                    <property name="visible">True</property>
                    <child>
                      <widget class="GtkImageMenuItem" id="imagemenuitem6">
                        <property name="visible">True</property>
                        <property name="label" translatable="yes">gtk-cut</property>
                        <property name="use_underline">True</property>
                        <property name="use_stock">True</property>
                      </widget>
                    </child>
                    <child>
                      <widget class="GtkImageMenuItem" id="imagemenuitem7">
                        <property name="visible">True</property>
                        <property name="label" translatable="yes">gtk-copy</property>
                        <property name="use_underline">True</property>
                        <property name="use_stock">True</property>
                      </widget>
                    </child>
                    <child>
                      <widget class="GtkImageMenuItem" id="imagemenuitem8">
                        <property name="visible">True</property>
                        <property name="label" translatable="yes">gtk-paste</property>
                        <property name="use_underline">True</property>
                        <property name="use_stock">True</property>
                      </widget>
                    </child>
                    <child>
                      <widget class="GtkImageMenuItem" id="imagemenuitem9">
                        <property name="visible">True</property>
                        <property name="label" translatable="yes">gtk-delete</property>
                        <property name="use_underline">True</property>
                        <property name="use_stock">True</property>
                      </widget>
                    </child>
                    <child>
                      <widget class="GtkImageMenuItem" id="">
                        <property name="visible">True</property>
                        <property name="label" translatable="yes">gtk-preferences</property>
                        <property name="use_underline">True</property>
                        <property name="use_stock">True</property>
                        <signal name="activate" handler="on_menuEditPreferences_activate"/>
                      </widget>
                    </child>
                  </widget>
                </child>
              </widget>
            </child>
            <child>
              <widget class="GtkMenuItem" id="menuitem3">
                <property name="visible">True</property>
                <property name="label" translatable="yes">_Ansicht</property>
                <property name="use_underline">True</property>
              </widget>
            </child>
            <child>
              <widget class="GtkMenuItem" id="menuitem4">
                <property name="visible">True</property>
                <property name="label" translatable="yes">_Hilfe</property>
                <property name="use_underline">True</property>
                <child>
                  <widget class="GtkMenu" id="menu3">
                    <property name="visible">True</property>
                    <child>
                      <widget class="GtkImageMenuItem" id="imagemenuitem10">
                        <property name="visible">True</property>
                        <property name="label" translatable="yes">gtk-about</property>
                        <property name="use_underline">True</property>
                        <property name="use_stock">True</property>
                      </widget>
                    </child>
                  </widget>
                </child>
              </widget>
            </child>
          </widget>
          <packing>
            <property name="expand">False</property>
          </packing>
        </child>
        <child>
          <placeholder/>
        </child>
      </widget>
    </child>
  </widget>
  <widget class="GtkWindow" id="PreferencesWindow">
    <child>
      <widget class="GtkVBox" id="vbox1">
        <property name="visible">True</property>
        <child>
          <placeholder/>
        </child>
        <child>
          <widget class="GtkButton" id="button1">
            <property name="visible">True</property>
            <property name="can_focus">True</property>
            <property name="receives_default">True</property>
            <property name="border_width">10</property>
            <property name="label" translatable="yes">gtk-close</property>
            <property name="use_stock">True</property>
            <property name="response_id">0</property>
            <signal name="clicked" handler="on_buttonClose_clicked"/>
          </widget>
          <packing>
            <property name="fill">False</property>
            <property name="position">1</property>
          </packing>
        </child>
      </widget>
    </child>
  </widget>
</glade-interface>


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jul 14, 2008 3:39 pm 
Offline

Joined: Fri Jul 11, 2008 4:34 pm
Posts: 3
I experimented a bit further and tried this:
Code:
        signals = { "on_MainWindow_destroy" : self.mainWindow.on_MainWindow_destroy,
                    "on_menuEditPreferences_activate": self.mainWindow.on_menuEditPreferences_activate }               
        self.builder.connect_signals(signals)
       
        signals2 = { "on_buttonClose_clicked": self.mainWindow.preferencesWindow.on_buttonClose_clicked }
        self.builder.connect_signals(signals2)


Again, the second call of connect_signals doesn't effect the behaviour off the application:
the signals on_MainWindow_destroy and on_menuEditPreferences_activate work, but on_buttonClose_clicked does not.

Regards,
benny


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 2 posts ] 

All times are UTC


Who is online

Users browsing this forum: Google [Bot] and 4 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group