Displaying a lot of information in a small space is often the biggest challenge given to GUI programmers. The NoteBook widget is designed to help do just this. It allows us to have many pages of text, but lets only one be shown at a time. Each page in the NoteBook has a tab associated with it. The tab can display text or an image. Let's look at a simple example:
use Tk; $mw = MainWindow->new( ); # Create the notebook and fill the whole window $nb = $mw->NoteBook( )->pack(-expand => 1, -fill => 'both'); # Page 1 on the notebook, with button on that page $p1 = $nb->add('page1', -label => 'Page 1'); $p1->Button(-text => 'Click me!')->pack( ); # Empty page 2 $nb->add('page2', -label => 'Page 2'); MainLoop;
It creates a window with a NoteBook widget, shown in Figure 23-15. The notebook has two pages, named Page 1 and Page 2, respectively. Page 1 has a button on it, so the size of the NoteBook is determined by Page 1 (because it is the largest).
When you create a page in a NoteBook, you assign it a name using the add method. From then on, when calling NoteBook methods, you refer to that page by that name. In our example, we used page1 and page2 as the internal page names. The displayed label can either be the same or something completely different. It is important that you use different internal names for every single page in the NoteBook, or you'll get an error. Here are some examples using the add method:
$p = $notebook->add('internalname', -label => 'Displayed Name'); $p2 = $notebook->add('internalname2', -bitmap => 'bitmapname');
The first argument passed to add is the internal storage name of the page. There are several options that will determine how the tab information is displayed:
Once the page is created, you still need to put something on it. Use the reference returned by the add method and create widgets using that reference as the parent widget.
There are three ways to put something on a page:
Using MainLoop when you create the page, before the window is displayed.
Using the -createcmd option, which creates the page the first time the user clicks on that tab.
Using the -raisecmd, which can change what is displayed on the page every time the user raises that page.
To delete a page, use the delete method and pass it the internal name of the page:
$notebook->delete("page1");
There are two methods used to get and set information associated with a page: pagecget and pageconfigure. Both methods will work only with the same options that can be used with the add method.
To get the value of an individual option, use pagecget:
$state = $notebook->pagecget("pagename", -state);
To change the value of one or more options, use pageconfigure:
$notebook->pageconfigure('pagename', -label => 'new label'); $notebook->pageconfigure('pagename', -label => 'new label', -underline => 3);
You can cause a page to be displayed (or raised) by using the raise method:
$notebook->raise("page4"); ## OR check to see if that page is already showing: $page = $notebook->raised( ); if ($page ne "page4") $notebook->raise("page4");
A NoteBook allows us to display data in an organized fashion. In this example, we are going to parse through some files (passed in as command-line parameters) and index out all the words contained within the files. The resulting window is shown in Figure 23-16; the code follows.
Half of the following code preps the list of words to display and the other half does the work of displaying it. To sort the words, we use a hash based on the first character in each word.
use Tk; require Tk::NoteBook; $mw = MainWindow->new( ); # Show the user the names of files we are parsing # This might end up too long to see it all $mw->title('Word Count:' . join (',', @ARGV)); # Use a courier font to display the tab text $nb = $mw->NoteBook(-font => 'Courier 10 bold')->pack; my %textWidgets; %seen = ( ); while (<>) { while ( /(\w['\w-]*)/g) { $seen{lc $1}++; } } # go through the index in order and create the tabs and text widgets. foreach my $word (sort (keys %seen)) { if ($word =~ /^(.)/) { $letter = $1; $t = $textWidgets{$letter}; # Create the text widget if it doesn't already exist if (! defined $t) { my $p = $nb->add($letter, -label => $letter); $t = $p->Scrolled("Text")->pack(-expand => 1, -fill => 'both'); $textWidgets{$letter} = $t; } $t->insert("end", $seen{$word} . " " . $word . "\n"); } } MainLoop;
You can't have the tabs for a NoteBook automatically wrap around and make more than one line of tabs. Consequently, you might make so many tabs that your window will be too big to be displayed properly. In that case, you might consider having a page contain another NoteBook widget, which will essentially give you two rows of tabs.
In order to disable a tab page, the recommended solution is to use an InputO widget, which covers everything on that tab page. However, InputO isn't supported on Win32 systems.
Copyright © 2002 O'Reilly & Associates. All rights reserved.