TypeError erkenne Fehler nicht

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
ichbins
User
Beiträge: 40
Registriert: Samstag 5. September 2020, 07:07

Das gui erzeugt Entries mit 5 Zeilen. Nehmen wir an ich gebe nur 3 Zeilen ein

ich ich
bin bin
da da
(leer) (leer)
(leer) (leer)

Nach der 3. Zeile soll das Programm abrechen. Jetzt möchte ich aber auf Zeile 4 wo (leer) ist zugreifen.

Bei self.seriennummer_ware steht "(<tkinter.Entry object .!entry>,". Ich möchte aber die Elemente sehen. Bei self.self.seriennummer_ware ist ein Fehler.
seriennummer.get() wird richtig angezeigt. Ich brauche in diesem Fall aber die nächste Zeile wo (leer) steht. Wenn ich versuche mit seriennummer(zeilen).get() draufzugreifen kommt "TypeError: can only concatenate str (not "int") to str"
Wie kann ich aber auf die nächste Zeile zugreifen

Code: Alles auswählen

    def vergleichen(self):
        zeilen=0
        for seriennummer, ware in self.seriennummer_ware:
            if seriennummer.get()=='' or ware.get()=='':
                tk.messagebox.showwarning('Warning', "Fehler 1")
                break
            else:
                zeilen +=1
                print (self.seriennummer_ware)
                print(seriennummer.get())
                print(seriennummer[zeilen].get())
                if seriennummer[zeilen].get() == '' and ware[zeilen].get()=='':
                    break
Sirius3
User
Beiträge: 17749
Registriert: Sonntag 21. Oktober 2012, 17:20

Warum möchtest Du auf eine leere Zelle zugreifen?

Erkläre was Du machen möchtest, nicht wie (da das wie so nicht funktioniert). Was ist das Ziel?
ichbins
User
Beiträge: 40
Registriert: Samstag 5. September 2020, 07:07

Keine Eingabe => Showwarning wird angezeigt
Eine Eingabe fehlt => Showwarning
Eingabe seriennummer und ware => kein Showwarning

Wenn ich es so schreibe wird wieder kein Fehler angezeigt wenn eine Eingabe fehlt.

Seriennummer und Ware waren ja eine globale Variable. Wie verwende und gebe ich ein print() aus bzgl. Elemente von self.seriennummer_Ware in einer anderen Datei.

Danke!

Code: Alles auswählen

beispiel.py
 
 class Fenster:
    def vergleichen(self):
        zeilen=False
        for seriennummer, ware in self.seriennummer_ware:
            if seriennummer.get()=='' or ware.get()=='':
                if zeilen==False:
                    tk.messagebox.showwarning('Warning', "Fehler 1")
                break
            else:
                zeilen=True
                
    
                
   daten.py
   
   import beispiel

print(beispiel.Fenster.seriennummer_ware)
Benutzeravatar
__blackjack__
User
Beiträge: 13103
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@ichbins: Ich verstehe immer noch nicht was da genau passieren soll und vor allem nicht warum Du in einem Schleifendurchlauf schon auf das *nächste* Eingabefeld(paar) zugreifen willst, welches ja ganz regulär im nächsten Schleifendurchlauf behandelt werden kann.

Der Versuch im `daten`-Modul dann über die *Klasse* auf ein Attribut einer nicht existierenden *Instanz* zuzugreifen geht natürlich nicht.

Ich finde die Namen `seriennummer` und `ware` hier auch ein wenig problematisch, denn das ist ja keine Seriennummer, sondern ein Eingabeelement für eine Seriennummer. Eine (potentielle) Seriennummer ist das was die `get()`-Methode liefert. Wenn man diesen Rückgabwert hier an einen lokalen Namen binden will, bekommt man Probleme sich einen Namen dafür auszudenken, weil der offensichtliche schon belegt ist. Gleiches gilt für `ware`.

`vergleichen()` ist als Methodenname auch nicht besonders aussagekräftig.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Sirius3
User
Beiträge: 17749
Registriert: Sonntag 21. Oktober 2012, 17:20

Was soll dann das Flag `zeilen`? Was für Gedanken hast Du Dir gemacht?
Du hast drei verschiedene Fälle, Zeile gefüllt, Zeile halb gefüllt und Zeile leer. Welchen Fall prüft Dein if? Und was übersiehst Du dabei? Welche Bedingung wird noch gar nicht geprüft?
Lass das mit den verschiedenen Dateien oder globalen Variablen. Das ist eine falsche Denkweise. Bei GUIs muß man sowieso komplett umdenken. Was soll denn mit der Eingabe passieren?
ichbins
User
Beiträge: 40
Registriert: Samstag 5. September 2020, 07:07

Es funktioniert jetzt. Hier ist der Code falls ihr euch interessiert. Es hätte unterscheiden sollen ob nichts eingegeben wurde oder ob etwas eingegeben wurde und die nächste Zeile leer ist. Dementsprechend soll eine Warnung ausgegeben werden oder nicht.

Ich glaube ich werde komplett umdenken müssen.
Ich habe ein Python-Programm welches Messinstrumente steuert. Zuerst wird erkannt auf welchem USB welches Gerät ist und eine CSV-Datei erstellt und danach eine while Loop welches Relais schaltet und die Daten vom jeweiligen Messinstrument bearbeitet. Jetzt wollte ich die Grafik hinzufügen wo die Daten gesendet werden vor der while Loop an das Steuerprogramm. Es wurde aber hauptsächlich alles global bearbeitet und nur paar funktionen benutzt. Hauptsächlich wurde aber alles sequentiell untereinander geschrieben.
Jetzt brauche ich ja die Grafik und muss es mit dem alten Programm verbinden.

Habe schon gelesen dass ich vermutlich Threads und Queues benötigen werde. Das mache ich aber später. Wichtig ist einmal dass die Daten die das Hauptprogramm von der globalen Nebendatei empfangen hat von der GUI bekommt.

LG

Code: Alles auswählen

    def vergleichen(self):
        zeilen=False
        for seriennummer, ware in self.seriennummer_ware:
            if seriennummer.get()=='' and ware.get()=='':
                if zeilen==False:
                    tk.messagebox.showwarning('Warning', "Fehler 1")
                    return False
                else:
                    return True
            elif seriennummer.get()=='' or ware.get()=='':
               tk.messagebox.showwarning('Warning', "Fehler 1")
               return False 
            else:
                zeilen=True
        return True
Sirius3
User
Beiträge: 17749
Registriert: Sonntag 21. Oktober 2012, 17:20

Wer soll denn den Rückgabewert verarbeiten? Bisher war das ein Callback, dem der Rückgabewert egal ist.
`vergleichen` ist immer noch ein schlechter Methodennamen, denn was wird da mit was verglichen?
Mir wäre es ja egal, ob Zeilen leer sind, oder nicht. Der Nutzer wäre wohl verwirrt, dass manche Eingaben nicht verwendet werden.
Dann würde ich das Ergebnis zur Weiterverarbeitung in eine Liste exportieren:

Code: Alles auswählen

def parse_form(self):
    result = []
    for seriennummer_entry, ware_entry in self.seriennummer_ware_entries:
        seriennummer = seriennummer_entry.get()
        ware = ware_entry.get()
        if not seriennummer and not ware:
            # ignore empty lines
            pass
        elif not seriennummer or not ware:
            raise ValueError("Fehler keine Seriennummer oder Ware angegeben")
        else:
            result.append((seriennummer, ware))
    return result
Und diese Methode kann man dann dort aufrufen, wo mit den Daten weiter gearbeitet werden soll.
ichbins
User
Beiträge: 40
Registriert: Samstag 5. September 2020, 07:07

Der Button "senden" ruft alle Funktionen auf die vom GUI die Daten an die Hauptdatei schickt. So war mein Gedanke man kann es aber auf viele Arten machen.

"Mir wäre es ja egal, ob Zeilen leer sind, oder nicht. Der Nutzer wäre wohl verwirrt, dass manche Eingaben nicht verwendet werden"

Wie meinst du das. Die Funktion "senden" wird verarbeitet wenn die Eingabe passt bzw. etwas drinnen steht.

Code: Alles auswählen

    def senden(self):
        if self.vergleichen()==True
            self.speicherort()
        
    
    def vergleichen(self):
        zeilen=False
        for seriennummer, ware in self.seriennummer_ware:
            if seriennummer.get()=='' and ware.get()=='':
                if zeilen==False:
                    tk.messagebox.showwarning('Warning', "Fehler 1")
                    return False
                else:
                    return True
            elif seriennummer.get()=='' or ware.get()=='':
               tk.messagebox.showwarning('Warning', "Fehler 1")
               return False 
            else:
                zeilen=True
        return True
                
     
    def speicherort(self):
        ort=self.entry_pfad.get()
        print(ort)
        if ort=='':
            pass
Sirius3
User
Beiträge: 17749
Registriert: Sonntag 21. Oktober 2012, 17:20

Deine Wortwahl lässt erahnen, dass Du eine falsche Vorstellung davon hast, wie Programme ablaufen: ›Hauptdatei schicken‹ ist so ein falsches Bild. Wo welche Funktion definiert wird, ist egal. Bei der Komplexität Deines Programms sind mehrere Dateien noch nicht nötig.
Geschickt wird auch nichts, sondern Funktionen werden mit Parametern aufgerufen.
Dein gezeigter Code hat Syntaxfehler. Und die Namen der Methoden sind allesamt seltsam.
`senden` sendet nichts und speicherort ist keine Tätigkeit, die Funktion macht auch nichts.
Wo ist denn der Programmteil, der mit den eingegebenen Daten arbeitet?
ichbins
User
Beiträge: 40
Registriert: Samstag 5. September 2020, 07:07

Ich glaube ich darf den Programmteil nicht Online stellen. Deswegen habe ich irgendwelche Worte genommen und mir da keine Gedanken gemacht.
Speicherort ist nicht vollständig da habe ich nur etwas getestet. Da kommt später über localtime() wenn kein Eintrag ist das Datum hin und erzeugt den ganzen Pfad und erstellt eine .csv Datei.

Ich wollte nur zeigen wer den Rückgabewert verarbeitet.

Wie wird eigentlich not seriennummer verarbeitet dass oben die Eingabe steht und unten ein False.

Code: Alles auswählen

 print(seriennummer)
 print(not seriennummer)
ichbins
User
Beiträge: 40
Registriert: Samstag 5. September 2020, 07:07

Hallo

habt ihr einen Tippt wie ich das Problem mit EOFerror lösen kann.

Eine andere Frage: Wie wird eigentlich "not seriennummer" verarbeitet dass bei "seriennummer" die Eingabe steht und unten ein False.
print(seriennummer)
print(not seriennummer)

LG

Code: Alles auswählen

def __init__(self):
        
        self.window = tk.Tk()
        
        tk.Label(self.window, text="Seriennummer:").grid(row=0, column=0)
        tk.Label(self.window, text="Ware:").grid(row=0, column=1)
        self.seriennummer_ware_entries = []
        for row in range(1,6):
            entry_seriennummer = tk.Entry(self.window, width=10)
            entry_seriennummer.grid(row=row, column=0)
            entry_ware = tk.Entry(self.window, width=10)
            entry_ware.grid(row=row, column=1)
            self.seriennummer_ware_entries.append((entry_seriennummer, entry_ware))
        try:  
            datei=open('datei.txt', 'rb')
            liste=pickle.load(datei)
            datei.close()
            print('Liste: '+ liste)      
        except FileNotFoundError:
            datei=open('datei.txt', 'wb')
            datei.close()
            
            
            
    def senden(self):
        if self.parse_form() != False:
            parse_form=self.parse_form()
            speicherort=self.speicherort()
            return(parse_form, speicherort)
            
    
    def parse_form(self):
        text=False
        result = []
        for seriennummer_entry, ware_entry in self.seriennummer_ware_entries:
            seriennummer = seriennummer_entry.get()
            ware = ware_entry.get()
            if seriennummer=='' and ware=='':
                # ignore empty lines
                if text==False:
                    tk.messagebox.showwarning('Warning', 'Fehler 1')
                    return False
                else:
                    return result
            elif seriennummer=='' or ware=='':
                tk.messagebox.showwarning('Warning', 'Fehler 2')
                return False
            else:
                text=True
                try:
                    result.append((seriennummer, float(ware)))
                    speichern=open('datei.txt', 'wb')
                    liste=pickle.dump(result, speichern)
                    speichern.close()
                    print('Speicher gespchrieben')
                except ValueError:
                    tk.messagebox.showwarning('Warning', 'Fehler 3')
                    return False                       
        return result
        
        
        
        
        Traceback (most recent call last):

  File "<ipython-input-5-4927f97cc2b2>", line 1, in <module>
    runfile('/home/Dokumente/grafik/beispiel.py', wdir='/home/Dokumente/grafik')

  File "/usr/lib/python3/dist-packages/spyder_kernels/customize/spydercustomize.py", line 678, in runfile
    execfile(filename, namespace)

  File "/usr/lib/python3/dist-packages/spyder_kernels/customize/spydercustomize.py", line 106, in execfile
    exec(compile(f.read(), filename, 'exec'), namespace)

  File "/home/Dokumente/grafik/beispiel.py", line 115, in <module>
    main()

  File "/home/Dokumente/grafik/beispiel.py", line 111, in main
    fenster = Fenster()

  File "/Dokumente/grafik/beispiel.py", line 30, in __init__
    liste=pickle.load(datei)

EOFError: Ran out of input
Sirius3
User
Beiträge: 17749
Registriert: Sonntag 21. Oktober 2012, 17:20

Was soll das mit dem "datei.txt"-Lesen in __init__. Das wird doch gar nicht gebraucht und kann weg.
In `senden` rufst Du zwei mal parse_form auf, was quatsch ist, weil da immer das selbe Ergebnis kommt. `self.speicherort` wird nirgends definiert, und `senden` nirgends aufgerufen.
`parse_form` liefert mal False und mal eine Liste. Das sollte nicht sein. Ich habe absichtlich eine Exception bei einem Fehler geworfen, denn so kann man an der Stelle, wo mit den Daten gearbeitet wird entscheiden, was bei einem Fehler passieren soll.
Du hast jetzt in parse_form aber alles mögliche an Aufgaben hineingepackt. Eine Funktion sollte immer nur EINE Sache machen. Nicht Formulardaten einlesen, Warnungen ausgeben und noch irgendetwas in Dateien schreiben.
An der Stelle, wo Du was schreibst, ist das auch total falsch.

Der EOF-Fehler kommt daher, dass Du in __init__ eine leere Datei erzeugst. Und aus der kann man schlecht was lesen.
Übrigens: Pickel ist nicht zum dauerhaften Speichern von Daten gedacht. Das ist auch kein Text-Format, wie der Dateiname suggerieren will.
Ich verstehe immer noch nicht, was Du eigentlich mit den Daten machen willst.
ichbins
User
Beiträge: 40
Registriert: Samstag 5. September 2020, 07:07

Durch den EOF-Fehler wurde es ja noch nicht getestet und ist nicht ganz fertig. Beim Neustart soll es die Datei.txt auslesen und die Werte in die Entries von der Seriennummer und Ware eintragen. Bei parse_form kann der Rückgabewert ein False oder die Liste von der Seriennummer und sein. Bei False soll es alles abbrechen und wenn es ungleich False ist soll die Liste mit der Seriennummer und Ware gesendet werden. Momentan teste ich nur einige Sachen. Später sollen die Werte der Variablen an die jetzige Hauptdatei geschickt werden bzw. durch den Aufruf der Funktion in eine Variable gespeichert werden.
Ich habe nur gedacht das result gespeichert werden soll bevor die Methode ein return schickt.

Eigentlich soll es die Datei auslesen und die Werte in die Entries eintragen. Aber beim ersten Mal muss ich ja zuerst eine Datei erstellen damit die Datei ausgelesen werden kann. Wenn er eine leere Datei ausliest soll halt nichts in die Entry-Widgets eingetragen werden. Das Problem ist dass aber ein Fehler erscheint.

Wozu ist dann Pickel was kann ich sonst verwenden?

Es stehen bestimmte Werte wie die Seriennummer, Gewicht, wieviele Kanäle usw. Somit soll das Hauptprogramm blockieren bis die Werte aus der GUI gesendet werden. Wenn das Hauptprogramm diese Werte hat soll das Hauptprogramm weiterlaufen und in eine while-Loop wo Sachen berechnet werden bzw. der Speicherort verwendet wird um eine csv mit den jeweiligen Daten verwendet wird usw.

Hier ist der jetzige Code:

Code: Alles auswählen

import tkinter as tk
from tkinter import messagebox
from time import localtime,strftime
import pickle
 
class Fenster:
    def __init__(self):
        
        self.window = tk.Tk()
        
        tk.Label(self.window, text="Seriennummer:").grid(row=0, column=0)
        tk.Label(self.window, text="Ware:").grid(row=0, column=1)
        self.seriennummer_ware_entries = []
        for row in range(1,6):
            entry_seriennummer = tk.Entry(self.window, width=10)
            entry_seriennummer.grid(row=row, column=0)
            entry_ware = tk.Entry(self.window, width=10)
            entry_ware.grid(row=row, column=1)
            self.seriennummer_ware_entries.append((entry_seriennummer, entry_ware))
        try:  
            datei=open('datei.txt', 'rb')
            liste=pickle.load(datei)
            datei.close()
            #print('Liste: ')      
        except FileNotFoundError:
            datei=open('datei.txt', 'wb')
            datei.close()

        
        
        self.entry_pfad = tk.Entry(self.window, width=20)
        self.entry_pfad.grid(row=7)
        
        self.label_pfad=tk.Label(self.window, text="Pfad:  ", justify=tk.LEFT)
        self.label_pfad.grid(row=8)
        
        
    
        tk.Button(self.window, text='Senden', command=self.senden).grid(row=7, column=1)
    
    
    
    def senden(self):
        if self.parse_form() != False:
            parse_form=self.parse_form()
            speichername=self.speichername()
            print(self.speichername(), self.parse_form)
            return(parse_form, speichername)
            
    
    def parse_form(self):
        text=False
        result = []
        for seriennummer_entry, ware_entry in self.seriennummer_ware_entries:
            seriennummer = seriennummer_entry.get()
            ware = ware_entry.get()
            if seriennummer=='' and ware=='':
                # ignore empty lines
                if text==False:
                    tk.messagebox.showwarning('Warning', 'Fehler 1')
                    return False
                else:
                    return result
            elif seriennummer=='' or ware=='':
                tk.messagebox.showwarning('Warning', 'Fehler 2')
                return False
            else:
                text=True
                try:
                    result.append((seriennummer, float(ware)))
                    speichern=open('datei.txt', 'wb')
                    liste=pickle.dump(result, speichern)
                    speichern.close()
                    #print('Speicher gespchrieben')
                except ValueError:
                    tk.messagebox.showwarning('Warning', 'Fehler 3')
                    return False                       
        return result
        
    

            
    def speichername(self):
        zeit=localtime()
        datum=strftime("%d-%m-%Y",zeit)

        if self.entry_pfad.get()=='':
            name=datum
            self.entry_pfad.insert(0, name)
            self.label_pfad.config(text='Pfad:  '+ 'Pfad/' + name + '.csv')
        else:
            name=self.entry_pfad.get()
            if ' ' in name:
                name=name.replace(' ', '-')
                self.entry_pfad.delete(0,'end')
                self.entry_pfad.insert(0, name)
            self.label_pfad.config(text='Pfad:  ' + 'Pfad/' + name + '.csv')
            return name
            
 
           
                
def main():
    fenster = Fenster()
    fenster.window.mainloop()

if __name__ == '__main__':
    main() 
Sirius3
User
Beiträge: 17749
Registriert: Sonntag 21. Oktober 2012, 17:20

Warum wiederholst Du das, was Du schon geschrieben hast, ohne auf das einzugehen, was ich schreibe? So kommen wir hier nicht weiter.
Es macht keinen Sinn, eine leere Datei anzulegen. Das ist Dein EOF-Fehler. Und jetzt steht das immer noch im Code.
Auch sonst sind immer noch die selben Fehler im Code. Eine Funktion sollte immer nur einen Typ zurückgeben. Fehler werden nicht per False mitgeteilt, sonder per Exception.
Statt die low-level-Funktion localetime nimmt man datetime.datetime. Doppelten Code sollte man vermeiden:

Code: Alles auswählen

    def get_speichername(self):
        name = self.entry_pfad.get()
        if not name:
            name = f'{datetime.datetime.now():%d-%m-%Y}'
        else:
            name = name.replace(' ', '-')
        self.entry_pfad.delete(0,'end')
        self.entry_pfad.insert(0, name)
        self.label_pfad["text"] = f'Pfad:  Pfad/{name}.csv'
        return name
Benutzeravatar
__blackjack__
User
Beiträge: 13103
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@ichbins: Das Du das mit der Liste und dem `False` noch mal erklärst was das sollte, macht es nicht besser oder richtiger. Das kann man nicht irgendwie wegerklären, das ist einfach eine kaputte Schnittstelle.

Falls die Unterscheidung Liste und „irgend etwas lief nicht so wie es sollte“ wichtig ist, dann nimmt man dafür Ausnahmen. Die wurden extra erfunden um fehleranfällige ”Spezialwerte” los zu werden. Falls die Unterscheidung zwischen den beiden Fällen *nicht* wichtig ist, kann man auch einfach eine leere Liste zurück geben, und hat beim Aufrufer dann keinen Sonderfall via Typ mehr zu prüfen und hat da dann keinen komisch riechenden oder fehleranfälligen Code mehr.

Selbst wenn man denn auf biegen und brechen einen Sonderwert verwenden will, wäre das in diesem Fall sicher nicht `False` sondern `None`. Denn eine API die einen der beiden Wahrheitswerte liefern kann, aber niemals den anderen ist falsch/kaputt.

Du verwendest schon wieder/immer noch diese komische „senden“- und „an Hauptdatei schicken“-Formulierungen. Man schickt/sendet nichts an Dateien, man schreibt in Dateien. Wenn Du von Senden sprichst, weckt das beim Leser automatisch Assoziationen zu Sockets und/oder gar Kommunikation mit anderen Geräten oder Prozessen.

„Senden“ oder „schicken“ kann in bestimmten Fällen auch bei Beschreibung von Kommunikation zwichen Objekten verwendet werden. Weil das in der ursprünglichen Diskussion von objektorientierter Programmierung zur Beschreibung des gedanklichen Modells so formuliert wurde. Das ein Programm aus Objekten besteht, die einen inneren Zustand haben und die über Nachrichten mit anderen Objekten im Programm kommunizieren. Aber selbst in diesem Modell macht es keinen Sinn zu sagen „eine Methode schickt ein return“. Es sei denn „return“ wäre wirklich ein Wert den man in einer Nachricht schicken könnte. Darum geht es hier ja aber nicht.

Du musst keine leere Datei erstellen, Du musst einfach nur den Fall das keine Datei exsistiert sinnvoll behandeln in dem die Ausnahme die beim öffenen einer nicht existierenden Datei (oder generell wenn die Datei nicht geöffnet werden kann) sinnvoll behandelt wird.

Das `pickle`-Modul ist grundsätzlich erst einmal zum serialisieren von Python-Objekten gedacht. Das kann man auch zum ”dauerhaften” speichern verwenden, dabei sollte man aber Probleme beachten die auftreten können. Es werden von Datentypen beispielsweise nur der Typ selbst mit voll qualifiziertem Namen und der Zustand des Objekts gespeichert. Sollte sich der Name mal ändern, beispielsweise weil die Definition des Datentyps in ein anderes Modul verschoben wird, kann so ein Objekt nicht mehr gelesen werden. Falls man die Zusammensetzung des Zustands eines Datentyps ändert, kann das zwar noch gelesen werden, der gelesene Zustand passt dann aber nicht mehr zur akuellen Implementierung des Typs. Last but not least ist das ein Python-spezifisches Format.

Man kann `pickle` für längerfristige Speicherung von Daten verwenden wenn man darauf achtet nichts zu machen was das auslesen später verhindern könnte.

Ansonsten ist es ein brauchbares Format um kurzfristig Daten zwischen zu speichern, oder Daten bei denen es nicht so wichtig ist, wenn sie nicht mehr gelesen werden können. Ein Cache beispielsweise, wo man aufwändig zu erstellende Objekte speichert, die man aber notfalls auch wieder neu erstellen könnte, falls sie nicht wieder gelesen werden können.

Ein weiterer Einsatzzweck ist die Kommunikation zwischen Python-Programmen. Man kann Objekte serialisieren, über eine Verbindung über die Bytes übertragen werden können, zu einem anderen Python-Programm schicken, und dort dann wieder deserialisieren. In der Standardbibliothek wird das beispielsweise vom `multiprocessing`-Modul so angewendet.

Falls sich die Daten die serialisiert werden sollen, auf das beschränken was sich mit JSON ausdrücken lässt, wäre das ein sinnvolles Format. Bei rein textbasierten, tabellenartig strukturierten Daten wäre auch CSV eine Möglichkeit. Für beides gibt es Module in der Standardbibliothek.

An das Hauptprogramm senden ist etwas das so nicht vorgesehen ist. Man würde da einen Dialog öffnen der die Daten erfasst, und von dem hinterher im Hauptprogramm die Daten abfragen. Um modale Dialoge zu programmieren gibt es auch bereits einen vorgefertige Rahmen: `tkinter.simpledialog.Dialog`.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
ichbins
User
Beiträge: 40
Registriert: Samstag 5. September 2020, 07:07

Danke für die ausführlichen Beschreibungen!
ichbins
User
Beiträge: 40
Registriert: Samstag 5. September 2020, 07:07

Irgendwie hänge ich wieder beim Auslesen von mehreren Entries bei tkinter. Hier ist ein Versuch aber entweder wird immer nur die letzte Zahl eingetragen oder es kommt ein Fehler. Ich versuche aus mehreren Entries die Werte auszulesen und in die Liste zu speichern. Habt ihr vielleicht ein Beispiel.

Danke!

Code: Alles auswählen

def __init__(self): 
 	self.entries=[]
        for column in range(0,10):
            self.entry=tk.Entry(root, width=3)
            self.entry.pack(side=tk.LEFT, anchor=tk.W)
            self.entries.append(self.entry.get())
            
def auslesen(self):
	i=0
	for x in self.entries:
     		x=x.get()   
  		self.entries.insert(i, x)
 		i=i+1
	print (str(x))
Sirius3
User
Beiträge: 17749
Registriert: Sonntag 21. Oktober 2012, 17:20

Deine Einrückungen sind kaputt. Damit ist der code nicht lesbar. Einen Wert an ein Attribut ( hier entry) innerhalb einer for Schleife zubinden ist eigentlich nie sinnvoll. entry wird ja auch nicht mehr verwendet. Zu dem Zeitpunkt, zudem du entry.get aufrufst, kann der Nutzer doch noch gar nichts eingegeben haben. Der Name der Liste entries ist daher auch irreführend.
In auslesen ist dann so einiges nicht gut. Der Name x der Laufvariable für die Einträge von entries ist schlecht, da er nicht beschreibt was das für Einträge sind. Wenn diese Einträge eine get-Methode hätten, warum sollte dann auch das Ergebnis des Aufrufs der get-Methode in dieselbe Liste gepackt werden?
Zudem ist das Ändern einer Liste, über die gerade mit einer for-Schleife iteriert wird, ein Fehler. Generell ist es unüblich in Python Listen zu verändern. Stattdessen macht man einfach neue Listen.
ichbins
User
Beiträge: 40
Registriert: Samstag 5. September 2020, 07:07

entry.get wird später verwendet da die Werte gespeichert werden mit pickle. Ich bin jetzt nur dabei Werte die ich eintrage in die Entry Widgets in eine Liste gespeichert werden.

Die Eingabefelder sind ja für die Vorgabe von Werten bestimmter Kanäle von der Hardware. Somit werden die Eingaben an das Hauptprogramm der Hardware geschickt. Die Werte werden mit pop und insert an den jeweiligen Stellen gelöscht und in die Liste an der jeweiligen Position eingetragen.
Benutzeravatar
__blackjack__
User
Beiträge: 13103
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@ichbins: `entry.get()` wird nicht später verwendet das wird in der `__init__()` verwendet, zu einem Zeitpunkt wo das garantiert die leere Zeichenkette ergibt und damit gar keinen Sinn macht. Und später kannst Du die `Entry`-Objekte gar nicht mehr verwenden, denn Du speicherst sie ja nicht. Lass Dir am Ende der `__init__()` einfach mal `self.entries` ausgeben.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Antworten