在我的程序中,我有一个带有一组RadioMenuItem条目的菜单。选择其中一个应该触发一个可以成功或失败的功能。如果失败,则不应标记此RadioMenuItem(前一个应该保留)。此外,有时我想设置标记项而不运行选择处理功能。 这是我目前的代码:
# Update seat menu list
def update_seat_menu(self, seats, selected_seat=None):
seat_menu = self.builder.get_object('seat_menu')
# Delete seat menu items
for menu_item in seat_menu:
# TODO: is it a good way? does remove() delete obsolete menu_item from memory?
if menu_item.__class__.__name__ == 'RadioMenuItem': seat_menu.remove(menu_item)
# Fill menu with new items
group = []
for seat in seats:
menu_item = Gtk.RadioMenuItem.new_with_label(group, str(seat[0]))
group = menu_item.get_group()
seat_menu.append(menu_item)
if str(seat[0]) == selected_seat: menu_item.activate()
menu_item.connect("activate", self.choose_seat, str(seat[0]))
menu_item.show()
# Process item choice
def choose_seat(self, entry, seat_name):
# Looks like this is called when item is deselected, too; must check if active
if entry.get_active():
# This can either succeed or fail
self.logind.AttachDevice(seat_name, '/sys'+self.device_syspath, True)
无论choose_seat()
执行结果如何,选择的RadioMenuItem都会被标记;并且在不触发choose_seat()
的情况下设置标记项目的唯一方法是使用update_seat_menu()
参数重新运行selected_seat
,这是一种过度杀伤。
如果choose_seat()
成功,我尝试将'button-release-event'
与'activate'
联系起来而不是entry.activate()
并在choose_seat()
中致电AttachDevice()
,但这会导致整个X桌面锁定,直到AttachDevice()
超时,所选项目仍然被标记。
答案 0 :(得分:0)
在我看来,不同的方法会更好。当用户单击某个项目时,显示一个微调器或某些内容以让用户知道正在进行的操作,然后在后台执行长时间运行的choose_seat()
。如果失败,则将单选按钮更改为非活动状态并将其设置为不敏感(因为您现在知道它不起作用。)
答案 1 :(得分:0)
感谢irc.gnome.org/gtk+上的人们提供的帮助,我已经通过handler_block_by_func()
/ handler_unblock_by_func()
获得了此信息:
# Update chosen seat menu item (without triggering choose_seat)
def update_chosen_seat(self, seat):
self.seat_menu_items[seat].handler_block_by_func(self.choose_seat)
self.seat_menu_items[seat].activate()
self.seat_menu_items[seat].handler_unblock_by_func(self.choose_seat)
在choose_seat()
中,我使用相同的方法激活先前选择的项目,然后运行实际的处理程序代码并激活所选项目(如果成功)。