Seite 1 von 1
Bildgröße anpassen und im Frame anzeigen
Verfasst: Freitag 16. Februar 2018, 22:06
von suk
Hallo,
ich habe mir schon diverse Beiträge zum Thema angesehen, jedoch immer noch nicht verstanden, wo mein Problem liegt.
Ich möchte einen Dialog für eine Bildauswahl zur Verfügung stellen. Das ausgewählte Bild soll auf eine bestimmte Größe angepasst und in einem Frame dargestellt werden.
Ich bekomme jedoch das Bild nicht angezeigt?! Es wird immer nur der graue Hintergrund darstellt.
Hinweis: Den Auswahldialog habe ich mal weggelassen und nur versucht, den Code auf die Bildumwandlung und -darstellung zu reduzieren.
Könnt Ihr mal bitte den Fehler erklären und auf ein Lösungsbeispiel anpassen.
Danke.
Code: Alles auswählen
#!/usr/bin/env python
# -*- coding: utf-8 -*-
### Import der erforderlichen Module ###
try:
# Tkinter for Python 2.xx
import Tkinter as tk
except ImportError:
# Tkinter for Python 3.xx
import tkinter as tk
from functools import partial
import tkinter.font as tkf
from PIL import ImageTk, Image
### Fensterdefinition ###
APP_TITLE = "Template"
APP_WIDTH = 600
APP_HEIGHT = 300
### Inhalt Canvas-Applikation ###
class App_Canvas():
def __init__(self, canvasmaster):
self.mycanvas = canvasmaster
### Inhalt Frame-Applikation ###
class App_Frame():
def __init__(self, framemaster):
self.myframe = framemaster
self.myframe.pack()
self.obj_image = Image.open("/home/pi/python_scripts/python-GUI/Images/person1.gif")
self.obj_image = self.obj_image.resize((200, 200), Image.ANTIALIAS)
self.myimage = ImageTk.PhotoImage(self.obj_image)
self.mylabel = tk.Label(self.myframe, image=self.myimage, width=200, height=200, relief="groove")
self.mylabel.pack()
### Applikationsstart ###
def main():
win_master = tk.Tk()
win_master.title(APP_TITLE)
app_canvas = tk.Canvas(win_master, width=APP_WIDTH, height=APP_HEIGHT, relief="groove", bg="white", bd=5)
# app_canvas.pack()
app_frame = tk.Frame(win_master, width=APP_WIDTH, height=APP_HEIGHT, relief="sunken", bg="gray", bd=3)
app_frame.pack()
button1 = tk.Button(win_master, text="close", command=win_master.destroy)
button1.pack()
# App_Canvas(app_canvas)
App_Frame(app_frame)
win_master.mainloop()
if __name__ == '__main__':
main()
Re: Bildgröße anpassen und im Frame anzeigen
Verfasst: Samstag 17. Februar 2018, 12:24
von wuf
Hi suk
Kannst du das folgende Skript einmal ausprobieren?:
Code: Alles auswählen
#!/usr/bin/env python
# -*- coding: utf-8 -*-
### Import der erforderlichen Module ###
try:
# Tkinter for Python 2.xx
import Tkinter as tk
except ImportError:
# Tkinter for Python 3.xx
import tkinter as tk
from functools import partial
import tkinter.font as tkf
from PIL import ImageTk, Image
### Fensterdefinition ###
APP_TITLE = "Template"
APP_WIDTH = 600
APP_HEIGHT = 300
### Inhalt Canvas-Applikation ###
class App_Canvas():
def __init__(self, canvasmaster):
self.mycanvas = canvasmaster
### Inhalt Frame-Applikation ###
class App_Frame():
def __init__(self, framemaster):
self.myframe = framemaster
self.myframe.pack()
self.obj_image = Image.open("/home/pi/python_scripts/python-GUI/Images/person1.gif")
#self.obj_image = Image.open("person1.gif")
self.obj_image = self.obj_image.resize((200, 200), Image.ANTIALIAS)
self.myimage = ImageTk.PhotoImage(self.obj_image)
self.mylabel = tk.Label(self.myframe, image=self.myimage, width=200, height=200, relief="groove")
self.mylabel.pack()
### Applikationsstart ###
def main():
win_master = tk.Tk()
win_master.title(APP_TITLE)
app_canvas = tk.Canvas(win_master, width=APP_WIDTH, height=APP_HEIGHT, relief="groove", bg="white", bd=5)
# app_canvas.pack()
app_frame = tk.Frame(win_master, width=APP_WIDTH, height=APP_HEIGHT, relief="sunken", bg="gray", bd=3)
app_frame.pack()
button1 = tk.Button(win_master, text="close", command=win_master.destroy)
button1.pack()
# App_Canvas(app_canvas)
app = App_Frame(app_frame)
win_master.mainloop()
if __name__ == '__main__':
main()
Gruss wuf
Re: Bildgröße anpassen und im Frame anzeigen
Verfasst: Samstag 17. Februar 2018, 12:45
von wuf
Hi suk
Dein Applikationsskript würde ich wie folgt gestalten:
Code: Alles auswählen
#!/usr/bin/env python
# -*- coding: utf-8 -*-
### Import der erforderlichen Module ###
from functools import partial
try:
# Tkinter for Python 2.xx
import Tkinter as tk
import tkFont as tkf
except ImportError:
# Tkinter for Python 3.xx
import tkinter as tk
import tkinter.font as tkf
from PIL import ImageTk, Image
### Fensterdefinition ###
APP_TITLE = "Personal Images"
APP_WIDTH = 600
APP_HEIGHT = 300
### Inhalt Canvas-Applikation ###
class App_Canvas(tk.Canvas):
def __init__(self, canvas_master, **kwargs):
self.canvas_master = canvas_master
tk.Canvas.__init__(self, canvas_master, **kwargs)
### Inhalt Frame-Applikation ###
class App_Frame(tk.Frame):
def __init__(self, frame_master, **kwargs):
self.frame_master = frame_master
tk.Frame.__init__(self, frame_master, **kwargs)
self.obj_image = Image.open("/home/pi/python_scripts/python-GUI/Images/person1.gif")
#self.obj_image = Image.open("person1.gif")
self.obj_image = self.obj_image.resize((200, 200), Image.ANTIALIAS)
self.myimage = ImageTk.PhotoImage(self.obj_image)
self.mylabel = tk.Label(self, image=self.myimage, width=200,
height=200, relief="groove")
self.mylabel.pack()
### Applikationsstart ###
def main():
win_master = tk.Tk()
win_master.title(APP_TITLE)
app_canvas = App_Canvas(win_master, width=APP_WIDTH, height=APP_HEIGHT,
relief="groove", bg="white", bd=5)
app_canvas.pack()
app_frame = App_Frame(win_master, width=APP_WIDTH, height=APP_HEIGHT,
relief="sunken", bg="gray", bd=3)
app_frame.pack()
button1 = tk.Button(win_master, text="close", command=win_master.destroy)
button1.pack()
win_master.mainloop()
if __name__ == '__main__':
main()
Gruss wuf
Re: Bildgröße anpassen und im Frame anzeigen
Verfasst: Samstag 17. Februar 2018, 18:58
von suk
@Wuf: Danke für die Antwort.
Ich habe Deine erste Version übernommen und geht. Jetzt ist die Frage, warum. Entweder bin ich blind oder ich konnte den Unterschied nicht finden. Oder beides
Hilf mir mal bitte auf die Sprünge, wo Dein erstes Script abweicht.
Re: Bildgröße anpassen und im Frame anzeigen
Verfasst: Samstag 17. Februar 2018, 20:01
von wuf
Hi suk
Du glaubst es nicht aber ich habe einzig die Zeile
50 in deinem Skript:
abgeändert auf (in meinem Skript ist es übrigens die Zeile
51:
Wenn du dich mit Tkinter beschäftigt wirst du mit der Zeit ein Zauberer.
Gruss wuf
Re: Bildgröße anpassen und im Frame anzeigen
Verfasst: Samstag 17. Februar 2018, 22:18
von suk
gute Show
:K
Kannst Du mir den "Trick" auch erklären?
Re: Bildgröße anpassen und im Frame anzeigen
Verfasst: Sonntag 18. Februar 2018, 10:54
von wuf
Hi suk
Kannst Du mir den "Trick" auch erklären?
Kann ich dir leider nicht. Ich möchte mich nicht als Experten bezeichnen. Komme selber eher aus der Sparte der
Tüftler. Weicht man von einer gängigen Skriptgestaltung ab offenbaren sich manchmal Dinge die jemand so nicht erwartet. Da brauche ich auch die Hilfe von unseren Forumexperten. Habe dein Skript auf das wesentliche reduziert. So entstanden die drei folgenden Varianten. Die ersten zwei davon funktionieren bei mir nicht.
Variante-1:
Code: Alles auswählen
#!/usr/bin/env python
# -*- coding: utf-8 -*-
try:
# Tkinter for Python 2.xx
import Tkinter as tk
except ImportError:
# Tkinter for Python 3.xx
import tkinter as tk
APP_TITLE = "Template"
APP_WIDTH = 600
APP_HEIGHT = 300
class App_Frame(object):
def __init__(self, frame):
self.myimage = tk.PhotoImage(file="person1.gif")
self.mylabel = tk.Label(frame, image=self.myimage, width=200, bg='red',
height=200, relief="groove")
self.mylabel.pack()
def main():
win_master = tk.Tk()
win_master.title(APP_TITLE)
app_frame = tk.Frame(win_master)
app_frame.pack()
App_Frame(app_frame)
button1 = tk.Button(win_master, text="close", command=win_master.destroy)
button1.pack()
win_master.mainloop()
if __name__ == '__main__':
main()
Variante-2:
Code: Alles auswählen
#!/usr/bin/env python
# -*- coding: utf-8 -*-
try:
# Tkinter for Python 2.xx
import Tkinter as tk
except ImportError:
# Tkinter for Python 3.xx
import tkinter as tk
APP_TITLE = "Template"
APP_WIDTH = 600
APP_HEIGHT = 300
class App_Frame(object):
def __init__(self, master):
frame = tk.Frame(master)
frame.pack()
self.myimage = tk.PhotoImage(file="person1.gif")
self.mylabel = tk.Label(frame, image=self.myimage, width=200, bg='red',
height=200, relief="groove")
self.mylabel.pack()
def main():
win_master = tk.Tk()
win_master.title(APP_TITLE)
App_Frame(win_master)
button1 = tk.Button(win_master, text="close", command=win_master.destroy)
button1.pack()
win_master.mainloop()
if __name__ == '__main__':
main()
Variante-3:
Code: Alles auswählen
#!/usr/bin/env python
# -*- coding: utf-8 -*-
try:
# Tkinter for Python 2.xx
import Tkinter as tk
except ImportError:
# Tkinter for Python 3.xx
import tkinter as tk
APP_TITLE = "Template"
APP_WIDTH = 600
APP_HEIGHT = 300
class App_Frame(tk.Frame):
def __init__(self, master):
tk.Frame.__init__(self, master)
self.myimage = tk.PhotoImage(file="person1.gif")
self.mylabel = tk.Label(self, image=self.myimage, width=200, bg='red',
height=200, relief="groove")
self.mylabel.pack()
def main():
win_master = tk.Tk()
win_master.title(APP_TITLE)
App_Frame(win_master).pack()
button1 = tk.Button(win_master, text="close", command=win_master.destroy)
button1.pack()
win_master.mainloop()
if __name__ == '__main__':
main()
Kannst du diese drei Varianten auch bei dir ausprobieren. Wie gesagt bei mir läuft nur die Variante-3 korrekt.
Gruss wuf
Re: Bildgröße anpassen und im Frame anzeigen
Verfasst: Sonntag 18. Februar 2018, 11:41
von Sirius3
@wuf: Deine Klassen in den ersten beiden Varianten sind eigentlich keine. Eine einfache Funktion hätte den selben Effekt:
Code: Alles auswählen
def App_Frame(frame):
myimage = tk.PhotoImage(file="person1.gif")
mylabel = tk.Label(frame, image=myimage, width=200, bg='red',
height=200, relief="groove")
mylabel.pack()
Dadurch, dass Du keine Referenz auf die Instanz der Klasse speicherst, wird sie sofort wieder vom Speichermanagement abgeräumt, und damit auch die Referenz auf das Bild.
Im letzten Fall hast Du einen Frame, der durch ›pack‹ eine Referenz in den internen Strukturen behält.
Am einfachsten zu Verstehen ist immer noch, die Imagereferenz direkt im Label zu speichern:
Code: Alles auswählen
def label_with_image(frame, filename):
image = tk.PhotoImage(file=filename)
label = tk.Label(frame, image=image, width=200, bg='red',
height=200, relief="groove")
label.image = image
return label
def main():
win_master = tk.Tk()
label_with_image(win_master, "person1.gif").pack()
tk.Button(win_master, text="close", command=win_master.destroy).pack()
win_master.mainloop()
Re: Bildgröße anpassen und im Frame anzeigen
Verfasst: Sonntag 18. Februar 2018, 12:08
von wuf
Hi Sirius3
Besten Dank für deine klärenden Worte. Habe mein Variante-2 Skript noch weiter reduziert auf:
Code: Alles auswählen
#!/usr/bin/env python
# -*- coding: utf-8 -*-
try:
# Tkinter for Python 2.xx
import Tkinter as tk
except ImportError:
# Tkinter for Python 3.xx
import tkinter as tk
APP_TITLE = "Template"
APP_WIDTH = 600
APP_HEIGHT = 300
class App_Frame(object):
def __init__(self, master):
self.myimage = tk.PhotoImage(file="person1.gif")
self.mylabel = tk.Label(master, image=self.myimage, width=200, bg='red',
height=200, relief="groove")
self.mylabel.pack()
def main():
win_master = tk.Tk()
win_master.title(APP_TITLE)
App_Frame(win_master)
button1 = tk.Button(win_master, text="close", command=win_master.destroy)
button1.pack()
win_master.mainloop()
if __name__ == '__main__':
main()
Welche immer noch nicht funktioniert. Erst wenn von der Klasse
App_Frame eine Instanz
app wie folgt erzeugt wird klapp es:
Code: Alles auswählen
#!/usr/bin/env python
# -*- coding: utf-8 -*-
try:
# Tkinter for Python 2.xx
import Tkinter as tk
except ImportError:
# Tkinter for Python 3.xx
import tkinter as tk
APP_TITLE = "Template"
APP_WIDTH = 600
APP_HEIGHT = 300
class App_Frame(object):
def __init__(self, master):
self.myimage = tk.PhotoImage(file="person1.gif")
self.mylabel = tk.Label(master, image=self.myimage, width=200, bg='red',
height=200, relief="groove")
self.mylabel.pack()
def main():
win_master = tk.Tk()
win_master.title(APP_TITLE)
app = App_Frame(win_master)
button1 = tk.Button(win_master, text="close", command=win_master.destroy)
button1.pack()
win_master.mainloop()
if __name__ == '__main__':
main()
Gruss wuf
Re: Bildgröße anpassen und im Frame anzeigen
Verfasst: Sonntag 18. Februar 2018, 12:20
von wuf
Ergänzend noch das folgende Skript, welches auch funktioniert:
Code: Alles auswählen
#!/usr/bin/env python
# -*- coding: utf-8 -*-
try:
# Tkinter for Python 2.xx
import Tkinter as tk
except ImportError:
# Tkinter for Python 3.xx
import tkinter as tk
APP_TITLE = "Template"
APP_WIDTH = 600
APP_HEIGHT = 300
class App_Frame(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
self.title(APP_TITLE)
self.myimage = tk.PhotoImage(file="person1.gif")
self.mylabel = tk.Label(self, image=self.myimage, width=200, bg='red',
height=200, relief="groove")
self.mylabel.pack()
button1 = tk.Button(self, text="close", command=self.destroy)
button1.pack()
self.mainloop()
App_Frame()
Gruss wuf
Re: Bildgröße anpassen und im Frame anzeigen
Verfasst: Sonntag 18. Februar 2018, 12:48
von Sirius3
@wuf: wenn man eine Instanz erzeugt, dann aber nichts damit macht, deutet das immer auf einen Fehler hin, zumindest in der Logik. ›__init__‹ ist zum Initialisieren da und nicht, dass sie unbegrenzt läuft.
Das Programm sollte also zumindest so aussehen:
Code: Alles auswählen
class App_Frame(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
self.title(APP_TITLE)
self.myimage = tk.PhotoImage(file="person1.gif")
self.mylabel = tk.Label(self, image=self.myimage, width=200, bg='red',
height=200, relief="groove")
self.mylabel.pack()
tk.Button(self, text="close", command=self.destroy).pack()
app = App_Frame()
app.mainloop()
Re: Bildgröße anpassen und im Frame anzeigen
Verfasst: Sonntag 18. Februar 2018, 13:20
von wuf
Hi Sirius3
OK. Währe das folgende Skript dann besser?:
Code: Alles auswählen
#!/usr/bin/env python
# -*- coding: utf-8 -*-
try:
# Tkinter for Python 2.xx
import Tkinter as tk
except ImportError:
# Tkinter for Python 3.xx
import tkinter as tk
APP_TITLE = "Template"
APP_WIDTH = 600
APP_HEIGHT = 300
class App_Frame(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
self.title(APP_TITLE)
self.build()
def build(self):
self.myimage = tk.PhotoImage(file="person1.gif")
self.mylabel = tk.Label(self, image=self.myimage, width=200, bg='red',
height=200, relief="groove")
self.mylabel.pack()
button1 = tk.Button(self, text="close", command=self.destroy)
button1.pack()
self.mainloop()
App_Frame()
Gruss wuf
Re: Bildgröße anpassen und im Frame anzeigen
Verfasst: Sonntag 18. Februar 2018, 13:48
von __deets__
Nein, denn du rufst doch einfach nur eine Methode auf, immer noch aus dem __init__.
Das haben wir doch aber neulich schon alles mal durchdekliniert:
viewtopic.php?f=18&t=41785&start=30#p319571
Re: Bildgröße anpassen und im Frame anzeigen
Verfasst: Sonntag 18. Februar 2018, 16:11
von wuf
Das haben wir doch aber neulich schon alles mal durchdekliniert: viewtopic.php?f=18&t=41785&start=30#p319571
Danke für deinen Hinweis.