[python-users] Tkinterprobleme

prof. dr. peter ziese p.ziese at t-online.de
Fr Apr 20 18:33:44 CEST 2007


Hallo Thomas,

danke für Deine Ausführungen. Dazu kann ich folgendes sagen: Unter WIndows und 
zwar mit Vb, C# als auch Delphi funktioniert das so, wie ich es versucht 
habe. Auch unter Linux mit Kylix funktioniert es. Unter Java ebenfalls. Wie 
Michael es beschireb funktioniert es natürlich. Die Methode kann aber recht 
umständlich werden, wenn es sich um verschiedene Programmteile handelt und 
wenn diese in sich selbst auch noch verschiedene Tempi haben sollen.

MfG

Peter

(nach scheiben für 2 Tage verreist)


Am Donnerstag, 19. April 2007 20:45 schrieb Thomas Lenarz:
> prof. dr. peter ziese schrieb:
>
> Hallo Peter,
>
> Deine Frage hat mich gereizt, einmal grundsätzlich darauf antworten.
> Auch wenn es nicht Python-spezifisch ist. Vor ca. 12 (?) Jahren haben mich
> ähnliche überraschende Effekte im Rahmen der
> OS/2-Presentation-Manager-Programmierung beschäftigt. Also los...
>
> > 1) Warun ist das so?
>
> Zumindest alle GUI-Systeme, die ich kenne, arbeiten intern
> nachrichtenbasiert. Wenn man z.B. Win32 direkt in C programmiert, hat man
> damit auch direkten Kontakt.
>
> Alle GUI-Programme melden sich zunächst in irgendeiner Form beim grafischen
> System (Windows, Presentation-Manager etc.) an. Das System hat eine
> Nachrichten- Warteschlange, in die alle möglichen Ereignisse eingestellt
> werden. Die Ereignisse besitzen ein identifizierendes Merkmal (Maus hat
> sich bewegt, Maustaste wurde gedrückt usw.), viele weitere Parametern und
> den Adressaten, der letztendlich (etwas vereinfacht beschrieben) Dein
> Programm ist.
>
> Das Herz jeden Programmes ist eine Schleife, die ständig Nachrichten aus
> der Nachrichten- Wartenschlange entnimmt und diese dann an eine
> Call-Back-Prozedur weitereicht.
>
> while (GetMessage(...) )
> {
>   DispatchMessage(..)
> }
>
> So etwas ähnliches müsste auch in TK's mainloop() verpackt sein.
>
> In der Call-Back-Prozedur wird dann "die eigentliche Arbeit" gemacht.
> Letztendlich entspricht die Call-Back-Prozedur den Methoden, die Du bei
> Tkinter mittels bind() an bestimmte Ereignisse binden kannst. Immer wenn
> das Ereignis kommt (Mouse-Click auf Button) dann wird eine bestimmte
> Methode aufgerufen.
>
> Nun ist die Call-Back-Prozedur viel allgemeiner, weil sie alle möglichen
> Ereignisse verarbeitet. Auch solche, die Dich gar nicht interessieren.
> Diese Ereignisse werden dann von der selbstprogrammierten
> Call-Back-Prozedur an eine vom System angebotene Call- Back-Prozedur
> weitergereicht, die sich um die Nachricht kümmert.
>
> Nun komme ich endlich zu Deiner   "Warum ist das so?"-Frage   : Eine von
> den möglichen Nachrichten ist (in Windows) die WM_PAINT-Nachricht. Sie wird
> immer dann vom System an ein Programm gerichtet, wenn der Inhalt eines
> Fensters neu gezeichnet werden soll. Das passiert andauernd z.B.: auch dann
> wenn ein Fenster zeitweise durch ein anderes verdeckt war. Das Zeichnen
> Deines Fensterinhaltes, den Du ja auf das Canvas gemalt hast übernimmt
> irgendwo TK für Dich.
>
> Wie sieht nun Dein Programm aus?
>
> -Du bereitest zunächst alles vor und malst intern Grafiken auf eine
> Leinwand (Canvas). TK macht das auch und berücksichtigt auch die sleep's,
> die Du eingebaut hast. Währenddessen stauen sich vermutlich schon WM_PAINT
> (oder ähnliche)-Nachrichten in der Warteschlange an.
>
> -Dann betrittst Du Deine Nachrichtenschleife mittels mainloop() und gibtst
> dem System die Chance die Nachricht(en) zum Zeichnen zu verarbeiten und
> plöpp, Deine Grafik erscheint auf einmal und ohne die Pausen, die Du
> eingebaut hast.
>
> Der von Michael vorgeschlagene Timer-Callback ist aus meiner Sicht auch die
> richtige Lösung für Dein Problem. Er gibt Dir die Möglichkeit Deinen
> Vorgang des "Malens" in den Kontext der mainloop zu verlagern.
>
> Du malst also einen Strahl und sagst dem System: Rufe mich bitte nach einer
> gewissen Zeit zurück, dann malst Du den nächsten Strahl usw.. Dadurch
> dürftest Du dann schön animiert den Vorgang verfolgen können. Im Windows
> würde das der WM_TIMER-Nachricht entsprechen.
>
> Ein interessantes Experiment wäre es dann auch tatsächlich einmal, längere
> Warteschleifen in solche an Ereignisse gebundene Methoden einzubauen. Im
> OS/2-Presentation-Manager und zumindest in älteren Windows-Versionen hatte
> das den Effekt, dass für den Zeitraum der Warteschleife die gesamte (!)
> Oberfläche eingefroren war. Das deswegen, weil alle Programme sich aus
> derselben System-Nachrichten-Warteschlange bedienen. Wenn ein "böses"
> Programm nun seine Nachrichten nicht mehr abholt, gibt es Verkehrsstau und
> alle anderen warten auch. (Ich weiß allerdings nicht wie es in TK ist. Habe
> es nie probiert.)
>
> Das ist jetzt viel länger geworden, als ich eigentlich wollte. Ich hoffe,
> ich werde jetzt nicht kiloweise mit Tomaten beworfen, da es auch noch etwas
> OT war, da nicht python- spezifisch. Mir hilft es aber manchmal sehr über
> die Grundlagen nachzudenken, um bestimmte Dinge auf höherer Ebene zu
> verstehen.
>
> Viele Grüße
> Tommes




Mehr Informationen über die Mailingliste python-users