This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: ttk.OptionMenu radiobuttons change variable value twice
Type: behavior Stage: resolved
Components: Tkinter Versions: Python 3.11, Python 3.10, Python 3.9
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: Nosy List: epaine, fhdrsdg, lukasz.langa, miss-islington, serhiy.storchaka
Priority: normal Keywords: patch

Created on 2021-09-10 07:13 by fhdrsdg, last changed 2022-04-11 14:59 by admin. This issue is now closed.

Pull Requests
URL Status Linked Edit
PR 28291 merged epaine, 2021-09-11 14:45
PR 29131 merged miss-islington, 2021-10-21 20:26
PR 29132 merged miss-islington, 2021-10-21 20:26
PR 29416 merged lukasz.langa, 2021-11-04 23:21
PR 29420 merged miss-islington, 2021-11-05 08:51
PR 29421 merged miss-islington, 2021-11-05 08:52
PR 29425 merged serhiy.storchaka, 2021-11-05 13:32
Messages (10)
msg401557 - (view) Author: fhdrsdg (fhdrsdg) Date: 2021-09-10 07:13
Found when trying to answer this SO question: https://stackoverflow.com/questions/53171384/tkinter-function-repeats-itself-twice-when-ttk-widgets-are-engaged

The ttk.OptionMenu uses radiobuttons for the dropdown menu, whereas the tkinter.OptionMenu uses commands. Both of them use `_setit` as command, presumably first used for tkinter and then copied to the ttk implementation. The `_setit` does two things: changing the associated `variable` and calling the associated callback function. This is needed for the tkinter.OptionMenu since commands don't support changing a `variable`.

However, for the ttk.OptionMenu an additional reference to the variable was added to the radiobutton following this issue: https://bugs.python.org/issue25684. This was needed to group radiobuttons, but now leads to the variable being changed twice: once by the radiobutton and once through `_setit`. When tracing the variable this leads to the tracing callback being called twice on only one change of the OptionMenu.

The solution is to not use `_setit` for the radiobutton command but instead just use `command=self._callback`
msg401567 - (view) Author: E. Paine (epaine) * Date: 2021-09-10 10:08
Thank you for reporting this issue (and doing your research!). I don't think we could use `command=self._callback` since this wouldn't pass the new value, but something like `command=lambda val=val: self._callback(val)` would work perfectly. Would you like to open a pull request for this (with accompanying news entry and test), or would you rather I did it?
msg401634 - (view) Author: fhdrsdg (fhdrsdg) Date: 2021-09-11 08:47
Ah yes, you're right that `command=self._callback` doesn't pass the new value like it should.
Your suggestion does, but throws a "TypeError: 'NoneType' object is not callable" when no command is given when creating the OptionMenu. The current `_setit` implementation uses a `if self.__callback:` check for that.

Should we do something like this?

for val in values:
    menu.add_radiobutton(label=val,
        variable=self._variable)
    if self._callback:
        menu.entryconfigure('last', command=lambda val=val: self._callback(val))


I don't have any experience making pull requests. I might look into it at some point but for now it would be great if you could make it.
msg404649 - (view) Author: Łukasz Langa (lukasz.langa) * (Python committer) Date: 2021-10-21 20:26
New changeset add46f84769a7e6fafa50954f79b7c248231fa4e by E-Paine in branch 'main':
bpo-45160: Ttk optionmenu only set variable once (GH-28291)
https://github.com/python/cpython/commit/add46f84769a7e6fafa50954f79b7c248231fa4e
msg404657 - (view) Author: Łukasz Langa (lukasz.langa) * (Python committer) Date: 2021-10-21 20:59
New changeset 04485ac9886cd807aae854fb905a88c791cfdde6 by Miss Islington (bot) in branch '3.9':
bpo-45160: Ttk optionmenu only set variable once (GH-28291) (GH-29132)
https://github.com/python/cpython/commit/04485ac9886cd807aae854fb905a88c791cfdde6
msg404658 - (view) Author: Łukasz Langa (lukasz.langa) * (Python committer) Date: 2021-10-21 21:02
New changeset 98f157de1260801fd26c72eb6bfae0d9295e5ab3 by Miss Islington (bot) in branch '3.10':
bpo-45160: Ttk optionmenu only set variable once (GH-28291) (GH-29131)
https://github.com/python/cpython/commit/98f157de1260801fd26c72eb6bfae0d9295e5ab3
msg404660 - (view) Author: Łukasz Langa (lukasz.langa) * (Python committer) Date: 2021-10-21 21:03
Thanks for the fix, E. Paine, and fhdrsdg for the report! ✨ 🍰 ✨
msg405770 - (view) Author: Łukasz Langa (lukasz.langa) * (Python committer) Date: 2021-11-05 08:52
New changeset 54d1e3f72ed1ad8e860888c30ee7a285b931c0d1 by Łukasz Langa in branch 'main':
bpo-45160: Fix refleak in test_ttk_guionly introduced in GH-28291 (GH-29416)
https://github.com/python/cpython/commit/54d1e3f72ed1ad8e860888c30ee7a285b931c0d1
msg405778 - (view) Author: Łukasz Langa (lukasz.langa) * (Python committer) Date: 2021-11-05 10:00
New changeset 276a3a6a16ebf489607db31ad86c58dd89567306 by Miss Islington (bot) in branch '3.9':
bpo-45160: Fix refleak in test_ttk_guionly introduced in GH-28291 (GH-29416) (GH-29420)
https://github.com/python/cpython/commit/276a3a6a16ebf489607db31ad86c58dd89567306
msg405779 - (view) Author: Łukasz Langa (lukasz.langa) * (Python committer) Date: 2021-11-05 10:00
New changeset 099a94fba3f9437e29d16ed54215ec8cf65de868 by Miss Islington (bot) in branch '3.10':
bpo-45160: Fix refleak in test_ttk_guionly introduced in GH-28291 (GH-29416) (GH-29421)
https://github.com/python/cpython/commit/099a94fba3f9437e29d16ed54215ec8cf65de868
History
Date User Action Args
2022-04-11 14:59:49adminsetgithub: 89323
2021-11-05 13:32:53serhiy.storchakasetpull_requests: + pull_request27681
2021-11-05 10:00:22lukasz.langasetmessages: + msg405779
2021-11-05 10:00:09lukasz.langasetmessages: + msg405778
2021-11-05 08:52:37miss-islingtonsetpull_requests: + pull_request27674
2021-11-05 08:52:03lukasz.langasetmessages: + msg405770
2021-11-05 08:51:46miss-islingtonsetpull_requests: + pull_request27673
2021-11-04 23:21:33lukasz.langasetpull_requests: + pull_request27669
2021-10-21 21:03:59lukasz.langasetmessages: + msg404660
2021-10-21 21:03:50lukasz.langasetmessages: - msg404659
2021-10-21 21:03:34lukasz.langasetstatus: open -> closed
versions: - Python 3.6, Python 3.7, Python 3.8
messages: + msg404659

resolution: fixed
stage: patch review -> resolved
2021-10-21 21:02:28lukasz.langasetmessages: + msg404658
2021-10-21 20:59:26lukasz.langasetmessages: + msg404657
2021-10-21 20:26:37miss-islingtonsetpull_requests: + pull_request27408
2021-10-21 20:26:27miss-islingtonsetnosy: + miss-islington
pull_requests: + pull_request27407
2021-10-21 20:26:01lukasz.langasetnosy: + lukasz.langa
messages: + msg404649
2021-09-11 14:45:20epainesetkeywords: + patch
stage: patch review
pull_requests: + pull_request26707
2021-09-11 08:47:08fhdrsdgsetmessages: + msg401634
2021-09-10 10:08:50epainesetnosy: + serhiy.storchaka, epaine
messages: + msg401567
2021-09-10 07:13:00fhdrsdgcreate