http://qs1969.pair.com?node_id=398074

water has asked for the wisdom of the Perl Monks concerning the following question:

Thanks everyone for all the Tk help.

I'm trying to add tabs to a notebook dynamically while the program is running, after MainLoop has started.

# silly toy example use strict; use Tk; use Tk::NoteBook; my $i=0; my $top = MainWindow->new( -title => 'client', ); my $nb = $top->NoteBook(); $top->repeat(200, \&add_tab); &add_tab() for 1 .. 20; MainLoop(); sub add_tab { exit if $i>50; $i++; print "adding tab $i\n"; my $tab = $nb->add($i, -label => $i ); $nb->pack; }
Here, the first 20 tabs are added fine, as MainLoop hasn't started yet, but the later tabs don't show up.

Without destroying and rebuilding the entire top window, how can I add a tab to a notebook after MainLoop has started?

Thanks!

water

UPDATE:
Thought I could solve the problem by preallocating a set of tabs for later use. Sure, but after MainLoop has started, if I change the options on the preallocated tab, those changes don't seem to be visible. So this preallocation scheme (as least as I implemented it) does not work. Suggestions, wise monks?

Considered: kelan dup of 398068
Unconsidered: ysth enough keep votes, positive rep - Keep/Edit/Delete: 2/2/20

Replies are listed 'Best First'.
TK: adding notebook tabs dynamically
by water (Deacon) on Oct 11, 2004 at 01:20 UTC
    Thanks everyone for all the Tk help. I've changed my app to use -textvariables heavily, so the display changes as the underlying data changes. Now, all that remains is to understand / solve / engineer-around the tab issue:

    I'm trying to add tabs to a notebook dynamically while the program is running, after MainLoop has started.

    # silly toy example use strict; use Tk; use Tk::NoteBook; my $i=0; my $top = MainWindow->new( ); my $nb = $top->NoteBook(); $top->repeat(200, \&add_tab); &add_tab() for 1 .. 20; MainLoop(); sub add_tab { exit if $i>50; $i++; print "adding tab $i\n"; my $tab = $nb->add($i, -label => $i ); $nb->pack; }
    Here, the first 20 tabs are added fine, as MainLoop hasn't started yet, but the later tabs don't show up.

    Without destroying and rebuilding the entire top window, how can I add a tab to a notebook after MainLoop has started?

    Thanks!

    water

    20041011 ysth Reparented under later duplicate

      use Tk; use Tk::NoteBook; my $top = MainWindow->new( ); my $nb = $top->NoteBook()->pack(); add_tab(); $top->Button( -text => "Add Tab", -command => \&add_tab )->pack(); $top->Button( -text => "Delete Tab", -command => \&delete_tab )->pack( +); MainLoop(); sub delete_tab { $nb->delete($i--) } sub add_tab { $nb->add(++$i, -label => $i )->pack() }

      cheers

      tachyon

Re: TK: adding notebook tabs dynamically
by qumsieh (Scribe) on Oct 11, 2004 at 02:58 UTC
    Here, the first 20 tabs are added fine, as MainLoop hasn't started yet, but the later tabs don't show up.

    They do, but your window is too small to show them all. If you resize your window, and make it wider, then you'll see them (you have to do this quickly since your code exits when it's done).

    Having said that, Tk::NoteBook is severly limited: You can't place tabs except at the top, and you can't have multiple rows of tabs, which would have solved your problem. There is an alternative widget, Tk::DynaTabFrame, which attempts to overcome those problems.

      No, it has nothing to do with the size of the main window. In the following code, I made the window wide enough, but still those newly added tabs does not show up.

      However, when you click on any existing tab, those new tabs pop up. This is about how and when the window get redraw.

      use strict; use Tk; use Tk::NoteBook; my $id = 0; my $top = MainWindow->new(-title => 'client'); $top->geometry("500x100+0+0"); my $nb = $top->NoteBook()->pack(); $top->Button(-text => "Click", -command => \&add_tab)->pack(); add_tab() for 1 .. 3; MainLoop(); sub add_tab() { $nb->add(++$id, -label => $id); }
      Dynatabframe sounds great.

      I am having trouble getting it to work (XP, activestate).

      Am I / how am I using it wrong? Thanks for the help!

      use strict; use Tk; use Tk::DynaTabFrame; my @tab; my $top = MainWindow->new(); my $nb = $top->DynaTabFrame; &add_tab() for 1 .. 6; $nb->pack; MainLoop(); my $i = 0; sub add_tab { $i++; print "adding tab $i\n"; $tab[$i] = $nb->add( -caption => 'Tab label' . $i, -tabcolor => 'black', ); $tab[$i]->Label( -text => 'dsdss' ); }
        You have a really bad placement of your my $i = 0 line. But the reason your code dosn't work is you need to pack in the sub.
        #!/usr/bin/perl use warnings; use strict; use Tk; use Tk::DynaTabFrame; my @tab; my $top = MainWindow->new(); my $nb = $top->DynaTabFrame->pack; my $i = 0; for(1..6){ &add_tab()}; MainLoop(); sub add_tab { $i++; print "adding tab $i\n"; $tab[$i] = $nb->add( -caption => 'Tab label' . $i, -tabcolor => 'black', )->pack; $tab[$i]->Label( -text => 'dsdss' )->pack; }

        I'm not really a human, but I play one on earth. flash japh
        Personally i have found tixnotebook much easier to use. i had similar/same problem with update of the notebook using tknotebook. in tixnotebook you can also color the background of each tab, have soft or sharp corners etc.
Re: TK: adding notebook tabs dynamically
by zentara (Archbishop) on Oct 11, 2004 at 16:05 UTC
    Have you tried running the demo which comes with Dynatabframe? It does just what you ask.

    I'm not really a human, but I play one on earth. flash japh