Bild in GUI

Fragen zu Tkinter.
Antworten
Lubber
User
Beiträge: 3
Registriert: Montag 18. Januar 2021, 08:39

Hallo Forum und ein frohes neues Jahr!

Ich möchte hier zuerst sagen das ich ein absoluter Neuling in Sachen Python bin, und bitte dumme Fragen gleich im vorraus zu entschuldigen.

Ich habe dieses Jahr mit angefangen um mir Python ein wenig selber beizubringen und mache verschiedene Übungen und Toturials.
Ich habe Python 3.9 auf meinen Windows10 rechner laufen und benutze Atom als Editor.

Jetzt habe ich eine Übung zum erstellen einer GUI und die Einbindung von Texten und Bildern mit der label funktion.

Folgend poste ich den Übungscode mit folgender Frage:
Führe ich den Code auf meinem Android-Smartphone mit der App Pydroid3 funktioniert er eigentlich.
Mache ich das selbe auf dem Windows-Rechner bringt mir Atom folgenden Fehler:

Traceback (most recent call last):
File "C:\Users\xxx\Desktop\Python_learning\GUI_test.py", line 13, in <module>
pic1 = tk.PhotoImage(file="biene.png")
File "C:\Program Files\Python39\lib\tkinter\__init__.py", line 4062, in __init__
Image.__init__(self, 'photo', name, cnf, master, **kw)
File "C:\Program Files\Python39\lib\tkinter\__init__.py", line 4007, in __init__
self.tk.call(('image', 'create', imgtype, name,) + options)
_tkinter.TclError: couldn't open "biene.png": no such file or directory

So sieht der Code aus:

Code: Alles auswählen

import tkinter as tk  # Improtiert das Modul Tkinter

root = tk.Tk()

root.minsize(500, 500)
root.title("Meine BlaBlaBox")

# Textausgabe erzeugen
label1 = tk.Label(root, text="Hallo Neuling").pack(side="left")


# Grafik einbetten
pic1 = tk.PhotoImage(file="biene.png")
label2 = tk.Label(root, image=pic1).pack()


root.mainloop()  # Hauptschleife damit die GUI bleibt
Was läuft falsch? Da er auf dem Android funktioniert und auf dem Windows-Rechner nicht, gehe ich davon aus das es mit Windows zusammen hängt.

Kann mir hier jemand einen hilfreichen Tip geben?

Vielen Dank,
Gruß
Lubber
Sirius3
User
Beiträge: 17750
Registriert: Sonntag 21. Oktober 2012, 17:20

Du rufst das Skript unter Windows nicht aus dem Verzeichnis heraus aus, wo biene.png liegt, sondern irgendein anderes Verzeichnis. Also entweder gibst Du einen absoluten Pfad an, oder startest das Skript aus dem richtigen Verzeichnis heraus.

PS: Das Binden von None an label1 und label2 ist ziemlich nutzlos. Ausführbarer Code sollte in einer Funktion stehen. Wenn biene.png parallel zur .py-Datei liegt, könnte man das so lösen:

Code: Alles auswählen

import tkinter as tk # Improtiert das Modul Tkinter
from pathlib import Path
BASEPATH = Path(__file__).parent

def main():
    root = tk.Tk()
    root.minsize(500, 500)
    root.title("Meine BlaBlaBox")
    tk.Label(root, text="Hallo Neuling").pack(side="left")

    # Grafik einbetten
    picture = tk.PhotoImage(file=str(BASEPATH  / "biene.png"))
    tk.Label(root, image=picture).pack()

    root.mainloop()

if __name__ == "__main__":
    main()
Benutzeravatar
peterpy
User
Beiträge: 188
Registriert: Donnerstag 7. März 2013, 11:35

Hallo Lubber,

Die Fehlermeldung

Code: Alles auswählen

tkinter.TclError: couldn't open "biene.png": no such file or directory
sagts doch schon.
Das Bild der Biene wird nicht gefunden.
Überprüfe deine Pfadangaben.
Gruss und viel Freude am lernen.
Peter
Lubber
User
Beiträge: 3
Registriert: Montag 18. Januar 2021, 08:39

@Sirius3 und @PeterPy,

vielen Dank für Eure Antworten. Das Bild liegt auf jedem Fall in dem selben Verzeichnis wie das Skript (die .py Datei).
Deshalb bin ich verwirrt warum es auf dem Android Smartphone funktioniert und auf dem PC nicht.

Der gepostete Code ist nur aus einer Übung raus. Deshalb steht der ausführbare Code wohl in keiner Funktion.

Die Fehlermeldung hab ich schon verstanden, aber nicht kapiert ;). Da wie oben schon geschrieben die .py Datei und das Bild im selben Verzeichnis liegen.

Seis drum, ich versuche zum einen mal den Vorschlag von Sirus, gehe aber wohl lieber, unabhängig von diesem Problem, ersteinmal weiter step für step im Toturial weiter.

Vielen Dank nochmal, und Ihr werdet bestimmt demnächst öfter von mir hören ;).

Gruß
Lubber
Lubber
User
Beiträge: 3
Registriert: Montag 18. Januar 2021, 08:39

Guten Morgen zusammen.

Einen Nachtrag noch zu meiner Frage/meinem Anliegen.

Wie beschrieben bringt Atom ja die Fehlermeldung wenn dich das Script innerhalb vom Editor laufen lasse.

Starte ich die .py Datei per Doppelklick funktioniert es. Das Bild wird quasi wie gewollt gezeigt.

Bedeudet das nun das es quasi ein Fehler innerhalb von Atom ist?
Das ganze ist jetzt nicht wirklich wichtig da ich wie gesagt am Anfang meines "Selbststudiums" stehe und hier noch ein langer
steiniger Weg bevorsteht. Aber interessant wäre es dennoch.

Gruß und Schönes Wochenende,
Lubber
Sirius3
User
Beiträge: 17750
Registriert: Sonntag 21. Oktober 2012, 17:20

@Lubber: unterschiedliche Umgebungen gehen mit dem Arbeitsverzeichnis unterschiedlich um. Normalerweise will man das Arbeitsverzeichnis unabhängig von dem Ort, an dem das Programm liegt, wählen können.
Dass sich da dieser Doppelklick anders verhält, liegt einfach daran, dass es da kein explizites Arbeitsverzeichnis gibt, und dann nimmt halt das System als Arbeitsverzeichnis den Ort der .py-Datei.
Der Fehler liegt also, wie wir schon geschrieben haben, in Deinem Programm, weil es das Arbeitsverzeichnis nicht richtig berücksichtigt.
Benutzeravatar
sparrow
User
Beiträge: 4193
Registriert: Freitag 17. April 2009, 10:28

@Lubber: Hast du verstanden was ein Arbeitsverzeichnis ist?

Trennen wir uns kurz davon, dass du ein Programm mit GUI schreibst. Stell dir vor, du schreibst ein Programm für die Konsole und das invertiert die Farben eines Bildes. Das heißt inverter.py und ist Systemweit installiert. Es kann also in der Konsole/Eingabeaufforderung von jedem Verzeichnis aus aufgerufen werden. Als erstes Argument erwartet es den Dateinamen des Bildes, das geändert werden soll.
Wenn du inverter.py von irgendwo aufrufst, dann ist dieses "irgendwo" dein Arbeitsverzeichnis.
Und weil du es einfach machen willst, sucht inverter.py die zu ändernde Datei im aktuellen Arbeitsverzeichis, damit man nicht den vollen Pfad angeben kann.

Beispiel:
Du hast ein Verzeichnis c:\lubber\ und darin das Bild bild.png. Das möchtest du invertieren. inverter.py liegt irgendwo ganz anders in einem Verzeichnis c:\users\irgendwer\meineprogramme\lubber.py, das in PATH aufgenommen ist. Du wechselst also in das Verzeichnis und rufst dein Programm auf.:

Code: Alles auswählen

c:\lubber>inverter.py bild.png
c.\lubber war in dem Moment dein Arbeitsverzeichnis und hat nichts mit er Örtlichkeit von c:\users\irgendwer\meineprogramme\lubber.py zu tun. Wäre ja auch unsinnig, wenn das Programm dort nach Dateien suchen würde, die es ändern soll.

So verhält es sich im deinem Programm auch: Du musst dafür sorgen, dass nicht im Arbeitsvzeichnis sondern realtiv zu deinem Script gesucht wird. Es ist also kein Problem von Atom, sondern du musst dafür sorgen, dass dein Programm die Bilder an der richtigen Stelle sucht. Entweder indem du absolute Pfade verwendest, oder Pfade, die relativ zu einem Pfad sind, den du sicher kennst. Zum Beispiel dem Pfad des Scripts.

Code: Alles auswählen

from pathlib import Path

script_directory = Path(__file__).parent
Antworten