Hallo zusammen,
ich habe auf meinen Fileserver Bilder, welche ich gerne in einem Label anzeigen lassen will. Leider bekomme ich immer wieder die Fehlermeldung, dass der Pfad nicht existiert, obwohl dies der Fall ist.
Gibt es noch eine andere Möglichkeit Bilder von einem Fileserver zuladen und dies dann in einem Label anzuzeigen?
Oder kann mir jemand sagen, was ich an meinen Code verändern muss, damit es funktioniert?
file = smbclient.open_file("\\Server/"+picture,username=username,password=password)
root = tk.Tk()
root.configure(background='black')
sheight = root.winfo_screenheight()
swidth = root.winfo_screenwidth()
root.minsize(width=swidth, height=sheight)
root.maxsize(width=swidth, height=sheight)
l = tk.Label()
l.place(x=0, y=0, width=swidth, height=sheight, anchor="center")
image: Image = Image.open(file.name)
img2 = ImageTk.PhotoImage(image)
l.config(image=img2)
root.mainloop()
Vielen Dank
Python smbclient Bild im TKinter Label anzeigen
- __blackjack__
- User
- Beiträge: 13533
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@PotterParsel: Nein, den Pfad gibt es nicht. `Image.open()` sucht den in Deinem System und wenn dort nicht unter dem Pfad das SMB-Share eingebunden ist und das System überhaupt solche Dateinamen/-pfade versteht, dann gibt es die Datei dort nicht. Wenn es die dort gäbe, wäre es auch unsinnig `smbclient` zu verwenden, weil man dann ja auch einfach so, ohne diese Bibliothek darauf zugreifen könnte.
`Image.open()` kann man ein Dateiobjekt übergeben. Das muss im Binärmodus geöffnet worden sein und `seek()`, `tell()`, und `read()` unterstützen.
Dateien die man öffnet, sollte man auch explizit wieder schliessen. Am besten in dem man die ``with``-Anweisung verwendet. Wird auch in der Dokumentation von `smbclient.open_file()` empfohlen.
Namen sollten keine kryptischen Abkürzungen enthalten, oder gar nur daraus bestehen. Wenn man `screen_` meint, sollte man nicht nur `s` schreiben, und `l` ist nicht nur absolut nichtssagend, sondern kann in vielen Schriftarten, auch noch einfach mit 1 verwechselt werden. Namen nummeriert man auch nicht. Dann will man sich entweder bessere Namen ausdenken, oder gar keine Einzelname und -werte verwenden, sondern eine Datenstruktur. Oft eine Liste. Oder vielleicht auch nicht jedes kleine Zwischenergebnis an einen eigenen Namen binden.
Die Fenstergrösse so festzulegen ist nicht wirklich sinnvoll. Das sieht eher so aus, als sollte das Fenster „full screen“ dargestellt werden.
Man sollte sich bei Anzeigeelementen nicht darauf verlassen, dass `master` implizit das Hauptfenster ist, wenn man da nichts angibt.
Wenn man Tk-Argumente hat, die eine besondere Bedeutung haben und deshalb als Konstante im `tkinter`-Modul definiert sind, sollte man diese Konstante benutzen, statt eine literale Zeichenkette mit dem Wert.
Das Bild hätte man vor dem erstellen des `Label` laden können und sich den extra `config`-Aufruf sparen können.
Ungetestet:
`Image.open()` kann man ein Dateiobjekt übergeben. Das muss im Binärmodus geöffnet worden sein und `seek()`, `tell()`, und `read()` unterstützen.
Dateien die man öffnet, sollte man auch explizit wieder schliessen. Am besten in dem man die ``with``-Anweisung verwendet. Wird auch in der Dokumentation von `smbclient.open_file()` empfohlen.
Namen sollten keine kryptischen Abkürzungen enthalten, oder gar nur daraus bestehen. Wenn man `screen_` meint, sollte man nicht nur `s` schreiben, und `l` ist nicht nur absolut nichtssagend, sondern kann in vielen Schriftarten, auch noch einfach mit 1 verwechselt werden. Namen nummeriert man auch nicht. Dann will man sich entweder bessere Namen ausdenken, oder gar keine Einzelname und -werte verwenden, sondern eine Datenstruktur. Oft eine Liste. Oder vielleicht auch nicht jedes kleine Zwischenergebnis an einen eigenen Namen binden.
Die Fenstergrösse so festzulegen ist nicht wirklich sinnvoll. Das sieht eher so aus, als sollte das Fenster „full screen“ dargestellt werden.
Man sollte sich bei Anzeigeelementen nicht darauf verlassen, dass `master` implizit das Hauptfenster ist, wenn man da nichts angibt.
Wenn man Tk-Argumente hat, die eine besondere Bedeutung haben und deshalb als Konstante im `tkinter`-Modul definiert sind, sollte man diese Konstante benutzen, statt eine literale Zeichenkette mit dem Wert.
Das Bild hätte man vor dem erstellen des `Label` laden können und sich den extra `config`-Aufruf sparen können.
Ungetestet:
Code: Alles auswählen
#!/usr/bin/env python3
import tkinter as tk
import smbclient
from PIL import Image, ImageTk
def main():
...
root = tk.Tk()
root.configure(background="black")
root.attributes("-fullscreen", True)
with smbclient.open_file(
fR"\Server/{picture}", username=username, password=password
) as file:
image = ImageTk.PhotoImage(Image.open(file))
tk.Label(root, image=image).place(x=0, y=0, anchor=tk.CENTER)
root.mainloop()
if __name__ == "__main__":
main()
Code: Alles auswählen
- (void)countSheep {
unsigned int sheep = 0;
while ( ! [self isAsleep]) { ++sheep; }
}
-
- User
- Beiträge: 20
- Registriert: Montag 5. September 2022, 08:58
__blackjack__ hat geschrieben: ↑Montag 5. September 2022, 10:28 @PotterParsel: Nein, den Pfad gibt es nicht. `Image.open()` sucht den in Deinem System und wenn dort nicht unter dem Pfad das SMB-Share eingebunden ist und das System überhaupt solche Dateinamen/-pfade versteht, dann gibt es die Datei dort nicht. Wenn es die dort gäbe, wäre es auch unsinnig `smbclient` zu verwenden, weil man dann ja auch einfach so, ohne diese Bibliothek darauf zugreifen könnte.
`Image.open()` kann man ein Dateiobjekt übergeben. Das muss im Binärmodus geöffnet worden sein und `seek()`, `tell()`, und `read()` unterstützen.
Dateien die man öffnet, sollte man auch explizit wieder schliessen. Am besten in dem man die ``with``-Anweisung verwendet. Wird auch in der Dokumentation von `smbclient.open_file()` empfohlen.
Namen sollten keine kryptischen Abkürzungen enthalten, oder gar nur daraus bestehen. Wenn man `screen_` meint, sollte man nicht nur `s` schreiben, und `l` ist nicht nur absolut nichtssagend, sondern kann in vielen Schriftarten, auch noch einfach mit 1 verwechselt werden. Namen nummeriert man auch nicht. Dann will man sich entweder bessere Namen ausdenken, oder gar keine Einzelname und -werte verwenden, sondern eine Datenstruktur. Oft eine Liste. Oder vielleicht auch nicht jedes kleine Zwischenergebnis an einen eigenen Namen binden.
Die Fenstergrösse so festzulegen ist nicht wirklich sinnvoll. Das sieht eher so aus, als sollte das Fenster „full screen“ dargestellt werden.
Man sollte sich bei Anzeigeelementen nicht darauf verlassen, dass `master` implizit das Hauptfenster ist, wenn man da nichts angibt.
Wenn man Tk-Argumente hat, die eine besondere Bedeutung haben und deshalb als Konstante im `tkinter`-Modul definiert sind, sollte man diese Konstante benutzen, statt eine literale Zeichenkette mit dem Wert.
Das Bild hätte man vor dem erstellen des `Label` laden können und sich den extra `config`-Aufruf sparen können.
Ungetestet:Code: Alles auswählen
#!/usr/bin/env python3 import tkinter as tk import smbclient from PIL import Image, ImageTk def main(): ... root = tk.Tk() root.configure(background="black") root.attributes("-fullscreen", True) with smbclient.open_file( fR"\Server/{picture}", username=username, password=password ) as file: image = ImageTk.PhotoImage(Image.open(file)) tk.Label(root, image=image).place(x=0, y=0, anchor=tk.CENTER) root.mainloop() if __name__ == "__main__": main()
Danke für deine Hilfestellung. Du hast mit deinen Punkten recht, sauberer Code sieht anders aus.
Leider bekomme ich auch mit deinen Code die gleiche Fehlermeldung. Hättest du spontan noch eine andere Idee oder Methode um das zu realisieren?
-
- User
- Beiträge: 20
- Registriert: Montag 5. September 2022, 08:58
ich bekomme Folgende Fehlermeldung:
Code: Alles auswählen
File "/home/pi/Desktop/test.py", line 26, in main
image = ImageTk.PhotoImage(Image.open(file.name))
File "/home/pi/.local/lib/python3.9/site-packages/PIL/Image.py", line 3092, in open
fp = builtins.open(filename, "rb")
FileNotFoundError: [Errno 2] No such file or directory: \\Servername/Ordner/Bild.jpg
Na wenn es mal geht und mal nicht, dann kann das ja nicht an deinem Code liegen. Sondern an einer variierenden Verfuegbarkeit der Netzwerkresource. Das ist ein Windows-Problem. Wenn du das nicht dauerhaft garantieren kannst, dass es die Datei gibt, dann kann man nur mit einem Workaround arbeiten. ZB koennte man in diesem Fall eine gecachte Version des Bildes aus einem lokalen Verzeichnis anbieten, und mit einem Timer periodisch pruefen, ob es wieder Verbindung gibt - um dann das Bild zu updaten.
- __blackjack__
- User
- Beiträge: 13533
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@PotterParsel: Der gezeigte `FileNotFoundError` passt nicht zu meinem Code weil ich dort keinen Dateinamen übergebe. Genau das ist ja der Punkt. Den hast Du da wieder auf den falschen Code zurück geändert.
Code: Alles auswählen
- (void)countSheep {
unsigned int sheep = 0;
while ( ! [self isAsleep]) { ++sheep; }
}
-
- User
- Beiträge: 20
- Registriert: Montag 5. September 2022, 08:58
Kannst du mir das genauer erklären?__blackjack__ hat geschrieben: ↑Montag 5. September 2022, 15:05 @PotterParsel: Der gezeigte `FileNotFoundError` passt nicht zu meinem Code weil ich dort keinen Dateinamen übergebe. Genau das ist ja der Punkt. Den hast Du da wieder auf den falschen Code zurück geändert.
-
- User
- Beiträge: 20
- Registriert: Montag 5. September 2022, 08:58
wenn ich file.name weglasse bekomme ich die folgende Fehlermeldung:
raise UnidentifiedImageError(PIL.UnidentifiedImageError: cannot identify image file <_io.TextIOWrapper name='\\Server/Bild1.png' encoding='ISO-8859-15'>
deswegen habe ich das .name gelassen.
- __blackjack__
- User
- Beiträge: 13533
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@PotterParsel: Ui, im Beitragstext wusste ich es noch, im Code habe ich es dann wieder vergessen: Die Datei muss im Binärmodus geöffnet werden. Mit Textdateien kann PIL an der Stelle nichts anfangen. Ähm, war natürlich Absicht, um zu schauen ob Du aufpasst.
Code: Alles auswählen
- (void)countSheep {
unsigned int sheep = 0;
while ( ! [self isAsleep]) { ++sheep; }
}
-
- User
- Beiträge: 20
- Registriert: Montag 5. September 2022, 08:58
Achso das gehörte dazu .__blackjack__ hat geschrieben: ↑Dienstag 6. September 2022, 09:37 @PotterParsel: Ui, im Beitragstext wusste ich es noch, im Code habe ich es dann wieder vergessen: Die Datei muss im Binärmodus geöffnet werden. Mit Textdateien kann PIL an der Stelle nichts anfangen. Ähm, war natürlich Absicht, um zu schauen ob Du aufpasst.
muss ich noch eine Bibliothek installieren oder so? Der Raspberry Pi erkennt das Asleep und Inc nicht.
Code: Alles auswählen
Sheep := 0;
WHILE NOT Asleep DO Inc(Sheep);
-
- User
- Beiträge: 20
- Registriert: Montag 5. September 2022, 08:58
-
- User
- Beiträge: 20
- Registriert: Montag 5. September 2022, 08:58
Er zählt Schafe bis er eingeschlafen ist.PotterParsel hat geschrieben: ↑Dienstag 6. September 2022, 10:41 Kannst du mir den Witz erklären, ich verstehe den nicht.
Ich dachte Programmierer würden eher Bit's zählen, aber vielleicht ist die Signatur auch nach dem 5 Bit entstanden
"When I got the music, I got a place to go" [Rancid, 1993]
- __blackjack__
- User
- Beiträge: 13533
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
Naja so ein richtiger Witz ist es ja auch nicht. Ich hatte das mal irgendwo als Beispielcode in Python und fand es zum schmunzeln, wobei das in OOP-Sprachen wo man das Objekt mit einer Schreibweise von „self“ referenziert noch ein bisschen eingängiger zu lesen ist. Und das hatte ich in verschiedene Programmiersprachen übersetzt und in meine Signatursammlung gesteckt. In Python wäre das:
Wobei man das bei Object Pascal im Gegensatz zum klassischen Pascal was in der Signatur steht, auch machen kann:
Code: Alles auswählen
while not self.asleep():
sheep += 1
Code: Alles auswählen
sheep := 0;
while not Self.Asleep do Inc(sheep);
Code: Alles auswählen
- (void)countSheep {
unsigned int sheep = 0;
while ( ! [self isAsleep]) { ++sheep; }
}