GRIDPLUS2 is a grid-based GUI builder system which builds on, simplifies and extends the existing Tk grid manager.
GRIDPLUS layouts are defined as a hierarchy of grids. A layout is represented as a a sequence of rows delimited by the newline character, where each row is list of cells, with each cell containing zero, one, or two items (see patch below to make GRIDPLUS properly handle newline characters that are not row delimiters). Each cell usually contains a text label and some other widget such as an entry, but may also contain a widget and a label, two labels, two widgets, or nothing. GRIDPLUS grids can also be stretched to neatly fill the cells in which they are positioned. While the GRIDPLUS grid can be used "native", GRIDPLUS commands/options exist to create grids of Buttons, Checkbuttons, Date-selectors, Dropdowns (comboboxes), Entries, Links, Menubuttons and Radiobuttons. All places where text can be displayed make use of the Tcl message catalog facility.
GRIDPLUS is much more than an alternative to the grid geometry manager, it provides most, if not all, of the facilities required to build complete screens/windows. In many cases, using GRIDPLUS to code an application GUI will be quicker than using a "Visual" screen design tool. Although aimed at producing data entry/update/display form screens for database applications, it may be useful for other tasks.
GRIDPLUS also includes the following features:-
Here Are Some Screens Created Using GRIDPLUS2:
Jeff Smith 2020-08- : Below is an online demo using CloudTk. This demo runs GridPlus2 example 6 in an Alpine Linux Docker Container. It is a 29.3MB image which is made up of Alpine Linux + tclkit + gridplus.kit + + libx11 + libxft + fontconfig + ttf-linux-libertine. It is run under a user account in the Container. The Container is restrictive with permissions for "Other" removed for "execute" and "read" for certain directories.
adavis 2015-11-29: GRIDPLUS 2.11 has been released and is available from:-
http://www.satisoft.com/tcltk/gridplus2
ENHANCEMENTS:
-- I hope this means "-maintainsort"? Larry Smith - adavis 2017-11-15: it does indeed - Corrected!!!
CHANGES:
BUG FIXES:
adavis 2013-07-03: GRIDPLUS 2.10 has been released and is available from:-
ENHANCEMENTS:
CHANGES:
BUG FIXES:
adavis 2012-07-12: GRIDPLUS 2.9 has been released and is available from:-
BUG FIXES:
adavis 2012-04-04: GRIDPLUS 2.8 has been released and is available from:-
http://www.satisoft.com/tcltk/gridplus2
ENHANCEMENTS:
CHANGES
BUG FIXES:
adavis 2012-02-27: GRIDPLUS 2.7 has been released and is available from:-
http://www.satisoft.com/tcltk/gridplus2
ENHANCEMENTS:
BUG FIXES:
adavis (29th February 2012): I have corrected an error in the documentation example for setting default date values. Both the website and the documentation download have been updated.
adavis 2010-10-25: GRIDPLUS 2.6 has been released and is available from:-
http://www.satisoft.com/tcltk/gridplus2
ENHANCEMENTS:
BUG FIXES:
adavis 2009-11-11: GRIDPLUS 2.5 has been released and is available from:-
http://www.satisoft.com/tcltk/gridplus2
ENHANCEMENTS:
CHANGES:
BUG FIXES:
EXAMPLES:
Here are examples of the the calendar and date selector widgets:-
adavis 2009-09-06: GRIDPLUS 2.4 has been released and is available from:-
http://www.satisoft.com/tcltk/gridplus2
ENHANCEMENTS:
CHANGES:
BUG FIXES:
adavis 2008-05-27: GRIDPLUS 2.3 has been released.
ENHANCEMENTS:
CHANGES:
BUG FIXES:
adavis 2007-07-26: GRIDPLUS 2.2 has been released.
ENHANCEMENTS:
CHANGES:
BUG FIXES:
adavis 2007-02-28: GRIDPLUS 2.1 has been released.
ENHANCEMENTS:
CHANGES:
BUG FIXES:
adavis 2006-10-10: GRIDPLUS 2.0 has been released.
GRIDPLUS2 is a Tile based version of GRIDPLUS. Whereas GRIDPLUS Version 1 has features to control widget style as well as window layout - GRIDPLUS2 assumes that the Tile style engine facilities will be used to control widget styles. GRIDPLUS2 instead provides significantly enhanced screen layout/design functionality which can further reduce the coding required to create the desired window/widget layout.
One of the main enhancements is the new GRIDPLUS2 Widget Grid [L2 ]. With GRIDPLUS1 it was only possible to create one type of widget in a particular Grid (Buttons, checkbuttons, entries etc.). In order to mix widgets in a Grid it was necessary to create additional Grids for the other widget types and then "embed" them into a parent Grid. The new widget Grid allows all of the GRIDPLUS widget types to be mixed in the same Grid.
There are many more changes and enhancements - See the GRIDPLUS2 Readme [L3 ] for further details.
PYK 2021-07-29:
The current version, 2.11, and and prior versions fail to correctly handle newlines in values used in layouts.
::gridplus::gpWidget splits a layout using the following line:
foreach row [split $options(layout) "\n"] { set columnCount 0 foreach column $row {
Changing that line to the following remedies the issue:
set row {} foreach rowpart [split $options(layout) \n] { if {[string length $row]} { append row \n } append row $rowpart if {![info complete $row\n]} continue set columnCount 0
AET 2007-03-01: As usual, Adrian, A top-notch offering. A well thought out utility, and documentation that is exemplary. Thanks very much. I am still struggling to put together a database using GRIDPLUS, but will be porting it to GRIDPLUS 2 as soon as I can.
Ro 2007-03-03: Fantastic project! Currently, resizable toplevels are not supported, but you can do it with wm resizable .mytoplevel 1 1 if you really need to. I don't think it's necessary for these kinds of apps (database + well behaved windows apps) but it's interesting to know. Thanks Adrian for this superb package.
WHD: The GRIDPLUS2 home page says that it's only been tested on Windows XP. Has anyone used it successfully on Linux?
Effe: I didn't check each and every detail, but GRIDPLUS 2.4 works well on Linux (tested with ActiveTcl 8.6 on fluxflux Linux).
MHo 2009-11-10:
adavis (11th November 2009): I'm assuming that "C:/Programme/Tcl/lib/tcl8.5" is your Tcl library path (info library) - If this is the case, have you installed/copied the "TkIcons" file to this location? If this isn't the problem can you give me an example? MHo No I forgot this...
MHo 2009-11-14:
This works:
gpset .mytree2 { /a /a/b /a/b/c }
This one does not work:
gpset .mytree2 { /a/b /a/b/c }
Does this mean that trees always have to begin with the root element?
adavis 2009-11-16: More generally, it is required that the parent for a node be created explicitly, unless the parent is the root.
MHo 2009-12-05: More questions:
adavis 2009-12-07:
MHo 2009-12-07:
adavis 2009-12-08 PYK 2021-07-30: Currently that is true.
However - Adding a...
single/space { bind $options(name).tree <Button-1> [list after 1 [ list ::gridplus::gpTreeSelect $options(name) .$window $options(-validate) [list $command]]] bind $options(name).tree <space> [ list after 1 [list ::gridplus::gpTreeSelect $options(name) .$window $options(-validate) [list $command]]] }
...case to the $options(-action) switch in ::gridplus::gpTree will add an option (-action single/space) to implement this functionality. I will include this modification in the next GRIDPLUS2 release.
nb 2010-09-05:
Really good stuff Adrian I've been putting off doing a complex db/form app for awhile now due to "packing hell" that comes along with these forms.I'm blowing this app off like nothing with your package, bravo... If I'm not careful, I'm risking finishing it too early ;-)
OTOH, Maybe I'm missing something obvious, I went through the docs but did not see anywhere a way to set the state of individual widgets (as opposed to the whole grid), e.g. set an entry to disabled.
regards
adavis 2010-02-05: In GRIDPLUS2 there are a couple of ways to achieve this - depending on what you are trying to do.
If you simply want to set the state of an individual widget when it is created you can use the "<" (create as disabled) or ">" (create as enabled) widget option. The GRIDPLUS2 documentation Example 1 uses this for the "ID" field.
You can also use the Groups facility to enable/disable named groups of widgets.
nb 2010-05-08:
I've also found the following very helpful which is referenced in the docs
http://www.satisoft.com/tcltk/gridplus2/reference.html#modes
"It maybe neccessary to reference Tablelist, Text or Tree widgets directly in order to get information about the widget -or- to set an attribute not available through GRIDPLUS."
GRIDPLUS uses a simple widget naming scheme which makes this easy.
Examples assuming a GRIDPLUS widget called ".mywidget" of each of the above types:-
Tablelist: .mywidget.tablelist
Text: .mywidget.text
Tree: .mywidget.tree
For example: To get the number of rows in a tablelist:-
.mywidget.tablelist size
Figure I'd save someone sometime ;-)
milarepa 2010-10-17 07:54:41:
Hi, I am testing gridplus 2.5 on Linux. I am trying to run the "Container Example 1" GRIDPLUS2 Container without success. I tested it with both tcl/tk 8.5.9 and 8.6b1 versions and both Ubuntu 10.10 and Archlinux and is not working properly. It does only works on Windows XP. Please any help or thoughts. This is the error log:
invalid command name ".win2" invalid command name ".win2" while executing "$options(name) configure -menu {}" (procedure "gpClear" line 24) invoked from within "gpClear" (procedure "::gridplus::gridplus" line 116) invoked from within "::gridplus::gridplus clear .win2" ("eval" body line 1) invoked from within "eval $gpInfo($options(-in):wcmd)" (procedure "gpWindow" line 29) invoked from within "gpWindow" (procedure "gridplus" line 138) invoked from within "gridplus window .win1 -in .mycont" (procedure "display_win1" line 3) invoked from within "display_win1" invoked from within ".select,win1 invoke " invoked from within ".select,win1 instate {pressed !disabled} { .select,win1 state !pressed; .select,win1 invoke } " (command bound to event)
THANK YOU
adavis 2010-10-19: I now have a fix for this (still testing). I intend to upload to the website within the next week. If you need it urgently please email me.
milarepa 2010-10-19 18:11:47:
Thank you Adrian for your quick reply and for trying to solve the issue. I can wait for the fix. And thank you for your work on gridplus, I love this package, it is so easy to build applications and I always find a way to arrange the widgets the way I want it.
adavis 2010-10-25: This problem is fixed in GRIDPLUS 2.6.
nb 2010-11-29: Hi all,
Was wondering if there's any preferred way to read/write to an sqlite db from a gridplus application interface, outside of looping over the "" array where the widget values are stored.
Currently trying to use nstcl w/ sqlite backend?
Any hints would be welcome
regards
milarepa 2010-11-29 10:30:05:
Currently I am developing an application with gridplus and sqlite as backend. I don't use any database layer, just the standard sqlite3 library for tcl.
For example, let say you are developing an application for a school and you want to load a dropdown widget with a list of lessons:
gpset .form,dropdown_lesson [db eval "SELECT lesson_name FROM lesson"]
To save it:
db eval "INSERT INTO new_lesson (lesson_name) VALUES ('[.form,dropdown_lesson get]'"
I do not quite understand what you mean when you said "outside of looping over the array". If you could be more specific.
adavis 2010-11-29: You can also use gpmap to set multiple interface items with a single command - See Mapping of a SQLite resul . All GRIDPLUS interface items have their value in the null named array. If you have an item called ".form,dropdown_lesson" its value can be referenced as: $(.form,dropdown_lesson)
nb 2011-01-27: Thanks for the advice above, I've gotten my simple items working ok. While this is probably not gridplus specific, the difficulties I'm facing now is a strategy for storing the multiple items selected in a treeview. While storing the selected values of a tree in a single field is straightforward, e.g just store "/u1 /u1/3 /u1/6 /u1/8 /u2 /u2/2 /u2/4 /u2/6 /u2/18 /u3/2 /u3/3 /u6" /u2", this approach does not facilitate future queries, like what "find all the /u1's"....
MHo 2011-05-29: I miss scrolled windows as a gridplus widget type. 2nd question: I noticed that, when doing a gridplus window operation to define a new toplevel window, for a short time, a blank windows is appearing just before the final layout is configured and the window is packed. Is there a way to avoid the flicker? The code (fragment) is as follows:
gridplus window .main -modal 1 -topmost 1 -windowcommand main:buttons,exit wm withdraw .main eval [format {gridplus widget .main.userWidget -title $fTitle %s} $args] gridplus button .main.buttons { {Weiter .ok} {Abbruch .exit} } gridplus layout .main.layout -wtitle $wTitle { .main.userWidget .main.buttons:e } bind .main <Escape> [list main:buttons,exit] pack .main.layout
adavis 2011-05-31: I don't have a complete cure for this (for the moment at least) - but you could try the following...
gridplus window .main -modal 1 -topmost 1 -windowcommand main:buttons,exit -overrideredirect 1 wm withdraw .main wm overrideredirect .main 0
...the flicker should be much less noticable.
MHo: Thanks, that works. Another remark: As you may guess from the code fragment above, I'll try to encapsulate gridplus in a way that one could quickly define a simple dialog without caring about the tricky details. The call from the shelling application's perspective than looks something like:
if {[gpDialog1 TestFensterTitel TestFrameTitel { {&e "Benutzer" .benutzer} {&e "Neues Kennwort" .passwort +} {"Optionen" &c .unlock} {} }] == 1} { msgBox ">>>$gpDialog1bValues<<<" }
which is pretty simple, I think. The only thing which isn't possible this way is using constructs which needs explicitely coded callbacks. This was the reason that I first choosed tepam as part of my program. With tepam, one could build complex dialogs without using callbacks. As I discovered several things which does not work as I expected and the dialog layout doesn't fullfill my needs though, I switched to gridplus2 again...
adavis 2011-05-31: Can you give me an example of how you would like it to behave?
adavis 2011-06-01: Something you may find useful - maybe if developing a dialog builder which allows users to create/customise their own dialogs/screens - is to use GRIDPLUS defined widgets.
This is best explained using a simple example:-
#-------------------------------# # First, define some widgets... # #-------------------------------# gridplus define { userid {&e "User ID" .userid 25 +} password {&e "Password" .password 25 *} ok-cancel {|&b "OK" .ok |> "Cancel" .cancel} } #----------------------------------# # Then, use the defined widgets... # #----------------------------------# gridplus widget .dialog -wtitle Login { @userid @password = @ok-cancel } pack .dialog #-------------------------------------# # ...to create a simple login dialog. # #-------------------------------------#
MHo Thanks again, later I will give a complete example, which illustrates better, what I want. Here's another questions:
More questions:
% clock format [clock seconds] -format %A Friday; # wrong % clock format [clock seconds] -format %A -locale current Freitag; # correct % clock format [clock seconds] -format %A -locale system Freitag; # correct %
adavis 2011-06-12: I now have a test version of GRIDPLUS2 which allows the locale to be explicitly set -and- has a fix for the calendar/topmost problem. I am hoping you would be able to test this for me - If you would like to do this, please email me.
The calendar does (for the moment) only handle mouse clicks. I will add cursor key control in a future release.
I will add an entry with "..." button file/directory selector in a future release. In the meatime, there is a special optionset which helps in creating this kind feature (See: http://www.satisoft.com/tcltk/gridplus2/embedded-grid.html#example3 )
Default values cannot currently be set as the value is initialised to null. Do you have an application where it is important to set the value of an entry before it is created? I guess I could add a gpdefault command? MHo: Yes, or an option similar to -variables 0 which say no clear at init.
Can you tell me what page the "<tab>" mistake is on? MHo I didn't find it again by myself. Maybe I stared at the screen too long...
ARR 2012-02-13: I've started to use this great package in my apps and I like to help, fix some bugs, add functions... Is Gridplus2 still maintained? Is there a newer Version than 2.6 from 23/10/2010?
adavis 2012-02-14: GRIDPLUS2 is still being maintained/enhanced. I have recently finished the coding for version 2.7 and I am currently in the process of updating the documentation. If you have any enhancement requests or bugs to report please email me at [email protected].
ARR 2012-02-15: Dear Adrian, thanks for quick response, here are some bugs and enhancements:
Bugs: - I think internal group data is not completely deleted when doing "gridplus clear …“ - When using an embedded grid and a -group name I get an error when trying to disable the group widgets: "gridplus::gridplus set -group view_dummy -state disabled" -> Error: unknown option "-state" - An embedded grid takes some more left and right space than a normal grid (some pixels only!) - I cannot get locale days in german because of the clock behaviour in 8.5 as already mentioned by [MHo] Enhancements: - a spinbox widget - a time selection widget i.e. a clock with moveable hands (like iWidgets) - I would like to call a given proc with a parameter from a button like this: "{&b .name=para :image ~:::namespace::myproc}"
adavis 2012-02-16: I have sent you a copy of GRIDPLUS 2.7 for evaluation. Please see below for my comments:-
- I think internal group data is not completely deleted when doing "gridplus clear …“
Can you give me a simple example to illustrate this?
ARR: I'm updating my running app by resourcing tcl files at runtime. If I delete a gp widget it is still in the group but it's state cannot be changed. Of course the problem will never happen if I restart the app. I think 'gridplus clear ..' should erase these widets from the group's names list. I will make an example.
- When using an embedded grid and a -group name I get an error when trying to disable the group widgets - ([ARR] -> solved! see below...)
Thanks for pointing this out - It is something that I should make clear in the documentation...
...Embedded grids do not inherit options from the parent grid. I had considered this, but I found too many occasions (for my purposes) where this was not the desired behaviour.
To use the group facility within embedded grids there are two options:-
1) Specify the group for each widget item in the embedded grid...
gridplus widget .mygrid { {"My Label" || |&e "Entry 1" .entry1 %mygroup |> "Entry 2" .entry2 %mygroup |> "Entry 3" .entry3 %mygroup} } pack .mygrid gridplus set -group mygroup -state disabled
2) Use a style/optionset for the embedded grid...
gridplus optionset myoptions { -group mygroup -style {} } gridplus widget .mygrid { {"My Label" || |#myoptions |&e "Entry 1" .entry1 |> "Entry 2" .entry2 |> "Entry 3" .entry3} } pack .mygrid gridplus set -group mygroup -state disabled
Again, this is something that needs clarification in the documentation. The "|#" widget option can set a style to use for an embedded grid. Additionally, if there is an optionset with the same name, this is also applied. What I don't think I've made clear is that, if you wish to use "|#" to specify an optionset only (where there is not style with the same name) it is necessary to explicitly specify a style option in the optionset - Otherwise you will get a "layout not found" error.
In GIRDPLUS 2.7 I have added a Gridplus.optionsetDefaultStyle option database option. To maintain backward compatibility the default for this is "0" (false).
When set to true...
option add *Gridplus.optionsetDefaultStyle 1
..."-style {}" is added automatically to each optionset if "-style" is not explictly specified.
- An embedded grid takes some more left and right space than a normal grid (some pixels only!)
I will investigate this.
- I cannot get locale days in german because of the clock behaviour in 8.5
I have added an explict -locale option in GRIDPLUS 2.7 - (ARR solved and tested in V2.7)
- a spinbox widget
You can, for the moment, use the normal tk/ttk spinbox widget as demonstrated in: http://www.satisoft.com/tcltk/gridplus2/groups.html - (ARR works fine!)
- a time selection widget i.e. a clock with moveable hands (like iWidgets)
I'm sorry - I don't have any plans to do this at the moment. - (ARR I'm currently working on a clock widget like this. I'll send it when it's running if you like.)
- I would like to call a given proc with a parameter from a button
Would something like the following suit your purpose? - (ARR Oh yes that works. Somehow I didn't get it before...)
proc myproc {parameter} { puts $parameter } gridplus button .mygrid { {"Press Me" .mybutton "~myproc myparameter"} } pack .mygrid
MHo 2012-02-24: I've problems to line up colums properly. Here's a fragment of a wrapper I use to encapsulated part of the gridplus functionality, but I think the wrapper is not relevant here:
{:fileopen16 "^Quelle:w" |: } { |: "Datei(en)/Ordner:" |> &e .source 30 |: &b "Datei(en)..." .button=chooseFile |: &b "Ordner..." .button=chooseDir} {} = {:devpc16 "^Ziel:w" |: } { |: "Maschine(n):" |> &e .dest 30 |: &b "AusGruppe..." .button=chooseADGrp |: &b "QueryFarm..." .button=getFarm} { |: "Zielpfad:" |> &e .dPath 30 |: ^ |: ^ } {} = {:apptools16 "^Optionen:w" |: } { |: &c .testOnly "Testmodus"} { |: &c .overWrite "Vorhandene Zieldateien überschreiben" +}
The lines with Maschinen(n): and Zielpfad: near the beginning do not show as I want.... Unfortunally, I couldn't upload a screenshot at the moment.
adavis 2012-02-24: Unfortunately there isn't (currently) a really neat way to do exactly what I think you want. This will require an enchancement. I'll have a look tomorrow to see if it will be simple enough to incorporate in (the very soon to be released) GRIDPLUS 2.7. In the meantime something like the following may do:-
gridplus optionset x { -cfmt {0 10} -style {} } gridplus widget .test { {:fileopen16 "^Quelle" |>} {|: |#x &e "Datei(en)/Ordner:" .source 30 |> &b "Datei(en)..." .button=chooseFile |: &b "Ordner..." .button=chooseDir} {} = {:devpc16 "^Ziel" |>} {|: |#x &e "Maschine(n):" .dest 30 |> &b "AusGruppe..." .button=chooseADGrp |: &b "QueryFarm..." .button=getFarm} {|: |#x &e "Zielpfad:" .dPath 30 |>} {} = {:apptools16 "^Optionen" |>} {|: &c .testOnly "Testmodus" |>} {|: &c .overWrite "Vorhandene Zieldateien überschreiben" + |>} } pack .test
MHo: Thank you for your fast response and the great tool! Here's a screenshot, produced from the minimal modified code shown first:
(...removed dead-link...)
One alternative could be to use a separate {block} (grid) for each cell like this:
{:fileopen16 "^Quelle:w" |: } { |: "Datei(en)/Ordner:" |> &e .source 30 } {&b "Datei(en)..." .button=chooseFile |: &b "Ordner..." .button=chooseDir} {} = - - - - {} {:devpc16 "^Ziel:w" |: } { |: "Maschine(n):" |> &e .dest 30 } {&b "AusGruppe..." .button=chooseADGrp |: &b "QueryFarm..." .button=getFarm} { |: "Zielpfad:" |> &e .dPath 30 } {} = - - - - {} {:apptools16 "^Optionen:w" |: } { |: &c .testOnly "Testmodus"} { |: &c .overWrite "Vorhandene Zieldateien überschreiben" +}
But then, the separation lines to not look like they should (specifying = = = = = don't work, either):
(...removed dead link...)
I should mention that, because of the special environment (wrapper/encapsulation, single call to construct and handle the "map" like with tepam) I could only use "inline" constructs like &c, &e, &b etc., explizit commands like gridplus line are currently not available (with the exception of a variant of gpset). Maybe publishing gridplus define could help here, as you mention earlier. Here's an simple example of how the whole thing could look (part of a password change dialogue):
if {[gpDialog1 dlg1 {Kennwort zurücksetzen} [list -taborder row] { {&e "Benutzer :e" .benutzer 20 +} {&e "Neues Kennwort :e" .passwort 20} {=} {&c .mustchg "Änderung bei 1.Anmeldung erzwingen :w" +} }] == 1} { array set myVals $dlg1_Val } else { return } # : # : # now we can use $myVals(benutzer), $myVals(passwort), etc. # :
where the code for gpDialog1 is a "black box" within my program... (not too large, but to many lines to show here ;-). The "body" of gpDialog1 (that is, the content of the last arg) are the args for a gridplus widget command!
Meanwhile I've adapted your workaround. Don't exactly now why, but it works perfect!!!
adavis 2012-02-25: I've enhanced the GRIDPLUS 2.7 grid command so that it is possible to specify the width of a label. Using this option the following code will give the same result as my previous solution without the need to use an optionset:-
gridplus widget .test { {:fileopen16 "^Quelle" |>} {|: &e "Datei(en)/Ordner:10" .source 30 |> &b "Datei(en)..." .button=chooseFile |: &b "Ordner..." .button=chooseDir} {} = {:devpc16 "^Ziel" |>} {|: &e "Maschine(n):10" .dest 30 |> &b "AusGruppe..." .button=chooseADGrp |: &b "QueryFarm..." .button=getFarm} {|: &e "Zielpfad:10" .dPath 30 |>} {} = {:apptools16 "^Optionen" |>} {|: &c .testOnly "Testmodus" |>} {|: &c .overWrite "Vorhandene Zieldateien überschreiben" + |>} {} } pack .test
In this example you can see that the label "suffix" can now specify a width in characters in addition to a sticky indicator. If both are to be specified the sticky indicator must come before the width.
If you would like a pre-release copy of GRIDPLUS 2.7 to try this please email me.
MHo Thanks again. Another question:
How can I define an editable dropdown combox with default list entries using the {&d ....} syntax? Using gridplus dropdown .name {...}, everything works...
adavis 2012-02-26: You seem to have discovered a minor inconsistency with the dropdown. I'm not going to change this in 2.7 as it is possible that it may break existing code. I'll need to think carefully about this. In the meantime you can get an editable dropdown using the "&d" syntax by explicitly setting the state of the widget by using the ">" option. For example:-
{&d "Dropdown One" .dropdown1 {+"Option one" "Option two" "Option three"} >}
Mho: It works now. Thanks again. And how to set the active Item of a dropdown widget? My dialoge restores the last settings if called again, but do I have to re-order the list with the combobox items, or is there another way?
adavis 2012-02-26: When setting the value of the dropdown item as it is created it will set to the first item in the list. You can also use gpset to set any value you require.
MHo: Me again... (03rd March 2012): it seems that setting a value for a checkbox wich defaults to the on state via + via gpdefault is toggling instead of setting... That means, gpdefault .xyz 1 switches a checkbox off.
adavis 2012-03-05: This is working as designed. gpdefault sets a default value - The + option selects/invokes the widget. As the value is set before the select, using both together does result in the behaviour you describe. Can you give me an example of what you are trying to achieve?
MHo: The dialog saves it's state for later recall. So, regardless how the default state is, this last state should be restored. For the very first default (before the 1st call), the setting is determined via the "+" flag in the &b-clause. Then, the user either leaves this default or switches it to off. The actual value is then saved.
adavis: 2012-03-07: The simplest way to save the values of GRIDPLUS items and then to restore them is to use array get and array set.
Something like...
set mydata [array get {}]
...will save the window/dialog data into "mydata" - then...
array set {} $mydata
...will restore the values.
Is this solution useful?
MHo: Hm... Don't remember the details, but there where some reasons for gpdefault (maybe we can read somewhere on this page?). I think setting {} before defining the dialog has no effect because it's resetted or so...
adavis 2012-03-09: {} does need to be set after defining the dialog.
To get the behaviour I think you require - Change...
if {$select} { $widgetName invoke }
...In the "Create checkbutton" section of ::gridplus::gpWidget to...
if {$select} { set ($widgetName) 0 $widgetName invoke }
I don't think this is likely to break any existing code. If not, I will incorporate this into the next release.
MHo: Hm, I have to include a little (or more) extra logic, as the code I'm constructing the dialog with does not neccessarily know at every place, what type of widget it's constructing...., say:
if {type_of_widget is checkbox} { if {save_value} { widget invoke } }
But that's not enough. Since the default could be "on", when the saved value instead is "off", the visible value remains "on"...
MHo: Meanwhile, I reorderd my code. Now, all values are set after the dialoge is constructed, via gpset and gpselect; no more gpdefault. So, the "checkbox problem" is gone. But I hit other problems, the biggest of what is: I cannot restore the current "selection" of a set of radiobuttons. The radiobutton window is of type TLabelframe and contains many other windows of type TFrame... I cannot find the widgets of type TRadiobutton, so I cannot do a widgetname invoke to select the right radiobutton...
Ideally, gpselect should be able, given the last selected value of a radiobutton set or of a combobox, to "activate" the right value.
adavis 2012-03-11: gpset can be used to set the value of any GRIDPLUS item including radiobuttons and dropdown/comboboxes. gpselect is only used the select tree nodes, tablelist rows and calendar dates.
I have, however, just discovered a bug such that: If gpset is called immediately after a window is created/updated it is possible that the gpset is executed before the window update is complete. In this case the radiobutton may not be set correctly. I will release a bug fix soon - But, in the meantime, calling update idletasks before the gpset should resolve this problem. For example:-
gridplus widget .mydialog -wtitle Dialog { {&e "Entry" .myentry} {&c "Checkbutton" .mycheck} {&r "Radiobutton 1" . +radio1 *radiogroup} {&r "Radiobutton 2" . -radio2 *radiogroup} {&d "Dropdown" .mydrop {+"Option One" "Option Two" "Option Three"}} } pack .mydialog update idletasks gpset { .mydialog,myentry "Test String" .mydialog,mycheck 1 .mydialog,mydrop "Option Two" .mydialog,radiogroup radio2 }
MHo Yes, experimenting with a demo prog and reading your help over again, I just discovered the same. I put an update idletasks before the relevant code, and now it works as expected.... I came about this when I intersperse the code with tk_messageBoxes, and when they are there, everything worked as expected, so it seems like some window update issue...
Just went back here to remove my last question and leave some remarks, but I was too slow (or, better: you were too fast!)...;-) Thanks!
MHo 2012-03-14:
adavis 2012-03-15:
* It seems that using -title title for a widget automatically forces the -relief value to theme?
Yes that is the case. For frames with a label/title it seems best to leave it up to the theme to set the style for the border.
* Using -relief theme alone (without a title) "interrupts" the border where otherwise the title would be?
This is the result of, what I believe to be, a long standing bug in ttk::labelframe. I have noticed that this also still seems to be the case in Tcl 8.6. I have developed a workaround which works on XP (Themes: winnative, clam, alt, default, classic, and xpnative). I may give up on waiting for the bug fix and implement the workaround...
* Keyboard Shortcuts in Buttons would be great (So one can press Alt+O for Ok, or Alt+C for cancel).
I'll consider this for a future release.
MHo Another question:
adavis 2012-03-17: I have just added this option (and the labelframe work-around) to GRIDPLUS 2.8 - To be released shortly. If you would like a "preview" copy of 2.8 please email me.
milarepa 2012-06-23 17:48:44:
I am trying to migrate my software from version 2.6 to 2.8, however is not displaying correctly the GUI on 2.8 version of gridplus, just a small square on the top right hand corner of the screen.
Here is my source code:
package require Tk package require gridplus namespace import gridplus::* set c 0;set row 0; set inTime 0; set nearTime 0; set pastTime 0 set cmbName ""; set cmbWard "" option add *Gridplus.linkColor /blue option add *Gridplus.icon right1wbw option add *Gridplus.linkStyle 10/10 option add *Gridplus.labelStyle 10/10 ttk::setTheme clam ttk::style configure title.TLabel -font {"Tahoma" 16} ; # -foreground white -background dodgerblue ttk::style configure TLabel -font {"Tahoma" 10 bold} ttk::style configure TButton -font {"Tahoma" 10 bold} #=======================================================================# # WINDOW SETTINGS # #=======================================================================# wm title . "TrakPil" bind . <Escape> {exit} wm geometry . +0+0 #=======================================================================# # INCLUDE SOURCES # #=======================================================================# source "./Menu.tcl" source "./FormRegistration.tcl" #=======================================================================# # CONTAINERS CONFIGURATION # #=======================================================================# gridplus container .ctrMenu -height 600 -width 150 -relief groove -sticky new gridplus container .ctrForm -height 600 -width 700 -relief groove -sticky new gridplus container .ctrTop -height 50 -width 860 -relief ridge -sticky new gridplus container .ctrBtm -height 65 -width 860 -relief raised -sticky new #=======================================================================# # TOP BAR (TITLE) # #=======================================================================# if {! [gridplus window .top -in .ctrTop]} {return} ttk::label .top.lblTitle -text "TRAKPIL v0.4 - PRESCRIPTION TRACKER SYSTEM" -style title.TLabel gridplus layout .top.display { .top.lblTitle:c } pack .top.display -expand 1 -fill both #=======================================================================# # SET LAYOUT AND DISPLAY # #=======================================================================# gridplus layout .mainDisplay -wtitle "TrakPil 0.4" { .ctrTop - .ctrMenu .ctrForm .ctrBtm - } pack .mainDisplay focus -force .mainDisplay proc formInit {} { if {! [gridplus window .form -in .ctrForm]} {return} foreach tag {. .form} { bind $tag <F1> {tkcon show} bind $tag <Escape> {exit} bind $tag <Alt-Key-1> menu:main,registration bind $tag <Alt-Key-2> menu:main,tracking bind $tag <Alt-Key-3> menu:main,queue bind $tag <Alt-Key-4> menu:main,complete bind $tag <Alt-Key-5> menu:main,logout bind $tag <Alt-Key-6> menu:main,mainmenu } if {[winfo exists .gpValidateError]} {wm withdraw .gpValidateError} } Menu
proc Menu {} { formInit if {! [gridplus window .menu -in .ctrMenu]} {return} gridplus link .menu.main -iconfile tkIcons.sat { {: "1. Registration" .registration} {: "2. Tracking" .tracking} {: "3. Work Queue" .queue} {: "4. Scan Barcode" .scan} {: "5. Complete" .complete} {: "6. Logout" .logout} } ttk::label .form.lblTitle -text "\n\n\n\nPLEASE CLICK ON MENU ITEM\n\n\n\n\ OR PRESS ALT + MENU NUMBER" -style title.TLabel -justify center gridplus layout .form.display { .form.lblTitle:c } pack .form.display -expand 1 -fill both gridplus layout .menu.display { .menu.main } pack .menu.display -expand 1 -fill both } proc menu:main,registration {} { FormRegistration } proc menu:main,tracking {} { FormTracking } proc menu:main,queue {} { FormQueue }
proc FormRegistration {} { formInit #=======================================================================# # TITLE # #=======================================================================# ttk::label .form.lblTitle -text "REGISTRATION OF PRESCRIPTION" -style title.TLabel #=======================================================================# # REGISTRATION FORM # #=======================================================================# gridplus entry .form.registration -validatepopup 1 { { "PATIENT DETAILS:"} { "Hospital Number: " .txtHospNum 20 "!int?Please enter correct Hospital Number" } { "Surname: " .txtSurname 20 } { "Forename: " .txtForename 20} {&d "Ward: " .cmbWard 17} = {"PRESCRIPTION DETAILS:"} ^ {&d "Prescription Type: " .cmbType 17 } { "Number of Items: " .txtItem 5 "!int?Must be a valid number" } {&d "Initial Comments: " .cmbComment 40} {&c "Fast Track " .chkFast } {&b .register :actcheck16 "Register" ! |: &b .clear :actstop16 "Clear Form" } } .form.registration,cmbComment configure -state normal # click to open comment combobox because is editable bind .form.registration,cmbComment <ButtonPress> {event generate %W <Down>} focus .form.registration,txtHospNum gpset .form.registration,cmbType [db eval {SELECT typename FROM type}] gpset .form.registration,cmbWard [db eval {SELECT wardName FROM ward}] gpset .form.registration,cmbComment [db eval {SELECT comText FROM comment}] .form.registration,cmbType current 0 gridplus layout .form.display { .form.lblTitle .form.registration } pack .form.display -expand 1 -fill both }
adavis 2012-06-27: Sorry about the delay - I've been away for a few days. Just to let you know I'm investigating. I can reproduce the problem, which seems to have occurred between 2.7 and 2.8 - Odd , as there were no major changes here...
adavis 2012-06-27: I think I now have a fix for this. If you would like me to send you a copy for testing please email me.
EE 2012-06-28: There's an error on your website, in the installation instructions there's still a reference to version 2.7.
adavis 2012-06-29: Thanks for letting me know - I'll update soon.
MHo 2012-10-24: I've buttons with mixed text and icons, here are some examples:
{ &b "Nach oben" .upList ~m_dlgKS_CB_moveUpInList 15 < %rightGrp2 :nav1uparrow16 } { &b "Nach unten" .downList ~m_dlgKS_CB_moveDownInList 15 < %rightGrp2 :nav1downarrow16 } { &b "Pause einfügen" .pauseList ~m_dlgKS_CB_insPauseInList 15 :appclock16 }
adavis 2012-11-09: Sorry about the delay - I missed this Wiki update...
To have the button images on the right you can specify the -compound right option. To force the text to be left justified pad out the shorter text(s) with trailing spaces:-
gridplus widget .mygrid -compound right { {&b "Nach oben " .upList ~m_dlgKS_CB_moveUpInList 15 < %rightGrp2 :nav1uparrow16 } {&b "Nach unten " .downList ~m_dlgKS_CB_moveDownInList 15 < %rightGrp2 :nav1downarrow16} {&b "Pause einfügen" .pauseList ~m_dlgKS_CB_insPauseInList 15 :appclock16 } }
Can you give me sample code to demonstrate the Tablelist focus issue?
MHo: Thanks for response. I'll have to put some demo together, as I cannot post or mail the actual code, as it's part of my shell around gridplus2 and therefore not executable by itself but my interpretring Simple Program Menu.
MHo: How to alter the title of a labelframe around a textbox dynamically?
adavis 2013-01-28: If you created this textbox...
gridplus text .mytext -width 25 -height 8 -scroll y -title "Text Box"
...You could change the title like this...
.mytext configure -text "New Title"
MHo: Is there an essential difference between inserting text into a text widget via
gpinsert name index text
and
name.text insert index text
? I want to use tags, which is as far as I know not possible with gpinsert.
adavis 2013-01-30: Yes there is a difference. For editable text widgets it ensures that value for the widget and the modfied flag are updated. For tags enabled text widgets it ensures that the tags are processed.
I'm not sure what you are planning to do with the tags, but the GRIDPLUS text widget does support some HTML style tag definitions - See This Example .
The GRIDPLUS tags reference can be found Here .
The GRIDPLUS tags can be used with gpinsert - If you created this textbox...
gridplus text .mytext -menu .mymenu -tags 1 gridplus layout .main -wtitle "Text Example" { .mytext } pack .main gpset .mytext { <b>This Text is Bold</b> This text is not bold }
...You can use the gpinsert command like this...
gpinsert .mytext end "Here is some <color red>red</color> text" gpinsert .mytext end "Here is some <color blue>blue</color> text" gpinsert .mytext end "<u>This text</u> is underlined"
sai 2013-06-07:
How can I use tcl's built-in commands? e.g."text .t ; .t see end" It is autoscrolling in textbox. I am not sure whether the gridplus2 also can likes it's effect or not. Thanks.
adavis 2013-06-07: If you have created a GRIDPLUS text widget called ".mywidget"...
.mywidget.text see end
...should do what you require.
NOTE: The naming convention used for GRIDPLUS widgets can be found Here .
sai 2013-06-10: This can be seen in the following example.
gridplus text .mywidget -state disabled -font {courier 8} -scroll xy -wrap none .mywidget.text see end
adavis 2013-06-10: I'm sorry sai; I obviously don't understand your issue correctly. Can you provide more detail? What are you expecting to see?
sai 2013-06-10: The following example don't have effect of auto scrolling.
package require gridplus namespace import gridplus::* gridplus text .mywidget -scroll xy -wrap none gridplus layout .main -wtitle "Test" { .mywidget } pack .main for {set i 1} {$i < 30} {incr i} { after 300 gpinsert .mywidget $i $i ;update }
But I think the information in text that can presented immediately ; in other words, the scroll bar was scrolled with text together.
package require gridplus namespace import gridplus::* gridplus text .mywidget -scroll xy -wrap none gridplus layout .main -wtitle "Test" { .mywidget } pack .main for {set i 1} {$i < 30} {incr i} { after 300 gpinsert .mywidget $i $i ;update #effect of auto scrolling ? .mywidget.text see end }
adavis 2013-06-10: I would recommend something like your second example - Though I think "update idletasks" would be preferred. You can also insert at the "end"...
for {set i 1} {$i < 30} {incr i} { after 300 gpinsert .mywidget end $i update idletasks .mywidget.text see end }
I will be adding a -seeinsert option to the text widget in the next release of GRIDPLUS. If you would like a pre-release copy of GRIDPLUS 2.10 please send me an email.
sai 2013-06-10: Cool,this is great grid manager.I very like your gridplus2. I have emailed to you.
sai 2013-06-14: Hello, adavis. I try tablelist of gridplus2, it present the error messages in the following example:
gridplus tablelist .mytable { 4 "Column1" 4 "Column2" 0 "Column3" } gridplus layout .main -wtitle "Tablelist Example" { .mytable } pack .main
error message
can't access "::tablelist::ns.::data": parent namespace doesn't exist can't access "::tablelist::ns.::data": parent namespace doesn't exist while executing "upvar ::tablelist::ns${win}::data data" (procedure "tablelist::addActiveTag" line 2) invoked from within "tablelist::addActiveTag ." (command bound to event)
My tcl is Active 8.15.13 ,tablelist is 5.9.
adavis 2013-06-14: I have tried this example with Tcl/Tk 8.5.11 and 8.6.0, each of these with Tablelist 5.8 and 5.9 - I cannot reproduce this error. The above error messages come from the Tablelist package - Maybe Csaba will be able to help?
Csaba Nemethi 2013-06-17: The reported error message was due to the fact that the name of the Tcl script was "tablelist.tcl", thus the main window "." had the class name "Tablelist". This is no Tablelist-specific problem: A script named "entry.tcl" or "listbox.tcl", etc. will equally throw error messages on Windows, for the same reason.
sai: Yes,thank reply of Csaba Nemethi.
milarepa 2013-08-29 09:50:52:
I need to position a scrollbar on the left side of a text widget. On plain Tcl/Tk a scrollbar is like another widget, so it is possibe to position it where we want. How can I achieve this in gridplus?
adavis 2013-08-29: I'm sorry, GRIDPLUS doesn't currently have that option. I may add this in GRIDPLUS 2.11. In the meantime, you could try something like...
grid .mytext.ybar -row 0 -column 0 -sticky ns grid .mytext.text -row 0 -column 1 -sticky nsew
...to swap the positions (assuming the GRIDPLUS text is called ".mytext").
milarepa 2013-08-29 12:56:43: Thank you adavis. It works!
MHo 2013-08-30: Can't figure out how to dynamically enable or disable a menu entry (within a popup menu). I can create in disabled state with <, ok, but then how to switch state later?
adavis 2013-08-30: GRIDPLUS widget and menu option states can be set dynamically using "Groups" - See http://www.satisoft.com/tcltk/gridplus2/groups.html
MHo Yes I know, but I thought there was a way to enable/disable individual objects by their name, not only via groups...
adavis 2013-08-30: I'm sorry, "Groups" is the supported GRIDPLUS way to do this.
kap 2014-07-03: Is there a way to add icons so they are not buttons, and do not have a proc associated with them (like if I could set an icon to a label)? Currently I set the icon as a link and create a dummy proc so it doesn't try and execute a command when clicking as so:
gridplus widget .statusbar -relief groove -stretch 0 { {"^Connection Status: " .status} {&l .connect :disconnect} } proc statusbar,connect {} {}
kap 2014-07-03: Also is there a way to dynamically change the icon set to a gridplus widget? In the code above I'd like to be able to dynamically change the .statusbar,connect icon from "disconnect" to "connect" later in my code.
adavis 2014-07-06: Assuming you have already created two images called "connect" and "disconnect", I would suggest...
gridplus widget .statusbar -relief groove -stretch 0 { {"^Connection Status: " .status} {.connect} } .statusbar,connect configure -image disconnect
...you can then change the icon using...
.statusbar,connect configure -image connect
If what you are actually trying to do is have the text "Connection Status:" with the icon immediately to the right, it can be simplified to something like...
gridplus widget .statusbar -relief groove -stretch 0 { {"^Connection Status: " .connection} } .statusbar,connection configure -image disconnect
kap 2014-08-04: Is there a way to configure a gridplus entry box to dynamically resize as the window size changes?
adavis 2014-08-08: Yes. You need to use the "-stretch" option on the widget/entry grid and the ":ew" anchor suffix on the entry widgets that are to be resized.
For example: If your window only contains and a widget/entry grid...
gridplus entry .myentry -stretch 0 -width 30 -title "Entry Grid" { {"Entry One" .entry1:ew} {"Entry Two" .entry2:ew} {"Entry Three" .entry3:ew} } gridplus pack .myentry -resize xy
If the widget/entry grid is in a layout then the :ew anchor suffix must also be specified for the grid in the layout...
gridplus entry .myentry -stretch 0 -width 30 -title "Entry Grid" { {"Entry One" .entry1:ew} {"Entry Two" .entry2:ew} {"Entry Three" .entry3:ew} } gridplus layout .mylayout -wtitle "Resize Example" { .myentry:ew } gridplus pack .mylayout -resize xy
kap 2014-10-17: Is it possible to configure a grid such that the widgets will stretch to fill the rest of the grid, right up to the next widget? For example, the entry box in the following entry grid, when stretched, resizes only to the midpoint of the window. This is the expected behavior since it is filling its half of the grid, though I'd like it to instead stretch all the way to the button as it's resizing.
gridplus entry .entry -stretch 0 { .entry:ew {&b .button Foo} } gridplus layout .main { .entry:ew } gridplus pack .main -resize x
LAM 2014-10-18: What about this ?
gridplus entry .entry -stretch 0 { {entry .entry:ew } } gridplus button .button { {Foo .button } } gridplus layout .main { .entry:ew ^ .button+ } gridplus pack .main -resize x
adavis 2014-10-20: You can use "-spacestretch"...
gridplus entry .entry -stretch 0 -spacestretch {000} { .entry:ew {&b .button Foo} } gridplus layout .main { .entry:ew } gridplus pack .main -resize x
kap 2014-11-03: Is there a way to tie an ensemble command to a widget specified in a grid? For example, let's say there exists ensemble commands foo bar and foo baz that should be fired when certain buttons in a gridplus button grid are pushed.
adavis 2014-11-10: I've not tried ensemble commands - In what way would calling them be different to "normal" commands?
kap 2014-11-11: I ended up using the configure method of the widget object to add the ensemble command explicitly. I was curious if it were possible to do this via the gridplus syntax similar to the following where I'd like foo bar to fire when .b,b1 is pressed (this fails, shown to supplement the question).
gridplus button .b { {Foo .b1 ~{foo bar}} {Bar .b2} }
adavis 2014-11-14: Have you tried the following?:-
gridplus button .b { {Foo .b1 "~foo bar"} {Bar .b2} }
kap 2014-11-16: Works great, thanks.
kap 2014-11-16: Bug report, with gridplus 2.10, the gridplus text find dialog throws errors whenever a string beginning with "-" (ambiguous switch error) is provided.
adavis 2014-11-22: That's odd. I thought I'd fixed that in 2.10 -and- it does seem to work OK with my 2.10 installation. Are you sure you are actually using 2.10? (package version gridplus) - If so, can you give me some sample code which has this problem?
kap 2014-11-22: Just did a fresh install of 2.10 (and verified with package version gridplus). After requiring / importing the package this snippets generates the problem:
gridplus text .t gridplus pack .t
Upon right-clicking the text box and selecting 'Find', I select the 'Find What' box and input a hyphen '-' and click the 'Find Next' button. This yields an error dialog "Error: ambiguous switch "-": must be --, -all...".
adavis 2014-11-24: Thanks for pointing this out - It seems I'd only fixed one of the text find procedures. I have fixed this in version 2.11.
MHo 2016-03-29: How to delete all data rows from a tablelist (like a reset to initial state - i mean something .x delete 0 end)?
adavis 2016-04-11: The following should do what you require:-
gpset .mytable {}
beware 2016-04-11: What's the best way of doing scrolled frames? If it matters I have a notebook within a notebook and for each of the slave notebook tabs I would like to put a scrolled frame. BWidgets Scrollable Frame doesn't seem to work for me.
adavis 2016-04-21: I'm afraid GRIDPLUS2 does not have a scrolled frame.
MHo 2016-05-02: I noticed that popping up a -menu (with right click) from a tablelist clears the selected rows (in modes multiple or extended)...
MHo 2016-05-02: I missed the -underline option here and there. How to specify accelerator keys for buttons, e.g.?
MHo 2016-11-13: The spinbox should support a -command so that things could be triggered when the value changes. Workaround is to use a trace.
adavis 2016-11-16: Thanks for the suggestion - I'll add it to the list.
MHo 2016-11-18: Thanks! Is there a way to centrally manage tooltips? Something like this would be very helpfull:
gpset tooltips { widget {text...} widget {text...} : }
adavis 2016-11-22: I'm afraid not. The tooltips are "part" of a widget and are created/destroyed as such. I'll have a think about possibilities...
MHo 2016-11-30: Another thought. In certain constellations, it would make sense if entryfields (and text boxes) could grow in width if the main window is resized in x direction. Don't know how to achive this actually.
And, as mentioned earlier, I'm missing an -underline option, so that hotkey bindings to navigate around edit fields by keyboard can visually be marked in labels (like "Sure&name").
adavis 2016-12-14: There is an example of text box resizing at: http://www.satisoft.com/tcltk/gridplus2/resize.html
Entry fields can be made to resize using an ":ew" sticky. For example:-
gridplus entry .name { {"First name " .firstname:ew} {"Last name " .lastname:ew} }
MHo 2017-12-12: I wonder why the <TAB> did not do what I expect (moving the focus to the next TEXT field), whereas <Shift><TAB> do (move to the previous TEXT field).
adavis 2017-12-20: Can you give me a code example?
MHo Sorry, I forgot this.... so here is an example:
package require gridplus namespace import gridplus::* gridplus text .mytext1 -width 80 -height 5 -title "Titel!" gridplus text .mytext2 -width 80 -height 5 gridplus layout .main -wtitle "Text Menu Example" { .mytext1 .mytext2 } pack .main
LAM 02018-10-2 : Is the development of this package still active?
MHo 2019-10-28: There's no working binding for <tab> in text boxes (binding is break). Here is my workaround:
bind $w <Tab> {tk::TabToWindow [tk_focusNext %W]; break}
And:
Addition 2019-11-26: If there's any widget after the notebook, the taborder gets wrong....