Schrift
[thread]5053[/thread]

Entry & Scale via -textvariable: Problem...



<< |< 1 2 >| >> 16 Einträge, 2 Seiten
pktm
 2005-08-12 05:16
#44349 #44349
User since
2003-08-07
2921 Artikel
BenutzerIn
[Homepage]
user image
Hallo!

Ich habe da ein Programm bei dem man in einem Entry-Widget eine Zahl zwischen 0 und 100 eingeben können soll die dann auf einer Scale repräsentiert wird.

Wenn ich die beiden Widgets über das Attribut -textvariable=>\$wert verknüpfe gibt es das Problem, dass das Progtramm abstürzt, wenn der Benutzer etwas anderes als eine  Zahl eingibt.

Fehler:
Quote
Tcl_VarTraceProc returned 'can't assign non-numeric value to scale variable'

This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.


Leider klappt das Abfangen von invaliden Einagben im Entry-Widget mit Hilfe der Funktionen -validate=>'all', -validatecommand und -invalidCommand nicht.
Vollständiges Testscript:
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
44
45
#!/Perl/bin/perl

use strict;
use warnings;
use Tk;
use Tk::Scale;
use Tk::Balloon;

my $mw = Tk::MainWindow->new(-width=>150,-height=>150,);
$mw->gridPropagate(0);
$mw->packPropagate(0);

my $wert = 0;

my $e = $mw->Entry(-textvariable=>\$wert);

my $s = $mw->Scale(
-variable => \$wert,
-from => 0,
-to => 100,
-length => 50,
-showvalue => 0,
-sliderlength => 6,
-sliderrelief => 'raised',
-orient => 'horizontal',
);

$e->configure(
-validate => 'all',
-validatecommand => sub {
if( $wert =~ m/\D/g ) {
$wert =~ s/\D//g;
# invalid-command kommt hier zum Zuge
return 0;
}
return 1;
},
);



$e->pack();
$s->pack();

Tk::MainLoop;


Ich nehme mal an, dass das Problem daher rührt, dass $wert geändert wird, bevor es durch die Validation des Entry-Widgets geschickt wird. Deshalb wird auch versucht die Scale mit einem ungültigen Wert zu füttern.

Gibt es eine Möglichkeit das zu umgehen?
Die Scale hat glaube ich auch so etwas wie ein -validate - Kommando, aber so ganz habe ich das nicht verstanden (bin leider ein Englisch-Banause):
Quote
Name: command

Class: Command

Switch: -command

Specifies the prefix of a perl/Tk callback to invoke whenever the scale's value is changed via a method. The actual command consists of this option followed by a space and a real number indicating the new value of the scale.


> Gibt es eine Möglichkeit das zu umgehen?
Es gäbe natürlich auch die Möglichkeit (glaube ich), die Änderungen über eine Methode zu überwachen und bei gültigen Werten die Scale zu ändern.
Aber das habe ich bisher nicht hinbekommen (ist ja auch schon spät).
Öhm, das hat nicht zufällig schon jemand mal gemacht? :blush:

Grüße, pktm
http://www.intergastro-service.de (mein erstes CMS :) )
renee
 2005-08-12 10:31
#44350 #44350
User since
2003-08-04
14371 Artikel
ModeratorIn
[Homepage] [default_avatar]
Du kannst gleich im Entry das -validateCommand oder Strats CPAN:Tk::EntryCheck nutzen...
OTRS-Erweiterungen (http://feature-addons.de/)
Frankfurt Perlmongers (http://frankfurt.pm/)
--

Unterlagen OTRS-Workshop 2012: http://otrs.perl-services.de/workshop.html
Perl-Entwicklung: http://perl-services.de/
ptk
 2005-08-12 12:34
#44351 #44351
User since
2003-11-28
3645 Artikel
ModeratorIn
[default_avatar]
pktm
 2005-08-12 16:42
#44352 #44352
User since
2003-08-07
2921 Artikel
BenutzerIn
[Homepage]
user image
So, kurz gesagt: Es geht nicht!

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
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
#!/Perl/bin/perl

use strict;
use warnings;
use Tk;
use Tk::Scale;
use Tk::Balloon;
use Tk::NumEntryPlain;
use Tk::EntryCheck;
use Tk::NumEntry;

my $mw = Tk::MainWindow->new(-width=>150,-height=>150,);
$mw->gridPropagate(0);
$mw->packPropagate(0);

my $wert = 10;

my $s = $mw->Scale(
-variable => \$wert,
-from => 0,
-to => 100,
-length => 50,
-showvalue => 0,
-sliderlength => 6,
-sliderrelief => 'raised',
-orient => 'horizontal',
);

my $e = $mw->NumEntry(
-minvalue => 0,
-maxvalue => 100,
-width => 5,
-bell => 1,
-text => $wert,
);

my $l = $mw->Label(
-textvariable => \$wert,
);

# ------------ configure

$e->configure(
-validate => 'key',
-vcmd => sub{
if( main::setScale($e, $s) ){
return 1;
}else{
return 0;
}
},
);

$s->configure(
-command => sub{
main::setEntry($e, $s, \$wert);
},
);

$e->pack();
$s->pack();
$l->pack();

Tk::MainLoop;

sub setScale {
my ($e, $s) = @_;
# ist Wert ist auf jeden Fall numerisch
# $wert ist bereits durch -variable gesetzt
$e->configure(-text=>$wert);
return 1;
} # /setScale

sub setEntry {
my ($e, $s, $wert_ref) = @_;

# $zw kann "" sein
my $zw = $e->get();
if( $zw =~ m/.{0,0}/ ){
$zw = 0;
}
$$wert_ref = $zw;
$s->set($zw);
} # /setScale


Entweder bin ich einfach zu dumm um die Tk-Callbacks zu nutzen oder Tk ist zu dumm.
Aber wenn das so weiter geht lege ich mir einen Timer zu der alle 500ms die das Entry-Feld ausliest und bei Abweichung die Scale ändert (andersherum ist es kein Problem, -command bei funktioniert ja).

Kann man denn nicht einfach erzwingen, dass eine Methode bei jeglicher Input-Modifikation eines Entrys ausgeführt wird?
-validate = >'all' funktioniert bei mri nicht (um genau zu sein wird es manchmal 2mal, manchmal aber auch nur einmal ausgeführt und dann nicht mehr).

Geht sowas eventuell mit bind?

Grüße, pktm
http://www.intergastro-service.de (mein erstes CMS :) )
ptk
 2005-08-12 21:12
#44353 #44353
User since
2003-11-28
3645 Artikel
ModeratorIn
[default_avatar]
Du machst in deinem Code zu viel: Callbacks per -command UND -textvariable, NumEntry-eigene Validation UND selber mit -vcmd. Mach jeweils nur eins von beiden. Leider scheint es beim Teilen von -textvariable zwischen NumEntry und Scale einen Bug zu geben, so dass du wahrscheinlich nur mit Callbacks arbeiten solltest.
pktm
 2005-08-13 01:40
#44354 #44354
User since
2003-08-07
2921 Artikel
BenutzerIn
[Homepage]
user image
Ok,nachdem ich meiner Frustration durch das Verschlingen eines Dönsers Luft gemacht hatte habe ich nochmal ganz klein angefangen (sieht nur nach viel aus):
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
44
45
46
47
48
#!/Perl/bin/perl

use strict;
use warnings;
use Tk;
use Tk::Scale;
use Tk::Balloon;
use Tk::NumEntryPlain;
use Tk::EntryCheck;
use Tk::NumEntry;

my $mw = Tk::MainWindow->new(-width=>150,-height=>150,);
$mw->gridPropagate(0);
$mw->packPropagate(0);

my $wert = 10;

my $e = $mw->NumEntry(
-minvalue => 0,
-maxvalue => 100,
);

my $s = $mw->Scale(
-from => 0,
-to => 100,
-orient => 'horizontal',
);

my $l = $mw->Label(-textvariable=>\$wert,);

$e->configure(
-validate => 'key',
-vcmd => sub{ setScale($e, $s, $wert); },
);

$e->pack();
$s->pack();
$l->pack();

Tk::MainLoop;

sub setScale {
my ($e, $s, $wert) = @_;
my $zw = $e->get();
if( $zw =~ m/.{0,0}/ ){
print "Feld leer ($zw)!\n";
}
}


Dieser (vollständige) Code erzeigt ein kleines Fenster mit einem NumEntry, Einer Scale (die noch nicht benutzt wird) und einem Label zum Anzeigen der $wert-Variable.

Wenn ich jetzt über die Option -validate=>'key' Änderungen am Inhalt des Entry-Feldedes mit der Tastatur überwache erhalte ich seltsamerweise folgende Ausgabe:
Quote
Feld leer (100)!
Feld leer ()!


Mit der Tatsache, dass der Feldinhalt nur überprüft wird wenn man Enter drückt kann ich mich ja noch abfinden, aber ich verstehe nicht, warum da steht, dass mein Feld keinen Inhalt hätte obwohl vorher der Inhalt von 100 bestätigt wird unmd auch 100 drin steht.

Mir ist dieses Verhalten sehr suspekt.
Ich habe beschlossen meinem Programm die Möglichkeit die Zahl einzutippen zu nehmen, das Entry-Widget auf readonly zu setzen und statt dessen die Buttons von NumEntry in Verbindung mit der Scale zur Verfügung zu stellen.

Nichtsdestotrotz wäre es doch sinnvoll, wenn es einen Weg gäbe Änderungen an einem Widget zu überwachen.
Kann mir jemand gute Links zu bind und dergleichen schicken (perldoc bin ich bereits am welzen - harter Stoff für jemanden der schlecht Englisch kann)?

Grüße, pktm
http://www.intergastro-service.de (mein erstes CMS :) )
Crian
 2005-08-15 14:19
#44355 #44355
User since
2003-08-04
5866 Artikel
ModeratorIn
[Homepage]
user image
Du testest ob ein beliebiges Zeichen Null mal vorhanden ist in Deinem String. Das ist Unsinn.
s--Pevna-;s.([a-z]).chr((ord($1)-84)%26+97).gee; s^([A-Z])^chr((ord($1)-52)%26+65)^gee;print;

use strict; use warnings; Link zu meiner Perlseite
pktm
 2005-08-15 18:49
#44356 #44356
User since
2003-08-07
2921 Artikel
BenutzerIn
[Homepage]
user image
[quote=Crian,15.08.2005, 12:19]Du testest ob ein beliebiges Zeichen Null mal vorhanden ist in Deinem String. Das ist Unsinn.[/quote]
Ja, das ahbe ich auch gemerkt.
Das war einer der vielen Versuche eine leere Zeichenkette abzufangen.
Habe es dann wieder geändert.
http://www.intergastro-service.de (mein erstes CMS :) )
ptk
 2005-08-15 21:17
#44357 #44357
User since
2003-11-28
3645 Artikel
ModeratorIn
[default_avatar]
Und geht's jetzt?
pktm
 2005-08-16 00:20
#44358 #44358
User since
2003-08-07
2921 Artikel
BenutzerIn
[Homepage]
user image
Nun, wie gesagt, ich habe ein NumEntry im readonly-Modus, dafür aber mit Inc- und Decrementbuttons benutzt. Bei der Benutzung der Buttons (-browsecmd) wird die Scale per Methode angepasst und bei bewegung der Scale wird per Methode das NumEntry angepasst.
Aber ich finde es einfach schöner, wenn man die Zahl eingeben kann, immerhin sind manche Menschen sowas auch von professionellen Grafikprogrammen gewöhnt...
http://www.intergastro-service.de (mein erstes CMS :) )
<< |< 1 2 >| >> 16 Einträge, 2 Seiten



View all threads created 2005-08-12 05:16.