tkinter/python 2.4.2 verliert sporadisch Kontakt zur GUI

Fragen zu Tkinter.
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Und weil du dir keine Zeit zum Kürzen nehmen möchtest sollen sich nun andere durch 200 Zeilen wühlen? Es helfen hier ja wirklich alle viel, gerne und geduldig, aber wenn du dir nicht die Mühe machst uns zu entgegen zu kommen, warum sollten wir dann unsere Zeit für _dein_ Problem investieren?

Mit kürzerem Code erhöhst du deine Chancen, dass jemand mal drauf schaut.

Über Threads brauchst du dir keine Gedanken machen, da du keine verwendest. Das scheidet also schon mal aus.

Sebastian
Das Leben ist wie ein Tennisball.
egerlach
User
Beiträge: 43
Registriert: Samstag 14. März 2009, 21:32

auch python 2.6.2 macht den gleichen Ärger. Schade. Es ist und bleibt offenbar ein feature von Python. Mit reinem TkTcl lief das Programm einwandfrei, mit python gibs Ärger.

Eckard
BlackJack

Sorry, aber das kannst Du Python IMHO nicht einfach so anlasten. Es ist weder ausgeschlossen, dass Du irgend etwas falsch machst, noch das es irgendwie an Deiner Installation liegt. Umgekehrt kann ich mich nämlich nicht daran erinnern solche Probleme schon öfter gehört oder gelesen zu haben.

Und der Quelltext sieht stellenweise ziemlich schräg aus. Kommentare wie "dummy wert, wird nie erreicht" oder das Ausführen der externen Programme für Aufgaben, die ganz einfach in Python erledigt werden können, und dass das alles auf Modulebene herumsteht, erwecken nicht gerade Vertrauen in den Quelltext. Oder die "maximan x verschiedene y sollten reichen"-Kommentare beim erstellen von Listen mit x Einträgen, von denen dann nur ein paar (hoffentlich) mit Werten belegt werden -- Python ist keine statisch kompilierte Sprache bei dem man solche Grössen vorher festlegen müsste und sich so künstlich beschränken muss.

Neben der Tatsache, dass anscheinend niemand Lust hatte sich durch den Quelltext zu wühlen, wäre es auch hilfreich, wenn Du, wenn schon kein minimales Beispiel, wenigstens ein echtes, überhaupt lauffähiges gezeigt hättest. Dass da hast Du offensichtlich so nie laufen lassen, das enthält nämlich Syntaxfehler. Wenn man die behebt, kann es ja sogar sein, dass *der* Quelltext auch bei Dir keine Probleme machen würde.

Wenn man die Syntaxfehler beseitigt, ist mir als nächstes aufgefallen, dass `patWahl` verwendet werden soll, ohne das etwas zugewiesen wird. Und das `nr` für meinen Geschmack viel zu oft wiederverwendet wird. Da würden Funktionen/Methoden helfen.

Warum verwendest Du `re.findall()` wenn Du doch offensichtlich immer nur den ersten Treffer brauchst? Und selbst bei `findall()` wäre es dann günstiger *einmal* vor der Zuweisung den ersten Treffer aus der Liste zu holen und nicht bei *jedem* Zugriff.

Das Programm sieht nicht wirklich nach Python aus, eher wie ein Versuch eine andere Sprache in Python-Syntax zu zwängen. Insbesondere die Aufrufe der externen Programme kann man auch ganz einfach in Python selbst implementieren. Die grossen Schleifen über die "config"-Datei sehen redundant aus, dass kann man sicher zusammenfassen und vereinfachen. Ausserdem sind GUI und Programmlogik nicht getrennt.

Die Importe `dircache` und `os` werden nicht verwendet.

Wurde eigentlich schon gefragt, ob Du das aus IDLE heraus startest?
egerlach
User
Beiträge: 43
Registriert: Samstag 14. März 2009, 21:32

Vielen Dank erstmal an BlackJack für den ausführlichen Kommentar dazu. Ich möchte an dieser Stelle (nochmal??) erwähnen, dass der Code unter Linux läuft und per ssh -X auf den Linux-Clients dargestellt wird. In der originalen reinen TkTcl-Programmierung war ein Code-Stück enthalten, der alle 10 Sekunde die (gleiche!) Hintergrundfarbe neu gesetzt hat und anfangs sofort gleich einmal, also eine dummy-Operation damit die Anwendung nicht den Kontakt zum X-Server verliert. Der Grund von dem Code war allerdings wegen XDMCP-Clients (die es jetzt nicht mehr gibt), die bei Absturz von X nicht auch noch die TkTCL-Anwendung geschlossen haben. Dieses Codestück:

Code: Alles auswählen

# TkTcl-Code:
proc NOP-X-Kom {} {
    global Hintergrundfarbe
    .erledigt configure -background $Hintergrundfarbe
    after 10000 NOP-X-Kom
}
werde ich heute mal nach python portieren. Es kann sein, dass dieser Code dann als segenreicher Seiteneffekt auch verhindert hat, dass die TkTcl-Anwendung den Kontakt zu X verloren hat. Es könnte alles ein Problem von X mit per ssh -X gestarteten python-Anwendungen sein und somit ist tatsächlich python "unschuldig".
Ich melde mich wieder. Echte Testergebnisse kann ich allerdings erst Montag liefern, dann erst ist der Code wieder im betrieblichen Einsatz.

Gruss
Eckard
egerlach
User
Beiträge: 43
Registriert: Samstag 14. März 2009, 21:32

hier der Code, den ich eingesetzt habe, einfach die Farbe alle 5 Sek ändern.

Code: Alles auswählen

def wechsele_hintergrFarbe(t):
   while True:
        t.config(background="#eeeee6")
        time.sleep(5)
        t.config(background="#e6eade")
        time.sleep(5)
thread.start_new_thread(wechsele_hintergrFarbe,(root,))
Gestern sah es so aus als wäre es das gewesen, heute so viele Hänger und die gleich hintereinander wie nie zuvor. Also werde ich mal weiter debuggen, der "senden" Button wird die ausgelesenen Felder in ein Textfeld in der GUI selbst schreiben bevor das eigentliche Senden erfolgt. Vielleicht wird auch dieser Code schon nicht mehr ausgeführt, bald weiss ich mehr. Ich werde mich Stück für Stück an die Stelle des "Hängers" rantasten.
BlackJack

@egerlach: Mal davon abgesehen, dass man `threading` statt `thread` verwenden sollte, darf man nicht von verschiedenen Threads aus auf die GUI zugreifen. Da können die interessantesten Probleme auftauchen.
egerlach
User
Beiträge: 43
Registriert: Samstag 14. März 2009, 21:32

Lösung: wenn Umlaute oder sz eingegeben wurden als Nachrichtentext, dann
kam die schon hinreichend bekannte Fehlermeldung:

'ascii' codec can't encode character u'\xfc' in position 41

Da ich die Fehlermeldungen nirgendwo angefangen hatte (schlecht programmiert von mir) sah es so aus, als hätte die GUI den Kontakt zum Programmcode verloren.

Habe mich ausführlichen mit UTF und latin und ... und beschäftigt, da ich eigentlich keine Textverarbeitung mit python mache, sondern eingegebenen Text direkt in eine Datei schreibe, convertiere ich erst gar nicht erst in unicode sondern schreibe den Text direkt mit print heraus, was von einem bash-Skript dann entgegen genommen wird, in den iso-8859-Zeichensatz:

Code: Alles auswählen

print str(listeNachr).encode('iso-8859-1') + freierText.get().encode('iso-8859-1')
Jetzt läufts wie geschmiert :-)
Eckard
BlackJack

@egerlach: Das wird wahrscheinlich so lange wie geschmiert laufen, bis jemand etwas eingibt, was sich nicht in 'iso-8859-1' kodieren lässt. ;-)
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

@egerlach Zumindest bei dir würde dein Code schon bei mir versagen weil meine Shell UTF-8 nutzt, sehr ungewöhnlich dürfte dass auch nicht sein. Mal abgesehen davon dass str() (unter 2.x) den Code nach 'ascii' enkodiert.

Besser wäre du nutzt sys.stdout.encoding(wenn vorhanden) für die Ausgabe und sys.stdin.encoding(wenn vorhanden) für die Dekodierung des eingegebenen Textes von der Konsole, bei GUIs sollte unicode zurückkommen. Sollte das encoding der Standardausgabe nicht ermittelbar sein kann man immer noch auf sys.getdefaultencoding() zurückfallen, mit 'replace' um Fehler zu behandeln.
Dav1d
User
Beiträge: 1437
Registriert: Donnerstag 30. Juli 2009, 12:03
Kontaktdaten:

egerlach hat geschrieben:hier der Code, den ich eingesetzt habe, einfach die Farbe alle 5 Sek ändern.

Code: Alles auswählen

def wechsele_hintergrFarbe(t):
   while True:
        t.config(background="#eeeee6")
        time.sleep(5)
        t.config(background="#e6eade")
        time.sleep(5)
thread.start_new_thread(wechsele_hintergrFarbe,(root,))
ich hab so gut wie keine Ahnung von Tkinter, aber von wx.Python

In wxPython schaut das so aus:

Code: Alles auswählen

          self.timer = wx.Timer(self)
          self.timer.Start(5000) # 5000ms     
          self.Bind(wx.EVT_TIMER, self.on_refresh_bgcolor)
      def on_refresh_bgcolor(self, event):
          # Alle 5 Sekunden wird diese Funktion aufgerufen
          pass
Jetzt bin ich mir nicht ganz sicher, ich glaube das heist in Tkinter

Code: Alles auswählen

root.after(5000, wechsele_hintergrFarbe)
mfg
the more they change the more they stay the same
Antworten