2.Teil: WxPerl Dialoge und Events

Joachim on 13.3.2016

Das erste Ereignis

In Wx können manche Widgets über ein Dutzend Ereignisse auslösen. Das Ereignis selbst ist, wie fast alles in Wx, ein Objekt, hier eine abgeleiteten Klasse von Wx::Event. Um einen Callback für das Drücken des Buttons zu definieren, brauch es die Zeile:

Wx::Event::EVT_BUTTON(
            $knopf,
 $knopf,
 sub { $frame->SetTitle('Wurde geändert!') }
);
Als Grundlage nutzte ich die Tutorials von Herbert Breunung ( http://lichtkind.de/) aus dem Perl-Magazin $foo. Dieses Magazin wird leider nicht mehr vertrieben.

Dies ist wieder die "bewegliche" Version, ohne Anmeldung. Mit einem vorangehenden

use Wx::Event qw(EVT_BUTTON);

oder

use Wx::Event qw( :everything );

reicht ein

EVT_BUTTON(
            $knopf,
 $knopf,
 sub { $frame->SetTitle('Wurde geändert!') }
);

Weil WxPerl die WxWidgets-Schreibweise emuliert besitz EVT_BUTTON die gleiche Schreibweise wie Konstanten. In C++ sind Konstanten, Menü und Eventdefinition mit Macros gelöst, die per Konvertion so geschrieben werden.

Einfache Dialoge

MessageBox und CO die immer wieder benötigt werden.

Wx::MessageBox

Wx::MessageBox ist vielfältig einsetzbar! Der erste und einzig notwendige Parameter ist die Botschaft, gefolgt von der Überschrift (Titelleiste) und dem Style. Es können auch noch Elternwidget und Koordinaten angegeben werden. Entscheidend ist der Stil, da er bestimmt, welches Icon im Dialog erscheint und welche Knöpfe er hat. Folgende Stile sind hier wählbar: • wxICON_ERROR • wxICON_EXCLAMATION • wxICON_QUESTION • wxICON_INFORMATION Als Knöpfe stehen zur Verfügung: • wxYES • wxNO • wxCANCEL • wxOK • für wxYES|wxNO gibt es noch die Schreibweise wxYES_NO • default is wxICON_INFORMATION|wxOK Beispiel:

my $ret = Wx::MessageBox(
	'Wirklich beenden?',
	'Es ist doch grad so schön.',
	wxYES_NO | wxICON_QUESTION
);
app_herunterfahren() if $ret == wxYES;

Dateiauswahl mit Wx::FileSelector

Das FD in der Konstante steht für File Dialog und ist eine erst kürzlich eingeführte Gruppe von Konstanten. Mit dem setzen der Konstante wxFD_MULTIPLE können mehrere Dateien ausgewählt werden. Beispiel:

my $datei = Wx::FileSelector(
		'Datei auswählen',# Ueberschrift
		'.',
 					# Startverzeichnis
		'',
 		 			# Text im Dateinamefeld
		'',
 					# ausgewählte Filter
		"*.*",
 					# alle Filter
		wxFD_OPEN			        # Art des Dialogs
	);

Hinweis zum Parameter "alle Filter". Mit *.* werden alle Dateien angezeigt, möchte ich aber nur Perl-Skripte mit der Endung pl sehen muss ich den Filter auf "*.pl" setzen. Sollen mehrere Filter gesetzt werden ist die Logik folgende:

"Perl Dateien (*.pl;*.pm)|*.pl;*.pm|'.
'Alle Dateien (*.*)|*.*"    

Hier sollen alle Perl Skripte und Package Dateien angezeigt werden. Der erste Filter ist der aktuell vom Dialog verwendete. Senkrechte Striche trennen nicht nur die Filtergruppen, sondern den ersten und zweiten Teil des Filters, wobei der erste Teil der sichtbare Text ist.

Verzeichnisauswahl mit Wx::DirSelector

Beispiel:

my $dirname = Wx::DirSelector(
		'Verzeichnis auswählen'				
);

Weitere Standarddialoge: • Wx::GetColourFromUser • Wx::GetFontFromUser • Wx::GetNumberFromUser • Wx::GetTextFromUser Beispielprogramm:

use strict;
use warnings;
# Das Paket ServusWelt wird durch den Befehl use base ...; zum Hauptprogramm,
# da es dadurch von Wx::App alle Methoden erbtum ein vollständiges WxPerl-Programm zu sein.
package EventDialog;
# Es müssen alle benötigten Konstanten angemeldet werden
# z.B. use Wx qw(wxYES_NO wxICON_QUESTION);
# Während der Entwicklung ist es sinnvoll :everything anzugeben!
use Wx qw(:everything);
# Bei Listen von Strings ist es mithilfe des Listenoperators qw möglich,
 auf Kommata und 
# doppelte Anführungszeichen zu verzichten. Die einzelnen Strings werden dann nur 
# durch Leerzeichen getrennt. 
use base qw(Wx::App);
# Lediglich die Methode OnInit definieren wir hier neu,
 um zu bestimmen was bei Programmstart 
# ausgeführt wird
sub OnInit{
	my $app = shift;
	# Hier wird das Hauptfenster erstellt. Da es kein übergeordnetes Widget hat,
	# bleibt für den ersten Parameter nur undef,
  ID's sind jetzt auch noch unwichtig also 
	# wird der zweite Parameter auf "-1" gesetzt. Parameter 3 ist die Überschrift des Fensters,
	# Para 4 die Position die per default mittig ist und Para 5 die Größe.
	my $frame = Wx::Frame->new( undef,
  -1,
 'WxPerl Events u. Dialoge',
 [-1,
 -1],
 [300,
 300],
 );
	# Panel,
  Fläche auf der Widgets plaziert werden. Der nackte Hintergrund eines Wx::Frame
	# ist absichtlich optisch nicht dazu geeignet,
 darauf Knöpfe zu legen,
 da deren Hintergrundfarbe
	# tranparent ist und damit das dunkle Grau des Hauptfensters annehmen würde. Da das Panel 
  # weder Position noch Größe kennt,
  nimmt es automatisch den ganzen Hintergrund des 
	# Hauptfensters ein.
	my $panel = Wx::Panel->new( $frame,
 -1 );
	# Hier wird auf dem Panel noch ein Button zugefügt
	# [20,
 20] 	= Fensterposition - Array mit einer x und einer y-Koordinate - Optional
	# [250,
 40]	= Größe des Buttons - Array mit Breite und Höhe - Optional
	my $knopf 	= Wx::Button->new( $panel,
 -1,
 'MessageBox ',
 [20,
 20],
  [250,
 40]);
	my $knopf1 	= Wx::Button->new( $panel,
 -1,
 'MessageBox ',
 [20,
 70],
  [250,
 40]);
	my $knopf2 	= Wx::Button->new( $panel,
 -1,
 'Wx::FileSelector',
 [20,
 120],
 [250,
 40]);
	my $knopf3 	= Wx::Button->new( $panel,
 -1,
 'Wx::DirSelector',
 [20,
 170],
 [250,
 40]);
	# Definition EVENTS
	Wx::Event::EVT_BUTTON( $knopf, $knopf, \&dialog1 );
	Wx::Event::EVT_BUTTON( $knopf1,$knopf1,\&dialog2 );
	Wx::Event::EVT_BUTTON( $knopf2,$knopf2,\&dialog3 );
	Wx::Event::EVT_BUTTON( $knopf3,$knopf3,\&dialog4 );
	# Fenster zeichnen
	$frame->Show(1);
	# Fenster als oberstes bestimmem
	$app->SetTopWindow( $frame );
	# Das abschließende 1; ist der Rückgabewert, der uns versichert das die Applikation
	# wiklich gestartet wird.
	1;
}
# MessageBox Abfrage
sub dialog1{
	my($self,
 $event) = @_;
	my $ret = Wx::MessageBox(
		'Wirklich beenden?',
 		'Es ist doch grad so schön.',
 		wxYES_NO | wxICON_QUESTION
	);
	# Ändert den Title des Buttons!
	$self->SetTitle('wurde gedrückt!');
}
# Für Warnungen empfiehlt sich wxICON_EXCLAMATION
sub dialog2{
	my($self,
 $event) = @_;
	my $ret = Wx::MessageBox(
		'Es ist ein Fehler aufgetreten.',
 		'WARNUNG',
 		wxICON_EXCLAMATION
	);
	# Ändert den Title des Buttons!
	$self->SetTitle('wurde gedrückt!');
}
sub dialog3{
	my($self,
 $event) = @_;
	my $datei = Wx::FileSelector(
			'Datei auswählen',  							# Ueberschrift
			'.',   												# Startverzeichnis
			'',													# Text im Dateinamefeld
			'',													# ausgewählte Filter
			"Perl Dateien (*.pl;*.pm)|*.pl;*.pm|". 	# Filter Perl Skripte und Package Dateien
			"Alle Dateien (*.*)|*.*",							# alle Filter
			wxFD_OPEN | wxFD_MULTIPLE									# Art des Dialogs
		);
	# Ändert den Title des Buttons!
	$self->SetTitle('wurde gedrückt!');
}
sub dialog4{
	my($self,
  $event) = @_;
	my $dirname = Wx::DirSelector(
			'Verzeichnis auswählen'
		);
	$self->SetTitle('wurde gedrückt!');
}
sub spring_weg {
	my $frame = shift;
	my $screen = Wx::GetDisplaySize();
	my ($x_size,
  $y_size) = $frame->GetSizeWH();
	my $x_pos = int rand $screen->GetWidth() - $x_size;
	my $y_pos = $y_size; # int rand $screen->GetHeigth() - $y_size;
	$frame->SetSize( $x_pos,
 $y_pos,
  $x_size,
  $y_size );
}
package main;
# Programminstanz erzeugen und starten
EventDialog->new->MainLoop;

WX_DIALOG

Zurück