So, I've got this code
import customtkinter
from tkinter import Canvas
import tkinter as tk
from PIL import Image, ImageTk
app = customtkinter.CTk()
app.title = 'spectrum (v1.0.0)'
app.minsize(800, 600)
frame1 = customtkinter.CTkFrame(master=app)
frame2 = customtkinter.CTkFrame(master=app)
frame1.pack(padx=10, pady=10, expand=True, fill="both", side="left")
frame2.pack(padx=10, pady=10, expand=False, fill="y", side="right")
canvas1 = customtkinter.CTkCanvas(master=frame1, bg="black")
canvas1.create_line(0, 0, canvas1.size()[0], canvas1.size()[1], fill="#FFFFFF")
canvas1.pack(expand=True, fill="both")
canvas2 = Canvas(master=frame1, bg="black")
canvas2.pack(expand=True, fill="both")
canvas3 = Canvas(master=frame2, width=400, height=800, bg="black")
canvas3.pack(expand=True, fill="y")
print(canvas1.size())
print(canvas2.size())
print(canvas1.winfo_width(), canvas1.winfo_height())
print(canvas2.winfo_width(), canvas2.winfo_height())
app.mainloop()
nor Ctk.CtkCanvas (canvas1), nor Trinter.Canvas (canvas2) shows real size of the canvas widget. I expect this code to... "draw" a line from top-left to bottom-right corner of canvas1
P.S. canvas1 is the top one on the left side. and app.title doesn't work... Why? How do I fix it?
I've tryed to get size by .size() and .winfo_width(), .winfo_height()screenshot of output
The size of the canvas can't be determined until the window actually renders, because the size is dependent on the size of the window, the geometry manager that you use (pack
, grid
, etc), the other widgets, and other variables.
You can either call app.update()
before trying to get the size, or configure it so that a function is called as soon as the widget is displayed (ie: bind to <Map>
or <Visibility>
.
Also, the size()
method doesn't return the size of the widget. It is an alias for grid_size
, and returns the number of rows and columns being managed by grid
inside the canvas. Since you haven't added any widgets to any rows or columns in the canvas, it's going to return (0,0)
.
...
app.update()
print(canvas1.size())
print(canvas2.size())
print(canvas1.winfo_width(), canvas1.winfo_height())
print(canvas2.winfo_width(), canvas2.winfo_height())
...
def do_something(event):
print(canvas1.size())
print(canvas2.size())
print(canvas1.winfo_width(), canvas1.winfo_height())
print(canvas2.winfo_width(), canvas2.winfo_height())
canvas1.bind("<Visibility>", do_something)
You have to be a bit more careful with the binding. For one, you're trying to manipulate both canvas1
and canvas2
which might not be updated at precisely the same time. Also, with the binding, the function will be called every time the event triggers, not just the first time the app starts.