Datum:
Hallo
Wenn ich in Python 3 mit "name= askopenfilename()" (aus
tkinter.filedialog)
eine Dateiauswahlbox aufrufe, sollte die mir einen Pfad auf die Datei
als String zurückgeben. Das passiert auch so, und funktioniert.
Wenn ich nach Programmstart die Dateiauswahlbox zum ersten mal Aufrufe,
und ohne eine Auswahl abbreche, kommt ein Leerstring zurück. Das
passiert auch so, und funktioniert.
Soweit ok.
Wenn ich aber schon über die Dateiauswahlbox erfolgreich eine Datei
geöffnet hatte, und nun erneut die Dateiauswahlbox aufrufe und ohne eine
Auswahl abbreche, passiert was merkwürdiges:
print(name) gibt dann "()". Aber das ist kein String, wie in den obigen
beiden Fällen, sondern ein Tupel.
Wenn ich den "Pfadstring" für eine Darstellung mit
"Pfad = ("Pfad: " + name)" aufbereiten möchte, kommt die Fehlermeldung,
das Python das Tupel nicht in einen String konvertieren kann.
Konvertiere ich aber name explizit per "stName = str(name)", liefert mir
"Pfad = ("Pfad: " + stName)" den String: "Pfad: ()".
Wieso liefert mir Pfad = ("Pfad: " + stName) meistens einen String (wie
erwartet) aber gelegentlich auch ein Tupel (was ich nicht erwarte) das
aber so stringähnlich ist, das ich es problemlos konvertieren kann,
ausser es steht in einem zusammengesetzten Ausdruck?
print(type(name)) zum testen eingefügt liefert übrigens in den ersten
beiden Fällen <class 'str'> und in dem letzten fraglichen Fall <class
'tuple'> für das was von "name= askopenfilename()" zurückkommt.
Betriebssystem hier ist Debian "squeeze".
Mit freundlichem Gruß: Bernd Wiebus alias dl1eic
http://www.dl0dg.de
Datum:
Nachtrag zu Beitrag #2728537: Ich habe das Problem mit name= askopenfilename() name =str(name) gelöst, indem ich name mit dem Hammer zum String umgeschmiedet habe. Der Workaround funktioniert.... Trozdem verstehe ich nicht, was der Grund für das merkwürdige Verhalten ist.... Mit freundlichem Gruß: Bernd Wiebus alias dl1eic http://www.dl0dg.de
Datum:
Das ist möglicherweise ein Bug (hab's aber nicht näher untersucht, vielleicht ist es auch Absicht). Normalerweise liefert askopenfilename ein String-Tuple oder einen Einzel-String zurück, je nachdem, ob die Option multiple True ist oder nicht. Bei einem leeren Ergebnis kommt die Funktion wohl etwas durcheinander. Das sollte aber kein größeres Problem sein, wenn du die Abfrage des Ergebnisses mit
if name:
...
|
machst, da sowohl ein leerer String als auch ein leeres Tupel in einem Booleschen Ausdruck als False gewertet wird. Bernd Wiebus schrieb: > Ich habe das Problem mit > > name= askopenfilename() > name =str(name) > > gelöst, indem ich name mit dem Hammer zum String umgeschmiedet habe. > Der Workaround funktioniert.... Sicher? Damit wird doch aus dem leeren Tupel der String '()'. Du kannst also nicht mehr unterscheiden, ob der User Cancel gedrückt oder eine Datei namens "()" ausgewählt hat.
Datum:
Angehängte Dateien:Hallo, ist mit Python 2.6 genauso (die Module heißen anders, das Verhalten ist gleich). Siehe Anhang. Das erwähnte 'if name' funktioniert aber definitiv besser als Stringgefummel.
Datum:
Angehängte Dateien:Hallo Yalu X, hallo Tom. Danke für Eure Antworten und Tipps. > Sicher? Damit wird doch aus dem leeren Tupel der String '()'. Du kannst > also nicht mehr unterscheiden, ob der User Cancel gedrückt oder eine > Datei namens "()" ausgewählt hat. Ok. Hast Recht, dann funktioniert es auch für den Fall, das einer seine Datei "()" nennt..... > ist mit Python 2.6 genauso (die Module heißen anders, das Verhalten ist > gleich). Danke. Wenn Bug, scheint er wohl so uninteressant, das sich keiner weiter darum gekümmert hat. > Siehe Anhang. Das erwähnte 'if name' funktioniert aber > definitiv besser als Stringgefummel. Mein erster Reflex war, zu sagen, wenn einer seine Datei "()" nennt, ist er selber schuld....auf der anderen Seite bin ich selber schräg genug drauf, um genau sowas zu machen....es hat auch seinen Grund, warum mir das merkwürdige Verhalten beim Abbrechen der Dateiauswahlbox aufgefallen ist. ;O) Ich werde das also umschreiben. Als Anhang übrigens das Programm (PyGerbAnalyse_A6.py), soweit es bisher geschrieben ist..... Ich bin dabei, das, was ich vor gut 1 1/2 Jahren in Gambas geschrieben habe, in Python umzuschreiben......viel können kann es aber noch nicht. Mit freundlichem Gruß: Bernd Wiebus alias dl1eic http://www.dl0dg.de
Datum:
Statt name in einen String umzuwandeln, wie hier
name= askopenfilename()
name = str(name)
GerberAnalyse.stPfad = name
if name =="":
Pfadanzeige["text"] = "Pfad: Leer"
Listanzeige1.delete(0, END)
Listanzeige2.delete(0, END)
return()
if name =="()":
Pfadanzeige["text"] = "Pfad: Leer"
Listanzeige1.delete(0, END)
Listanzeige2.delete(0, END)
return()
|
kannst du ihn auch direkt mit dem Tupel vergleichen:
name= askopenfilename()
GerberAnalyse.stPfad = name
if name =="":
Pfadanzeige["text"] = "Pfad: Leer"
Listanzeige1.delete(0, END)
Listanzeige2.delete(0, END)
return()
if name ==():
Pfadanzeige["text"] = "Pfad: Leer"
Listanzeige1.delete(0, END)
Listanzeige2.delete(0, END)
return()
|
Damit ist auch der Dateiname "()" erlaubt. Da sich beide If-Anweisungen nur in der Bedingung unterscheiden, kannst du sie auch zusammenfassen:
name= askopenfilename()
GerberAnalyse.stPfad = name
if name =="" or name ==():
Pfadanzeige["text"] = "Pfad: Leer"
Listanzeige1.delete(0, END)
Listanzeige2.delete(0, END)
return()
|
Etwas pythonischer sieht die Bedingung so aus:
name= askopenfilename()
GerberAnalyse.stPfad = name
if name in ["", ()]:
Pfadanzeige["text"] = "Pfad: Leer"
Listanzeige1.delete(0, END)
Listanzeige2.delete(0, END)
return()
|
Oder eben gleich so:
name= askopenfilename()
GerberAnalyse.stPfad = name
if not name:
Pfadanzeige["text"] = "Pfad: Leer"
Listanzeige1.delete(0, END)
Listanzeige2.delete(0, END)
return()
|
Wenn du den Code in anderer Reihenfolge hinschreibst, bekommst du auch noch das hässliche "not" vor name weg:
name= askopenfilename()
GerberAnalyse.stPfad = name
if name:
GerberAnalyse.iZeilenzahl = 0
...
else:
Pfadanzeige["text"] = "Pfad: Leer"
Listanzeige1.delete(0, END)
Listanzeige2.delete(0, END)
|
Nur so am Rande :)
Datum:
Hallo Yalu X. > Statt name in einen String umzuwandeln, wie hier ~~~~~~~~~~~~ ~~~~~~~~~~~~ > > > > Nur so am Rande :) Ich habs jetzt so gemacht:
# Funktion Dateiauswahl Gerberfile
def Dateiwahl():
name= askopenfilename()
if name: #Nur Wahr, wenn Pfad gewählt wurde. Sonst Leerstring/Tupel
GerberAnalyse.stPfad = name
GerberAnalyse.iZeilenzahl = 0
Pfad = ("Pfad: " + name)
Pfadanzeige["text"] = Pfad
Listanzeige1.delete(0, END) #Neue Datei, altes Listing...Clear
Listanzeige2.delete(0, END) #Neue Datei, alte Analyse...Clear
GerberList1 = open(GerberAnalyse.stPfad, mode="rt")
while True:
Lesezeile = GerberList1.readline()
if len(Lesezeile) ==0:
break # EOF wenn lesezeile nicht mehr kommt.
Listanzeige1.insert(END, Lesezeile) #Neues Listimng
Listanzeige1.yview(END) #Anzeige zum Ende
GerberList1.close()
return()
|
Bei Cancel passiert jetzt "garnichts" mehr, was ja auch die eigentliche Intention von Cancel ist.... Der komplette Block wird dann übersprungen und das Unterprogramm verlassen, ohne das was geändert wird. Mit freundlichem Gruß: Bernd Wiebus alias dl1eic http://www.dl0dg.de
Datum:
hi, vorab: ich habe nicht alles gelesen, aber ein Tupel könnte sinnvoll sein, soweit man mit dem Dialog mehrere Dateien auswählen lassen können wollte ..
Datum:
Hallo Daniel. > > vorab: ich habe nicht alles gelesen, aber ein Tupel könnte > sinnvoll sein, soweit man mit dem Dialog mehrere Dateien auswählen > lassen können wollte .. Richtig, so ist das wohl auch gedacht. Nur war diese Option nicht gewählt worden. Wenn ich nnur die Option für eine einzige Datei wähle, erwarte ich einen String oder halt auch einen Leerstring bei cancel. Wenn ich die Option multiple wähle, erwarte ich halt auch ein Tupel bzw. Leertupel bei cancel. Aber hier hatte ich die Option multiple nicht gewählt, und bekam zuerst einen Leerstring bei cancel, aber später dann ein Leertupel bei cancel. Ich konnte immer nur eine Datei wählen, und diese einzelne Datei wurde auch erwartungsgemäß richtig als einzelner String übergeben. Und das machte mich halt ratlos. Mit freundlichem Gruß: Bernd Wiebus alias dl1eic http://www.dl0dg.de
Datum:
Ggf mußt du auch die Option für Einzelauswahl jedesmal neu setzen? Manche 'API' wandert auf verschlungenen Pfaden... Schon allein die Annahme leerer String = nix ausgewählt ist blöde wenn man auf einmal ein Filesystem hat wo der leere String eben gültig ist (warum auch immer).
Datum:
Hallo Läubi. > Ggf mußt du auch die Option für Einzelauswahl jedesmal neu setzen? ???? Das ist eine Funktion, die jedesmal neu angesprungen wird, wenn der Dateiauswahlbutton gedrückt wird.....theoretisch erwarte ich in dem Falle auch immer gleiches Verhalten. Wie meinest Du das denn? > Manche 'API' wandert auf verschlungenen Pfaden... Schon allein die > Annahme leerer String = nix ausgewählt ist blöde wenn man auf einmal ein > Filesystem hat wo der leere String eben gültig ist (warum auch immer). In dem Falle kann "Abbruch/cancel" NICHT über den Pfadstring übergeben werden, weil in letzter Konsequenz jeder gültige String auch eine gültige Datei sein könnte. Es gäbe daher keinen Platz für einen Abbruch im String und es müsste für den Zweck eine extra Variable existieren. Andersherum.....es währe ein "verbotener" Dateinahme unter Milliarden von erlaubten. Vermutlich könnte ich damit leben. Vor allem, wenn es um Gerberdatensätze geht. ;O) Mit freundlichem Gruß: Bernd Wiebus alias dl1eic http://www.dl0dg.de
Datum:
Nachtrag: > Andersherum.....es währe ein "verbotener" Dateinahme unter Milliarden > von erlaubten. Vermutlich könnte ich damit leben. Vor allem, wenn es um > Gerberdatensätze geht. ;O) Ich könnte auch z.B. bei jedem Cancel eine Warnung an den User ausgeben, daß, falls er in Wirklichkeit eine Datei mit einem Leerstring als Name oder Pfad gewählt hätte, speziell diese Datei wegen ihres Namens nicht gelesen werden kann und er sie darum bitteschön umbenennen möge. ,O) Mit freundlichem Gruß: Bernd Wiebus alias dl1eic ttp://www.dl0dg.de
Datum:
Bernd Wiebus schrieb: > Ich könnte auch z.B. bei jedem Cancel eine Warnung an den User ausgeben, > daß, falls er in Wirklichkeit eine Datei mit einem Leerstring als Name > oder Pfad gewählt hätte, speziell diese Datei wegen ihres Namens nicht > gelesen werden kann und er sie darum bitteschön umbenennen möge. ,O) Gibt es eigentlich ein OS, in dem der Leerstring als Dateiname erlaubt ist? In Unix geht ja fast alles, was ein krankes Hirn sich auszudenken in der Lage ist, aber leere Dateinamen sind auch hier nicht möglich :)
Datum:
Bernd Wiebus schrieb: > ???? Das ist eine Funktion, die jedesmal neu angesprungen wird Ich kenne nun die Implementierung nicht, hatte deine Beschreibung aber so verstanden, dass irgendwo [pre]setSingleSelection(true)[pre] aufrufen muss. Bernd Wiebus schrieb: > In dem Falle kann "Abbruch/cancel" NICHT über den > Pfadstring übergeben werden, Kennt Python kein 'null' oder Objekte? Yalu X. schrieb: > Gibt es eigentlich ein OS, in dem der Leerstring als > Dateiname erlaubt ist? Keine Ahnung... zumindest wenn du im Web surfst wird der leere Pfad auf eine Menge von index files von den meisten Webserver gemappt. Das war jetzt nicht so ernst gemeint, sonder war auch nur eine hypothetische Anmerkung, in Java kann man so einem Filedialog ein eigenes FileSystemView mitgeben in welchem man sich theoretisch nach belieben austoben kann :-) Dort wird cancel/ausgewählte Date(en) aber auch über ein Zustandsobjekt behandelt. Yalu X. schrieb: > aber leere Dateinamen sind auch hier nicht möglich Konnte man unter MacOS nicht irgendwie Dateien nur aus Leerzeichen angeben?
Datum:
Läubi .. schrieb: > Konnte man unter MacOS nicht irgendwie Dateien nur aus Leerzeichen > angeben? Das geht in Unix auch. Auch Tabs, Linefeeds, Carriage-Returns, Backspaces und anderes Ungeziefer dürfen verwendet werden. Nur ein richtig leerer Name (also mit 0 Zeichen Länge) geht halt nicht.
Datum:
Hallo Yalu. > Gibt es eigentlich ein OS, in dem der Leerstring als Dateiname erlaubt > ist? In Unix geht ja fast alles, was ein krankes Hirn sich auszudenken > in der Lage ist, aber leere Dateinamen sind auch hier nicht möglich :) Wenn Du schon so anfängst, müsstest Du auch berücksichtigen, das irgendjemand mal ein Operationssystem schreiben könnte, in dem ein Leerstring als Dateiname möglich und sogar sinnvoll ist. ;O) Mit freundlichem Gruß: Bernd Wiebus alias dl1eic http://www.dl0dg.de
Datum:
Hallo Läubi. > Bernd Wiebus schrieb: >> ???? Das ist eine Funktion, die jedesmal neu angesprungen wird > Ich kenne nun die Implementierung nicht, hatte deine Beschreibung aber > so verstanden, dass irgendwo [pre]setSingleSelection(true)[pre] aufrufen > muss. ...Du bringst mich auf eine Idee. Genau das habe ich explizit NICHT gemacht. Aber vieleicht sollte ich das ja mal machen. Ich werde es ausprobieren. > > Bernd Wiebus schrieb: >> In dem Falle kann "Abbruch/cancel" NICHT über den >> Pfadstring übergeben werden, > Kennt Python kein 'null' oder Objekte? So wie ich das aber Verstanden habe, ist "Null" ein spezieller Typ und eben kein String mehr. Vieleicht sollte ich mir das noch einmal genau durchlesen. Mit freundlichem Gruß: Bernd Wiebus alias dl1eic http://www.dl0dg.de
Datum:
Ich habe es ausprobiert.
# Funktion Dateiauswahl Gerberfile
def Dateiwahl():
name= askopenfilename(multiple = False) #Hier wird ausdrücklich auf EIN File festgenagelt.
GerberAnalyse.stPfad = name
GerberAnalyse.iZeilenzahl = 0
Pfad = ("Pfad: " + name)
Pfadanzeige["text"] = Pfad
Listanzeige1.delete(0, END) #Neue Datei, altes Listing...Clear
Listanzeige2.delete(0, END) #Neue Datei, alte Analyse...Clear
GerberList1 = open(GerberAnalyse.stPfad, mode="rt")
while True:
Lesezeile = GerberList1.readline()
if len(Lesezeile) ==0:
break # EOF wenn lesezeile nicht mehr kommt.
Listanzeige1.insert(END, Lesezeile) #Neues Listimng
Listanzeige1.yview(END) #Anzeige zum Ende
GerberList1.close()
return()
|
Einmal "Datei wählen" direkt nach dem Start aufgerufen und cecancelt. Dann eine lesbare Datei aufgerufen. Dann nochmalEinmal "Datei wählen" aufgerufen und cecancelt. Fehlermeldungen in der Shell:
Exception in Tkinter callback
Traceback (most recent call last):
File "/usr/lib/python3.1/tkinter/__init__.py", line 1402, in __call__
return self.func(*args)
File "/home/wiebus/python/PyGerbAnalyse_A8-2.py", line 841, in Dateiwahl
GerberList1 = open(GerberAnalyse.stPfad, mode="rt")
IOError: [Errno 2] No such file or directory: ''
Exception in Tkinter callback
Traceback (most recent call last):
File "/usr/lib/python3.1/tkinter/__init__.py", line 1402, in __call__
return self.func(*args)
File "/home/wiebus/python/PyGerbAnalyse_A8-2.py", line 837, in Dateiwahl
Pfad = ("Pfad: " + name)
TypeError: Can't convert 'tuple' object to str implicitly
|
"IOError: [Errno 2] No such file or directory: '' "ist das erste canceln. Hier kommt der Leerstring zurück, und "TypeError: Can't convert 'tuple' object to str implicitly " ist das zweite canceln, wo dann das Leertupel zurückkommt. Das explizite Angeben, das nur ein File geöffnet werden soll, hat also keinen Einfluss auf dieses Verhalten. Mit freundlichem Gruß: Bernd Wiebus alias dl1eic http://www.dl0dg.de