Thread Tk: Toplevel funktioniert nicht bei 2tem Aufruf
(9 answers)
Opened by Juergen at 2011-03-02 08:51
Hallo Jürgen,
hier ein paar Beispiele: kleines Beispiel für Toplevel Windows. Da ich hier sowohl für das Main Window als auch für die Toplevel Windows die gleichen Widgets benutze, hab ich sie einfach mal in eine sub ausgelagert. Mit dem Button kann "Create Toplevel Window" Button kann man nun vom Main Window als auch von bereits erzeigten Toplevel Windows aus neue Toplevels erstellen. Dabei hängen alle erzeugten Toplevel Windows hängen am Main Window und sind voneinander unabhängig. So ungefähr: Code (perl): (dl
)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 #!/usr/local/bin/perl use strict; use warnings; use Tk; #main window my $mw = MainWindow->new(-title=>'Main Window'); create_widgets($mw); MainLoop(); sub create_toplevel_window { # create toplevel window my $top=$mw->Toplevel(-title=>"Toplevel Window"); # create toplevel frames create_widgets($top); } sub create_widgets { my $thiswindow = shift; my $frame_top = $thiswindow->Frame-> pack(-side=>'top',-fill => 'both', -anchor,'nw'); my $frame_bottom = $thiswindow->Frame-> pack(-side=>'top',-fill => 'both', -anchor,'nw'); my $edit_button = $thiswindow->Button(-text => "Create Toplevel Window",-state => 'normal',-width => 30,-activebackground=>'gray', -command => sub{create_toplevel_window()})->pack (-in => $frame_top,-side=>'top',-padx => 3,-pady => 5); my $mw_close_button = $thiswindow->Button(-text => 'Close',-background=>'gray',-width=>60,-command => sub{$thiswindow->destroy})->pack(-in=>$frame_bottom,-side => 'top',-expand => '0',-fill => 'x'); } Im folgenden Beispiel hänge ich die Toplevel Windows an das Window, das den Aufruf ausführt. Erzeuge ich damit mehrere Toplevels und schliesse ein übergeordnetes Window, dann werden alle daran hängenden und darunterliegenden Windows geschlossen. So ungefähr: Code: (dl
)
1 |-Toplevel Code (perl): (dl
)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 #!/usr/local/bin/perl use strict; use warnings; use Tk; #main window my $mw = MainWindow->new(-title=>'Main Window'); create_widgets($mw); MainLoop(); sub create_toplevel_window { my $thiswindow = shift; # create toplevel window my $top=$thiswindow->Toplevel(-title=>"Toplevel Window"); # create toplevel frames create_widgets($top); } sub create_widgets { my $thiswindow = shift; my $frame_top = $thiswindow->Frame-> pack(-side=>'top',-fill => 'both', -anchor,'nw'); my $frame_bottom = $thiswindow->Frame-> pack(-side=>'top',-fill => 'both', -anchor,'nw'); my $edit_button = $thiswindow->Button(-text => "Create Toplevel Window",-state => 'normal',-width => 30,-activebackground=>'gray', -command => sub{create_toplevel_window($thiswindow)})->pack (-in => $frame_top,-side=>'top',-padx => 3,-pady => 5); my $mw_close_button = $thiswindow->Button(-text => 'Close',-background=>'gray',-width=>60,-command => sub{$thiswindow->destroy})->pack(-in=>$frame_bottom,-side => 'top',-expand => '0',-fill => 'x'); } Das dritte Beispiel dürfte deinem Anliegen nahe kommen. Aus dem Main Window wird ein Toplevel gestartet. Im Toplevel werden daten geladen und in einer MListbox angezeigt. Ein Add Button sorgt dafür, daß neue Daten hinzugefügt werden können. Der Refresh Button ist nicht wirklich bedeutsam, da die MListbox nach dem Hinzufügen durch die sub fill_tasklist refreshed wird. aber der Refresh Button bewirkt auch eine Dumper Ausgabe in der Shell. Code (perl): (dl
)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 #!/usr/local/bin/perl use strict; use warnings; use Tk; use Tk::MListbox; use Tk::DialogBox; use Tk::LabEntry; use Data::Dumper; #main window my $mw = MainWindow->new(-title=>'Main Window'); my $frame_top = $mw->Frame-> pack(-side=>'top',-fill => 'both', -anchor,'nw'); my $frame_bottom = $mw->Frame-> pack(-side=>'top',-fill => 'both', -anchor,'nw'); my $edit_button = $mw->Button(-text => "Edit Tasks",-state => 'normal',-width => 30,-activebackground=>'gray', -command => sub{edit_tasks()})->pack (-in => $frame_top,-side=>'top',-padx => 3,-pady => 5); my $mw_close_button = $mw->Button(-text => 'Close',-background=>'gray',-width=>60,-command => sub{$mw->destroy})->pack(-in=>$frame_bottom,-side => 'top',-expand => '0',-fill => 'x'); MainLoop(); sub edit_tasks { # load your data my $tasks=load_data(); # create toplevel window my $top=$mw->Toplevel(-title=>"Toplevel Window"); # create toplevel frames my $frame_top = $top->Frame-> pack(-side=>'top',-fill => 'both', -anchor,'nw'); my $frame_bottom = $top->Frame-> pack(-side=>'top',-fill => 'both', -anchor,'nw'); my $tasklist = $top->Scrolled('MListbox', -scrollbars => 'ose',-separatorcolor => 'darkgrey',-height=>15,-width=>300)->pack(-in=>$frame_top,-expand=>1,-fill=>'both'); $tasklist->columnInsert('end',-text=>'Task',-width=>15); $tasklist->columnInsert('end',-text=>'Date',-width=>15); $tasklist->columnInsert('end',-text=>'Time',-width=>15); #buttons my $add_button = $top->Button(-text => "Add Task",-state => 'normal',-width => 30,-activebackground=>'gray', -command => sub{add_task($top,\$tasks); fill_tasklist($tasklist,\$tasks);})->pack (-in => $frame_top,-side=>'top',-padx => 3,-pady => 5); my $refresh_button = $top->Button(-text => "Refresh",-state => 'normal',-width => 30,-activebackground=>'gray', -command => sub{fill_tasklist($tasklist,\$tasks);})->pack (-in => $frame_top,-side=>'top',-padx => 3,-pady => 5); my $mw_close_button = $top->Button(-text => 'Close',-background=>'gray',-width=>60,-command => sub{$top->destroy})->pack(-in=>$frame_bottom,-side => 'top',-expand => '0',-fill => 'x'); fill_tasklist($tasklist,\$tasks); } sub add_task { my $parent=shift; my $tasksref=shift; my $tasks=$$tasksref; my $ewidth=40; my $thistaskname; my $thisdate; my $thisstart; my $thisstop; my $add_dialog = $parent->DialogBox( -title => "Add task",-buttons => [ "Save", "Cancel" ] ); my $task_entry=$add_dialog->LabEntry(-label => "Task ", -bg=>'white', -labelFont => 'monospaced8', -labelPack => [-side => "left", -anchor => "w"], -width => 30, -textvariable => \$thistaskname)->pack(-side => "top", -anchor => "nw", -fill=>'x'); my $date_entry1=$add_dialog->LabEntry(-label => "Date ", -bg=>'white', -labelFont => 'monospaced8', -labelPack => [-side => "left", -anchor => "w"], -width => $ewidth, -textvariable => \$thisdate)->pack(-side => "top", -anchor => "nw", -fill=>'x'); my $time_start_entry=$add_dialog->LabEntry(-label => "Time Start ", -bg=>'white', -labelFont => 'monospaced8', -labelPack => [-side => "left", -anchor => "w"], -width => $ewidth, -textvariable => \$thisstart)->pack(-side => "top", -anchor => "nw", -fill=>'x'); my $time_stop_entry=$add_dialog->LabEntry(-label => "Time Stop ", -bg=>'white', -labelFont => 'monospaced8', -labelPack => [-side => "left", -anchor => "w"], -width => $ewidth, -textvariable => \$thisstop)->pack(-side => "top", -anchor => "nw", -fill=>'x'); $task_entry->focus; #set focus depending on type of command (add,edit) and erros (alias,user or password invalid) my $clicked_button = $add_dialog->Show; if ($clicked_button eq 'Save') { my $thistime="$thisstart\-$thisstop"; push(@{$tasks->{$thistaskname}->{$thisdate}},$thistime); } } sub fill_tasklist { my $tasklistwidget=shift; my $tasksref=shift; my $tasks=$$tasksref; $tasklistwidget->delete(0,'end'); foreach my $thistaskname (sort keys %{$tasks}) { foreach my $thisdate (sort keys %{$tasks->{$thistaskname}}) { foreach my $thistime (@{$tasks->{$thistaskname}->{$thisdate}}) { my @row; push(@row,$thistaskname); push(@row,$thisdate); push(@row,$thistime); $tasklistwidget->insert('end', [@row]); $tasklistwidget->see('end'); $tasklistwidget->update; } } } print Dumper($tasks); } sub load_data { my $tasks; my $pos= tell(DATA); while (<DATA>) { chomp $_; my @line=split(/,/,$_); my $thistaskname=$line[0]; my $thisdate=$line[1]; my $thisstart=$line[2]; my $thisstop=$line[3]; my $thistime="$thisstart\-$thisstop"; push(@{$tasks->{$thistaskname}->{$thisdate}},$thistime); } seek DATA, $pos, 0; return $tasks; } __DATA__ Task1,20110329,08:00,12:00 Task2,20110329,13:00,18:00 Task3,20110330,09:00,17:00 Gruß Kalle |