Schrift
[thread]5182[/thread]

"Abbruch" Funktion in wxPerl-Programm: Button "abbrechen" wird ignoriert

Leser: 2


<< |< 1 2 >| >> 14 Einträge, 2 Seiten
Christian
 2006-05-11 22:16
#45412 #45412
User since
2003-08-05
29 Artikel
BenutzerIn
[default_avatar]
Hallo an die wx-Guru's,

ich habe eine "kleines" wxPerl Prog. erstellt. Nachdem der Benutzer alle notwendigen Eingaben gemacht hat, kann er die Simulation starten.
Zum vorzeitigen abbrechen der Simulation hatte ich einen "Abbruch"-Button eingebaut. Dieser Button sollte eine Variable setzen, die innerhalb der Sim-Schleife geprüft und zum Abbruch der Simulation führen sollte.

Soweit zur Theorie, in der Praxis funktioniert es auch soweit - dummerweise wird das Event "Klick-Button" erst am Ende der Simulation ausgewertet und die gew. Variable erst dann gesetzt. Ein vorzeitiger Abbruch erfolgt somit nicht.

Hatte zwischenzeitlich auch schon mal versucht mit der ->Update Funktion versch. Widgets zu aktualisieren, in der Hoffnung, dass dann auch des Event erkannt wird ...

Wäre schon wenn jemand ein Stichwort hätte unter dem ich weitersuchen könnte.

Besten Dank und Grüße
Christian\n\n

<!--EDIT|Christian|1147377299-->
renee
 2006-05-12 00:31
#45413 #45413
User since
2003-08-04
14371 Artikel
ModeratorIn
[Homepage] [default_avatar]
Zeig doch mal etwas Code, dann können die Wx-Kenner vielleicht schon erkennen, ob etwas nicht ganz richtig gemacht wurde...
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/
lichtkind
 2006-05-13 00:03
#45414 #45414
User since
2004-03-22
5679 Artikel
ModeratorIn + EditorIn
[Homepage]
user image
hast du auch bedacht das man fenster auch durch das rote x beenden kann?

ich würde wenn man den abbrechen knopf drückt das gleiche ereignis auslösen und erst innerhalb dieses eventhändlers die reguläre shutdownsequenz reinbringen.

das kommt dann in die sub quit der basis app klasse rein oder von dor eine weiterleitung wohin du willst\n\n

<!--EDIT|lichtkind|1147464549-->
Wiki:Tutorien in der Wiki, mein zeug:
kephra, baumhaus, garten, gezwitscher

Es beginnt immer mit einer Entscheidung.
Christian
 2006-05-13 22:00
#45415 #45415
User since
2003-08-05
29 Artikel
BenutzerIn
[default_avatar]
Stimmt Renee, wahrscheinlich ist etwas Beispielcode doch hilfreicher, also hier im folgenden ein verkürztes Beispiel.

Nach dem Klick auf den Start-Button, läuft die Schleife 10 mal ab. Währenddessen will ich zu einem x-beliebigen Zeitpunkt über abbrechen die Schleife vorzeitig beenden.
Tatsächlich passiert aber entweder nichts oder nach dem zweiten oder dritten Klick wird das Text-Feld nicht mehr aktualisiert aber die Schleife läuft bis zum Ende (i=11) fort.

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

use strict;
use Wx;

package MyFrame;
use Wx qw[:everything];
use base 'Wx::Frame';

my $abbruch;

sub new {
my $class = shift;
my $frame = $class->SUPER::new( undef, -1, 'StopLoop', [-1, -1], [175, 150] );
$frame->{panel} = Wx::Panel->new( $frame, -1, );
$frame->{bt_start} = Wx::Button->new( $frame->{panel}, -1, 'starten', [-1, -1], [150, -1] );
$frame->{txt_status} = Wx::TextCtrl->new( $frame->{panel}, -1, "", [-1, -1], [150, -1] );
$frame->{bt_stop} = Wx::Button->new( $frame->{panel}, -1, 'abbrechen', [-1, -1], [150, -1] );
$frame->{sizer_1} = Wx::BoxSizer->new(wxVERTICAL);
$frame->{sizer_2} = Wx::BoxSizer->new(wxVERTICAL);
$frame->{sizer_1}->Add($frame->{panel}, 1, wxEXPAND, 0);
$frame->{sizer_2}->Add($frame->{bt_start}, 0, wxALL|wxALIGN_CENTER_HORIZONTAL, 10);
$frame->{sizer_2}->Add($frame->{txt_status}, 0, wxALL|wxALIGN_CENTER_HORIZONTAL, 10);
$frame->{sizer_2}->Add($frame->{bt_stop}, 0, wxALL|wxALIGN_CENTER_HORIZONTAL, 10);
$frame->SetSizer($frame->{sizer_1});
$frame->{panel}->SetSizer($frame->{sizer_2});

Wx::Event::EVT_BUTTON($frame, $frame->{bt_start}->GetId, \&starte_schleife);
Wx::Event::EVT_BUTTON($frame, $frame->{bt_stop}->GetId, \&abbrechen_schleife);

return $frame;
}

sub starte_schleife{
my $frm = shift;

for(my $i=1; $i<=10; $i++){
$frm->{txt_status}->SetValue("$i. Schleifendurchlauf");
$frm->{txt_status}->Update;
sleep(1);
last if($abbruch);
}
}

sub abbrechen_schleife{
$abbruch = 1;
}
1;



package MyApp;
use base 'Wx::App';

sub OnInit {
my $frame = MyFrame->new;
$frame->Show(1);
}
1;



package main;

my $wxapp = MyApp->new;
$wxapp->MainLoop;



Besten Dank schon einmal vorab.
lichtkind
 2006-05-13 22:30
#45416 #45416
User since
2004-03-22
5679 Artikel
ModeratorIn + EditorIn
[Homepage]
user image
warum benutzt du nicht statuszeile umstatus auszugeben?
warum benutzt du 2 sizer wenn du nur einen brauchst?
und natürlich bricht das programm nicht ab. lies bitte das von mir geschriebene Wiki:Wissensbasis.WxPerlTutorial, denn du brauchst etwas grunverständnis. mom poste gleich den code.

ausserdem fehlt da ein UpdateUI\n\n

<!--EDIT|lichtkind|1147545339-->
Wiki:Tutorien in der Wiki, mein zeug:
kephra, baumhaus, garten, gezwitscher

Es beginnt immer mit einer Entscheidung.
lichtkind
 2006-05-13 22:53
#45417 #45417
User since
2004-03-22
5679 Artikel
ModeratorIn + EditorIn
[Homepage]
user image
hier etwas code der wenigstens teilweise funktioniert vielleicht hilft es dir in einigen dingen klarer zu sehen.
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
#!/usr/bin/perl -w

use strict;
use Wx;

MyApp->new->MainLoop;

package MyFrame;
use Wx qw[:everything];
use base 'Wx::Frame';

sub new {
my $class = shift;
my $frame = $class->SUPER::new( undef, -1, 'StopLoop', [-1, -1], [175, 150] );
$frame->{panel} = Wx::Panel->new( $frame, -1 );
$frame->{bt_start} = Wx::Button->new( $frame->{panel}, -1, 'starten', [-1, -1], [150, -1] );
$frame->{txt_status} = Wx::TextCtrl->new( $frame->{panel}, -1, "", [-1, -1], [150, -1] );
$frame->{bt_stop} = Wx::Button->new( $frame->{panel}, -1, 'abbrechen', [-1, -1], [150, -1] );
$frame->{sizer_2} = Wx::BoxSizer->new(wxVERTICAL);
$frame->{sizer_2}->Add($frame->{bt_start}, 0, wxALL|wxALIGN_CENTER_HORIZONTAL, 10);
$frame->{sizer_2}->Add($frame->{txt_status}, 0, wxALL|wxALIGN_CENTER_HORIZONTAL, 10);
$frame->{sizer_2}->Add($frame->{bt_stop}, 0, wxALL|wxALIGN_CENTER_HORIZONTAL, 10);
$frame->{panel}->SetSizer($frame->{sizer_2});

Wx::Event::EVT_BUTTON($frame, $frame->{bt_start}->GetId, \&starte_schleife);
Wx::Event::EVT_BUTTON($frame, $frame->{bt_stop}->GetId, \&abbrechen_schleife);

return $frame;
}

sub starte_schleife{
my $frm = shift;

for my $i(1..1000) {
$frm->{txt_status}->SetValue("$i. Schleifendurchlauf");
$frm->{txt_status}->Update;
}
}

sub abbrechen_schleife{
my $frm = shift;
$frm->Close(1);
}

package MyApp;
use base 'Wx::App';
sub OnInit { MyFrame->new->Show(1) }


was versuchst zu erreichen wird wahrscheinlich so nicht gehen. ich rate dir dich mit dem koncept der WxTimer und WxThreads (weiss nicht ob implementiert) vertraut zu machen, vielleicht gehts auch mit fork aber da sleep die berühmte gun ist, die direkt auf deinen fuss zielt, würd ich es zuerst mit den genannten versuchen.\n\n

<!--EDIT|lichtkind|1147549076-->
Wiki:Tutorien in der Wiki, mein zeug:
kephra, baumhaus, garten, gezwitscher

Es beginnt immer mit einer Entscheidung.
Christian
 2006-05-13 23:15
#45418 #45418
User since
2003-08-05
29 Artikel
BenutzerIn
[default_avatar]
Besten Dank für deine Mühe, Lichtkind

zu 1) Ja, eine Statuszeile wäre auch möglich gewesen, ändert aber nichts an der Problemstellung.
zu 2) Ertappt, ich hab die Oberfläche mit wxGlade gebaut und anschließend auf die Schnelle zusammengestrichen, damit ich nicht zuviel Code posten muß.
zu 3) darauf komm ich doch gleich zurück

zu deinem Beispiel:
WxThreads -> könnte wohl die Antwort sein|werden, ;-)
Christian
 2006-05-14 10:23
#45419 #45419
User since
2003-08-05
29 Artikel
BenutzerIn
[default_avatar]
Quote
$frm->Close(1);


Nicht das ganze Programm, nur die sub "starte_schleife" möchte ich abbrechen.
lichtkind
 2006-05-14 12:41
#45420 #45420
User since
2004-03-22
5679 Artikel
ModeratorIn + EditorIn
[Homepage]
user image
gut aber es wird nicht gehen das ein eventsystem darauf ausgelegt ist immer eine sache zugleich zu machen und du ja willst das der abbrechen knopf deinen befehl entgegen nimmt während die schleife rechnet.
Wiki:Tutorien in der Wiki, mein zeug:
kephra, baumhaus, garten, gezwitscher

Es beginnt immer mit einer Entscheidung.
Christian
 2006-05-14 15:03
#45421 #45421
User since
2003-08-05
29 Artikel
BenutzerIn
[default_avatar]
Unter TK funktionert es mit:

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
#!/usr/bin/perl -w
use Tk;
use strict;

my ($status, $abbruch);

my $Form2 = MainWindow->new;
$Form2->title("StoppLoop");
$Form2->geometry("200x140+8+8");

my $bt_start = $Form2->Button( -text => "starten", -command => \&starte_schleife )->pack(-pady=>10, -padx=>10);
my $txt_status = $Form2->Entry( -textvariable => \$status, -width => '150')->pack(-pady=>10, -padx=>10);
my $bt_stop = $Form2->Button( -text => "stoppen", -command => \sub{$abbruch=1} )->pack(-pady=>10, -padx=>10);

MainLoop;

sub starte_schleife{
undef($abbruch);

for my $i(1..10000){
$status = ($abbruch)?"Abbruch durch Benutzer" : "$i. Schleifendurchgang";
$Form2->update;
$i=10000 if defined $abbruch;
}
}


Wollt aber eigentlich langsam hin zu Wx da einige Widgets unter Windows ein etwas Windows-konformeres Verhalten haben.

WxThreads funktioniert übrigens ab Perl 5.8 und WxPerl 0.26. Hab nur leider auf den meisten Systemen noch 5.6 im Einsatz und ein Upgrade wär nicht so einfach.
Ich weiss aber auch noch nicht wie ich das Problem mit Threads lösen könnte, denn eine Schleife müßt ich dann noch immer abbrechen - oder?

Ich hoffte eigentlich, dass es eine Funktion ala "GetLastEvent" oder "Update::GUI::Events" gibt und ich diese bislang übersehen habe. :-)
<< |< 1 2 >| >> 14 Einträge, 2 Seiten



View all threads created 2006-05-11 22:16.