Perl/TK, Menüstruktuer mit Buttons
Steffen
- perl
Hallo liebe Forumsgemeinde,
bin Perl/TK Neuling und steh schon am Anfang vor nem kleinen Problem.
Beim Folgenden Script
will ich links nen paar Buttons haben und Links dann das Fenster wo man Arbeitet (je nachdem welches Menü durch den Button gewählt wurde)
jedoch erstellt der beim wechseln der Menüs durch die Buttons alles mehrfach...
Sicherlich muss ich das irgendwie schliessen...
klar mit destroy aber is das die korrekte lösung?
müsste sich das nicht überlagern???
am besten ihr schaut euch das kurze Script mal an und startet es dann wisst ihr was ich meine
DANKE & Gruß
Steffen
#! /usr/bin/perl -w
use strict;
use Tk;
use Tk::NoteBook;
use Win32::GUI;
my ($DOS) = Win32::GUI::GetPerlWindow();
Win32::GUI::Hide($DOS);
my $main = MainWindow->new;
my $frame_left=$main->Frame()->pack(-side => 'left');
my $frame_right=$main->Frame()->pack(-side => 'right');
my $schalter1 = $frame_left->Button("-text" => "Mitarbeiter","-height" => 2,"-width" => 10,"-command" => [&Show_Mitarbeiter] )
->pack();
my $schalter2 = $frame_left->Button("-text" => "Dienste","-height" => 2,"-width" => 10,"-command" => [&Show_Dienste] )
->pack();
my $schalter3 = $frame_left->Button("-text" => "Ende","-height" => 2,"-width" => 10,"-command" => sub { print "Zurück in der Konsole\n"; exit 0; } )
->pack();
MainLoop;
Win32::GUI::Show($DOS);
##############################################################
sub Show_Mitarbeiter {
#$frame_right->destroy;
my $radio1=$frame_right->Radiobutton(-text => "Optionsfeld 1" )
->pack();
my $radio2=$frame_right->Radiobutton(-text => "Optionsfeld 2")
->pack();
}
sub Show_Dienste {
my $nb = $frame_right->NoteBook()->pack();
my $page1 = $nb->add('PageID-1', -label => 'Dienste');
my $page2 = $nb->add('PageID-2', -label => 'neuer Dienst');
}
Halihallo Steffen
jedoch erstellt der beim wechseln der Menüs durch die Buttons alles mehrfach...
Sicherlich muss ich das irgendwie schliessen...
klar mit destroy aber is das die korrekte lösung?
Ich würde sagen: destroy :-)
Aaaaber: Du möchtest vielleicht nicht wirklich schliessen...
müsste sich das nicht überlagern???
Wieso? - Wenn du das Widget löschst, was soll sich dann noch
überlagern?
---
Grundsätzlich:
Wenn du links mehrere Buttons hast, die "staatisch" sind und rechts
dynamischen Inhalt (der z.B. durch drücken der linken Buttons
geändert wird), dann schmeiss den gesamten rechten Inhalt in ein
Frame-Widget (wie du es hast). Es ist dann einfach den Inhalt
auszutauschen, da alle Kinder implizit gelöscht/unsichtbar werden.
Das nur prinzipiell und so hast du es ja auch richtig gemacht.
Möglichkeit 1: In jede Subroutine folgendes einbauen:
$frame_right->destroy() if ($frame_right);
$frame_right = $main->Frame()->pack(-side => 'right');
... frame neu aufbauen ...
Damit sollte es funktionieren.
Es ist, sagen wir mal, keine schöne Lösung... Der Window-Manager
muss den Frame bei jedem Buttonclick neu erstellen, was natürlich
Zeit kostet und visuell über "flackern" wahrgenommen wird. Besser ist
es für jeden Button bereits ein Frame mit Content zu erstellen und
diesen dann anzuzeigen, wenn der entsprechende Button gedrückt wurde.
Falls nachher ein anderer Button gedrückt wird, soll der Frame wieder
versteckt werden und der für den Button geeigneten Frame angezeigt
werden (Möglichkeit II).
Dein Beispiel angepasst an Möglichkeit II:
Die Frames für ButtonI und ButtonII werden bereits vor MainLoop
erstellt. Da sie jedoch durch keinen Geometry Manager (pack,...)
gejagt werden, sind sie vorerst unsichtbar. Falls ein Button gedrückt wird (somit eine deiner Subroutinen aufgerufen wird), wird
einfach der _entsprechende_ Frame mit pack sichtbar und der
andere (falls aktiv) mit packForget unsichtbar gemacht.
So einfach und so effizient :-)
#!/usr/bin/perl
use strict;
use warnings;
use Tk;
use Tk::NoteBook;
my $main = MainWindow->new();
my $frame_left=$main->Frame()->pack(-side => 'left');
my $frame_right=$main->Frame()->pack(-side => 'right');
my $fr1 = $frame_right->Frame();
$fr1->Radiobutton(-text => "Optionsfeld 1" )->pack();
$fr1->Radiobutton(-text => "Optionsfeld 2" )->pack();
my $fr2 = $frame_right->Frame();
my $nb = $fr2->NoteBook();
$nb->pack();
$nb->add('PageID-1', -label => 'Dienste');
$nb->add('PageID-2', -label => 'neuer Dienst');
my $schalter1 = $frame_left->Button("-text" => "Mitarbeiter","-height" => 2,"-width" => 10,"-command" => [&Show_Mitarbeiter] )
->pack();
my $schalter2 = $frame_left->Button("-text" => "Dienste","-height" => 2,"-width" => 10,"-command" => [&Show_Dienste] )
->pack();
my $schalter3 = $frame_left->Button("-text" => "Ende","-height" => 2,"-width" => 10,"-command" => sub { print "Zurück in der Konsole\n"; exit 0; } )
->pack();
MainLoop;
##############################################################
##############################################################
sub Show_Mitarbeiter {
$fr1->pack( -side => 'top' );
$fr2->packForget();
}
sub Show_Dienste {
$fr2->pack( -side => 'top' );
$fr1->packForget();
}
Viele Grüsse
Philipp