in reply to Re^2: Perl-Tk Notebook - add a new tab to exisitng $mw
in thread Perl-Tk Notebook - add a new tab to exisitng $mw

Hi,

Now I understand what you're talking about

Yup, once program ends, everything is gone

When running program again , your program has to recreate everything, every window tab text .... and load all the content into it

See ->parent and ->children from Tk::Widget , use it to find all the children of a mainwindow, and with a bit of recursion, all their childrens children ...

Also get Tk::WidgetDump , use it for figuring out Tk

  • Comment on Re^3: Perl-Tk Notebook - add a new tab to exisitng $mw

Replies are listed 'Best First'.
Re^4: Perl-Tk Notebook - add a new tab to exisitng $mw
by shankar.chandra (Initiate) on Sep 20, 2016 at 16:32 UTC
    Hi, first thanks for your replies. It helps me to move ahead instead stagnant. But then, I get errors like

    XStoSubCmd: Not a Tk Window Tk::die_with_trace at /perl_install/lib/Tk/Submethods.pm line 37

    Tk::MainWindow=HASH(0xa56e270) is not a widget

    I did a miniature of my code to get a 'hello' success:

    I run this with $window->Label(-text=>"Hello 1")->pack(); and then $window->Label(-text=>"Hello 2")->pack(); to print bothe Hello 1 and 2 in the same window, but I get errors on second run.

    use Tk; use Tk::Widget; #use Tk::WidgetDump; use Data::Dumper; use Storable; use B::Deparse; $Storable::Deparse=1; use Storable qw(freeze thaw); use Safe; #use strict; my $safe = new Safe; # because of opcodes used in "use strict": $safe->permit(qw(:default require)); local $Storable::Deparse = 1; local $Storable::Eval = sub { $safe->reval($_[0]) }; sub ShowLog { my $window; if(-e "mainwindow.store") {$window=retrieve("mainwindow.store");} if(!defined($window)) {$window = Tk::MainWindow->new();} if(defined($window)) { $window->Label(-text=>"Hello 1")->pack(); store \%{$window}, "mainwindow.store"; } MainLoop(); }

    with trial and error , 300+ google clicks etc makes me a bit tierd. I want to give up but then quite sure this cannot be that difficult to do, but could be i am making it difficult ? help?

      It seems you can't simply freeze a Tk window, its XS foundations don't survive. Just save a structure with all the important values, and let the script populate the window with the values if they exist.

      ($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,

      Um, I ... suggest coffee or a walk or something

      #!/usr/bin/perl -- use strict; use warnings; use Path::Tiny qw/ path /; use Tk; GoTk( @ARGV ); exit( 0 ); sub GoTk { my( $file ) = @_; my %vars = ( pack => [qw/ -expand 1 -fill both /], label => 'the label '.gmtime. ' ', text => 'the text '.gmtime. ' ', LoadSaved( $file ), ); my $mw = tkinit; $mw->Label( -text => $vars{label} )->pack( @{ $vars{pack} } ); $mw->Entry( -text => $vars{text} )->pack( @{ $vars{pack} } ); $mw->protocol('WM_DELETE_WINDOW', sub { eval { SaveLoaded( $file, { %vars, label => Chaild($mw, 'label')->cget(-text), text => Chaild($mw, 'Entry')->cget(-text), }); 1 } or warn $@; Tk::exit; }); $mw->MainLoop; } sub Chaild { my( $w, $class ) = @_; for my $kid ( $w->children ){ return $kid if ref($kid) =~ /\Q$class\E/i; } return; } sub SaveLoaded { my( $file , $vars ) = @_; path( $file )->spew_raw( map { my $k = $_; my $v = $vars->{$k}; $v = sprintf "qw' %s '", join ' ' , @$v if ref $v; "$k=$v\n" } keys %$vars ); } sub LoadSaved { my %stuff; local $@; for my $line ( eval { path(@_)->lines_raw } ){ $line =~ s/[\r\n]+$//; my( $key, $val ) = split /=/, $line, 2; next unless $key and $val; $val = [split ' ', $1] if $val =~ m{qw'(.*)'}; $stuff{$key}=$val; } warn $@ if $@; return %stuff; } __END__

        :P ...guru, awake now :)

        Thanks. That was super rapid!

        I ran GoTk.pm. I do a small change in $mw->Entry, then I close the first $mw, I reran and I saw the text change in the secondly created window. (understood that I closed the first mainwindow to save changes to the $file !)

        My need is, when I re-run, I should 'add' new tab to a notebook in first opened $mw itself. My need is not saving values from the first $mw on WM_DELETE_WINDOW event but updating the existing mainwindow.

        any chance for this ?

        if this is not possible, then is it possible to trigger a timer kind of thing from the GUI itself to check for updates on a file (at regular interval) and when the file is updated with a new line, the GUI adds a new tab.

        ...

Re^4: Perl-Tk Notebook - add a new tab to exisitng $mw
by Anonymous Monk on Sep 15, 2016 at 20:11 UTC
    So I understood that there is no chance to reuse my previously created window. dumb question: is it not possible to save "Tk::MainWindow=HASH(0xa1eeed8)" like this to a file and re-create the window handler in next run?

      So I understood that there is no chance to reuse my previously created window. dumb question: is it not possible to save "Tk::MainWindow=HASH(0xa1eeed8)" like this to a file and re-create the window handler in next run?

      Use Tk::WidgetDump, it uses ->configure/->cget/->children and a few other methods to introspect widgets (get their settings properties sizes bindings configuration colors text values data ...)

      Thats how you "save" a window to disk, you dump all its ocnfiguration and data ... and later you "load" it from disk ... you use ->configure/->cget/->children.....