Why is the widget not at the center of the window although it is in the center of the grid? - tcl

I have created a label, which I placed in the center row and center column of a grid:
label .mytext -text "Hello!"
grid x x x -in .
grid x .mytext x
grid x x x -in .
grid rowconfigure . 0 -weight 1
grid rowconfigure . 1 -weight 1
grid rowconfigure . 2 -weight 1
grid columnconfigure . 0 -weight 1
grid columnconfigure . 1 -weight 1
grid columnconfigure . 2 -weight 1
wm geometry . 300x200
However, the label does not appear exactly at the center of the window; it is above the center:
Why is the label not exactly at the center of the window, even though I have placed it in the center of the grid?

Your grid x x x -in . command effectively does nothing. The grid x .mytext x command puts the label in the first empty row, which is row 0. You can verify this with grid info .mytext.
To achieve what you seem to be trying, you can do:
label .mytext -text "Hello!"
grid .mytext -row 1 -column 1
grid rowconfigure . {0 1 2} -weight 1
grid columnconfigure . {0 1 2} -weight 1
wm geometry . 300x200
When doing it that way, the label does end up centered.

Related

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?
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
}

Getting value from textvariable (entry widget)

I am trying to create a simple form box, ultimately to place data in a database. Right now I am simply testing it with puts statements, as follows:
package require Tk
wm title . "Add"
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::label .c.idlbl -width 7 -text "id"] -column 1 -row 1 -sticky we
grid [ttk::entry .c.id -width 7 -textvariable id] -column 2 -row 1 -sticky we
grid [ttk::label .c.txtlbl -text "text"] -column 1 -row 2 -sticky w
grid [ttk::entry .c.txt -width 7 -textvariable text] -column 2 -row 2 -sticky we
grid [ttk::button .c.calc -text "Add!" -command db_add] -column 1 -row 3 -sticky w
foreach w [winfo children .c] {grid configure $w -padx 5 -pady 5}
focus .c.id
proc db_add {} {
set id $::id
set text $::text
puts $id
puts $text
}
My question: why do I need to do set into another variable name, before I can do anything with the value? Why can I not just do puts $::id?
I have tried puts expr{$::id}, which gives an output like expr{Whatever Text Was Entered}, leaving me unsure why the expr does not go away. It seems my concept of variables in TCL is very murky at the moment.
You can use puts $::id, but until you have entered text into the entry fields, the variables don't exist. You can initialize them in parallel with creating the widgets, or test them for existence:
if {![info exists ::id]} {
set ::id {}
}
puts \$::id=$::id

best method for hide/show a widget

i would like to know if this method is good for hide or show a widget
maybe a better method ?
thanks in advance
ttk::treeview .tree
.tree insert {} end -id "Item 1" -text "Item 1"
.tree insert {} end -id "Item 2" -text "Item 2"
.tree insert {} end -id "Item 3" -text "Item 3"
text .text -bg green
button .b -text "H" -width 10 -command {grid .text -row 0}
button .b1 -text "B" -width 10 -command {grid .text -row 1}
wm geometry . 500x600
grid .tree -row 0 -columnspan 2 -sticky nsew
grid .text -row 1 -columnspan 2 -sticky nsew
grid .b -row 2 -sticky nsw
grid .b1 -row 2 -column 1 -sticky nse
grid columnconfigure . 0 -weight 1
grid rowconfigure . 0 -weight 1
You can use grid remove. Change the buttons to:
button .b -text "H" -width 10 -command {grid remove .tree}
button .b1 -text "B" -width 10 -command {grid .tree}
Of course if you also want the text area to expand into row 0, you
may also want to modify the text area's row.
grid remove will remember the configuration settings.
References: http://tcl.tk/man/tcl8.6/TkCmd/grid.htm
I think it is depends what you really wants. If you would like to retain the original grid configuration in order to use this widget again, you should use grid remove. But if you don't intend to use the widget after once hidden, you should use grid forget

Not able to move button in tcl/tk

GUI snapshot
In this code i want to move new_button to right most side.But After changing row, column,columnspan also,it stays there only. What are the changes required in code.
ttk::frame .c
.c configure -borderwidth 7 -relief groove -padding "200 25"
button .c.cancle -text cancel -command {destroy .}
ttk::label .c.l -text "yash"
ttk::checkbutton .c.one -text One -variable oe -onvalue 1
ttk::button .c.ok -text Okay -command sp12
button .c.lop -text New_button
grid .c -column 0 -row 4
grid .c.l -column 0 -row 1 -columnspan 2
grid .c.one -column 0 -row 3 -columnspan 2
grid .c.ok -column 3 -row 3 -columnspan 2
grid .c.cancle -column 9 -row 3 -columnspan 2
grid .c.lop -column 30 -row 10 -rowspan 10 -columnspan 15 -sticky w
grid can be tricky. If there are no widgets in one of the rows or columns, that row and/or column will be considered to have 0 width and/or 0 height. Thus increasing the row number and/or column number will not change anything.
In your current script, the padding to the frame prevents the widgets inside the .c grid to be near the .c border (padding adds a 'layer' of space between the border and the widgets inside it). So this is the first thing to remove. Once done, the widget will lose its size though, because the size of the widget depend on the size of the widgets inside it after all.
So a workaround here would be to define the minimum sizes:
ttk::frame .c
.c configure -borderwidth 7 -relief groove
wm minsize . 656 135 # Set a minimum size here
button .c.cancle -text cancel -command {destroy .}
ttk::label .c.l -text "yash"
ttk::checkbutton .c.one -text One -variable oe -onvalue 1
ttk::button .c.ok -text Okay -command sp12
button .c.lop -text New_button
# I cleaned up the columns
grid .c -row 0 -column 0 -sticky nsew # make it anchor all positions
grid .c.l -column 1 -row 1
grid .c.one -column 1 -row 2
grid .c.ok -column 2 -row 2
grid .c.cancle -column 3 -row 2
grid .c.lop -column 4 -row 3 -sticky se # make it anchor at south east position
# make the .c grid fit to the . window
grid columnconfigure . all -minsize 635 -weight 1
grid rowconfigure . all -weight 1
# force column before column 1 and row before row 1 to have some specific size
grid columnconfigure .c 0 -minsize 200
grid rowconfigure .c 0 -minsize 30
# make the last cell fill any spaces after it, if available
grid columnconfigure .c 4 -weight 1
grid rowconfigure .c 4 -weight 1
Result:

Tcl/Tk: How to scale the widgets when the user changes the size of the window

I have a window with widgets inside it. When I re-size the window manually, the widgets will scale them self when the height is reduced, but not when the width is changed or when the height is enlarged beyond the initial height. How do I make the widgets to be stack to the borders of the window?
The code for the creation of the window:
wm title $base "KitKite Sparam Viewer"
set frm_main [frame $base.main_frm]
pack $frm_main
grid [frame $frm_main.graph ] -row 1 -column 1
set g [sparam_graph_widget $frm_main.graph graph]
grid [set frm [frame $frm_main.frm]] -row 1 -column 2
#from and to frame
set from [frame $frm.from -relief ridge -bd 2]
set from_lbl [label $from.lbl -text "From:"]
set f_tbl_frm [frame $from.tbl_f]
set to [frame $frm.to -relief ridge -bd 2]
set to_lbl [label $to.lbl -text "To:"]
set t_tbl_frm [frame $to.tbl_t]
grid $from -column 1 -row 1 -sticky nwe
grid $from_lbl -row 1 -sticky nsew
grid $f_tbl_frm -row 2 -sticky nsew
grid $to -column 2 -row 1 -sticky nwe
grid $to_lbl -row 1 -sticky nsew
grid $t_tbl_frm -row 2 -sticky nsew
set from_t [sparam_table_widget $f_tbl_frm f_tbl]
set to_t [sparam_table_widget $t_tbl_frm t_tbl]
set data [frame $frm.data]
set data_lbl [label $data.lbl -text "Choose data type to show"]
set isi [checkbutton $data.cb_isi -variable cb(isi) -command [list __sp_data_changed isi $g] -text ISI ]
set xt [checkbutton $data.cb_xt -variable cb(xt) -command [list __sp_data_changed xt $g] -text XT ]
set ref [checkbutton $data.cb_ref -variable cb(ref) -command [list __sp_data_changed ref $g] -text Reflection]
set conf_button [button $data.bt_conf -text "Configure connections" -command [list __sp_configure_datapath]]
grid $data -column 1 -row 2 -columnspan 2 -sticky new
grid $data_lbl -column 1 -row 1 -columnspan 2 -sticky nsew
grid $isi -column 1 -row 2 -sticky nsw
grid $xt -column 1 -row 3 -sticky nsw
grid $ref -column 1 -row 4 -sticky nsw
grid $conf_button -column 2 -row 2 -rowspan 3 -sticky nsew
grid rowconfigure $frm 1 -weight 4 -uniform 1
grid rowconfigure $frm 2 -weight 1 -uniform 1
grid rowconfigure $frm_main 1 -weight 5 -uniform 1
$base is the name of the window created using toplevel
sparam_graph_widget and sparam_table_widget are procedures that create and place inside the frame given to them custom widgets of a graph and a table (accordingly)
In order for at least one widget to expand to consume the space, you need to set at least one column to have a non-zero weight.
grid columnconfigure $containerWidget $someWidgetOrIndex -weight 1
Note that once you do that, that column preferentially deals with all the size changes in the horizontal direction. You can adjust this by setting multiple columns to have non-zero weights, and give different columns different weights (-weight 2 will receive twice as large changes as -weight 1).
You might also need to adjust the options used to pack the outer frame. Debug by setting different frames to different colors so you can see what's going on…