• Re: Python3.6 tkinter bug?

    From Peter Smith@21:1/5 to Terry Reedy on Thu Sep 22 09:00:54 2022
    On Wednesday, February 1, 2017 at 11:55:35 AM UTC, Terry Reedy wrote:
    On 2/1/2017 1:37 AM, Christian Gollwitzer wrote:
    Am 01.02.17 um 00:02 schrieb MRAB:
    On 2017-01-31 22:34, Christian Gollwitzer wrote:
    .!frame.!checkbutton
    .!frame.!checkbutton2
    .!frame2.!checkbutton
    .!frame2.!checkbutton2


    Perhaps someone who knows Tcl and tk can tell me, but I notice that in
    the first example, the second part of the widget names are unique,
    whereas in the second example, the second part of the widget names are
    the reused (both "!checkbutton" and "!checkbutton2" occur twice).

    It is indeed the reason, but it has some strange legacy cause: the
    default name for the checkbutton-linked variable is the name of the
    button inside the parent. Therefore creating a checkbutton has the side effect of creating a variable with the button's name.

    In this case, the first buttons in the frames are linked to a variable called "!checkbutton" and the other two are linked to "!checkbutton2".
    (a variable name in Tcl can be anything apart from the empty string).
    This can also be demonstrated by this Tcl script:

    package require Tk

    pack [frame .f1]
    pack [frame .f2]

    pack [checkbutton .f1.c1 -text "A" ]
    pack [checkbutton .f1.c2 -text "B" ]

    pack [checkbutton .f2.c1 -text "C" ]
    pack [checkbutton .f2.c2 -text "D" ]

    which is equivalent to the Python code above.

    Note that this surprising behaviour was corrected for the (modern) ttk widgets, so if "checkbutton" is replaced by "ttk::checkbutton", they are not any longer linked. In Python, that would be

    from tkinter import ttk
    ...
    w = ttk.Checkbutton()

    (Personally, I'm not using the legacy widgets any longer)
    Christian, could you repeat any relevant parts of your comments on the tracker, especially any ideas on how we might fix tkinter? https://bugs.python.org/issue29402
    Do the names need to be:

    .!frame.!checkbutton
    .!frame.!checkbutton2
    .!frame2.!checkbutton3
    .!frame2.!checkbutton4
    Serhiy considered that but, not knowing that this would cause a
    regression, we both liked numbering within parent better.

    There is a similar issue with radiobuttons on ttk.OptionMenus that
    existed *before* the 3.6 name changes.
    https://bugs.python.org/issue25684
    So there seems to be a systematic issue with tk or how we are (mis)using it.
    Good question. Maybe there should be unique variable names? I.e., if the script is changed into package require Tk

    pack [frame .f1]
    pack [frame .f2]

    pack [checkbutton .f1.c1 -text "A" -variable v1]
    pack [checkbutton .f1.c2 -text "B" -variable v2]

    pack [checkbutton .f2.c1 -text "C" -variable v3]
    pack [checkbutton .f2.c2 -text "D" -variable v4]

    then they are also not linked.
    --
    Terry Jan Reedy

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Peter Smith@21:1/5 to Terry Reedy on Thu Sep 22 09:06:18 2022
    On Wednesday, February 1, 2017 at 11:55:35 AM UTC, Terry Reedy wrote:
    On 2/1/2017 1:37 AM, Christian Gollwitzer wrote:
    Am 01.02.17 um 00:02 schrieb MRAB:
    On 2017-01-31 22:34, Christian Gollwitzer wrote:
    .!frame.!checkbutton
    .!frame.!checkbutton2
    .!frame2.!checkbutton
    .!frame2.!checkbutton2


    Perhaps someone who knows Tcl and tk can tell me, but I notice that in
    the first example, the second part of the widget names are unique,
    whereas in the second example, the second part of the widget names are
    the reused (both "!checkbutton" and "!checkbutton2" occur twice).

    It is indeed the reason, but it has some strange legacy cause: the
    default name for the checkbutton-linked variable is the name of the
    button inside the parent. Therefore creating a checkbutton has the side effect of creating a variable with the button's name.

    In this case, the first buttons in the frames are linked to a variable called "!checkbutton" and the other two are linked to "!checkbutton2".
    (a variable name in Tcl can be anything apart from the empty string).
    This can also be demonstrated by this Tcl script:

    package require Tk

    pack [frame .f1]
    pack [frame .f2]

    pack [checkbutton .f1.c1 -text "A" ]
    pack [checkbutton .f1.c2 -text "B" ]

    pack [checkbutton .f2.c1 -text "C" ]
    pack [checkbutton .f2.c2 -text "D" ]

    which is equivalent to the Python code above.

    Note that this surprising behaviour was corrected for the (modern) ttk widgets, so if "checkbutton" is replaced by "ttk::checkbutton", they are not any longer linked. In Python, that would be

    from tkinter import ttk
    ...
    w = ttk.Checkbutton()

    (Personally, I'm not using the legacy widgets any longer)
    Christian, could you repeat any relevant parts of your comments on the tracker, especially any ideas on how we might fix tkinter? https://bugs.python.org/issue29402
    Do the names need to be:

    .!frame.!checkbutton
    .!frame.!checkbutton2
    .!frame2.!checkbutton3
    .!frame2.!checkbutton4
    Serhiy considered that but, not knowing that this would cause a
    regression, we both liked numbering within parent better.

    There is a similar issue with radiobuttons on ttk.OptionMenus that
    existed *before* the 3.6 name changes.
    https://bugs.python.org/issue25684
    So there seems to be a systematic issue with tk or how we are (mis)using it.
    Good question. Maybe there should be unique variable names? I.e., if the script is changed into package require Tk

    pack [frame .f1]
    pack [frame .f2]

    pack [checkbutton .f1.c1 -text "A" -variable v1]
    pack [checkbutton .f1.c2 -text "B" -variable v2]

    pack [checkbutton .f2.c1 -text "C" -variable v3]
    pack [checkbutton .f2.c2 -text "D" -variable v4]

    then they are also not linked.
    --
    Terry Jan Reedy

    It looks as if the issue is indeed that the expression to the right of CheckButton(... variable= must be an expression.

    This works for me
    global checkbix, checkbuttons
    checkbix += 1
    b = tk.Checkbutton(frame, text=text, variable=checkbuttons[checkbix], ...)

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)