Search code examples
pythonubuntu-14.04glade

I don't know how to add a function to a menu Item in glade/python (generated with quickly)


I am trying to add a function to a menu item when clicked I want that function to execute

the application is named Simpleadministration

code that I am using located in the Simpleadministrationwindow.py :

## functions
    class Handler:
        def on_account_add_menu_item_activate():
            print ("something")

    builder = Gtk.Builder()
    builder.add_from_file("data/ui/SimpleadministrationWindow.ui")
    builder.connect_signals(Handler())  

warning in the terminal:

WARNING:simpleadministration_lib: connect_signals() 'expected handler 'on_account_add_menu_item_activate' in /home/ami/simpleadministration/simpleadministration/SimpleadministrationWindow.py'

I don't know exactly what is going wrong can someone help me?

extra inf:

(Menu structure with selected item from SimpleadministrationWindow.ui) http://i57.tinypic.com/2s6pstx.png (cannot upload with reputation lower than 10)

trying to give as much information as possible

(SimpleadministrationWindow.ui)

<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.18.3 -->
<interface>
  <requires lib="gtk+" version="3.0"/>
  <requires lib="simpleadministration_window" version="1.0"/>
  <!-- interface-local-resource-path ../media -->
  <object class="SimpleadministrationWindow" id="simpleadministration_window">
    <property name="can_focus">False</property>
    <property name="title" translatable="yes">Simpleadministration</property>
    <property name="icon">../media/simpleadministration.svg</property>
    <child>
      <object class="GtkVBox" id="vbox1">
        <property name="visible">True</property>
        <property name="can_focus">False</property>
        <property name="spacing">5</property>
        <child>
          <object class="GtkMenuBar" id="menubar1">
            <property name="visible">True</property>
            <property name="can_focus">False</property>
            <child>
              <object class="GtkMenuItem" id="mnu_file">
                <property name="use_action_appearance">False</property>
                <property name="visible">True</property>
                <property name="can_focus">False</property>
                <property name="label" translatable="yes">_File</property>
                <property name="use_underline">True</property>
                <child type="submenu">
                  <object class="GtkMenu" id="menu1">
                    <property name="visible">True</property>
                    <property name="can_focus">False</property>
                    <child>
                      <object class="GtkImageMenuItem" id="mnu_new">
                        <property name="label">gtk-new</property>
                        <property name="use_action_appearance">False</property>
                        <property name="visible">True</property>
                    <property name="can_focus">False</property>
                    <property name="use_underline">True</property>
                    <property name="use_stock">True</property>
                    <accelerator key="n" signal="activate" modifiers="GDK_CONTROL_MASK"/>
                  </object>
                </child>
                <child>
                  <object class="GtkImageMenuItem" id="mnu_open">
                    <property name="label">gtk-open</property>
                    <property name="use_action_appearance">False</property>
                    <property name="visible">True</property>
                    <property name="can_focus">False</property>
                    <property name="use_underline">True</property>
                    <property name="use_stock">True</property>
                    <accelerator key="o" signal="activate" modifiers="GDK_CONTROL_MASK"/>
                  </object>
                </child>
                <child>
                  <object class="GtkSeparatorMenuItem" id="separatormenuitem3">
                    <property name="visible">True</property>
                    <property name="can_focus">False</property>
                  </object>
                </child>
                <child>
                  <object class="GtkImageMenuItem" id="mnu_save">
                    <property name="label">gtk-save</property>
                    <property name="use_action_appearance">False</property>
                    <property name="visible">True</property>
                    <property name="can_focus">False</property>
                    <property name="use_underline">True</property>
                    <property name="use_stock">True</property>
                    <accelerator key="s" signal="activate" modifiers="GDK_CONTROL_MASK"/>
                  </object>
                </child>
              </object>
            </child>
          </object>
        </child>
        <child>
          <object class="GtkMenuItem" id="mnu_edit">
            <property name="use_action_appearance">False</property>
            <property name="visible">True</property>
            <property name="can_focus">False</property>
            <property name="label" translatable="yes">_Edit</property>
            <property name="use_underline">True</property>
            <child type="submenu">
              <object class="GtkMenu" id="menu2">
                <property name="visible">True</property>
                <property name="can_focus">False</property>
                <child>
                  <object class="GtkMenuItem" id="account_menu_item">
                    <property name="visible">True</property>
                    <property name="can_focus">False</property>
                    <property name="label" translatable="yes">account</property>
                    <property name="use_underline">True</property>
                    <child type="submenu">
                      <object class="GtkMenu" id="menu3">
                        <property name="visible">True</property>
                        <property name="can_focus">False</property>
                        <child>
                          <object class="GtkMenuItem" id="account_add_menu_item">
                            <property name="visible">True</property>
                            <property name="can_focus">False</property>
                            <property name="label" translatable="yes">add</property>
                            <property name="use_underline">True</property>
                            <signal name="activate" handler="on_account_add_menu_item_activate" swapped="no"/>
                          </object>
                        </child>
                        <child>
                          <object class="GtkMenuItem" id="account_change_status_menu_item">
                            <property name="visible">True</property>
                            <property name="can_focus">False</property>
                            <property name="label" translatable="yes">change status</property>
                            <property name="use_underline">True</property>
                          </object>
                        </child>
                      </object>
                    </child>
                  </object>
                </child>
                <child>
                  <object class="GtkMenuItem" id="budget_menu_item">
                    <property name="visible">True</property>
                    <property name="can_focus">False</property>
                    <property name="label" translatable="yes">budget</property>
                    <property name="use_underline">True</property>
                    <child type="submenu">
                      <object class="GtkMenu" id="menu4">
                        <property name="visible">True</property>
                        <property name="can_focus">False</property>
                        <child>
                          <object class="GtkMenuItem" id="budget_add_menu_item">
                            <property name="visible">True</property>
                            <property name="can_focus">False</property>
                            <property name="label" translatable="yes">add</property>
                            <property name="use_underline">True</property>
                          </object>
                        </child>
                        <child>
                          <object class="GtkMenuItem" id="budget_change_menu_item">
                            <property name="visible">True</property>
                            <property name="can_focus">False</property>
                            <property name="label" translatable="yes">change</property>
                            <property name="use_underline">True</property>
                          </object>
                        </child>
                        <child>
                          <object class="GtkMenuItem" id="budget_delete_menu_item">
                            <property name="visible">True</property>
                            <property name="can_focus">False</property>
                            <property name="label" translatable="yes">delete</property>
                            <property name="use_underline">True</property>
                          </object>
                        </child>
                      </object>
                    </child>
                  </object>
                </child>
              </object>
            </child>
          </object>
        </child>
      </object>
      <packing>
        <property name="expand">False</property>
        <property name="fill">True</property>
        <property name="position">0</property>
      </packing>
    </child>
    <child>
      <placeholder/>
    </child>
    <child>
      <placeholder/>
    </child>
    <child>
      <object class="GtkStatusbar" id="statusbar1">
        <property name="visible">True</property>
        <property name="can_focus">False</property>
        <property name="spacing">2</property>
        <child>
          <object class="GtkLabel" id="label2">
            <property name="visible">True</property>
            <property name="can_focus">False</property>
            <property name="xalign">0</property>
            <property name="xpad">5</property>
            <property name="ypad">5</property>
            <property name="label" translatable="yes">Status Area</property>
          </object>
          <packing>
            <property name="expand">True</property>
            <property name="fill">True</property>
            <property name="position">0</property>
          </packing>
        </child>
      </object>
      <packing>
        <property name="expand">False</property>
        <property name="fill">True</property>
        <property name="pack_type">end</property>
        <property name="position">3</property>
      </packing>
    </child>
  </object>
</child>
  </object>
</interface>

this works now but I don't think you're supposed to do this something else you're probably not supposed to do is make the builder global but I don't know how I can access my windows another way (I should probably post another question) but I think my whole infrastructure needs to be changed

# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4     -*-
### BEGIN LICENSE
# This file is in the public domain
### END LICENSE

from locale import gettext as _

from gi.repository import Gtk # pylint: disable=E0611
import logging
logger = logging.getLogger('simpleadministration')

from simpleadministration_lib import Window
from simpleadministration.AboutSimpleadministrationDialog import   AboutSimpleadministrationDialog
from simpleadministration.PreferencesSimpleadministrationDialog import    PreferencesSimpleadministrationDialog

import tkMessageBox, Tkinter

import functions

class SimpleadministrationWindow(Window):
__gtype_name__ = "SimpleadministrationWindow"

  Global_build = ''

  def on_account_add_menu_item_activate(self, widget):
    window = Global_build.get_object("addaccountwindow")
    print ("account add activated")
    window.show()

  def on_Add_account_action_button_clicked(self, widget):
    fname = self.account_First_Name_entry.get_text()   
    lname = self.account_Last_Name_entry.get_text()
    balance = self.account_balance_entry.get_text()
    Tkinter.Tk().withdraw()
    if tkMessageBox.askquestion(title="account creation",message="Are you sure you want to create this account?"):
        #functions.create_account(fname,lname,balance)
        functions.update_accounts_array()
        window = Global_build.get_object("addaccountwindow")
        window.hide()   

  def finish_initializing(self, builder): # pylint: disable=E1002
    """Set up the main window"""
    super(SimpleadministrationWindow, self).finish_initializing(builder)

    ## don't try this at home
    global Global_build
    Global_build = builder

    self.AboutDialog = AboutSimpleadministrationDialog
    self.PreferencesDialog = PreferencesSimpleadministrationDialog

    objects = self.builder.get_object
    self.Add_account_action_button = objects('Add_account_action_button')

    #add account entries
    self.account_First_Name_entry = objects('account_First_Name_entry')
    self.account_Last_Name_entry = objects('account_Last_Name_entry')
    self.account_balance_entry = objects('account_balance_entry')

Solution

  • I would recommend looking at some more examples on how to structure the classes. The answer in this question contains a working example, and you should be able to quickly adapt it to your program:

    The warning you are seeing, means that the handler that you defined in Glade, is not found by the builder.connect_signals(Handler()) method. So maybe the class is not initialized properly (check the execution order?).

    If your project is open-source you could upload it somewhere that people can run the whole program and suggest improvements. You can also look at this program for some hints on how to structure a bigger project.