You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Environment information
Describe your environment information, such as:
OS: MacOS 12.6.3
python version: v3.8.17
pygame version: v2.2.0
pygame-menu version: v4.4.3
Describe the bug
When you have a nested menu structure that is more than one level deep, the parent menu "forgets" which widget was selected before you navigated into a submenu. This means that when you navigate back to the parent, the 0th widget is always selected. This creates a usability issue because the user's selection is not remembered.
To Reproduce
Run the sample code here. This has 2 levels of nesting, and has some extra buttons so that the bug doesn't get hidden because the 0th button itself is the one that should be "remembered" :)
menu
-> sub
-> sub2
To trigger the bug, press "Sub", and then press "Sub2". Then navigate back by either pressing the "Back" button, or F1. You will see that instead of the selection of the "Sub2" button being remembered, the selection has reset to the "Back" button. I would expect it not to reset like this.
Note that doing only one level of navigation does NOT trigger this bug. Meaning, if you simply press "Sub" and then go back to the root menu, the selection is remembered. I believe this because for the root menu only, self._top == self.
importpygame_menuimportpygameimportpdbdefshow():
pygame.init()
screen=pygame.display.set_mode((400, 400))
clock=pygame.time.Clock()
pygame_menu.controls.KEY_BACK=pygame.K_F1menu=pygame_menu.Menu("test", 400, 400) # the main menusub=pygame_menu.Menu("sub", 400, 400) # sub is nested under menusub2=pygame_menu.Menu("sub2", 400, 400) # sub2 is nested under sub# Add "sub" as a link within "menu"sub_link=menu.add.menu_link(sub)
sub.add.button("Back", pygame_menu.events.BACK)
# Add "sub2" as a link within "sub"sub2_link=sub.add.menu_link(sub2)
sub2.add.button("Back", pygame_menu.events.BACK)
defopensub(menu=menu, sub=sub, sub2=sub2, sub_link=sub_link):
print(
f"BEFORE: current={menu.get_current().get_title()} link_menu={sub_link._menu.get_title()} menu: {menu._index}/{len(menu._widgets)}, sub={sub._index}/{len(sub._widgets)}, sub2={sub2._index}/{len(sub2._widgets)})"
)
# pdb.set_trace()sub_link.open()
print(
f"AFTER: current={menu.get_current().get_title()} link_menu={sub_link._menu.get_title()} menu: {menu._index}/{len(menu._widgets)}, sub={sub._index}/{len(sub._widgets)}, sub2={sub2._index}/{len(sub2._widgets)})"
)
defopensub2(menu=menu, sub=sub, sub2=sub2, sub2_link=sub2_link):
print(
f"BEFORE: current={menu.get_current().get_title()} link_menu={sub2_link._menu.get_title()} menu: {menu._index}/{len(menu._widgets)}, sub={sub._index}/{len(sub._widgets)}, sub2={sub2._index}/{len(sub2._widgets)})"
)
# pdb.set_trace()sub2_link.open()
print(
f"AFTER: current={menu.get_current().get_title()} link_menu={sub2_link._menu.get_title()} menu: {menu._index}/{len(menu._widgets)}, sub={sub._index}/{len(sub._widgets)}, sub2={sub2._index}/{len(sub2._widgets)})"
)
menu.add.button("No-op Button")
# To see logging/breakpoints replace with:# menu.add.button("Sub", opensub)menu.add.button("Sub", sub_link.open)
# To see logging/breakpoints replace with:# sub.add.button("Sub2", opensub2)sub.add.button("Sub2", sub2_link.open)
running=Truewhilerunning:
events=pygame.event.get()
foreventinevents:
ifevent.type==pygame.QUITor (
event.type==pygame.KEYDOWNandevent.key==pygame.K_ESCAPE
):
running=Falsescreen.fill("black")
menu.update(events)
menu.draw(screen)
pygame.display.flip()
clock.tick(60)
pygame.quit()
if__name__=="__main__":
show()
Expected behavior
When I navigate into a submenu, and then navigate back out to to the parent, the parent should always remember which widget was selected before the navigation took place.
Additional context
I suspect this bug may be because of this line in _open() in menu.py:3556: self._current._select(0, 1, SELECT_OPEN, False, update_mouse_position=False)
I won't speculate too much about the purpose of this line of code since I'm not very familiar with the codebase, but if I hack this and change it to self._top._current._select(...) it does seem to fix the issue. I don't know if that's the correct fix though.
It seems that the lines right before attempt to change the current menu to be the one that is about to be opened by doing:
self._top._current = menu._current
but does the following _select() call on self._current (vs self._top._current or even menu._current), which is still the parent menu, thus selecting the 0th widget of the parent menu before opening the child.
And in the root case, self._top == self. Thus setting self._top._current actually sets self._current. Thus self._current IS actually the submenu (not the parent), and thus the submenu is the one who's widget index gets reset.
The text was updated successfully, but these errors were encountered:
Hi, I Added a new version of 4.4.8that adds theremember_selection`` to the Menu constructor. I used the same philosophy as discussed here. Thanks, and I'm sorry for the delay in finding a solution.
Environment information
Describe your environment information, such as:
Describe the bug
When you have a nested menu structure that is more than one level deep, the parent menu "forgets" which widget was selected before you navigated into a submenu. This means that when you navigate back to the parent, the 0th widget is always selected. This creates a usability issue because the user's selection is not remembered.
To Reproduce
Run the sample code here. This has 2 levels of nesting, and has some extra buttons so that the bug doesn't get hidden because the 0th button itself is the one that should be "remembered" :)
To trigger the bug, press "Sub", and then press "Sub2". Then navigate back by either pressing the "Back" button, or F1. You will see that instead of the selection of the "Sub2" button being remembered, the selection has reset to the "Back" button. I would expect it not to reset like this.
Note that doing only one level of navigation does NOT trigger this bug. Meaning, if you simply press "Sub" and then go back to the root menu, the selection is remembered. I believe this because for the root menu only,
self._top == self
.Expected behavior
When I navigate into a submenu, and then navigate back out to to the parent, the parent should always remember which widget was selected before the navigation took place.
Additional context
I suspect this bug may be because of this line in
_open()
inmenu.py:3556
:self._current._select(0, 1, SELECT_OPEN, False, update_mouse_position=False)
I won't speculate too much about the purpose of this line of code since I'm not very familiar with the codebase, but if I hack this and change it to
self._top._current._select(...)
it does seem to fix the issue. I don't know if that's the correct fix though.It seems that the lines right before attempt to change the current menu to be the one that is about to be opened by doing:
but does the following
_select()
call onself._current
(vsself._top._current
or evenmenu._current
), which is still the parent menu, thus selecting the 0th widget of the parent menu before opening the child.And in the root case,
self._top == self
. Thus settingself._top._current
actually setsself._current
. Thusself._current
IS actually the submenu (not the parent), and thus the submenu is the one who's widget index gets reset.The text was updated successfully, but these errors were encountered: