• How to set ttk::radiobutton -variable to an object's instancevariable?

    From Mark Summerfield@m.n.summerfield@gmail.com to comp.lang.tcl on Fri Jul 11 09:55:25 2025
    From Newsgroup: comp.lang.tcl

    Given this class:

    oo::class create App {
    # ...
    variable ShowState
    }

    And this method:

    oo::define App method make_controls {} {
    # ...
    ttk::radiobutton .controlsFrame.showFrame.asIsRadio \
    -text "Show as-is" -value asis -variable ShowState
    set ShowState asis

    The variable given to the radio button and the instance variable
    are _different_.

    I tried these variations, all of which gave errors:

    -variable [my ShowState]
    -variable [my $ShowState]
    -variable [self ShowState]
    -variable [self $ShowState]

    For now I'm using a global variable ::ShowState
    but I'd really like it to be an instance variable -
    if it can be done?
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Robert Heller@heller@deepsoft.com to comp.lang.tcl on Fri Jul 11 10:09:44 2025
    From Newsgroup: comp.lang.tcl

    At Fri, 11 Jul 2025 09:55:25 -0000 (UTC) Mark Summerfield <m.n.summerfield@gmail.com> wrote:

    Given this class:

    oo::class create App {
    # ...
    variable ShowState
    }

    And this method:

    oo::define App method make_controls {} {
    # ...
    ttk::radiobutton .controlsFrame.showFrame.asIsRadio \
    -text "Show as-is" -value asis -variable ShowState
    set ShowState asis

    The variable given to the radio button and the instance variable
    are _different_.

    I tried these variations, all of which gave errors:

    -variable [my ShowState]
    -variable [my $ShowState]
    -variable [self ShowState]
    -variable [self $ShowState]

    For now I'm using a global variable ::ShowState
    but I'd really like it to be an instance variable -
    if it can be done?

    I don't know anything about how Tcl OO system works, but with SNIT I can do this:
    package require snit
    package require Tk
    snit::widget foo {
    variable ShowState
    constructor {args} {
    # ...
    ttk::radiobutton $win.controlsFrame.showFrame.asIsRadio \
    -text "Show as-is" -value asis -variable [myvar ShowState]
    # ...
    }
    }

    --
    Robert Heller -- Cell: 413-658-7953 GV: 978-633-5364
    Deepwoods Software -- Custom Software Services
    http://www.deepsoft.com/ -- Linux Administration Services
    heller@deepsoft.com -- Webhosting Services
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Schelte@nospam@wanadoo.nl to comp.lang.tcl on Fri Jul 11 13:28:06 2025
    From Newsgroup: comp.lang.tcl

    On 11/07/2025 11:55, Mark Summerfield wrote:
    Given this class:

    oo::class create App {
    # ...
    variable ShowState
    }

    And this method:

    oo::define App method make_controls {} {
    # ...
    ttk::radiobutton .controlsFrame.showFrame.asIsRadio \
    -text "Show as-is" -value asis -variable ShowState
    set ShowState asis

    The variable given to the radio button and the instance variable are_different_.

    ttk::radiobutton .controlsFrame.showFrame.asIsRadio \
    -text "Show as-is" -value asis -variable [my varname ShowState]


    Schelte.

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Mark Summerfield@m.n.summerfield@gmail.com to comp.lang.tcl on Fri Jul 11 15:21:52 2025
    From Newsgroup: comp.lang.tcl

    On Fri, 11 Jul 2025 13:28:06 +0200, Schelte wrote:

    On 11/07/2025 11:55, Mark Summerfield wrote:
    Given this class:

    oo::class create App {
    # ...
    variable ShowState
    }

    And this method:

    oo::define App method make_controls {} {
    # ...
    ttk::radiobutton .controlsFrame.showFrame.asIsRadio \
    -text "Show as-is" -value asis -variable ShowState
    set ShowState asis

    The variable given to the radio button and the instance variable
    are_different_.

    ttk::radiobutton .controlsFrame.showFrame.asIsRadio \
    -text "Show as-is" -value asis -variable [my varname ShowState]


    Schelte.

    That silently didn't work.
    I also tried `-variable [my variable ShowState]` and that didn't work
    either.

    I don't use snit so I couldn't use that approach either.

    Given that Tcl 9 has the incredibly useful `callback` command
    which I use all the time with Tk widgets for their `-command`
    options, I'm surprised there isn't an equivalent for Tk widget
    variables: or perhaps there is and I haven't found it?
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Schelte@nospam@wanadoo.nl to comp.lang.tcl on Fri Jul 11 21:12:08 2025
    From Newsgroup: comp.lang.tcl

    On 11/07/2025 17:21, Mark Summerfield wrote:
    That silently didn't work.

    Then you have a bug somewhere in the code you didn't show, because [my
    varname ShowState] correctly produces the fully qualified name of the
    instance variable.

    Another way to get the fully qualified name of the variable is
    [namespace which -variable ShowState]. But as that produces the same
    result, it also won't work until you fix that other bug.


    Schelte.

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Emiliano@emiliano@example.invalid to comp.lang.tcl on Fri Jul 11 20:13:59 2025
    From Newsgroup: comp.lang.tcl

    On Fri, 11 Jul 2025 21:12:08 +0200
    Schelte <nospam@wanadoo.nl> wrote:

    ...
    Another way to get the fully qualified name of the variable is
    [namespace which -variable ShowState]. But as that produces the same
    result, it also won't work until you fix that other bug.

    Adding to what Schelte correctly pointed out, these are your options:

    * [my varname somevar]: This works inside TclOO objects, and works for scalar
    variables, arrays and array elements.
    * [namespace which -variable somevar]: This works inside TclOO objects and
    namespaces. Works for scalar variables and arrays, but not for array
    elements. See Tcl bug#472113 . If you need an array element, use
    [namespace which -variable somearray](element).
    * last but not least, [namespace current]::somevar works if somevar is
    a variable in the current namespace, including the namespace of any TclOO
    object, and works for scalar, array and array elements.

    Regards
    --
    Emiliano
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From et99@et99@rocketship1.me to comp.lang.tcl on Fri Jul 11 17:28:11 2025
    From Newsgroup: comp.lang.tcl

    On 7/11/2025 4:13 PM, Emiliano wrote:
    On Fri, 11 Jul 2025 21:12:08 +0200
    Schelte <nospam@wanadoo.nl> wrote:

    ...
    Another way to get the fully qualified name of the variable is
    [namespace which -variable ShowState]. But as that produces the same
    result, it also won't work until you fix that other bug.

    Adding to what Schelte correctly pointed out, these are your options:

    * [my varname somevar]: This works inside TclOO objects, and works for scalar
    variables, arrays and array elements.
    * [namespace which -variable somevar]: This works inside TclOO objects and
    namespaces. Works for scalar variables and arrays, but not for array
    elements. See Tcl bug#472113 . If you need an array element, use
    [namespace which -variable somearray](element).
    * last but not least, [namespace current]::somevar works if somevar is
    a variable in the current namespace, including the namespace of any TclOO
    object, and works for scalar, array and array elements.

    Regards


    As a learning exercise,

    I filled in Mark's code (added the 2 frames, a second radio button, and packed it up) and used the [my varname ...] form which worked for me.

    Here's a little debug procedure one can use to find object variables. It might prove helpful. Note, the [my varname ...] will register the variable in the object's namespace, but the variable is still unset, which this code can show.



    # Function to dump all object variables
    proc dovar {{all 0} {sep "-----------------------------------"} } {
    if { $sep ne "" } {
    puts $sep
    }
    foreach ns [namespace children ::oo] {
    if {[string match "Obj*" [namespace tail $ns]]} {
    set objName ::$ns
    set class "<unknown>"
    catch {
    set class [info object class $objName]
    }
    if {!$all && $class eq "<unknown>"} {
    continue
    }
    puts "Object: $objName (Class: $class)"
    foreach var [info vars ${ns}::*] {
    set shortName [namespace tail $var]
    if {[info exists $var]} {
    catch { set val [set $var] }
    } else {
    set val "<unset>"
    }
    puts " $shortName ($var) = $val"
    }
    }
    }
    if { $sep ne "" } {
    puts $sep
    }
    }


    -eric

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Mark Summerfield@m.n.summerfield@gmail.com to comp.lang.tcl on Mon Jul 14 09:00:32 2025
    From Newsgroup: comp.lang.tcl

    On Fri, 11 Jul 2025 21:12:08 +0200, Schelte wrote:

    On 11/07/2025 17:21, Mark Summerfield wrote:
    That silently didn't work.

    Then you have a bug somewhere in the code you didn't show, because [my varname ShowState] correctly produces the fully qualified name of the instance variable.

    Another way to get the fully qualified name of the variable is
    [namespace which -variable ShowState]. But as that produces the same
    result, it also won't work until you fix that other bug.


    Schelte.

    Thank you (and the others) for your help.

    The mistake I made was that I initialized the variable in the wrong place.
    Now I call `set ShowState asis` in the constructor and use
    `-variable [my varname ShowState]` and it all works fine.

    When I looked at the docs for `my` I couldn't find `varname` but now
    realise this is documented on the `oo::object` page.
    --- Synchronet 3.21a-Linux NewsLink 1.2