Schrift
[thread]12251[/thread]

MainLoop blockiert

Leser: 3


<< >> 8 Einträge, 1 Seite
theresa
 2008-07-25 14:23
#112700 #112700
User since
2007-07-17
90 Artikel
BenutzerIn
[default_avatar]
Hi,
ich habe gerade ein Problem mit Tk und ein Projekt, den ich versuche Objektorientiert zu machen. Habe ein Modul erstellt für ein Anmeldefenster. Dieses Anmeldefenster soll von einer anderen Stelle erzeugt werden.
Das Anmeldefenster braucht mainloop am Ende, aber die Datei, die es erzeugt, muss weitermachen, nicht da stehenbleiben.
Was kann ich da tun? ein Thread für das Anmeldefenster erzeugen? oder gibt es etwas anderes dafür?
renee
 2008-07-25 14:26
#112701 #112701
User since
2003-08-04
14371 Artikel
ModeratorIn
[Homepage] [default_avatar]
?? Kannst Du das etwas genauer erläutern?

Ist das aufrufende Programm/Modul ebenfalls Tk?
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/
theresa
 2008-07-25 15:57
#112704 #112704
User since
2007-07-17
90 Artikel
BenutzerIn
[default_avatar]
Ja, dies ist die aufrufende Datei:
Code: (dl )
1
2
3
use LoginFenster;
$LF = LoginFenster->new();
print "macht weiter!";

LoginFenster:
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
package LoginFenster;
use strict;
use Tk;
use vars qw($VERSION);
$VERSION = 0.01;

use Alias qw(attr);
use vars qw($MW);

my %felder = (
MW=>undef,
);

sub new {
my $that = shift;
my $class = ref($that)||$that;
my $self = {
%felder,
};
bless $self, $class;
init();
return $self;
}

sub init {
$MW = tkinit(-title=> 'Anmeldung');
#...
MainLoop;
}
renee
 2008-07-25 16:04
#112706 #112706
User since
2003-08-04
14371 Artikel
ModeratorIn
[Homepage] [default_avatar]
Wenn das aufrufende Modul ebenfalls mit Tk (und MainLoop) arbeitet, dann mach das ganze doch als Toplevel (siehe perldoc Tk::Toplevel)
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/
theresa
 2008-07-25 16:10
#112709 #112709
User since
2007-07-17
90 Artikel
BenutzerIn
[default_avatar]
Ich versuche es besser zu erklären. Es gibt auch noch ein Tray.pm, der auch angezeigt werden soll, für das LoginFenster. Wenn man auf das Tray klickt, soll das LoginFenster irgendwie benachrichtig werden.
Ich habe das so gemacht...
Bin dabei, zu lernen, also offen für allgemeine Kritik :o). Hab erst vor einer Woche ein Buch zur Objektorientierung in Perl ausgeliehen...
Die Dateien:
Tray.pm
Code (perl): (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
package Tray;
use Win32::GUI;

use Alias qw(attr);
use vars qw($BILD $TEXT $CONTROLLER $WIN32 @FUNKTIONEN);

my %felder = (
        BILD => undef,
        TEXT => undef,
        CONTROLLER => undef,
        WIN32 => undef,
        FUNKTIONEN => [],
);

sub new {
        my $that = shift;
        my $bildPfad = shift;
        my $text = shift;
        $CONTROLLER = shift;
                        
        my $class = ref($that)||$that;
        my $self = {
                %felder,
        };
        bless $self, $class;
        initWin($bildPfad, $text);
        return $self;
}

sub initWin {
        my $bildPfad = shift;
        my $text = shift;
        my $mw;
        $WIN32 = new Win32::GUI::DialogBox( -width => 0, -height => 0, -name => 'TrayWindow' );
        my $icon_nr = 0;
        my @icon = (new Win32::GUI::Icon( $bildPfad )); 
        new Win32::GUI::NotifyIcon( $WIN32, 
                            -name => "Notify", 
                            -id => 255, 
                            -icon => $icon[$icon_nr], 
                            -tip => $text,
                            -onClick => sub { clicked(); },  
                            #-onRightClick => sub { context_menu($mw, $main_win32); } ); 
                            -onRightClick => sub { context_menu(); } ); 
}

#Rechtsklickmenü aufrufen
sub context_menu { 
        #my $mw = shift;
        
        #my $popup = $mw->Menu( Name => 'popupMenu', -tearoff => 0 ); 
        $popup->command( -label => 'Verbindung trennen', -command => sub { &clean_exit } ); 
        $popup->Popup( -popover => 'cursor', -popanchor => 'nw' ); 
        return 1;
} 

#Hauptfenster verstecken / anzeigen
sub clicked {
        $CONTROLLER->tray_clicked();
}

#Icon verändern
sub toggle_icon {
   $icon_nr = !$icon_nr;
   Win32::GUI::NotifyIcon::Modify( $WIN32,
                                   -id => 255,
                                   -icon => $icon[$icon_nr],
                                   -tip => ' verändertes Icon ' ); 
}

#TrayIcon erntfernen und Beenden
sub clean_exit { 
        $WIN32->Notify->Delete( -id => 255 ); 
        CORE::exit;  
}
1;


LoginFenster.pm
Code (perl): (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
package LoginFenster;
use strict;
use Tk;
use vars qw($VERSION);
$VERSION = 0.01;

use Alias qw(attr);
use vars qw($MW);

my %felder = (
        MW=>undef,
);

sub new {
        my $that = shift;
        my $class = ref($that)||$that;
        my $self = {
                %felder,
        };
        bless $self, $class;
        init();
        return $self;
}

sub init {
        $MW = tkinit(-title=> 'Anmeldung');
        #...
        MainLoop;
}

sub isHidden {
        if ($MW->state eq 'withdrawn'){
                return 1;
        }
        return 0;
}

sub raiseup {
        $MW->deiconify;
    $MW->raise;
        $MW->focus;  
}

sub hide {
        $MW->withdraw;
}

sub toggle {
        if(isHidden()){
                raiseup();
        }
        else{
                hide();
        }
}
1;


Controller.pm, soll das ganze steuern
Code (perl): (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
package Controller;
use Tray;
use LoginFenster;

use Alias qw(attr);
use vars qw($TRAY $LF $SELF);

my %felder = (
        $TRAY = undef,
        $LF = undef,
        $SELF = undef,
);

sub new {
        my $that = shift;
        my $bildPfad = shift;
        my $text = shift;                        
        my $class = ref($that)||$that;
        my $self = {
                %felder,
        };
        bless $self, $class;
        $SELF = $self;
        init();
        return $self;
}

sub init {
        $TRAY = Tray->new('c:\\pfad', 'text', $SELF);
        $LF = LoginFenster->new();
#       $LF->show();
        print ref($LF);
}

sub tray_clicked {
        $LF->toggle();
}

1;
theresa
 2008-07-25 16:19
#112710 #112710
User since
2007-07-17
90 Artikel
BenutzerIn
[default_avatar]
Und mein Problem ist gerade, dass wenn ich auf das Tray klicke, und bei Controller tray_clicked() aufgerufen wird, $LW noch auf undef steht, weil in init() das LoginFenster noch in MainLoop steckt!
theresa
 2008-07-25 16:58
#112713 #112713
User since
2007-07-17
90 Artikel
BenutzerIn
[default_avatar]
Hab jetzt das init() aus dem Konstruktor vom LoginFenster entfehrnt, rufe den dann getrennt aus... glaube dass das die Lösung war.
MatthiasW
 2008-07-25 17:39
#112721 #112721
User since
2008-01-27
367 Artikel
BenutzerIn
[default_avatar]
MainLoop sollte nicht innerhalb deiner Module aufgerufen werden, sondern nur einmal im Skript, das die Module verwendet.
Den Rest der Initialisierung kannst du so lassen. Nur das MainLoop sollte da raus.

Noch was zu den package-Variablen.
Diese sollten nur dazu dienen, Daten für alle Instanzen der Klasse zur Verfügung zu stellen. Du benutzt sie aber um die Daten einer einzelnen Instanz abzuspeichern, dazu sind die Objekte selbst da.

MfG
perl -E'*==*",s;;%ENV=~m,..$,,$&+42;e,$==f;$"++for+ab..an;@"=qw,u t,,print+chr;sub f{split}say"@{=} me"'
<< >> 8 Einträge, 1 Seite



View all threads created 2008-07-25 14:23.