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

Fenster in Schleife

Leser: 1


<< |< 1 2 >| >> 11 Einträge, 2 Seiten
DrWhiteLetter
 2005-04-20 17:30
#43669 #43669
User since
2005-01-30
26 Artikel
BenutzerIn
[default_avatar]
Hi, ich hätte gerne, dass wen man das 1. Fenster schliesst das 2. mit dem nächsten Bild angezeigt wird. Nur leider klappt das irgendwie nicht, sondern es wird nur ein Fenster geöffnet, wird das geschlossen, erscheint das 2. nicht.
Ich denke, dass das Programm beim öffnen des Fensters nicht hält sondern die Schleife fortgesetzt wird, so kann das ja nicht gehen. Sehe ich das richtig? Nur fällt mir dazu irgendwie keine Lösung ein (bzw. wie man den Programmablauf anhalten kann, evt. mit ner while-Schleife, aber hab keine Ahnung wie ich damit kontrolliere ob das Fenster noch offen ist).

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

use strict;
use warnings;

use Tk;
use Tk::JPEG;

my @bilder;
my $j;
pic();

for($j=0;$j<@bilder;$j++)
{

# Hier muss der Fehler sein, die Schleife selbst funktioniert
#-------------------------------------------------------

my $fenster=MainWindow->new();
my $img = $fenster->Photo(-file =>$bilder[$j], -format => "JPEG");
$fenster->Label(-image => $img)->pack;
$fenster->Button(-text => 'OK', -command => 'exit')->pack;
MainLoop();
}


sub pic
{
my @datei;
my $i;

opendir(DIR,"test");
while(@datei = readdir(DIR))
{
for($i=0;$i<@datei;$i++)
{
if($datei[$i]=~/.jpg/)
{
push( @bilder, $datei[$i] )
}
}
}
closedir(DIR);
}


Danke schonmal
Strat
 2005-04-20 17:44
#43670 #43670
User since
2003-08-04
5246 Artikel
ModeratorIn
[Homepage] [default_avatar]
das problem ist, dass du mit exit das programm verlaesst...
versuch mal stattdessen, bei Button folgenden callback mitzugeben:
Code: (dl )
-command => sub { $fenster->destroy(); }
perl -le "s::*erlco'unaty.'.dk':e,y;*kn:ai;penmic;;print"
http://www.fabiani.net/
Strat
 2005-04-20 17:53
#43671 #43671
User since
2003-08-04
5246 Artikel
ModeratorIn
[Homepage] [default_avatar]
nebenbei:
Code: (dl )
while(@datei = readdir(DIR)) {

irgendwie ist das doppelt gemoppelt, weil readdir in listenkontext alle dateinamen einliest... entweder
Code: (dl )
1
2
my @datei = readdir(DIR);
for my $i (0..$#datei) {

oder:
Code: (dl )
1
2
3
while (my $datei = readdir(DIR)) {
 next unless /\.jpg$/; # . wird zu einem beliebigen zeichen, also escapen
 push (@bilder, $_);

Nebenbei bekommst du da probleme, wenn du das script von ausserhalb deines verzeichnisses ausfuehrst; da besser das Modul FindBin verwenden.
Du koenntest deinen Code auch noch etwas kuerzer machen, wenn du z.B. mit glob arbeitest... z.B.
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#! /usr/bin/perl
use warnings;
use strict;
use Tk;
use Tk::JPEG;
use FindBin;

my $pattern = "$FindBin::Bin/test/*.jpg";

foreach my $bild (glob($pattern)) {
 my $fenster = MainWindow->new();
 my $img = $fenster->Photo(-file =>$bild, -format => "JPEG");
 $fenster->Label(-image => $img)->pack;
 $fenster->Button(-text => 'OK', -command => sub { $fenster->destroy() })->pack;
 MainLoop();
} # foreach

spart dir\n\n

<!--EDIT|Strat|1114005258-->
perl -le "s::*erlco'unaty.'.dk':e,y;*kn:ai;penmic;;print"
http://www.fabiani.net/
DrWhiteLetter
 2005-04-20 20:40
#43672 #43672
User since
2005-01-30
26 Artikel
BenutzerIn
[default_avatar]
Hm, also im Büro hat dein Code (Strat) unter Windows 2k prima funktioniert. Unter Linux bekomme bekomme ich je nach Art der Ausführung einen Speicherzugriffsfehler.

Mit
perl code.pl
kann ich mir das 1. Bild ansehen, (beim 1. versuch ging es bis zum 2.) danach Speicherzugriffsfehler
setze ich u+x und führe die Datei dann mit ./code.pl aus, komme ich bis zum 3. Bild und dann erst der Speicherzugriffsfehler.

#Einige Zeit später:
#Vor dem Posten hab ich mir das nochmal angeschaut und mit dem perl debugger rumgespielt
Jetzt check ich garnichts mehr, das scheint total zufällig zu passieren, einmal bin ich mit dem perl debugger sogar bis zum 4. Bild gekommen, teilweise stürzt das Programm aber schon beim 2. ab.

Sorry, dass ich so wenig informationen geben kann, weiß nicht, was relevant ist. Fragt aber einfach, wenn ihr etwas wissen müsst.

OS: Fedora Core 3\n\n

<!--EDIT|DrWhiteLetter|1114015244-->
Strat
 2005-04-20 22:19
#43673 #43673
User since
2003-08-04
5246 Artikel
ModeratorIn
[Homepage] [default_avatar]
da scheint es unter linux irgendein problem zu geben... vielleicht kann ptk genaueres dazu sagen, ich kenne mich mit Tk nicht so gut aus...

ein MainWindow ist nur eine spezielle Form eines Tk::Toplevel... kannst du vielleicht darauf ausweichen?

ich wuerde das problem ein wenig anders angehen und das fenster nicht jedesmal komplett killen, sondern das bild in einen button reinsetzen (geht genauso wie als label) und nur das bild bei einem klick darauf killen und das naechste anzeigen, z.B. so mal ins blaue reingecoded, weiss nicht, ob es laeuft:
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
use FindBin;
....

my $image;
my $mw = MainWindow->new();

our @files = glob("$FindBin::Bin/test/*.jpg");

my ($imageFile) = &GetNextFile();

my $button = $imageFrame->Button(-image => $image)
->pack(-fill => 'both', -expand => 1);

$button->configure(-command => sub {
($imageFile) = &GetNextFile();
$button->configure(-image => $image);
});

&Tk::MainLoop;
# ---------------------------------------
sub GetNextFile {
while (my $file = shift(@files)) {
next if -d "$inputDir/$file";

if ($file =~ /\.jpe?g$/) {
unless (ref($image)) {
eval {
$image = $imageFrame->Photo(-file => "$file", -format => 'jpeg');
};
if ($@) {
print "$file: $@\n"; $image = undef; next;
} # if
} # unless

return (&File::Basename::basename($file));
} # while
} # GetNextFile

kann aber sein, dass das ein memory leak ist...\n\n

<!--EDIT|Strat|1114021217-->
perl -le "s::*erlco'unaty.'.dk':e,y;*kn:ai;penmic;;print"
http://www.fabiani.net/
ptk
 2005-04-20 23:15
#43674 #43674
User since
2003-11-28
3645 Artikel
ModeratorIn
[default_avatar]
[quote=Strat,20.04.2005, 15:53]Du koenntest deinen Code auch noch etwas kuerzer machen, wenn du z.B. mit glob arbeitest...[/quote]
ich rate von glob() ab, das kann mit Leerzeichen nicht gut umgehen:
Code: (dl )
1
2
3
4
5
6
$ mkdir "dir with spaces"
$ touch "dir with spaces"/haha
$ perl -e '@x = glob("dir with spaces/*"); warn @x'
dirwith at -e line 1.
$ perl -e '@x = glob("dir\\ with\\ spaces/*"); warn @x'
dir with spaces/haha at -e line 1.
ptk
 2005-04-20 23:19
#43675 #43675
User since
2003-11-28
3645 Artikel
ModeratorIn
[default_avatar]
Zum Speicherzugriffsfehler kann ich nichts sagen, nur, das RedHat oftmals nicht ganz optimale Perl-Versionen herausbringt :-( Vielleicht hat es auch was mit dem Threading zu tun?

Ich empfehle aber auch, nur ein MainWindow zu verwenden. Wenn du tatsaechlich immer das Hauptfenster zerstoeren willst, kannst du $mw per withdraw unsichtbar machen und die Fotos in einem neuen Toplevel zeigen. Oder du machst es so, wie Strat es vorschlaegt.
DrWhiteLetter
 2005-04-25 14:02
#43676 #43676
User since
2005-01-30
26 Artikel
BenutzerIn
[default_avatar]
So, neue Arbeitswoche hat begonnen und ich habe immernoch Probleme damit, warum auch immer. Hier erstmal mein aktueller Code (habe die Idee mit dem Button übernommen).

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

use strict;
use warnings;

use Tk;
use Tk::JPEG;

my @bilder;
my $j;

pic();



for($j=0;$j<@bilder;$j++)
{
my $fenster = MainWindow->new();
my $img = $fenster->Photo(-file => $bilder[$j], -format => "JPEG", );
$fenster->Button( -image => $img,
-command => sub

{

$fenster->destroy();

}

)->pack;

MainLoop();
}

sub pic
{
my @datei;
my $i;
opendir(DIR, "test");
@datei = readdir(DIR);

for $i (0..$#datei)
{
if($datei[$i]=~/.jpg/)
{
push( @bilder, $datei[$i] )
}
}
closedir(DIR);
}


Das seltsame ist, mit meinem Testordner und den Bildern die sich darin befinden (habe eines mehrfach kopiert) funktioniert das Programm wunderbar, jetzt wollte ich es jedoch einmal bei meinen richtigen Bilderverzeichnissen testen, doch da kommt dann folgender Error:
Code: (dl )
Cannot open &´test.jpg&´in mode &´r&´ at c:/Perl/site/lib/Tk/Image.pm line 21


Kann man mit dem Perl-Debugger irgendwie sehen, wo im Speicher gerade zugegriffen wird?

Achja, hätte mal jemand kurz Zeit, den Code bei sich zu testen? Muss nur das Verzeichnis angepasst werden (das bastel ich erst um wenn alles funktioniert). Also
Code: (dl )
opendir(DIR, "test")

test durch den entsprechenden Ordner ersetzen.

Danke schonmal
Strat
 2005-04-25 15:13
#43677 #43677
User since
2003-08-04
5246 Artikel
ModeratorIn
[Homepage] [default_avatar]
readdir gibt dir nur den Dateinamen ohne das verzeichnis.
also:
Code: (dl )
1
2
3
4
5
6
my $baseDir = "test";
...
opendir(DIR, $baseDir) or die "Error: couldn't open dir '$baseDir': $!\n";
my @datei = grep { -f "$baseDir/$_" and /\.jpe?g$/ } readdir(DIR);
...
my $img = $fenster->Photo(-file => "$baseDir/$bilder[$j]", -format => "JPEG", );

x) opendir verdient wohl schon eine fehlerbehandlung, oder?
x) /.jpg/ matcht auch auf xajpg.txt
x) for($j=0;$j<@bilder;$j++) kannst du einfacher schreiben: for my $j (0..$#bilder)\n\n

<!--EDIT|Strat|1114427718-->
perl -le "s::*erlco'unaty.'.dk':e,y;*kn:ai;penmic;;print"
http://www.fabiani.net/
Crian
 2005-04-25 15:50
#43678 #43678
User since
2003-08-04
5872 Artikel
ModeratorIn
[Homepage]
user image
[quote=Strat,25.04.2005, 13:13]for($j=0;$j<@bilder;$j++) kannst du einfacher schreiben: for my $j (0..$#bilder)[/quote]
Und wenn Du den Index in der Schleife gar nicht benutzt, mach doch einfach

Code: (dl )
1
2
3
for my $bild (@bilder) {
... # $bild statt $bilder[$i]
}


und

Code: (dl )
1
2
3
for my $dat(@datei) {
... # $dat statt $datei[$i]
}
\n\n

<!--EDIT|Crian|1114429846-->
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
<< |< 1 2 >| >> 11 Einträge, 2 Seiten



View all threads created 2005-04-20 17:30.