Olupo
Olupo

Reputation: 420

TCL/TK create and destroy widget with checkbutton

I want to create and destroy a widget with a checkbutton. The widget will be created when then checkbutton is checked and should be destroyed when the checkbutton will be unchecked. The creation works fine, but when the widget should be destroyed the error message Error: window name "ser" already exists in parent will be displayed.

package require Tk

wm title . "Some Test"
grid[ttk::frame .c -padding "3 3 12 12"] -column 0 -row 0 -sticky nwes
grid columnconfigure . 0 -weight 1; grid rowconfigure . 0 -weight 1
grid [ttk::checkbutton .c.checkSer -command createWidget \ 
    -variable CB -onvalue 1 -offvalue 0] -column 1 -row 3 -sticky w
    
set CB 0

proc createWidget {} {
    if {[catch {info exists $::ser} fid]} {
        grid [ttk::entry .c.ser -width 12 -textvariable ser] -column 2 -row 2 -sticky we
        grid [ttk::label .c.serlbl -text "Ser"] -column 1 -row 2 -sticky w
    } else {
        destroy .c.ser .c.serlbl
    }
}

How can the widget be destroyed without this error?

Upvotes: 0

Views: 684

Answers (1)

Schelte Bron
Schelte Bron

Reputation: 4813

The problem is your statement info exists $::ser. This tries to read the global variable ser and will then check if a variable exists with the name stored in that variable.

So you probably intended to use info exists ::ser (without the $). But that also won't work like you want. A ttk::entry widget doesn't actually create its textvariable until the user types something in the entry, and the variable doesn't get deleted when the widget is destroyed.

You will need a different method to determine whether to create or destroy the widgets. For example:

if {![winfo exists .c.ser]} {
    # Create the widgets
} else {
    # Destroy the widgets
}

Upvotes: 2

Related Questions