Wie kann man tkinter canvas dazu bringen, die Größe dynamisch an die Fensterbreite anzupassen?
Lesezeit: 5 Minuten
Anonym
Ich muss eine Leinwand in tkinter abrufen, um ihre Breite auf die Breite des Fensters einzustellen, und dann die Größe der Leinwand dynamisch ändern, wenn der Benutzer das Fenster kleiner/größer macht.
Gibt es eine Möglichkeit, dies (einfach) zu tun?
ebar
Ich dachte, ich würde zusätzlichen Code hinzufügen, um die Antwort von @fredtantini zu erweitern, da es nicht darum geht, wie die Form von Widgets aktualisiert wird, die auf gezeichnet werden Canvas.
Dazu müssen Sie die verwenden scale -Methode und markieren Sie alle Widgets. Ein vollständiges Beispiel finden Sie unten.
from Tkinter import *
# a subclass of Canvas for dealing with resizing of windows
class ResizingCanvas(Canvas):
def __init__(self,parent,**kwargs):
Canvas.__init__(self,parent,**kwargs)
self.bind("<Configure>", self.on_resize)
self.height = self.winfo_reqheight()
self.width = self.winfo_reqwidth()
def on_resize(self,event):
# determine the ratio of old width/height to new width/height
wscale = float(event.width)/self.width
hscale = float(event.height)/self.height
self.width = event.width
self.height = event.height
# resize the canvas
self.config(width=self.width, height=self.height)
# rescale all the objects tagged with the "all" tag
self.scale("all",0,0,wscale,hscale)
def main():
root = Tk()
myframe = Frame(root)
myframe.pack(fill=BOTH, expand=YES)
mycanvas = ResizingCanvas(myframe,width=850, height=400, bg="red", highlightthickness=0)
mycanvas.pack(fill=BOTH, expand=YES)
# add some widgets to the canvas
mycanvas.create_line(0, 0, 200, 100)
mycanvas.create_line(0, 100, 200, 0, fill="red", dash=(4, 4))
mycanvas.create_rectangle(50, 25, 150, 75, fill="blue")
# tag all of the drawn widgets
mycanvas.addtag_all("all")
root.mainloop()
if __name__ == "__main__":
main()
Ein Wort der Vorsicht: Verwenden Sie dies mit grid wird Ihren Fenstermanager töten!
– Stefan
3. April 16 um 19:53 Uhr
Und jetzt: Wie bekomme ich es zum Laufen, wenn der Canvas nicht das einzige Widget ist? In meinem Fall befindet sich unter der Leinwand ein Rahmen mit Knopf, der von der Leinwand herausgedrückt wird …
– Stefan
3. April 16 um 20:03 Uhr
Das ist ausgezeichnet. Ich möchte nur die Wichtigkeit betonen highlightthickness=0 beim Erstellen der ResizingCanvas, andernfalls wird die Leinwand so lange erweitert, bis Sie sie beenden.
– Plasma
22. Mai 17 um 8:23 Uhr
Vielen Dank! Aber es scheint, dass alle Objekte neu skaliert werden, außer Bilder, die mit auf die Leinwand hinzugefügt wurden mycanvas.create_image(cur_image_width/2, cur_image_height/2, image=cur_image_bg). Kennen Sie eine Möglichkeit, das Bild mit der self.scale-Funktion neu zu skalieren?
– schrottulk
26. Januar 19 um 11:53 Uhr
Sehr schön außer entfernen bg="red", was ablenkt und die rote Linie unsichtbar macht.
Können Sie Pack in einem anderen Rahmen mit Raster verwenden?
– Gründino
27. Mai 20 um 9:09 Uhr
Ja, du kannst. nur die Widgets auf demselben Master sollten auch denselben Manager verwenden pack, grid oder place.
– Billi
16. November 21 um 17:12 Uhr
Das tut es – zumindest in meiner Version von Python. Die Leinwandgröße wird sowohl horizontal (sticky=E+W & rowconfigure) als auch vertikal (sticky=N+S & columnconfigure) angepasst. Ich habe den Canvas-Hintergrund auf eine eklige Farbe gesetzt – aber zumindest sieht man, wann es funktioniert.
Um die Größe des Canvas-Objekts an die neue Fenstergröße anzupassen, verwenden Sie einfach die tkinter-Geometrie-Manager richtig.
Bei pack gibt es die expand- und fill-Optionen, bei grid müssen Sie die columnconfigure- und rowconfigure-Methoden des canvas master (das Widget, das die canvas enthält) verwenden und bei place manager gibt es die relwidth- und relheight-Optionen. Andererseits ändert dies nur die Leinwandabmessungen, ohne die Abmessungen seiner Objekte zu ändern. Um die Größe der Canvas-Objekte zu ändern, müssen Sie die Skalierungsmethode verwenden, wie vorgeschlagen wurde. Eine andere zu berücksichtigende Sache ist, dass einige Canvas-Objekte wie Text nicht von der Canvas-Skalierungsmethode betroffen sind.
Hier ist der Antwortcode ein wenig geändert:
import tkinter as tk
# a subclass of Canvas for dealing with resizing of windows
class ResizingCanvas(tk.Canvas):
def __init__(self, parent, **kwargs):
tk.Canvas.__init__(self, parent, **kwargs)
self.bind("<Configure>", self.on_resize)
self.height = self.winfo_reqheight()
self.width = self.winfo_reqwidth()
def on_resize(self,event):
# determine the ratio of old width/height to new width/height
wscale = event.width/self.width
hscale = event.height/self.height
self.width = event.width
self.height = event.height
# rescale all the objects
self.scale("all", 0, 0, wscale, hscale)
def main():
root = tk.Tk()
myframe = tk.Frame(root)
myframe.pack(fill=tk.BOTH, expand=tk.YES)
mycanvas = ResizingCanvas(myframe,width=850, height=400, bg="light blue")#, highlightthickness=0)
mycanvas.pack(fill=tk.BOTH, expand=tk.YES)
# add some widgets to the canvas
mycanvas.create_line(0, 0, 200, 100)
mycanvas.create_line(0, 100, 200, 0, fill="red", dash=(4, 4))
mycanvas.create_rectangle(50, 25, 150, 75, fill="blue")
# tag all of the drawn widgets
root.mainloop()
if __name__ == "__main__":
main()
.
4947600cookie-checkWie kann man tkinter canvas dazu bringen, die Größe dynamisch an die Fensterbreite anzupassen?yes