I have written an app indicator for Ubuntu (basically an icon next to the wifi and battery icons) to set the action for closing the lid. It worked perfectly but I wanted to add a checkmark ✓ to see which state is active. This can be done using CheckMenuItems instead of MenuItems in Gtk. The problem is, in my case, the active state of the CheckMenuItems are mutually exclusive. I.e. when one is active, the other is not. I have listed the most relevant parts of the code.
def build_menu():
menu = gtk.Menu()
item_suspend = gtk.CheckMenuItem('Set lid to suspend')
item_suspend.connect('activate', set_lid_suspend)
menu.append(item_suspend)
item_nothing = gtk.CheckMenuItem('Set lid to nothing')
item_nothing.connect('activate', set_lid_nothing)
menu.append(item_nothing)
menu.show_all()
return menu
def set_lid_suspend(menuItem):
call([os.path.join(__location__, "setLidSuspend.sh")])
noot.update("<b>Set lid to suspend.</b>", "", None)
noot.show()
# adjusting the checkmarks
menu = menuItem.get_parent()
for item in menu.get_children(): # loop over all children
if item.get_label() == 'Set lid to nothing':
item.set_active(False)
break
menuItem.set_active(True)
def set_lid_nothing(menuItem):
call([os.path.join(__location__, "setLidNothing.sh")])
noot.update("<b>Set lid to nothing.</b>", "", None)
noot.show()
# adjusting the checkmarks
menu = menuItem.get_parent()
for item in menu.get_children(): # loop over all children
if item.get_label() == 'Set lid to suspend':
print(item)
item.set_active(False)
break
print("broke from nothing")
menuItem.set_active(True)
The problem is that when I use the appIndicator and call one of both methods, everything is fine and it behaves well; but when I then pick the other method, they will loop forever alternating between both of them. Does anyone know what I'm doing wrong?
Also, is this the right way to find menuItems of a menu? I find it hard to believe that there is no such method implemented as replacement for the for loop I've used.
I think you are using the wrong approach. I would use a RadioMenuItem. Then I would block the 'changing' code if the active state of the radiomenuitem is False. That would result in something like this:
def build_menu():
menu = gtk.Menu()
item_suspend = gtk.RadioMenuItem('Set lid to suspend')
item_suspend.connect('activate', set_lid_suspend)
menu.append(item_suspend)
item_nothing = gtk.RadioMenuItem('Set lid to nothing')
item_nothing.connect('activate', set_lid_nothing)
menu.append(item_nothing)
item_suspend.join_group(item_nothing)
menu.show_all()
return menu
def set_lid_suspend(menuItem):
if menuItem.get_active() == False:
return
call([os.path.join(__location__, "setLidSuspend.sh")])
noot.update("<b>Set lid to suspend.</b>", "", None)
noot.show()
def set_lid_nothing(menuItem):
if menuItem.get_active() == False:
return
call([os.path.join(__location__, "setLidNothing.sh")])
noot.update("<b>Set lid to nothing.</b>", "", None)
noot.show()
Since you posted incomplete code, I cannot test this for sure. Try it and let me know.