tkinter/python 2.4.2 verliert sporadisch Kontakt zur GUI

Fragen zu Tkinter.
egerlach
User
Beiträge: 43
Registriert: Samstag 14. März 2009, 21:32

Hallo,
habe unter eine Suse 10.1 (linux, kernel 2.6.16) mit Python/TKinter 2.4.2 Programcode am laufen und der verliert sporadisch Kontakt zur GUI: eine ausgewählte Checkbox (Auswahl von Emfängernamen) wird vom Code als nicht ausgwählt ausgelesen, es erscheint dann der Benutzerhinweis in Form einer msgbox: "Sie haben keinen Empfänger ausgewählt". Das ist aber falsch! Ein Empfänger ist immer per default gesetzt und wird vom Bentzer fast nie verändert. Daher ist es eindeutig ein Fehler im Ablauf des Codes. Was kann ich dagegen tun? Python update? Wenn ja, auf welche Version?

Zweites Beispiel für Fehlerverhalten: in der Python-TKinter-Anwendung ist ein Eingabefeld für Freitext, eine ENTER- bzw RETURN-Taste unmittelbar danach gedrückt führt das durch, was eigentlich der "OK/weiter"-Button macht. Aber TKinter reagiert nicht mehr, der Tastendruck wird ignoriert. Wird dann mit der Maus auf den Button "OK/weiter" geklickt, dann kommt: "Sie haben keinen Empfänger ausgewählt". Es scheint python/TKinter dann irgendwie durcheinander gekommen zu sein und vieles funktioniert dann nicht mehr ("Absturz"?). Bei einem nochmaligen Start der python/TKinter-Anwendung gehts dann meistens wieder.

Die Fehlverhalten treten etwa alle 20 Starts der python/TKinter-Anwendungen auf. Es wird übrigens nach dem Start der Anwendung sofort mit Schreiben von Text begonnen und sofort danach mit "OK/weiter" die Anwendung beendet, meist nur 4-10 Sekunden. Der Fehler ist sicherlich nicht innerhalb einer längeren Zeitspanne zu suchen, in der TKinter auf Eingaben wartet.

danke schon mal
Eckard
Zuletzt geändert von egerlach am Donnerstag 11. Juni 2009, 17:43, insgesamt 1-mal geändert.
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

egerlach hat geschrieben:Daher ist es eindeutig ein Fehler im Ablauf des Codes. Was kann ich dagegen tun? Python update? Wenn ja, auf welche Version?
Mit so einer Aussage sollte man vorsichtig sein ;-)

Hast du das Programm selber geschrieben oder benutzt du es nur? Wenn der erste Falle zutrifft, dann solltest du etwas Code zeigen, sonst ist es vollkommen unmöglich dir zu Helfen. Im zweiten Fall ist natürlich interessant um welches Programm es sich handelt, dann wäre aber auch dessen Autor der beste Ansprechpartner.

Wenn ich ein Problem tippen müsste: GUI & Threads.
Das Leben ist wie ein Tennisball.
BlackJack

Andere mögliche Fehlerquelle: Mehrere Exemplare von `Tkinter.Tk` und damit mehr als eine Hauptschleife.
egerlach
User
Beiträge: 43
Registriert: Samstag 14. März 2009, 21:32

BlackJack hat geschrieben:Andere mögliche Fehlerquelle: Mehrere Exemplare von `Tkinter.Tk` und damit mehr als eine Hauptschleife.
Was sind "Exemplare" von TKinter? - Meinst Du dass von import tkinter as tk ... bis ... root.mainloop() mehr als eine aktiv sein könnte? Also innerhalb der gleichen TKinter-Anwendung zwei oder mehr Male diese loop?
Also das ist es 100% nicht, es ist nur ein einziges file.py mit dem üblichen Zeugs an Radiobuttons, Checkbuttons und einem Texteingabefeld. Es findet nur einmal import tkinter as tk und einmal root.mainloop am Ende statt.

Eckard
BlackJack

Exemplare, manchmal auch (IMHO falsch) übersetzt als Instanzen, sind Objekte, die aus Klassen erzeugt werden. Also wenn mehr als einmal im Programm mit ``tk.Tk()`` ein Objekt/Exemplar erzeugt wird, gibt's "lustige" Effekte.
egerlach
User
Beiträge: 43
Registriert: Samstag 14. März 2009, 21:32

BlackJack hat geschrieben:Exemplare, manchmal auch (IMHO falsch) übersetzt als Instanzen, sind Objekte, die aus Klassen erzeugt werden. Also wenn mehr als einmal im Programm mit ``tk.Tk()`` ein Objekt/Exemplar erzeugt wird, gibt's "lustige" Effekte.
achso, klar. Nein, keine OO-Programmierung sondern klassisch prozedural. Ist damit dieser Effekt einer doppelten Instanz auszuschliessen? - Das Phänomen tritt ja auch eher selten auf.
BlackJack

Äh, Du kannst Tkinter-GUIs weder ohne OO noch mit klassischer prozeduraler Programmierung realisieren. Du musst Objekte erzeugen, denn in Python ist nun einmal alles ein Objekt was man an einen Namen binden kann, und die lineare Programmierung aus dem rein Prozeduralen ist bei GUIs durch ereignisgetriebene Programmierung ersetzt.
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

egerlach hat geschrieben:achso, klar. Nein, keine OO-Programmierung sondern klassisch prozedural. Ist damit dieser Effekt einer doppelten Instanz auszuschliessen? - Das Phänomen tritt ja auch eher selten auf.
Nimm doch einfach mal die Suchfunktion deines Editors und sieh nach, wie oft Tk() im Code vorkommt: Es sollte genau einmal vorkommen.
BlackJack

Und das möglichst nicht in einer Schleife, oder in einer Funktion, die mehr als einmal aufgerufen wird.
egerlach
User
Beiträge: 43
Registriert: Samstag 14. März 2009, 21:32

es kommt genau einmal am Anfang des Codes vor, und NICHT in einer Schleife: root=tk.Tk()
tk() kommt sonst nicht mehr vor, weder groß noch klein geschrieben.

Danke für die Hinweise. Sonst noch Ideen?
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

egerlach hat geschrieben:es kommt genau einmal am Anfang des Codes vor, und NICHT in einer Schleife: root=tk.Tk()
tk() kommt sonst nicht mehr vor, weder groß noch klein geschrieben.

Danke für die Hinweise. Sonst noch Ideen?
Threads wurden ja schon angesprochen: Wie steht's damit?
egerlach
User
Beiträge: 43
Registriert: Samstag 14. März 2009, 21:32

numerix hat geschrieben: Threads wurden ja schon angesprochen: Wie steht's damit?
?? Verstehe nicht, welche threads?
Hier der Code, den Button den ich mit "OK/weiter" bezeichnet hatte heißt ihier "senden":

Code: Alles auswählen

#!/usr/bin/python
# -*- coding: utf-8 -*-
import dircache 
import os
import subprocess
import sys
import Tkinter as tk
import re
meine_Kng=sys.argv[1]
std_Empfaenger_Kng=sys.argv[2]  
def lies_Personendaten (Dateiname):
    pat={}
    datei=open(Dateiname)
    pat["nummer"] = datei.readline().strip()
    pat["nachname"] = datei.readline().strip()
    pat["vorname"] = datei.readline().strip()
    datei.readline().strip()
    datei.readline().strip()
    pat["gebdat"] = datei.readline().strip()
    datei.close()
    return pat

# Fenster:
root=tk.Tk()
nachrFensterBreite=500
nachrFensterHoehe=410
screenBreite=root.winfo_screenwidth()
screenHoehe=root.winfo_screenheight()
xFenster=screenBreite/2 - nachrFensterBreite/2
#xFenster=0
yFenster=screenHoehe/2 - nachrFensterHoehe/2  


root.geometry("%dx%d+%d+%d" % (nachrFensterBreite, nachrFensterHoehe, xFenster, yFenster))
root.title('Nachricht erstellen')
=============================================================================
# Nachrichteninhalte aus Datei config auslesen
============================================================================
wMsgFrame = tk.Frame(root, relief=tk.SUNKEN, bd=1)
wMsgFrame.grid(row=0, column=0, ipadx=10, ipady=10, sticky=tk.W)
cmd = "grep 'Nachricht ' config| grep -v '^#' | sed 's/Nachricht //'"
p = subprocess.Popen(cmd, shell=True, #bufsize=1,
    stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
p.stdin.close()
Nachrichten=p.stdout.read()
nachrWahl=[]
# nachrWahl.append(tk.StringVar())    so gehts nicht! Schade
nachrWahl=[tk.StringVar() for i in xrange(30)]   # maximal 30 versch. Nachr. sollten reichen 
nr=0
for i in Nachrichten.split("\n"):
    if i !="": 
       #print i
       msg=re.findall(r""(.*)"", i)
       shortcut=re.findall(r"(>.<)", msg[0])
       if shortcut and shortcut[0] != "":
          pos=msg[0].find(">")
          shortcut_char=shortcut[0][1:2].lower()
          msg[0]=msg[0].replace("<","").replace(">","")
       else:
          pos=100   # dummy-Stelle die nie erreicht wird
       cb=tk.Checkbutton(wMsgFrame,text=msg[0], underline=pos, onvalue=msg[0], offvalue="0", variable=nachrWahl[nr])
       cb.grid(row=nr, sticky=tk.W )
       if i.find("*VORAUSWAHL:") != -1 and i.find("ENDE*") != -1:
           arbeitspl=re.findall(r"\*VORAUSWAHL:(.*)ENDE\*", i)
           if arbeitspl[0].find(meine_Kng) != -1:
               cb.select()
       if shortcut and shortcut[0] != "":
           root.bind('<Alt-%c>' % shortcut_char, lambda dummy, c=cb: c.toggle())
           #print "bind ", shortcut_char
       # nachrWahl.append(tk.StringVar())  so gehts nicht , schade
       nr+=1
anzahlNachrichten=nr
=============================================================================
# Adressaten auslesen 
=============================================================================
wParentFrame = tk.Frame(root, relief=tk.SUNKEN, bd=1 )
wParentFrame.grid(row=0,column=1, sticky=tk.N)
wAddressFrame = tk.Frame(wParentFrame, relief=tk.SUNKEN, bd=1)
wAddressFrame.grid(row=0, column=0, ipadx=10, ipady=10, pady=0, sticky=tk.W)

cmd = "grep 'Empfaenger' config| grep -v '^#' | sed 's/Empfaenger //'"
p = subprocess.Popen(cmd, shell=True, #bufsize=1,
      stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
p.stdin.close()
Adressaten=p.stdout.read()

adressWahl=[tk.StringVar() for i in xrange(50)]   # maximal 50 Empfaenger sollten reichen
nr=0
for i in Adressaten.split("\n"):
    if i !="":
Liste! Daran "schuld" ist re
        kng=re.findall(r""(.*)"", i)
        nam=re.findall(r"'(.*)'", i)
        shortcut=re.findall(r"(>.<)", nam[0])
        if shortcut and shortcut[0] != "":
             pos=nam[0].find(">")
             shortcut_char=shortcut[0][1:2].lower()
             nam[0]=nam[0].replace("<","").replace(">","")
        else:
             pos=100    # dummy-Wert, hohe Zahl, die nie erreicht wird
        kng_nam=kng[0]+","+nam[0]
        if kng[0] != meine_Kng:
            cb=tk.Checkbutton(wAddressFrame,text=nam[0], underline=pos, onvalue=kng_nam, offvalue="", variable=adressWahl[nr])
            cb.grid(row=nr, sticky=tk.W)
            if i.find("*VORAUSWAHL:") != -1 and i.find("ENDE*") != -1:
                 arbeitspl=re.findall(r"\*VORAUSWAHL:(.*)ENDE\*", i)
                 #print arbeitspl[0]   # z.B. arbeitspl[0]=" ab ac "
                 if arbeitspl[0].find(meine_Kng) != -1:
                       cb.select()
            if shortcut and shortcut[0] != "":
                 root.bind('<Alt-%c>' % shortcut_char, lambda dummy, c=cb: c.toggle())
            nr+=1
        else:
            print nam[0]  # mein Name wird nach std out geschrieben! KEIN DEBUG!!!
anzahlAdressaten=nr
=============================================================================
# zuletzt bearbeitete Personen auslesen
=============================================================================
cmd = "ls /home/personen/export."+meine_Kng+"* -t"
p = subprocess.Popen(cmd, shell=True, #bufsize=1,
    stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
p.stdin.close()
dateiListe=p.stdout.read()
#print dateiListe
ppWahl=tk.IntVar()
wPPFrame = tk.Frame(wParentFrame, relief=tk.SUNKEN, bd=1)
wPPFrame.grid(row=1, column=0, ipadx=10, ipady=10, pady=20, sticky=tk.NSEW) 
nr=0
personen=[]
for i in dateiListe.split("\n"):
    if i != "": 
        #print i
        ppDaten=lies_Personendaten(i)
        PPRadioText=ppDaten["nachname"]+", "+ppDaten["vorname"]+", "+ppDaten["nummer"]+", "+ppDaten["gebdat"]
        personen.append({'nachname':ppDaten["nachname"], 'vorname':ppDaten["vorname"], \
                          'nummer':ppDaten["nummer"], 'gebdat':ppDaten["gebdat"]})        
        
        if nr <= 1:
            R=tk.Radiobutton(wPPFrame,text=PPRadioText, anchor=tk.NW, indicatoron='1',variable=patWahl,value=nr)
            R.grid(row=nr, sticky=tk.W)
        if nr == 0: R.select()  # wird evtl. wieder durch "keine Person" ueberschrieben
        nr+=1
nr=3   # muss immer = 3 (vierter Eintrag) sein, sonst klappt das mit dem Auslesen unten nicht
cmd = "grep 'Person' config| grep -v '^#' | sed 's/Person //'"
p = subprocess.Popen(cmd, shell=True, #bufsize=1,
        stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
p.stdin.close()
kPerson=p.stdout.read()
j=0
for i in kPerson.split("\n"):  # es gibt nur einen Eintrag , Stand 05.2009
   if i !="" and j<1:
       j+=1
       #print "i: "+i
       txt=re.findall(r""(.*)"", i)
       shortcut=re.findall(r"(>.<)", txt[0])
       if shortcut and shortcut[0] != "":
           pos=txt[0].find(">")
           shortcut_char=shortcut[0][1:2].lower()
           txt[0]=txt[0].replace("<","").replace(">","")
       else:
           pos=100   # dummy-Stelle die nie erreicht wird

       cb=tk.Radiobutton(wPPFrame, underline=pos,text=txt[0],variable=patWahl,value=nr)
       cb.grid(row=nr, sticky=tk.W)
       if i.find("*VORAUSWAHL:") != -1 and i.find("ENDE*") != -1:
            arbeitspl=re.findall(r"\*VORAUSWAHL:(.*)ENDE\*", i)
            if arbeitspl[0].find(meine_Kng) != -1:
                cb.select()
            if shortcut and shortcut[0] != "":
                root.bind('<Alt-%c>' % shortcut_char, lambda dummy, c=cb: c.select())
                #print "bind ", shortcut_char

personen.append({'nachname':"kein Person", 'vorname':"",'nummer':"", 'gebdat':""})
=============================================================================
# Eingabefeld, unten
=============================================================================

freierText=tk.Entry(width=70)
freierText.grid(row=1, columnspan=2)
freierText.focus()
####################################################################################

def werte_auslesen():
    print "nachr"
    listeNachr=""
    for i in xrange(anzahlNachrichten):
        if nachrWahl[i].get() != "":
            listeNachr=str(listeNachr)+nachrWahl[i].get()+" "
    print str(listeNachr) + freierText.get()

    #print personen
    gewaehlterPP=ppWahl.get()
    print personen[gewaehlterPP]['nummer']
    print personen[gewaehlterPP]['nachname']
    print personen[gewaehlterPP]['vorname']
    print personen[gewaehlterPP]['gebdat']
                                        
    for i in xrange(anzahlAdressaten):
        if adressWahl[i].get() != "":
            # z.B. aa,Empfang 
            print adressWahl[i].get()

    root.quit()

def print_abbrn():
    print "abbrn"
    root.quit()
    
def print_empfn():
    print "empfn"
    root.quit()
    
def print_gsndt():
    print "gsndt"
    root.quit()

tk.Button(root, text="empfangen", command=print_empfn).grid(row=3,column=0,padx=1,sticky=tk.W)
tk.Button(root, text="gesendet",  command=print_gsndt).grid(row=3,column=0,padx=1)
tk.Button(root, text="abbrechen", command=print_abbrn).grid(row=3,column=1,padx=1,sticky=tk.W)
tk.Button(root, text="Senden", command=werte_auslesen).grid(row=3,column=1,padx=1,sticky=tk.E)
#tk.Button(root, text="Senden", width=30, command=werte_auslesen).grid(row=3,column=1,padx=1) 

root.bind('<Escape>',lambda dummy: quit())
root.bind('<Return>',lambda dummy: werte_auslesen())
root.mainloop()

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

keiner mehr eine Idee?
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Es hat sicherlich niemand Lust sich durch über 200 Zeilen (unübersichtlichen) Code zu wühlen. Du solltest ihn so weit wie möglich kürzen, so das der Fehler noch immer auftritt. Auch Minimalbeispiel genannt.
Das Leben ist wie ein Tennisball.
egerlach
User
Beiträge: 43
Registriert: Samstag 14. März 2009, 21:32

Dachte ichmir doch, dass diese Antwort mal kommt.Oben will einer, dass ich Code poste, unten, dass ich diesen Kürze. Leute, ich habe bei mir hier nie diesen latent auftretenden Fehler gesehen, bei anderen, bei denen der Code auch läuft, kommt der Fehler eben alle 20 python-Aufrufe einmal vor, vielleicht auch alle 40 Aufrufe einmal. Ich weiss nicht wo der Fehler ist, wenn python plötzlich nicht mehr eine Checkbox auslesen kann und ein "ENTER" nicht mehr als Shortcut für ein click auf "senden" annimmt. Ok, ich werde eben mit try-and-error rangehen müssen, mal auf python 2.5 updaten oder den python-code kompilieren. Mal sehn. Trotzdem danke an alle hier,

Gruss Eckard
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.
Antworten