2017-11-02 4 views
-1

Ich schrieb eine Anwendung mit tkinter, die Klassen als Struktur verwendet. Ich halte mich sehr nahe an die oft gesehene sentdex Struktur (Siehe Link: Tkinter and ttk in python 2.7), wobei jede neue Seite grundsätzlich ein Rahmen ist, der über eine Controller-Funktion nach oben gehoben wird. Derzeit versuche ich eine Lösung für die automatische Größenanpassung von Hintergrundbildern zu finden, wenn das Hauptfenster maximiert/minimiert ist. Ich habe eine Lösung gefunden, die aber nicht zu 100% passt, weil die Funktion in derselben Klasse wie das Bild ist: (Siehe Link: Tkinter resize background image to window size (Python 3.4))tkinter Bild Größenänderung über Controller

Ich brauche eine allgemeine Funktion, die einen Verweis auf die Seite nimmt (zu wissen wo, um die Größe eines Bildes) und ändert dann die Größe eines Bildes, das - im besten Fall - auf dieser bestimmten Seite gespeichert wird.

Alle meine Versuche zu verwenden Lambda: Controller fehlgeschlagen. Ich wäre sehr froh, wenn mich jemand daran hindern könnte, die resizeimage-Funktion auf jeder Seite zu codieren.

Dies ist mein Code:

import tkinter as tk 
from tkinter import font as tkfont 
from PIL import Image, ImageTk 

Hier erstelle ich die Controller-Klasse:

class SampleApp(tk.Tk): 
    def __init__(self, *args, **kwargs): 
     tk.Tk.__init__(self, *args, **kwargs) 


     container = tk.Frame(self) 
     container.pack(side="top", fill="both", expand=True) 
     container.grid_rowconfigure(0, weight=1) 
     container.grid_columnconfigure(0, weight=1) 

     self.frames = {} 
     for F in (StartPage, PageOne): 
      page_name = F.__name__ 
      frame = F(container,self) 
      self.frames[page_name] = frame 
      frame.grid(row=0, column=0, sticky="nsew") 

     self.show_frame("StartPage") 

    def show_frame(self, page_name): 
     #Show a frame for the given page name 
     frame = self.frames[page_name] 
     frame.tkraise() 

Dies ist die resizeImage-Funktion ich Code versuchen:

def resizeImage(self): 

     # give me an image 
     img = self.frames[StartPage].img 
     # give me an image copy 
     img_copy = self.frames[StartPage].img_copy 
     # give me background image 
     background_image = self.frames[StartPage].background_image 

     new_width = event.width 
     new_height = event.height 

     img = img_copy.resize((new_width, new_height)) 

     background_image = ImageTk.PhotoImage(img) 
     background.configure(image= background_image) 

Dieser Rahmen enthält ein Bild, das über die Controller-Funktion

skaliert werden soll
class StartPage(tk.Frame): 

    def __init__(self, parent, controller): 
     tk.Frame.__init__(self, parent) 


     self.img = Image.open("*.png") 

     self.img_copy= self.img.copy() 

     self.background_image = ImageTk.PhotoImage(self.img) 

     self.background = tk.Label(self, image=self.background_image) 
     self.background.grid() 
     self.background.bind('<Configure>',controller.resizeImage()) 

Und schließlich ist dies eine leere Rahmen/Seite, nur um sicher zu stellen, dass die Schleife in der Controller-Klasse funktioniert:

class PageOne(tk.Frame): 
# this is an empty frame 
    def __init__(self, parent, controller): 
     tk.Frame.__init__(self, parent) 

if __name__ == "__main__": 
    app = SampleApp() 
    app.mainloop() 
+0

Ich hätte lieber eine Klasse für Frames, die Bilder enthalten, und dann eine Methode für diese Klasse tbh. – Nae

+1

Bitte erstellen Sie ein [mcve]. –

+0

Wahrscheinlich möchten Sie 'thumbnail()' verwenden, um die Größe des Bildes zu ändern, während das Seitenverhältnis beibehalten wird. –

Antwort

0

ich den Rat von Nae gefolgt :)

Dank Kumpel!

import tkinter as tk 
from tkinter import ttk 
from PIL import Image, ImageTk 

# Custom Label Class 

class ResizingLabel(tk.Label): #inherit from Label Class 
    def __init__(self, parent, imagepath, *args, **kwargs): # specific for this Subclass: give me an image-path and resize image to label-size 
     tk.Label.__init__(self, parent, *args, **kwargs) # I can do everything what tk.Label can do 

     # Default configure settings (Label has no border) 
     self.configure(bd=0) 

     self.parent=parent 
     self.parent.bind('<Configure>', self._resize_image) 

     self.imagepath = imagepath 
     self.image = Image.open(self.imagepath) 
     self.img_copy= self.image.copy() 
     self.background_image = ImageTk.PhotoImage(self.image) 
     self.background = tk.Label(self, image=self.background_image,bd=0) 
     self.background.grid(row=0,column=0,sticky="NSEW") 
     self.background.grid_rowconfigure(0,weight=1) 
     self.background.grid_columnconfigure(0,weight=1) 
     self.background.bind('<Configure>', self._resize_image) 

    def _resize_image(self,event): 

     new_width = self.parent.winfo_width() 
     new_height = self.parent.winfo_height() 

     self.image = self.img_copy.resize((new_width, new_height)) 
     self.background_image = ImageTk.PhotoImage(self.image) 
     self.background.configure(image = self.background_image) 


# For the follwing code: See SentDex-Tutorial 

LARGE_FONT= ("Verdana", 12) 
class SeaOfBTC(tk.Tk): 

    def __init__(self, *args, **kwargs): 

     tk.Tk.__init__(self, *args, **kwargs) 

     tk.Tk.wm_title(self,"Sea of BTC") 

     container = tk.Frame() 
     container.pack(side="top", fill="both", expand = True) 
     container.grid_rowconfigure(0, weight=1) 
     container.grid_columnconfigure(0, weight=1) 

     self.frames = {} 

     for F in (StartPage, PageOne): 
      frame = F(container,self) 
      self.frames[F] = frame 
      frame.grid(row=0, column=0, sticky="nsew") 

     self.show_frame(StartPage) 

    def show_frame(self, cont): 
     frame = self.frames[cont] 
     frame.tkraise() 

class StartPage(tk.Frame): 

    def __init__(self, parent, controller): 
     tk.Frame.__init__(self,parent) 

     # Create string object with path 
     path = "banner.png" 
     # Create custom label with reference to path 
     label = ResizingLabel(self, path) 
     label.grid() 

     # Create example button on top of custom label 
     button = tk.Button(label,text="Example Button") 
     button.grid(column=0,row=0) 

class PageOne(tk.Frame): 

    def __init__(self, parent, controller): 
     tk.Frame.__init__(self, parent) 
     # This frame contains nothing (only exists so that for-loop (see above) can iterate) 

app = SeaOfBTC() 
app.mainloop()