3

When using _setit I get the following warning in PyCharm: enter image description here

Why do I use _setit?

I want to add or remove dynamically options to a dropdown list. To do so, I extract the tk.Menu object from the tk.OptionMenu I defined. And I add_command to this tk.Menu object. Problem is, when I click on the dropdown list, the element is not selected.

Hence, I use the protected member _setit like so: MY_MENU.add_command(label=LABEL, command=tk._setit(MY_STRING_VAR, LABEL)). MY_STRING_VAR is obviously the tk.StringVar associated to the tk.OptionMenu object defined earlier.

This works perfectly but I'm not allowed to use any # noqa in my project and I'm not allowed any weak warnings either. So two questions:

  • Is it actually a problem to use a "protected member of a module"? whatever that means?
  • Is there any workaround? Am I doing it the wrong way?
  • In my understanding this seems like an implantation error of tkinter in python. *The return value from tk_optionMenu is the name of the menu associated with pathName, so that the caller can change its configuration options or manipulate it in other ways.* [source](https://www.tcl-lang.org/man/tcl/TkCmd/optionMenu.htm) – Thingamabobs Aug 26 '22 at 18:05
  • I don't think it's an error, the option menu wasn't designed to have items added after it has been created. – Bryan Oakley Aug 26 '22 at 18:31
  • @BryanOakley I find it weird to believe that OptionMenu isn't designed to have items added after it's been created but is designed to have items removed (https://i.imgur.com/FXj43Iv.png) – FluidMechanics Potential Flows Aug 26 '22 at 21:48
  • @FluidMechanicsPotentialFlows after reading this [discussion](https://wiki.tcl-lang.org/page/tk_optionMenu) I feel Bryan is right by the intentional design. – Thingamabobs Aug 26 '22 at 21:59

1 Answers1

1

As a general rule, no, you should not be calling the private functions of objects. Being private, it could change on any future release of tkinter. In reality it probably won't, but it's still a bad practice.

The simple solution is to create your own implementation of _setit.

Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685
  • I can't even find how to access the source code of `_setit` so I'm not sure I know how to create my own implementation. Apart from destroying the `OptionMenu` and recreating it, but this sounds not optimal at all? – FluidMechanics Potential Flows Aug 26 '22 at 18:41
  • You can find the file it's in with this from the command line: `python -c 'import tkinter; print(tkinter.__file__)'` – Bryan Oakley Aug 26 '22 at 19:35
  • @FluidMechanicsPotentialFlows Perhaps you want to create your Optionmenu, with a label and a [contextmenu](https://stackoverflow.com/q/12014210) instead. – Thingamabobs Aug 26 '22 at 20:54
  • @BryanOakley I don't understand why `add_command` would be public if `_setit` isn't though. I don't see a situation where you would to add a label to your dropdown list without being able to interact _at all_ with it. – FluidMechanics Potential Flows Aug 26 '22 at 21:45
  • @Thingamabobs this is interesting although I'd like to have a dropdown list, and it seems that this isn't really a dropdown list. Also that sounds a bit overkill for me to use. I find it weird to believe that OptionMenu isn't designed to have items added after it's been created (but it's designed to have items removed). – FluidMechanics Potential Flows Aug 26 '22 at 21:46
  • 1
    @FluidMechanicsPotentialFlows: OptionMenu was never designed to be a first class widget. In the original tcl/tk source code it's just a little helper function that combines a menubutton and a menu and a little code to glue them together. That's all it was ever designed to be. I think in most cases you're better off using a `ttk.Combobox` – Bryan Oakley Aug 26 '22 at 21:57
  • What do you mean by `first class widget`? – FluidMechanics Potential Flows Aug 27 '22 at 09:26
  • @FluidMechanicsPotentialFlows: a first class widget means an actual widget - a single object that has standard methods and which behaves like all other widgets. – Bryan Oakley Aug 27 '22 at 16:02