Updated 2015-09-02 17:37:26 by pooryorick

adavis (10th October 2006): GRIDPLUS2 has been released.

LV Unless you specifically are dealing with a very old version of Gridplus, please ask questions on the GRIDPLUS2 page instead.

adavis (19th April 2005): GRIDPLUS 1.2 has been released and is available from:-

http://www.satisoft.com/tcltk/gridplus

ENHANCEMENTS:

  • New GRIDPLUS tree command/mode to create a scrollable tree widget.
  • Support for null named array variable substitution in layout parameter of Grid/Layout command modes.

CHANGES:

  • The Starkit now includes TABLELIST 3.8 (Previously 3.5).

BUG FIXES:

  • Fixes problem setting the contents of an updateable text widget (GRIDPLUS 1.1 only).

Example of new GRIDPLUS tree:


GRIDPLUS is a package intended to simplify GUI screen layout development for TCL/TK programmers. GRIDPLUS is the second in a series of packages aimed at producing a framework for development/distribution of "database" applications written in TCL/TK, but I feel that some of the packages may also be of more general interest. The first package ICONS, released 2002, was originally developed to be used with GRIDPLUS.

Firstly: GRIDPLUS is not a "Visual" design tool.

GRIDPLUS is a "Grid" based layout system which builds on, simplifies and extends the existing Tk grid manager. GRIDPLUS layouts are defined as a hierarchy of grids. Each cell in a grid consists of two elements. These will usually be a text label and some other widget such as an entry. It is also allowed to have just one element in a cell, or a cell which is empty. 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 exist to create grids of Buttons, Checkbuttons, Entries, Links and Radiobuttons. All places where text can be displayed make use of the TCL message catalogue facility.

In effect 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. 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:-

  • Scrollable text widget.
  • Scrollable tablelist.
  • Scrollable tree widget.
  • Basic notebook type widget.
  • Simple drop-down menus.
  • Simple method to specify widget traversal order when using the TAB key to navigate the screen.
  • A group facility to enable/disable groups of widgets and menu options.
  • Facility to include non-GRIDPLUS widgets in groups.
  • Simple pattern/procedure based entry validations.
  • Works with toplevel windows.

Here Are Some Screens Created Using GRIDPLUS:


JMN 2004-06-25 In this last example, how would you go about swapping the right hand side of the screen as each menu item is clicked? Do you simply replace the whole screen including the actions menu?

My usual approach would be to have a frame on the RHS and use 'pack forget' & pack to substitute the frame contents. I've been playing around trying to combine this with the use of GRIDPLUS, but I'm finding that my frame contents don't display because there's something strange with the stack order when placing the frame in a gridplus layout. I end up having to lower the frame and the layout to see my gridplus entry fields. (or else individually raise each entry item above their container)

For example:
 package require gridplus
 namespace import gridplus::*
 frame .frame -relief groove -border 1 -borderwidth 4
 gridplus entry .entries -labelstyle bold/ -size 12 -title "entry items" {
         {"entry1 " .entry1}
         {"entry2 " .entry2}
 }
 pack .entries -in .frame -fill both -expand 1
 gridplus layout .layout -taborder row -title "layout" {
         .frame:nw
 }
 pack .layout -fill both -expand 1
 console show

Type 'lower .frame' and 'lower .layout' in the console window to see the entry widgets.

Is there a better way of doing this? i.e without using a frame, can you somehow replace individual items within a layout once it's been packed?

I get similar stack ordering hassles when trying to incorporate a panedwindow into GRIDPLUS layouts.. and of course then one starts to get into resizing issues.

I understand GRIDPLUS isn't designed with resizable forms in mind - personally I think that's a pity as the panedwindow is one of my favourite widgets, but the extra readability and simplicity of a GRIDPLUS gui seem to make it a very interesting addition to the toolbox. Thanks for sharing.

adavis (25th June 2004): I'm afraid that GRIDPLUS isn't designed to work in this way. It is intended that the entire screen be drawn each time the layout changes. GRIDPLUS takes control of the stacking order because of how I'm using the grid geometry manager and to manage the "-taborder" functionality - It is quite fundamental to the functioning of GRIDPLUS and would be difficult to change. Also, the "gridplus clear" command/mode must be called before a new layout is created in the same window, as this command performs a number of essential housekeeping functions...

...However; having said that I'm starting to think about the idea of some kind of container based on a modified GRIDPLUS notebook. It would mean that all of the widget grids/layouts which may be displayed will need to be created at the same time. A new command/mode (gridplus select ?) could be created to select the displayed contents of the container instead of using buttons. Do you think that this would be any use? Just a thought at the moment - No promises!!

AET 26sep06 Well, it's been a while since any addition to this page. I'm just adding one to let adavis know that this work is still appreciated. I have been using it to create a little database that is a 'prototype' for a later one that is to be professionally built by others. I fully expect that the professionally built package will never eventuate, partially because of the professional look that gridplus has given it.

Gridplus is a wonderful package, which makes creation and (especially) maintenance of a professional-looking application much simpler and easier. Takes a little getting to know, but the excellent documentation makes that easy. Seriously, gridplus documentation should be held up as an example of excellence that is sadly almost universally lacking in the FOSS world.

Well done, and thanks.

adavis (26th September 2006): Your kind words are much appreciated. You may also be interested to know that I plan to release GRIDPLUS2 sometime in the next week. This is (where possible) based on Tile widgets and also features some major enhancements which can reduce even further the coding required to achieve the required window/widget layout. More later...

JAG - Adrian, I'm looking forward to GRIDPLUS2. I've got the perfect project waiting in the wings to try it out on... ;^)

AET is also looking forward to it. I'm sourcing gridplus.kit for simplicity while I develop my little DB. Having all the libraries included in the VFS makes it really simple, so a .kit version of GP2 would be appreciated.

ABU 9-mar-2007 - I'd like to use my own bunch of icons (i.e. a set of .gif files), but if I understand correctly, gridplus requires these should be packed in a special icon-library. Isn't there a way to work directly with gif-files or pre-loaded images (image create photo ...) ?

Alternatively, can you suggest a way for building and installing (referencing) my own icon-library ?

adavis (9th March 2007): Although it is not documented - You can use images created with the "image create photo" command. You need to give the image a name prefixed with "::icon::". For Example: If you created an image called "::icon::myimage1", you should then refer to the image as "myimage1" in GRIDPLUS. Many GRIDPLUS commands use a colon prefix to specify an icon - In this case, you would use ":myimage1".

rgf 2007-08-13: I find gridplus to be very helpful in quickly setting up a gui, but ... I was experimenting with a tree in version 1.2 (not using tcl/tk 8.5 yet) and found if a '-' was embedded in a node name I generated an error about an illegal action/command. Is this intended? I expected the '-' to require a space in front of it to be parsed as an action.

adavis (14th August 2007): Can you post (or email me) a sample which demonstrates this problem?

rgf 2007-08-14 This should demonstrate the difficulty ...
  # test=yes => '-' in node names,
  #             otherwise '_' in node names

  set test no ;#yes

  # define some nodes

  if {$test} {
    set treelst [list \
      "/code.vfs +" \
      "/code.vfs/main.tcl" \
      "/code.vfs/lib +" \
      "/code.vfs/lib/app-code +" \
      "/code.vfs/lib/app-code/pkgIndex.tcl" \
      "/code.vfs/lib/app-code/code.tcl"]
  } else {
    set treelst [list \
      "/code.vfs +" \
      "/code.vfs/main.tcl" \
      "/code.vfs/lib +" \
      "/code.vfs/lib/app_code +" \
      "/code.vfs/lib/app_code/pkgIndex.tcl" \
      "/code.vfs/lib/app_code/code.tcl"]
    set test no
  }

  # set up gridplus and display

  source gridplus.kit
  package require gridplus

  # FYI version info -> stdout

  puts "tcl version: $tcl_version"
  puts "gridplus version: [package versions gridplus]"

  #namespace import gridplus::*
  gridplus tree .mytree
  gridplus layout .main -title "- in node? $test" {.mytree}
  pack .main
  gpset .mytree $treelst

  # version info -> stdout
  puts "tcl version: $tcl_version"
  puts "gridplus version: [package versions gridplus]"

My code versions were:
  tcl version: 8.4
  gridplus version: 1.2

adavis (16th August 2007): Message to rgf - I have produced a possible fix. If you email me I'll send you a copy to try out.

rgf Thanks for the quick fix. It works in several sample cases I had handy (no exhaustive testing).

adavis (17th August 2007): When I get back after the weekend I'll do some more testing and post it to the GRIDPLUS website.

MHo (3rd Sep 2007): Some examples use a combobox, but I didn't find the documentation for that, yet...

adavis (3rd September 2007): The examples for GRIDPLUS use Brian Oakley's combobox (http://purl.oclc.org/net/oakley/tcl/combobox/). This is used as an example of how to use non-GRIDPLUS widgets in a GRIDPLUS grid/layout. GRIDPLUS2 supports the Tile combobox directly.

Mho Thanks! I've seen this page before but was to stupid to download and look into the .zip.... I'll switch to GRIDPLUS2 when I switch to Tcl 8.5. Nobody knows when this will happen....;-).

MHo, 2007 Sep 14: Addition: Let me say that this tool is absolutely superb. The last days I tested many tools up and down and down and up; GRIDPlus is the winner in that it's possible to build very impressive and complex GUIs with the fewest statements and cleanest code. Ok, the GUI I'm working on is far from complete... Just a few questions so far:

  • if I declare a field to be an integer with !int, e.g., I can't leave this field until I enter a valid value, not even with the mouse. This behaviour is a bit odd in that it prevents the user from navigating further around. I usually not blocking the user until he tries to "submit" or process the whole form(ular) or so.
  • It would be nice if one could easily specify not only the visual -width of entry fields, but the real-limit-of-characters (maxLen) (somewhere I saw this feature, BWidget or [Iwidget] don't remember). Either directly as a switch or via a validation mnemonic...
  • What about HotKey-Bindings, at least automatic underlining via a syntax like La&belname etc.
  • I wasn't able to put the -title of an entry grid, e.g., at the upper right corner of the grid... I think I tried -justify for this purpose by mistake....
  • Is there a simple method to assign the ENTER/RETURN in a way that the behaviour is equivalent to TAB, if pressed in an entry?
  • Just discovered, that moving my main window with the mouse, even only leftklicking on the title bar!, let the height of the window grow (uncolored growing area at the bottom.....) This only seems to happen on w2k, not on Windows XP...

Again, GRIDPLUS is my greatest discovery of the last weeks or months....

MHo, 2007 Sep 17: Meanwhile I found a solution for assigning TAB functionality to ENTER/RETURN:
 :
 gridplus entry .entry1 -state normal -padx 8 -size 80 -style bg1 -taborder row {
    {}                                              {}
    {"^Absender        :nw" .sender    +  ~x} {@prio}
    {"^Bezeichnung     :nw" .Bezeichnung  ~x}
    :
 :
 proc x {} {
      # tk_focusNext [focus]; # doesn't work...
      event generate [focus] <Tab>; # but this does
 }
 :

adavis (17th September 2007): Your questions have raised some good ideas for enhancements. However, I'm not doing any development on GRDIPLUS at the moment - Only bug fixes. Any enhancements will be incorporated into GRIDPLUS2 only.

Things that will be in the next release of GRIDPLUS2 are:-

  • An option to disable the "focusout" validations.
  • An option for "Enter/Return" to Tab to next field.
  • An option to set the position of the labelframe title.

A question of my own: Do you have a particular use in mind for "Hot Keys?" - Selecting menu options? Buttons?

I only have access to one Win2k machine with Tcl8.5/GRIDPLUS2, but I'm not in a position to install Tcl8.4/GRIDPLUS on it. All I can say is that I am unable to reproduce your problem with Tcl8.5/GRIDPLUS2 on Win2k. Does anybody else have experience of this problem?

MHo: Done further testing - it seems now that the Windows Blinds produces the problem with the growing window. Very misterious, because in the beginning of developing that app it does not happen, and Windows Blinds is alway loaded. I don't know any other app with this behaviour in conjunction with Windows Blinds. However, I think we should ignore this problem for now...

The hotkeys are for navigating only with the keyboard. I have an app with a navigation-section (grid) on the left side conating several gridplus LINKS, and an entry section on the right. I can step through all the entry fields via TAB, but how could I navigate to a link via keyboard?? Ok, I could bind some Keys and directly call the link handler by myself - but this leads to another problem: In the link definition, I could request that prior to executing the link proc, validations should happen. But if I call the handler directly by myself via BIND, how could I do the validations by myself too? Don't found an answer to this, so I completely removed the validations and coded them separately. A possibly workaround would be not to call the handler proc directly, but do a <link> invoke - but there is no invoke method available neither with links or buttons....

I don't switched to gridplus2 yet because I don't switched to tcl 8.5 yet, because I first have to change some of my own development framework code...

adavis (17th September 2007): It may be a bit clumsy, but you could use "event generate" to invoke a link validation/command...
  gridplus link .mygrid1 {
     {"Link One" .link1 !}
     {"Link Two" .link2 !}
  }

...then "event generate .mygrid1,link1 <ButtonRelease-1>" should perform the required validation then invoke the command for "Link One".

I would also be interested if you could e-mail me sample code for the screen layout in question. I'm not sure I can quite visualise it at the moment.

MHo: Yes, I forgot event generate. Thanks! EMail with code and screen example should be on its way... Another one:

  • if I set, e.g., -size 80 for my entries. How could I get this value back later? .x,y cget -size gives an error.

adavis (18th September 2007): You will need to use .x,y cget -width - In GRIDPLUS2 the -size option has been changed to -width for consistency.

Incidently, it is possible to do a crude form of entry field length check using validations...
   # Validation procedure

   proc max {entry parameter} {
      global {}

      if &#x7B;[string length $($entry)] > $parameter} {
         return 0
      }

      return 1
   }

   # Sample code using validation procedure.

   gridplus set -validation max -pattern proc:max -text "Maximum % characters allowed"

   gridplus entry .entry -size 20 {
      {"Entry One" .one !max:10}
      {"Entry Two" .two !max:20}
   }

   label .errormessage -foreground red

   gridplus layout .main -title "Validation" {
      .entry
      .errormessage
   }

   pack .main

...The validation will fail if the field contains more than the specified number of characters.

MHo Thanks for your kind responses. Meanwhile, as I want the validations to happen only if I explicitely call them, I wrote my own validation routine. I specify the validations that should happen in the following format, e.g.:
 set valspec {
     { Absender         .entry1,sender      {required email chr}  }
     { Bezeichnung      .entry1,bezeichnung {required chr}        }
     { Kategorie        .cbCategory         {required chr}        }
     { Plattform        .cbPlatform         {required chr}        }
     { Funktion         .tbFunction         {required chr1000}    }
     { Zieldatum        .entry1,datum       {required date chr10} }
     { Softwareversion  .entry1,version     {chr}                 }
     { Anwendergruppe   .entry1,audience    {required chr}        }
     { Lizenzen         .entry1,lizenzen    {int chr10}           }
     { Lizenzschlüssel  .entry1,lizenzkey   {chr}                 }
     { Vorbedingungen   .entry1,requires    {chr}                 }
     { Supportregelung  .entry1,support     {chr}                 }
     { Anbieter/Hotline .entry1,hotline     {chr}                 }
     { Fachberatung     .entry1,fachbera    {required chr}        }
     { Sonstiges        .entry1,misc        {chr}                 }
     { Konfiguration    .tbDetails          {required chr1000}    }
 }

Element 1 is the widget name. Element 2 is a list of validation types, for now the following types are defined:

  • required - same as !notnull
  • chr - field can not contain more characters than specified with -size
  • chrxxx - field can not contain more than xxx characters
  • int - same as !int
  • date - some basic test for date field, to be completed in the future....

What's new with that is, that an arbitrary number of tests could be performed, and that I could specify that a field has to be an integer, but that is only checked if the field is not empty (leaving out required). With GRIDPLUS, specifying !int, I have to fill in something just to satisfy the condition integer, even if the field is not strictly required (but only if filled in, than it has to be an integer).

Element 0 is the label that I need if I give an error message to the user, since I found no method yet to get the associated label from the GRIDPLUS entry - definitions automatically...

adavis (18th September 2007): You are correct, there is no simple way to get the label text associated with an entry. The way in which I have implemented validations is for the field to be highlighted if the validation fails. However, this maybe a useful facility - I'll think about it.

I know this doesn't fit with your need to validate explicitly, but for the benefit of other readers: It is possible to create other regexp "pattern" based validations. For example to have a validation for a field which must either be an integer or null...
   gridplus set -validation intnull -pattern {(^[0-9]+$)|(^$)} -text "Must be integer or null"

...creates a validation called intnull which will do this.

MHo: I wonder if there is an elegant solution for status lines...

adavis (19th September 2007): What do you mean by "status line?" - Can you point me to an example of something similar to your requirement?

MHo: A line of text at the bottom of the screen which changes from time to time according to the state of the program; it could contain various informational messages for the user. Currently I try it with a @included standard tk label widget.

adavis (19th September 2007): Can you give me some example code which shows what you want? Is the following (rather clunky) example useful?...
   gridplus text .spacefiller

   gridplus grid .status -relief sunken {
      {.text}
   }

   gridplus layout .main {
      .spacefiller
      .status:ew
   }

   pack .main

   gpset .status,text "This is a message"

...NOTE: When you specify (in a grid) a widget that doesn't already exist, a label is created that is automatically associated with an element in the null array - this can be set using the gpset command. MHo That last info I missed from the documentation...... now I'm doing:
 gridplus grid .status1 -justify left -background white -pady 0 -padx 4 -borderwidth 0 {
    {.lbl1}
 }

and later
 gpset .status1,lbl1 "blablaba"

The overall layout is:
 gridplus layout .main -title [wmTitle] -style bg1 -borderwidth 0 -pady 0 -padx 0 {
    .link1:nsew .entry1:nsew
    .status1:ew -
 }

But: How do I left-justify the "blablaba"-text?

adavis (19th September 2007): It should be left-justified by default. What is happening in your case? In the following example the message should be left-justified - Does it work OK for you?...
   gridplus text .spacefiller1
   gridplus text .spacefiller2

   gridplus grid .status1 -justify left -background white -pady 0 -padx 4 -borderwidth 0 {
      {.lbl1}
   }

   gridplus layout .main -borderwidth 0 -pady 0 -padx 0 {
      .spacefiller1 .spacefiller2
      .status1:ew   -
   }

   pack .main

   gpset .status1,lbl1 "This is a message"

MHo: No, it is centered both in my prog and in the above example...

adavis (19th September 2007): Just noticed I was using Tcl 8.5 (It's been a long time since I've used 8.4) - Yes, I do get a centered message with 8.4. Try replacing the .status1 grid with the following...
   gridplus grid .status1 -background white -pady 0 -padx 4 -borderwidth 0 {
      {.lbl1} {}
   }

MHo: Yes, this does the trick! Thanks a lot!

By-the-way: I'm not sure if you are aware - but you can insert any widgets into a grid or layout. For example...
   label .label1 -foreground red  -text "Label One Text"
   label .label3 -foreground blue -text "Label Three Text"

   gridplus grid .mygrid -title Grid {
      {"Label One: " .label1}
      {"Label Two: " .label2}
   }

   gridplus layout .main {
      .mygrid
      .label3
   }

   pack .main

   gpset .mygrid,label2 "Label Two Text"

...maybe this would also be useful to you? MHo: Yes, thanks again.

MHo, 20.Sep.: The story continues. If I do the following, .e.g.:
 option add *Button.font {-family Tahoma  -size 9 -weight bold}
 option add *Entry.font  {-family Courier -size 8}
 option add *Text.font   {-family Courier -size 8}
 :

I get errors later, e.g.:
 expected integer but got "Courier"
 expected integer but got "Courier"
     (processing "-font" option)
     invoked from within "$name.text tag configure $tagName -lmargin1 $indent -lmargin2 $indent -background $bgColor -foreground $fgColor -font "$f
 :

adavis (20th September 2007): Try...
   option add *Text.font {Courier 8}

It seems that only font specs in the other format are possible, {family size ...} etc.

MHo One (I hope) last thing: I've noticed that the default background colors of the entry and text widgets slightly differ.... Here's my fix:
 .someTextWidget.text configure -background [.gridx,someEntryWidget cget -background]

adavis (21st September 2007): That's odd - What OS/version/window-manager are you using?

I saw this behaviour on one w2k and two XP PCs. The w2k-PC is tweaked with Window Blinds, and the XP's are a little lifted by TuneUp Utilities, but no unusual settings are active...