Schrift
Wiki:Tipp zum Debugging: use Data::Dumper; local $Data::Dumper::Useqq = 1; print Dumper \@var;
[thread]5310[/thread]

Dynamische Buttons

Leser: 1


<< |< 1 2 >| >> 13 Einträge, 2 Seiten
Kean
 2007-04-25 17:01
#46306 #46306
User since
2004-08-18
463 Artikel
BenutzerIn

user image
Ich habe ein kleines Programm geschrieben mit dynamische Buttons. Die Buttons werden mit einer forSchleife erzeugt und mit Daten aus einer Ini-Datei gefüllt. Das klappt auch wunderbar. Alle Buttons werden mit ihrem individuellen Namen angelegt.
Jetzt möchte ich bei jedem Button beim Clicken eine eigene Routine ausführen. Hierbei musste ich allerdings feststellen das Perl hier die Sub-Routine erst beim clicken erstellt bzw. die Variablen in der Routine alle den gleichen (letzten) Wert haben.
Quasi ist jeder Button mit dem Code des letzten Buttons belegt.
Gibt es eine Möglichkeit das ich hier elegant rausfinden/abfragen kann welcher Button gedrückt wurde???

Hier mal der Code:

Code: (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
for (my $button=0; $button < readini(PRODUKTE, ANZAHL, 'produkte.ini'); $button++)
{
$produktnr[$button] = 'PRODUKT'.$button;
($textbutton = readini($produktnr[$button], NAMEDISPLAY, 'produkte.ini')) =~ s/\\n/\n/g;
$fontface = readini($produktnr[$button], FONTDISPLAY, 'produkte.ini');
$buttoncolor = readini($produktnr[$button], BUTTONCOLOR, 'produkte.ini');
$placex=readini($produktnr[$button], X, 'produkte.ini');
$placey=readini($produktnr[$button], Y, 'produkte.ini');
$placeh=readini($produktnr[$button], H, 'produkte.ini');
$placew=readini($produktnr[$button], W, 'produkte.ini');
$mw->Button( -text => $textbutton,
                       -relief => "raised",

-font => $fontface,

-background => $buttoncolor,

-activebackground => $buttoncolor,

-command => sub { print $produktnr[$button];if (readini($produktnr[$button], AKTIV, 'produkte.ini') == 1) {


 print "bindrin";$wahl = readini($produktnr[$button], NAMEBON, 'produkte.ini');


 $wert = readini($produktnr[$button], PREIS, 'produkte.ini');


 $pfand_kz = readini($produktnr[$button], PFAND, 'produkte.ini');


 $pfand_wert = readini($produktnr[$button], PFANDWERT, 'produkte.ini');


 $pid = 0; for($i=0;$i<$menge_wahl;$i++) { &ausgabesumme; &print;}


 $storno_kz = 0; $menge_wahl = 1;}


 }
                       )->place( -x => $placex, -y => $placey, -height => $placeh, -width => $placew);
}
Froschpopo
 2007-04-25 17:24
#46307 #46307
User since
2003-08-15
2653 Artikel
BenutzerIn
[default_avatar]
Hi,

du legst ja in deiner Schleife auch keinen neuen Button an, sondern schreibst einen immer wieder neu, nämlich $mw->Button().
Einen einmaligen Button legst du z.b. so an:
Code: (dl )
1
2
$count++;
$mw{$count}->Button(...)

Das ist sowieso besser, denn so kannst du später auch jeden Button über seine ID modifzieren\n\n

<!--EDIT|Froschpopo|1177507564-->
Kean
 2007-04-25 17:27
#46308 #46308
User since
2004-08-18
463 Artikel
BenutzerIn

user image
Ich dachte ich lege so x-verschiedene Buttons an. Es werden ja auch x-buttons angezeigt mit verschiedenen texten und farben z.b.

wie kann ich die ID eines Buttons auslesen?
Kean
 2007-04-25 17:30
#46309 #46309
User since
2004-08-18
463 Artikel
BenutzerIn

user image
Also mit :

Code: (dl )
$mw{$button}->Button(...)


bringt er mir folgende Fehlermeldung:

Code: (dl )
1
2
3
4
5
C:\Dokumente und Einstellungen\Kai\Desktop\BonPlus>Bonplus_test2.pl
Name "main::mw" used only once: possible typo at C:\Dokumente und Einstellungen\
Kai\Desktop\BonPlus\Bonplus_test2.pl line 77.
Can't call method "Button" on an undefined value at C:\Dokumente und Einstellung
en\Kai\Desktop\BonPlus\Bonplus_test2.pl line 90.
Froschpopo
 2007-04-25 17:31
#46310 #46310
User since
2003-08-15
2653 Artikel
BenutzerIn
[default_avatar]
Du musst ja vorher auch den Wert mit dem Button befüllen
Code: (dl )
1
2
3
4
$buttons{klickbutton} = $mw->Button(
-variable =>\&passwort_speichern,
-text => 'Passwort speichern'
)->pack;

die ids hast du alle in %buttons
Das ist dasselbe wie:
Code: (dl )
1
2
3
4
$klickbutton = $mw->Button(
-variable =>\&passwort_speichern,
-text => 'Passwort speichern'
)->pack;

aber dann hättest du die ids nicht bequem in einer Liste :)

Das bringt dir z.b. folgende Vorteile:
Code: (dl )
$buttons{klickbutton}->configure(-state => 'enable');

du kommst auf diesem Weg bequem an jeden Button in deiner %buttons-Liste.\n\n

<!--EDIT|Froschpopo|1177508140-->
Kean
 2007-04-25 17:36
#46311 #46311
User since
2004-08-18
463 Artikel
BenutzerIn

user image
Da gibt es leider einen Syntaxerror.
Froschpopo
 2007-04-25 17:42
#46312 #46312
User since
2003-08-15
2653 Artikel
BenutzerIn
[default_avatar]
das kann gut sein, nämlich dann, wenn du später versuchst über $mw->Button auf einen der Buttons zuzugreifen, denn die existieren dann ja nicht mehr.
Das betrifft alles, was mit dem Button zu tun hat.
Auch ein späteres place geht dann nur noch, wenn du den _einmaligen_ Button konkret ansprichst: $buttons{$id}->place()

Du musst quasi deine Denkweise etwas ändern und die Fehlermeldung rausrücken ;)

Übrigens mag ich place irgendwie nicht. Das sieht so schlampig aus, ein bisschen wie in CSS dieses komische position:fixed das mag ich nämlich auch nicht.\n\n

<!--EDIT|Froschpopo|1177508729-->
Kean
 2007-04-25 19:40
#46313 #46313
User since
2004-08-18
463 Artikel
BenutzerIn

user image
Also ich steig da nicht so durch. Ich will ja nicht über die id auf den Button zugreifen sondern über den button und das Sub auf eine Funktion und dort eben die id übergeben.

Hab es auch mal ausprobiert wie du es vorgeschlagen hast:

Code: (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
for (my $button=0; $button < readini(PRODUKTE, ANZAHL, 'produkte.ini'); $button++)
{
$produktnr[$button] = 'PRODUKT'.$button;
($textbutton = readini($produktnr[$button], NAMEDISPLAY, 'produkte.ini')) =~ s/\\n/\n/g;
$fontface = readini($produktnr[$button], FONTDISPLAY, 'produkte.ini');
$buttoncolor = readini($produktnr[$button], BUTTONCOLOR, 'produkte.ini');
$placex=readini($produktnr[$button], X, 'produkte.ini');
$placey=readini($produktnr[$button], Y, 'produkte.ini');
$placeh=readini($produktnr[$button], H, 'produkte.ini');
$placew=readini($produktnr[$button], W, 'produkte.ini');
my $buttons{$button} = $mw->Button( -text => $textbutton,
-relief => "raised",

-font => $fontface,

-background => $buttoncolor,

-activebackground => $buttoncolor,

-command => sub { print $produktnr[$button];if (readini($produktnr[$button], AKTIV, 'produkte.ini') == 1) {


print "bindrin";$wahl = readini($produktnr[$button], NAMEBON, 'produkte.ini');


$wert = readini($produktnr[$button], PREIS, 'produkte.ini');


$pfand_kz = readini($produktnr[$button], PFAND, 'produkte.ini');


$pfand_wert = readini($produktnr[$button], PFANDWERT, 'produkte.ini');


$pid = 0; for($i=0;$i<$menge_wahl;$i++) { &ausgabesumme; &print;}


$storno_kz = 0; $menge_wahl = 1;}


}
)->place( -x => $placex, -y => $placey, -height => $placeh, -width => $placew);
}


Hier kommt aber folgende Fehlermedlung:
Code: (dl )
1
2
3
4
5
C:\Dokumente und Einstellungen\Kai\Desktop\BonPlus>Bonplus_test2.pl
syntax error at C:\Dokumente und Einstellungen\Kai\Desktop\BonPlus\Bonplus_test2
.pl line 77, near "$buttons{"
Execution of C:\Dokumente und Einstellungen\Kai\Desktop\BonPlus\Bonplus_test2.pl
aborted due to compilation errors.
Kean
 2007-04-25 19:42
#46314 #46314
User since
2004-08-18
463 Artikel
BenutzerIn

user image
Nochmal zum besser verständnis. Das Programm besteht NUR aus Buttons und jeder Button ruft die gleiche Routine auf allerdings mit unterschiedlichen Werten.
An den Buttons wird nach dem generieren nichts mehr geändert.
PerlProfi
 2007-04-25 20:15
#46315 #46315
User since
2006-11-29
340 Artikel
BenutzerIn
[default_avatar]
Wenn sie später nicht verändert werden, musst du sie natürlich nicht speichern, benutze stattdessen ein anon. Array als Wert für -command.

Also anstatt:
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
-command => sub { print $produktnr[$button];if (readini($produktnr[$button], AKTIV, 'produkte.ini') == 1) {


print "bindrin";$wahl = readini($produktnr[$button], NAMEBON, 'produkte.ini');


$wert = readini($produktnr[$button], PREIS, 'produkte.ini');


$pfand_kz = readini($produktnr[$button], PFAND, 'produkte.ini');


$pfand_wert = readini($produktnr[$button], PFANDWERT, 'produkte.ini');


$pid = 0; for($i=0;$i<$menge_wahl;$i++) { &ausgabesumme; &print;}


$storno_kz = 0; $menge_wahl = 1;}


}

Schreibst du dir eine Subroutine (z.B. button_callback) und übergibst ihr folgendermaßen die benötigten Werte:
Code: (dl )
-command => [\&button_callback, $produktnr[$button]]

Das Problem gab es schon mal in einem früheren Thread.
Da hat Sucher erklärt, dass man in solchen Fällen keine anon. Subroutine mit den globalen Variablen verwenden kann.

MfG\n\n

<!--EDIT|PerlProfi|1177517809-->
<< |< 1 2 >| >> 13 Einträge, 2 Seiten



View all threads created 2007-04-25 17:01.