UBan
UBan

Reputation: 29

How to adjust size of widgets like frame,label,text inside a window with resizing of the window in tcl tk GUI

I am new in tcl\tk and I am developing a UI using it. The UI window has a frame that has dynamic number of labels and text widgets filled according to the number of columns in a table. There is an entry widget for each column, data typed in it by user populates each column in the table.

However the problem I am facing is that , I cannot find a way to make the size and position of the widgets inside the frame in the window adjust themselves according to the size of the window. That is if the user enlarges the window by dragging and enlarging its size the widgets inside the window should also increase in size and adjust their positions according to the window size. Vice versa if the window size id decreased. Something like bootstrap in HTML, CSS. Can anyone please give me any idea?? Any help is greatly appreciated. Thanks!

Upvotes: 0

Views: 1678

Answers (1)

Brad Lanam
Brad Lanam

Reputation: 5723

You need to read the documentation on the grid and pack commands.

With pack, the -fill and -expand options will help you adjust how the widget reacts to resizing.

Examples:

pack .widget -fill both -expand true
pack .widget -fill x -expand true -anchor s

With grid, the -sticky option and columnconfigure and rowconfigure sub-commands will be useful to you.

Examples:

grid .widget -sticky ew
grid columnconfigure . 0 -weight 1

In some cases there may be special actions you will need to take upon a resize. In this case, the bind command will be useful. You can bind to a <Configure> event and adjust widget sizes or take other actions as necessary.

Edit:

The grid columnconfigure applies to a column of a containing frame. So you don't have to run it for each widget. In the example above, .widget is contained in the . frame and the . frame's column is configured.

# in this example, the entry fields will adjust their width when
# the window is resized.
package require Tk
grid columnconfigure . 1 -weight 1
foreach {val} {1 2 3 4 5 6 7} {
  ttk::label .lab$val -text "Label $val:"
  ttk::entry .entry$val -textvariable mydata($val)
  grid .lab$val .entry$val -in . -sticky w
  # change the configuration for .entry$val only...
  grid configure .entry$val -sticky ew 
}

proc doresize { win } {
   puts "Win $win now has width: [winfo width $win]"
}

bind . <Configure> [list ::doresize %W]

Note that with this example, the bind also applies to all of the children of . as . is a top-level window. If you are only interested in changes to ., you can change the resize procedure:

proc doresize { win } {
   if { $win eq "." } {
      puts "Win $win now has width: [winfo width $win]"
   }
}

If the bind is applied to a frame or widget that is not a top-level window, the events are only received for that frame or widget.

Also note that you will receive all the events. Further changes can be made to check for changes to the width:

set vars(last.width) 0

proc doresize { win } {
   variable vars

   if { $win eq "." } {
      set newwidth [winfo width $win]
      if { $newwidth != $vars(last.width) } {
        puts "Win $win now has width: [winfo width $win]"
        if { $vars(last.width) != 0 } {
          # this is not the first time, as last.width is not zero
          # do something due to window resize.
        }
        set vars(last.width) $newwidth
      }
   }
}

References: grid, pack, bind

Upvotes: 0

Related Questions