I am creating a list of radiobuttons on a frame, the list eventually becomes huge and its difficult for user to select items.
Is there anyway i can add a scrollbar to this frame?
I tried adding listbox, but no help.
This is my code.
frame .top.d.b -width 100 -height 20 -borderwidth 2 -relief raised
label .top.d.b.l1 -font fontTEMP_varwidth -text "Comparision Libraries" -anchor center -padx 2 -pady 4
set whu .top.d.b
grid .top.d.b -row 7 -column 2 -sticky nsew
grid .top.d.b.l1 -row 1 -column 2
set w 0
foreach elem $mylist {
radiobutton .top.d.b.$w -text $elem -command [list selectlib $elem $w] -value $elem.abc -padx 2 -pady 2
grid .top.d.b.$w -row $a -column $r -sticky w
incr a
incr w
}
} else {
puts "STD_CELLS_LIBPATH not found\n"
}
}
You can use a canvas combined with scrollbars, than you put your widgets on the canvas. Example:
#!/usr/bin/env wish
ttk::frame .frAlles
# create canvas with scrollbars
canvas .frAlles.c -width 400 -height 200 -xscrollcommand ".frAlles.xscroll set" -yscrollcommand ".frAlles.yscroll set"
ttk::scrollbar .frAlles.xscroll -orient horizontal -command ".frAlles.c xview"
ttk::scrollbar .frAlles.yscroll -command ".frAlles.c yview"
pack .frAlles.xscroll -side bottom -fill x
pack .frAlles.yscroll -side right -fill y
pack .frAlles.c -expand yes -fill both -side top
# create frame with widgets
ttk::frame .frAlles.c.frWidgets -borderwidth 1 -relief solid -width 340 -height 700
for {set i 0} {$i <=20} {incr i} {
ttk::label .frAlles.c.frWidgets.lb$i -text "Label $i:"
ttk::entry .frAlles.c.frWidgets.en$i
ttk::button .frAlles.c.frWidgets.bt$i -text "Button $i" -command exit
grid .frAlles.c.frWidgets.lb$i -padx 2 -pady 2 -row $i -column 0
grid .frAlles.c.frWidgets.en$i -padx 2 -pady 2 -row $i -column 1
grid .frAlles.c.frWidgets.bt$i -padx 2 -pady 2 -row $i -column 2
}
# create frame with buttons
ttk::frame .frAlles.c.frButtons -borderwidth 1 -relief solid -width 340 -height 40
ttk::button .frAlles.c.frButtons.btOK -text "OK" -command exit
ttk::button .frAlles.c.frButtons.btAbbruch -text "Abbruch" -command exit
pack .frAlles.c.frButtons.btOK -padx 2 -pady 2 -side left
pack .frAlles.c.frButtons.btAbbruch -padx 2 -pady 2 -side left
# place widgets and buttons
.frAlles.c create window 0 0 -anchor nw -window .frAlles.c.frWidgets
.frAlles.c create window 200 650 -anchor c -window .frAlles.c.frButtons
# determine the scrollregion
.frAlles.c configure -scrollregion [.frAlles.c bbox all]
# show the canvas
pack .frAlles -expand yes -fill both -side top
Only widgets that implement Tk's scrolling protocol can be associated with a scrollbar; frames are not such a widget.
However, you can put your frame inside a canvas (via the “widget” canvas item type) and canvases are scrollable provided you tell the canvas what the scroll region is. You'll want to make sure that the frame and its contents are children of the canvas in order for the clipping of them to work right.
You can't do that. Only widgets that have scrollcommand options (-xscrollcommand, -yscrollcommand) and xview / yview widget commands can be scrolled.
The answer is late but colud help others.
You could think of using Bwidgets it has many widgets like scrolled windows, frames. https://wiki.tcl-lang.org/page/BWidget
Related
Currently:
Before execution (fig. 1)
after execution (fig. 2)
I am poor at tcl/tk. But nowadays I am studying tcl/tk for my work. I want to make GUI like figures. figure 1 is before clicking buttons. If I click right-side button and select files, the file names appear in the button text. I want to position these names in the middle-side entry region and want to use these file names as global variables. Here is my code. Could anyone help me?
#-------------------------------------------------------------------------
namespace eval ::dyna::partupdate {
variable p_mainWin ".partupdate";
variable str_curDir [file dirname [info script]];
variable str_basefile "";
variable str_appendfile "";
variable str_spotweldfile "";
variable str_outputfile "";
}
set types {
{"LS-DYNA Files" {.key .k .dyn .d } }
{"IGES Files" {.iges .igs } }
{"MCF Files" {.mcf } }
{"All files" *}
}
##############################################################################
##### Procedure Name: ::dyna::partupdate::CreateGUI
##### Functionality: creates the main window for file selection
##############################################################################
proc ::dyna::partupdate::CreateGUI {} {
variable p_mainWin;
destroy $p_mainWin;
set base [ toplevel $p_mainWin];
wm title $base {Update FE Model};
wm resizable $base 1 1;
set frm_main [frame $base.frm_main];
pack $frm_main -side top -anchor nw -padx 0 -pady 0;
set frm_fileselect [frame $frm_main.frm_fileselect -bd 0 -relief groove];
set frm_create [frame $frm_main.frm_create -bd 0 -relief groove]
# pack $frm_create -side right -anchor ne -padx 0 -pady 4;
grid $frm_fileselect -row 0 -padx 1 -pady 4 -sticky nw;
grid $frm_create -row 3 -padx 1 -pady 4 -sticky ne;
# set frm_create [frame $frm_main.frm_create -bd 0 -relief groove]
# pack $frm_create -side right -anchor ne -padx 0 -pady 4;
# UI for base file
set lbl_basefile [label $frm_fileselect.lbl_basefileName -text "Base File"];
set ent_basefile [entry $frm_fileselect.ent_basefileName -width 30 \
-textvariable "::dyna::partupdate::str_basefile" -state disabled];
set btn_basefile [button $frm_fileselect.btn_basefile -text " ... " \
-command "::dyna::partupdate::onSelect $frm_fileselect.btn_basefile" ]
grid $lbl_basefile -row 0 -col 0 -padx 5 -pady 7 -sticky nw;
grid $ent_basefile -row 0 -col 1 -padx 5 -pady 7 -sticky nw;
grid $btn_basefile -row 0 -col 2 -padx 0 -pady 6 -sticky nw;
# UI for appended file
set lbl_appendfile [label $frm_fileselect.lbl_appendfileName -text "Appended File"];
set ent_appendfile [entry $frm_fileselect.ent_appendfileName -width 30 \
-textvariable "::dyna::partupdate::str_appendfile" -state disabled];
set btn_appendfile [button $frm_fileselect.btn_appendfile -text " ... " \
-command "::dyna::partupdate::onSelect $frm_fileselect.btn_appendfile" ]
grid $lbl_appendfile -row 1 -col 0 -padx 5 -pady 2 -sticky nw;
grid $ent_appendfile -row 1 -col 1 -padx 5 -pady 2 -sticky nw;
grid $btn_appendfile -row 1 -col 2 -padx 0 -pady 6 -sticky nw;
# UI for spotweld file
set lbl_spotweldfile [label $frm_fileselect.lbl_spotweldfileName -text "Spotweld File"];
set ent_spotweldfile [entry $frm_fileselect.ent_spotweldfileName -width 30 \
-textvariable "::dyna::partupdate::str_spotweldfile" -state disabled];
set btn_spotweldfile [button $frm_fileselect.btn_spotweldfile -text " ... " \
-command "::dyna::partupdate::onSelect $frm_fileselect.btn_spotweldfile" ]
grid $lbl_spotweldfile -row 2 -col 0 -padx 5 -pady 2 -sticky nw;
grid $ent_spotweldfile -row 2 -col 1 -padx 5 -pady 2 -sticky nw;
grid $btn_spotweldfile -row 2 -col 2 -padx 0 -pady 6 -sticky nw;
# UI for output file
set lbl_outputfile [label $frm_fileselect.lbl_outputfileName -text "Output File"];
set ent_outputfile [entry $frm_fileselect.ent_outputfileName -width 30 \
-textvariable "::dyna::partupdate::str_outputfile" -state disabled];
set btn_outputfile [button $frm_fileselect.btn_outputfile -text " ... " \
-command "::dyna::partupdate::saveAs $frm_fileselect.btn_outputfile" ]
grid $lbl_outputfile -row 3 -col 0 -padx 5 -pady 2 -sticky nw;
grid $ent_outputfile -row 3 -col 1 -padx 5 -pady 2 -sticky nw;
grid $btn_outputfile -row 3 -col 2 -padx 0 -pady 6 -sticky nw;
set btn_update [hwt::CanvasButton $frm_create.btn_update \
[::hwt::DluWidth 40] [::hwt::DluHeight 14] \
-command "::dyna::partupdate::uPDATE" \
-text "Update" ]
set btn_close [hwt::CanvasButton $frm_create.btn_close \
[::hwt::DluWidth 40] [::hwt::DluHeight 14] \
-command "::dyna::partupdate::CloseWindow" \
-text "Close" ]
pack $btn_update -anchor ne -padx 5 -pady 5 -side left;
pack $btn_close -anchor ne -padx 5 -pady 5 -side left;
}
proc ::dyna::partupdate::onSelect { label } {
global types
set file [tk_getOpenFile -filetypes $types -parent .]
$label configure -text $file
}
proc ::dyna::partupdate::saveAs { label } {
global types
set file [tk_getSaveFile -filetypes $types -parent . -initialdir .]
$label configure -text $file
}
proc ::dyna::partupdate::uPDATE { args } {
variable str_basefile;
variable str_appendfile;
variable str_spotweldfile;
variable str_outputfile;
set executable C:\CENSor\\CENSor.exe
# base file name should not be empty
if {$str_basefile == ""} {
tk_messageBox -message "Please select an base file." -title "aaa" \
-type ok -icon info;
return;
}
# append file name should not be empty
if {$str_appendfile == ""} {
tk_messageBox -message "Please select an appended file." -title "aaa" \
-type ok -icon info;
return;
}
# execution case
if {$str_spotweldfile == ""} {
exec $executable -e 0 $str_outputfile $str_basefile $str_appendfile
}
else {
exec $executable -e 0 $str_outputfile $str_basefile $str_appendfile $str_spotweldfile
}
}
proc ::dyna::partupdate::CloseWindow { args } {
variable p_mainWin;
set windowPath [lindex $args 0];
if {[winfo exists $p_mainWin]} {
destroy $p_mainWin
}
}
# ----- bring up the main gui --------
::dyna::partupdate::CreateGUI;
For the first one, this line:
set btn_basefile [button $frm_fileselect.btn_basefile -text " ... " \
-command "::dyna::partupdate::onSelect $frm_fileselect.btn_basefile" ]
will execute this proc:
proc ::dyna::partupdate::onSelect { label } {
global types
set file [tk_getOpenFile -filetypes $types -parent .]
$label configure -text $file
}
The first line above will update the widget $frm_fileselect.btn_basefile which is the button, when onSelect is executed. You will first need to change the first line to modify the entry box, like so:
set btn_basefile [button $frm_fileselect.btn_basefile -text " ... " \
-command "::dyna::partupdate::onSelect $frm_fileselect.ent_basefile" ]
Then change the proc so that it is able to edit the entry text (entries don't have a -text option, you have to insert. Usually it's better to delete everything just in case)
proc ::dyna::partupdate::onSelect { label } {
global types
set file [tk_getOpenFile -filetypes $types -parent .]
$label configure -state normal ;# makes the entry normal to allow editing
$label delete 0 end ;# delete everything
$label insert end $file ;# insert the text
$label configure -state disabled ;# disable the entry again
}
Then you will have to modify the remaining 3 buttons similarly:
set btn_appendfile [button $frm_fileselect.btn_appendfile -text " ... " \
-command "::dyna::partupdate::onSelect $frm_fileselect.ent_appendfile" ]
set btn_spotweldfile [button $frm_fileselect.btn_spotweldfile -text " ... " \
-command "::dyna::partupdate::onSelect $frm_fileselect.ent_spotweldfile" ]
set btn_outputfile [button $frm_fileselect.btn_outputfile -text " ... " \
-command "::dyna::partupdate::saveAs $frm_fileselect.ent_outputfile" ]
manual for entry widget
As for the last part, you don't really need them to be global. You can use widget get, for example:
set filename [.partupdate.frm_main.frm_fileselect.ent_basefile get]
Will give you the text in the Base File entry (of course, if you have the widget path in a variable, it'll be easier)
set filename [.partupdate.frm_main.frm_fileselect.ent_spotweldfile get]
Will give you the one for Spotweld File, and so on.
Sidenote: I would probably rename the variable in onSelect from label to entry.
I want to put a combobox over a frame of a tk notebook. I arrange the frame and the components using grid. When i place the combobox over the frame, the frame in the background disappears. What can be the reason for this? My code is as follows:
ttk::notebook .f.n -width 1600 -height 800
frame .f.n.f1
frame .f.n.f2
.n add .f.n.f1 -text "TabOne"
.n add .f.n.f2 -text "TabTwo"
grid .f.n -sticky news -row 0 -column 0
#Code to create a side menu
grid [frame .f.n.TabOne.m -width 200 -height 800] -sticky news -row 0 -column 0
grid [ttk::combobox .f.n.Tabone.m.d -values {"val 1" "val 2"}] -sticky news
To put a combobox within a tab's pane, you have to make it a child of the widget (usually a frame — and definitely so in your case — but not necessarily) that is the interior of the tab. Otherwise it is not inside, but rather just stacked on top.
The easiest way of getting this consistently right is to build widget names from variables that reference their parents. Idiomatically, you store the name returned by the widget construction function and then build the child names by simple concatenation, like this:
set nb [ttk::notebook .f.n -width 1600 -height 800]
set tab_one [frame $nb.f1]
set tab_two [frame $nb.f2]
$nb add $tab_one -text "TabOne"
$nb add $tab_two -text "TabTwo"
grid $nb -sticky news -row 0 -column 0
#Code to create a side menu
grid [frame $tab_one.m -width 200 -height 800] -sticky news -row 0 -column 0
grid [ttk::combobox $tab_one.m.d -values {"val 1" "val 2"}] -sticky news
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
I am developing a Tcl based ui. I have couple of buttons on my main window. With each button action, i wanted to show a widget in same tcl frame, and also it should be be overwritten with another widget when button 2 is clicked.
Any example link will be appreciated.
Here goes my code for complete widget.
####################################################################################
package require Tk
set model_type None
wm title . "Impetus interactive: MXL Library Validation Tool V1.0"
wm iconname . "LibValidation"
wm geometry . +150+250
##+######################################################
## Set the COLOR SCHEME for the WINDOW ---
## and background colors for its WIDGETS.
##+######################################################
# set Rpal255 200
# set Gpal255 200
# set Bpal255 255
##set Rpal255 210
##set Gpal255 210
##set Bpal255 210
##set hexPALcolor [format "#%02X%02X%02X" $Rpal255 $Gpal255 $Bpal255]
#tk_setPalette "$hexPALcolor"
## Set color background for some WIDGETS.
##set scaleBKGD "#f0f0f0"
# set radbuttBKGD "#c0c0c0"
# set chkbuttBKGD "#c0c0c0"
# set listboxBKGD "#f0f0f0"
set entryBKGD "#f0f0f0"
set textBKGD "#f0f0f0"
##Set (temporary) FONT-NAMES.
##
## We use a VARIABLE-WIDTH FONT for LABEL and BUTTON widgets.
##
## We use a FIXED-WIDTH FONT for TEXT widgets (to preserve
## alignment of columns in text), LISTBOXES (to preserve
## alignment of characters in lists), and ENTRY fields
## (to make it easy to position the text cursor at narrow
## characters like i, j, l, and the number 1).
##+##########################################################
font create fontTEMP_varwidth \
-family {comic sans ms} \
-size -14 \
-weight bold \
-slant roman
font create fontTEMP_SMALL_varwidth \
-family {comic sans ms} \
-size -12 \
-weight bold \
-slant roman
font create fontTEMP_fixedwidth \
-family {liberation mono} \
-size -14 \
-weight bold \
-slant roman
font create fontTEMP_SMALL_fixedwidth \
-family {liberation mono} \
-size -12 \
-weight bold \
-slant roman
##+###########################################################
## Set GEOMETRY PARAMETERS for the various widget definitions.
## (e.g. width and height of canvas, and padding for Buttons)
##+###########################################################
## CANVAS geom parms:
##set initCan1WidthPx 200
#set initCan1HeightPx 150
##set initCan2WidthPx 255
##set initCan2HeightPx 255
# set BDwidthPx_canvas 2
##set BDwidthPx_canvas 0
## LABEL geom parameters:
set PADXpx_label 0
set PADXpx2_label 1
set PADYpx_label 0
set PADYpx2_label 1
set BDwidthPx_label 2
## BUTTON geom parameters:
set PADXpx_button 0
set PADYpx_button 0
set BDwidthPx_button 2
set PADXpx2_button 2
set PADXpx3_button 3
set PADYpx2_button 2
set PADYpx3_button 3
set BDwidthPx2_button 2
set PADXpx4_button 1
set PADXpx5_button 1
set PADYpx4_button 1
set PADYpx5_button 1
## SCALE geom parameters:
##set BDwidthPx_scale 2
#set initScaleLengthPx 300
##set scaleWidthPx 10
## ENTRY geom parameters:
set BDwidthPx_entry 2
set BDwidthPx_entry2 2
set initImgfileEntryWidthChars 25
##+###################################################################
## DEFINE *ALL* THE FRAMES:
##
## Top-level : '.fRbuttons' '.fRfile' 'fRfile2' '.fRimages'
##
## Sub-frames: '.fRimages.fRcanvas1' '.fRimages.fRcanvas2'
##+###################################################################
## FOR TESTING: (to check frame sizes as window is resized)
set BDwidth_frame 2
set RELIEF_frame flat
set BDwidth_frame 0
set RELIEF_frame flat
frame .top -borderwidth 10
pack .top -side top -fill both
frame .fRbuttons -relief $RELIEF_frame -borderwidth $BDwidth_frame
frame .fRfile -relief $RELIEF_frame -borderwidth $BDwidth_frame
################################################################################
##image create photo img -file "maxL.gif"
canvas .top.myCanvas -background white -width 100 -height 50
pack .top.myCanvas -side top -anchor nw -fill none -padx 2 -pady 2
set myImage [image create photo]
$myImage read "/home/dshaikh/Library_Val/FF_0.99v_125/maxL.gif"
.top.myCanvas create image 55 30 -image $myImage
#####################################################################################
menu .mbar
. configure -menu .mbar
menu .mbar.fm -tearoff 0
.mbar add cascade -menu .mbar.fm -label FILE \
-underline 0
menu .mbar.hm -tearoff 0
.mbar add command -label HELP \
-underline 0 -command {popup_msgVarWithScroll .topHelp "$HELPtext"}
menu .mbar.fm.sb
.mbar.fm.sb add command -label List
.mbar.fm.sb add command -label Bookmarks
.mbar.fm.sb add command -label Mail
labelframe .top.ff -font fontTEMP_varwidth -text "Input and Run options" -padx 2 -pady 2 -bd 2
button .f -text "Inputs" -relief raised -command {take_inputs}
#pack .f -side left -ipadx 2 -ipady 2 -padx 3 -pady 3
button .v -text "Unit Level" -relief raised -command {Run_Unit_level}
##pack .v -side left -ipadx 2 -ipady 2 -padx 3 -pady 3
button .u -text "Interaction Level" -relief raised -command {Run_Interaction_level}
#pack .u -side left -ipadx 2 -ipady 2 -padx 3 -pady 3
button .l -text "Flow Level" -relief raised -command {Run_Flow_Level}
button .e -text "LogFile" -relief raised -command {show_logfile}
pack .f .v .u .l .e -in .top.ff -fill both -padx 2 -pady 2
pack .top.ff -side left -anchor nw -ipadx 4 -ipady 4 -expand y
#############################################################
########### Creating a logfile area ###################
frame .p
set sum [text .p.log -width 80 -height 10 -borderwidth 2 -background LightYellow -relief raised -setgrid true -borderwidth 6 -relief raised -setgrid true -yscrollcommand {.p.scroll set}]
scrollbar .p.scroll -command {.p.log yview}
pack .p.scroll -side right -fill y
pack .p.log -side right -fill both -expand true
pack .p -side right -fill both -expand true
Thanks
Dan
I have a problem with my display of multiple choice questions. I have a frame which shows the questions and choices above a text widget which shows if the chosen answer is correct. Yet I want to hide the text while the test is not finished.
It looks like that:
My procedures are following:
proc beginTest { number } {
startTest
.frq.txt configure -state normal
.frq.txt delete 1.0 end
set score 0
set save 0
set path Files/Tutorials/$::Tuto
set numbers { 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 }
for {set i 1} {$i<=10} {incr i} {
if { $::stop == 1 } {
set answer [tk_dialog .dialog "Quit test?" "If you quit the test now, your answers will be lost. Do you want to continue?" \
question 1 "Continue test" "Quit test"]
if {$answer == 0} {
continue
} else {
break
}
} else {
set ind [expr {int(rand()*[llength $numbers])} ]
incr score [displayQuestion $path [lindex $numbers $ind] $i 10]
set numbers [lreplace $numbers $ind $ind]
}
}
.frq.txt insert end "Your score: $score/10"
.frq.txt configure -state disabled
if {[info exist user]} {
if {[lindex $::testScores $number]== "Not Taken" || [lindex $::testScores $number] < $score} {
set ::testScores [lreplace $::testScores $number $number $score]
}
}
destroy .frq.fr2
}
The following procedure called at the first line of the previous one create and define the windows, frames, text zone, etc.
proc startTest {} {
destroy .fr
#window definition
toplevel .frq
wm title .frq "Test"
wm geometry .frq 740x670+0+0
.frq configure -bg $::bgColour
# title of section
label .frq.titl
.frq.titl configure -font "arial 20" -pady 10
grid .frq.titl -column 0 -row 0 -sticky swe
.frq.titl configure -background "White"
# define the main text zone
text .frq.txt -wrap word -yscroll {.frq.vscroll set} -highlightthickness 0
.frq.txt configure -background "White" ;#"slate gray" to debug
scrollbar .frq.vscroll -orient vertical -command {.frq.txt yview}
grid .frq.txt -column 0 -row 1 -sticky snwe
grid rowconfigure .frq 1 -weight 1
grid columnconfigure .frq 0 -weight 1
grid .frq.vscroll -column 1 -row 1 -sticky snwe
.frq.txt tag configure center -justify center
.frq.txt configure -font "times 12" -state disabled
.frq.vscroll configure -orient vertical -command {.frq.txt yview}
grid .frq.txt -column 0 -row 1 -sticky snwe
.frq.txt configure -state normal
.frq.txt delete 1.0 end
#text styles
.frq.txt tag configure Normal -font "times 12"
.frq.txt tag configure subTitle -font "times 14"
.frq.txt tag configure Titlec -font "times 16" -justify "center"
.frq.txt tag configure subTitlec -font "times 14" -justify "center"
.frq.txt tag configure subTitlecu -font "times 14" -justify "center" -underline on
.frq.txt tag configure Titlecu -font "times 16" -justify "center" -underline on
.frq.txt tag configure Title -font "times 16"
.frq.txt tag configure link -foreground blue -font "times 12"
.frq.txt tag configure right -foreground "forest green"
.frq.txt tag configure wrong -foreground red
.frq.txt tag configure enhance -background "light goldenrod"
.frq.txt tag configure rightenhance -background "light goldenrod" -foreground "forest green"
.frq.txt tag bind link <Enter> ".fr.txt configure -cursor hand1"
.frq.txt tag bind link <Leave> ".fr.txt configure -cursor arrow"
#questions frame
frame .frq.fr2 -background white
grid .frq.fr2 -row 1
label .frq.lbl -relief flat -font arial -text "Question 1 of 5"
grid .frq.lbl -row 0
text .frq.fr2.txt -relief flat -background white -font "times 13" -wrap word
grid .frq.fr2.txt -columnspan 2 -row 1
.frq.fr2.txt tag configure center -justify center
grid rowconfigure .frq 1 -weight 1
checkbutton .frq.fr2.cb1 -command "choose A" -cursor hand1
grid .frq.fr2.cb1 -column 0 -row 2
label .frq.fr2.lblA -background white -font "arial 12" -pady 3
bind .frq.fr2.lblA <ButtonRelease> "choose A; .frq.fr2.cb1 toggle"
grid .frq.fr2.lblA -column 1 -row 2 -sticky w
checkbutton .frq.fr2.cb2 -command "choose B" -cursor hand1
grid .frq.fr2.cb2 -column 0 -row 3
label .frq.fr2.lblB -background white -font "arial 12" -pady 3
bind .frq.fr2.lblB <ButtonRelease> "choose B; .frq.fr2.cb2 toggle"
grid .frq.fr2.lblB -column 1 -row 3 -sticky w
checkbutton .frq.fr2.cb3 -command "choose C" -cursor hand1
grid .frq.fr2.cb3 -column 0 -row 4
label .frq.fr2.lblC -background white -font "arial 12" -pady 3
bind .frq.fr2.lblC <ButtonRelease> "choose C; .frq.fr2.cb3 toggle"
grid .frq.fr2.lblC -column 1 -row 4 -sticky w
checkbutton .frq.fr2.cb4 -command "choose D" -cursor hand1
grid .frq.fr2.cb4 -column 0 -row 5
label .frq.fr2.lblD -background white -font "arial 12" -pady 3
bind .frq.fr2.lblD <ButtonRelease> "choose D; .frq.fr2.cb4 toggle"
grid .frq.fr2.lblD -column 1 -row 5 -sticky w
frame .frq.bar
grid .frq.bar -row 2
button .frq.bar.next -text "Next question >>" -state disabled -pady 5 -borderwidth 0 -command "set ::goOn 1"
pack .frq.bar.next -padx 5 -pady 5 -side right -fill none
button .frq.bar.dp -text "Open drawing pad" -pady 5 -borderwidth 0 -command notepad
pack .frq.bar.dp -padx 5 -pady 5 -side right -fill none
button .frq.bar.calc -text "Open calculator" -pady 5 -borderwidth 0 -command calculator
pack .frq.bar.calc -padx 5 -pady 5 -side right -fill none
button .frq.bar.quit -text "Quit test" -pady 5 -borderwidth 0 -command "set ::stop 1; set ::goOn 1"
pack .frq.bar.quit -padx 5 -pady 5 -side right -fill none
}
And finally, the procedure which display the question:
proc displayQuestion {path filename ind maxind} {
set fd [open $path/$filename r]
set questionFile [split [read $fd] "\n"]
set ::goOn 0
set answers [list]
set imgFlag 0
set fd [open $path/answers/$filename r]
set goodAnswer [read $fd]
close $fd
.frq.lbl configure -text "Question $ind of $maxind"
.frq.fr2.txt configure -state normal
.frq.fr2.txt delete 1.0 end
.frq.fr2.txt insert end \n
foreach line $questionFile {
if {$line == "<image>"} {
set imgFlag 1
continue
}
if {$imgFlag == 1} {
set imgFlag 0
.frq.fr2.txt insert end " " center
.frq.fr2.txt image create end -image [image create photo -file [file join "$path/$line"]]
continue
}
if {[string match A)* $line]} {
.frq.fr2.lblA configure -text $line
lappend answers $line
continue
}
if {[string match B)* $line]} {
.frq.fr2.lblB configure -text $line
lappend answers $line
continue
}
if {[string match C)* $line]} {
.frq.fr2.lblC configure -text $line
lappend answers $line
continue
}
if {[string match D)* $line]} {
.frq.fr2.lblD configure -text $line
lappend answers $line
continue
}
.frq.fr2.txt insert end $line\n center
}
.frq.fr2.txt configure -state disabled
.frq.txt insert end [lindex $questionFile 0]\n
.frq.fr2.cb1 deselect
.frq.fr2.cb2 deselect
.frq.fr2.cb3 deselect
.frq.fr2.cb4 deselect
.frq.bar.next configure -state disabled
set ::choice 0
vwait ::goOn
switch $::choice {
A { set ind 0 }
B { set ind 1 }
C { set ind 2 }
default { set ind 3 }
}
if { $::choice == $goodAnswer} {
.frq.txt insert end "Correct answer: [lindex $answers $ind]\n\n" right
return 1
} else {
switch $goodAnswer {
A { set i 0 }
B { set i 1 }
C { set i 2 }
default { set i 3 }
}
.frq.txt insert end "Wrong answer: [lindex $answers $ind]\n\tYou should have pick [lindex $answers $i]\n\n" wrong
return 0
}
}
The widget concerned is ".frq.txt".
I have tried "pack" and "pack forget", even tried a way to use the option "-elide" but I am out of ideas.
Could you help me?
Since you're using grid to manage the contents of the .frq widget, including the .frq.txt widget, you need to use grid remove or grid forget to make the widget vanish. The difference between the two? With grid remove, the sizing metadata for the cell is remembered.
pack forget is for undoing a pack (strictly, a pack configure, though the simple pack pretends you said pack configure).