Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
Home
Discussion GroupsGeneralPHPASPPerlColdFusionFlashHTML, CSS, ScriptsBrowsers

Webmaster Forum / Perl / Tk / August 2008



Tip: Looking for answers? Try searching our database.

Is there any way to change the parent of any widget?

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
roberts.cse@gmail.com - 21 Aug 2008 13:48 GMT
Hi All,

Can you kindly let me know how can I change the parent of any widget.

In my utility I need to sometime pack the stuffs inside a Notebook and
sometime show them in a top level window.

So, one way is to destroy all the children and recreate them - but
this needs to keep track of all the changes done by the user - which
is not so easy for me.

So, in this scenario only re-parenting can help me as all the internal
stuffs need not to be recreated.

I have the following sample program for re-parenting but it doesn't
work. Please have a look and let me know your valuable suggestion.

Please click on 'Undock' button.

Thanks and Regards,
Robert

=================================================================
use strict;
use warnings;

use Tk;
use Tk::NoteBook;

my $top = MainWindow->new;

my $frame = $top-> NoteBook()->pack(-side => 'top' , -fill => 'both', -
expand => '1');

my $page_frame = $frame->add( 'page1' , -label => 'Page1');

my $frame1 = $page_frame->Frame()->pack;

my $innerWindow = $frame1->Label( -text => 'Inner Window')->pack(-side
=> 'bottom' );

my $button = $frame1->Button( -text => 'Undock', -command =>
[ \&reparentInnerWindow, $innerWindow] )->pack(-side => 'bottom' );

MainLoop;

sub reparentInnerWindow
{
   my $innerWindow = shift;
   $innerWindow->packForget;

   my $outerWindow = $top->Toplevel(
           -title      => 'New Window',
           );

   my $frame = $outerWindow->Frame()->pack;
   $outerWindow->pack( -after => $frame ); #Try 2 pack the inner
window into this new window

   $outerWindow->withdraw;
   $outerWindow->deiconify;
   $outerWindow->raise;
   $outerWindow->grab;
}

__END__
Jack D - 22 Aug 2008 07:31 GMT
> Hi All,
>
[quoted text clipped - 9 lines]
> So, in this scenario only re-parenting can help me as all the internal
> stuffs need not to be recreated.

Alas. You are looking for tix --- wmRelease/wmCapture which worked great in
Tk800 but ever since 804, it has been broken.

http://groups.google.ca/group/comp.lang.perl.tk/msg/a3ec14ccafdda521

I had to redesign an application to remove this functionality and many users
were NOT pleased.

> I have the following sample program for re-parenting but it doesn't
> work. Please have a look and let me know your valuable suggestion.

The only "workaround" I can think of is to "duplicate" your entire frameset
within a withdrawn toplevel window and packForget the Notebook frame while
raising the toplevel. It's more overhead but I don't see any other way to do
this unless.....

I would hope that the tcl/Tk group have accepted and implement the TIP #125
put forward many years ago.

http://www.tcl.tk/cgi-bin/tct/tip/125

I'm crossing my fingers that Vadim or John Cerney can complete the bridge to
tcl/Tk and then this functionality should be doable once again.

http://groups.google.ca/group/comp.lang.perl.tk/msg/bc3638f56d716f76

Jack
John Cerney - 22 Aug 2008 13:22 GMT
There is some code in the Tk::IDElayout package that does this function.
  See the IDEtabFrameCaptureRelease.t test case for an example.

Also, there is the CaptureReleaseTest file in the distribution, which is
a debugging test of the function. This will capture/release an entry
widget from within a widget to a top-level when a button is pressed.

To perform this function, the Tk::IDElayout package supplies a fixed
version of wmCapture and wmRelease that overrides the broken (or
removed) default versions.

-John

>> Hi All,
>>
[quoted text clipped - 40 lines]
>
> Jack
Jack D - 23 Aug 2008 05:53 GMT
> There is some code in the Tk::IDElayout package that does this function.
> See the IDEtabFrameCaptureRelease.t test case for an example.
[quoted text clipped - 8 lines]
>
> -John

Looks very intriguing. I have asked Jean-Louis to add a ppm to bribes.org (I
cc'd you). I can't wait to look at it.

Jack
Michael Carman - 23 Aug 2008 02:54 GMT
> Can you kindly let me know how can I change the parent of any widget.
>
> In my utility I need to sometime pack the stuffs inside a Notebook and
> sometime show them in a top level window.

I'm probably missing something here, but is there a reason that you
can't use the -in option to pack() to insert widgets into a master
that's not their parent?

-mjc
Jack D - 23 Aug 2008 05:36 GMT
>> Can you kindly let me know how can I change the parent of any widget.
>>
[quoted text clipped - 6 lines]
>
> -mjc

Direct from the "pack" documentation:
#################
RESTRICTIONS ON MASTER WINDOWS

The master for each slave must either be the slave's parent (the default) or
a descendant of the slave's parent. This restriction is necessary to
guarantee that the slave can be placed over any part of its master that is
visible without danger of the slave being clipped by its parent.
#################

Jack
zentara - 23 Aug 2008 13:03 GMT
>>> Can you kindly let me know how can I change the parent of any widget.
>>>
[quoted text clipped - 18 lines]
>
>Jack

I've been sleeping with the enemy lately :-)  Gtk2 can do this easily.
If you really need this functionality, maybe you should switch?

There are ways with Tk. What you want to do, is store all your info from
the pages in hashes, don't rely on widgets to store your data. You can
use the notebook's raise and lower cmds to save all data on that page.
Then instead of reparenting, just rebuild new widgets with the same hash
data. Once you get the idea, it's not hard. I suppose if you had a
canvas on the notebook frame, and the user was drawing scribbles on it,
it could get tricky; but text and entry widget data is easily saved to
hashes when the info{'focus'} or raisecmd tells you a page change
occured.

But here is a Gtk2 example (ducking :-) )

#!/usr/bin/perl
use warnings;
use strict;
use Glib qw/TRUE FALSE/;
use Gtk2 '-init';

my $window = Gtk2::Window->new('toplevel');
$window ->signal_connect( 'destroy' => \&delete_event );
$window->set_border_width(10);
$window->set_size_request(300,200);
$window->set_position('center');

my $window1 = Gtk2::Window->new('toplevel');
$window1->hide_all();

my $vbox = Gtk2::VBox->new( FALSE, 6 );
$window->add($vbox);
$vbox->set_border_width(2);

my $label_w_markup = Gtk2::Label->new();
$label_w_markup->set_markup("<span background = 'black' foreground=
'green'
 size=\"20000\">Label with <i>markup</i></span>");

$vbox->pack_start($label_w_markup,FALSE,FALSE,4);   

my $hbox= Gtk2::HBox->new( FALSE, 6 );
$vbox->pack_end($hbox,FALSE,FALSE,0);
$hbox->set_border_width(2);

my $button = Gtk2::Button->new_from_stock('gtk-quit');
$hbox->pack_end( $button, FALSE, FALSE, 0 );
$button->signal_connect( clicked => \&delete_event );

my $button1 = Gtk2::Button->new('Reparent');
$hbox->pack_end( $button1, FALSE, FALSE, 0 );
$button1->signal_connect( clicked => \&reparent );

my $button2 = Gtk2::Button->new('Send back');
$hbox->pack_end( $button2, FALSE, FALSE, 0 );
$button2->signal_connect( clicked => \&oldparent );

$window->show_all();

Gtk2->main;

#####################################
sub reparent{
  $window1->show_all();
  $label_w_markup->reparent($window1);
}

sub oldparent{
  $label_w_markup->reparent($vbox);
  $window1->hide_all();
}

sub delete_event {
Gtk2->main_quit;
return FALSE;
}  
__END__

zentara

Signature

I'm not really a human, but I play one on earth.
http://zentara.net/Remember_How_Lucky_You_Are.html

skw - 28 Aug 2008 16:51 GMT
I agree with zentara's advice regarding storing the user data edits in
a hash structure.  Keeping the data independent of the gui will give
you a great deal more flexibility with your forms/widgets.

I built a form app in Tk for users in our department to track work
flow notes.  The forms include a variety of notebook tabs as well as
listbox, entry, label, and text widgets all of which are used to
display and/or edit the task notes details.  In order to provide the
flexibility to work with the same data in all these widgets is to
store the user data in a anonymous hash structure.  The widgets can
then be linked to whatever piece of data is needed, even the same data
that some other widget also uses.

Most of the widgets are tied to the hash by setting the -textvariable=>
$hash->{myfield}.   If the user clicks the save button the hash data
is updated into a database.  If the user elects to view saved data, a
query pulls it from the database and populates the hash making it
immediately available to the widgets.

With the data independent of the widgets, you should be able to
display/edit the same data in any part of the application without
trying to bounce widgets from parent to parent.  Save functions are
also easier to code since the data is all in one concise place. Moving
to a data independent structure will require some reworking but can
ultimately make your app much more flexible.

Hope this is helpful.

-skw
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.