Let's take these frames out to see if they can be displayed normally. How do they look?
Also check width =(root.winfo_width() -21) / 3,height =(root.winfo_height() -33) / 3.
In the process of writing GUI, we need to separate the command of a button to execute, other normal execution, but the grid has no effect, this part of the code is as follows, Focus on the last piece of code
from tkinter import *
from draggableWindow import move_window as m_w
from windowSet import windowSet
import numpy as np
import os
import time
def close_window(event): # 设置关闭窗口的程序
from tkinter import messagebox
if messagebox.askokcancel('退出','请确认是否退出程序'):
root.destroy()
def _on_mousewheel(event): # 鼠标滚轮
main.yview_scroll(int(-1 * (event.delta / 120)), "units")
root = Tk()
sw = root.winfo_screenwidth()
sh = root.winfo_screenheight()
ww = 1280
wh = 720
x = int((sw - ww) / 2)
y = int((sh - wh) / 2)
root.title("燃烧炉监测窗口")
root.geometry(f'{ww}x{wh}+{x}+{y}')
#root.overrideredirect(True)
m_w(root)
root.bind('<Escape>',close_window) # 将close_window与Esc键绑定
savedSettings = {}
if os.path.isfile('Settings.npy'):
savedSettings = np.load('Settings.npy',allow_pickle = True).item()
canvas_main = Canvas(root,width = ww - 21,height = wh - 33,highlightthickness = 0,bg = 'pink')
scrollbar_main = Scrollbar(root,orient = "vertical",command = canvas_main.yview)
f_main = Frame(canvas_main)
f_main.bind("<Configure>",lambda e: canvas_main.config(scrollregion = canvas_main.bbox('all')))
canvas_main.create_window((0, 0),window = f_main,anchor = "nw")
canvas_main.config(yscrollcommand = scrollbar_main.set)
canvas_main.grid(row = 0,column = 0,sticky = NW)
scrollbar_main.grid(row = 0,column = 1,sticky = NS)
canvas_main.bind_all("<MouseWheel>", _on_mousewheel) # 绑定鼠标滚轮
btSet = Button(root,text = '设置',command = lambda: windowSet(root,savedSettings,f_main),font = ('微软雅黑',10))
btSet.place(relx=1,rely=1,anchor = SE)
if savedSettings != {}:
widgt_c = 0
for i in range(4):
if savedSettings[f"CheckVar{1 + i}"] == 1:
widgt_c += 1
if savedSettings[f"CheckVar{1 + i}"] == 1:
widgt_c += savedSettings['customizeWidgt_n']
for i in range(widgt_c):
print(1)
globals()[f"f_{1 + i}"] = Frame(f_main,width = (root.winfo_width() - 21) / 3,height = (root.winfo_height() - 33) / 3,bg = 'blue')
globals()[f"f_{1 + i}"].grid(row = int(i / 3),column = i % 3,sticky = NW)
globals()[f"f_{1 + i}"].grid_propagate(False)
root.mainloop()
The result is as follows
The effect performed by the button is as follows
0 Answer
Let's take these frames out to see if they can be displayed normally. How do they look?
Also check width =(root.winfo_width() -21) / 3,height =(root.winfo_height() -33) / 3.
windowSet function I have but I haven't typed it out, this problem should have nothing to do with this function
You can use the create_window() method to associate a position in the Canvas with a child control. In your code, you can add each child control to the Canvas with the following statement:
main.create_window((i%3*(root.winfo_width()-21)/3, i//3*(root.winfo_height()-33)/3), window=globals()[f"f_{i+1}"], anchor="nw")
Here, i%3*(root.winfo_width()-21)/3 and i//3*(root.winfo_height()-33)/3 Figure out where the child controls are in the Canvas. The anchor parameter specifies the anchor point of the child control, that is, the upper-left corner of the child control is aligned with the specified point on the Canvas.
This answer quotes ChatGPT
Based on the code you provided and the results you ran, you can see that the button's command calls the windowSet function through a lambda expression, passing main to the function as an argument. Inside the windowSet function, it may modify the controls in f_main, but your code does not update the Canvas scrollregion property, which causes the Canvas to not know the size of the area to scroll.
To fix this, add code in the windowSet function to update the Canvas's scrollregion property after f_main is updated, as follows:
def windowSet(root,savedSettings,f_main):
# do something to modify f_main
f_main.update_idletasks() # update f_main to get its new size
root.update_idletasks() # update root to get its new size
canvas_main.config(scrollregion=canvas_main.bbox("all"))
Here, the update_idletasks() method is called to ensure that all window controls have been updated, and canvas_main.bbox("all") returns a tuple representing the bounding box of all the child controls in Canvas, And use it as the value of the scrollregion property.
This way, when the windowSet function finishes executing, the Canvas will be able to display all the controls in f_main correctly, and the scrollbar will work as expected.
这家伙很懒,什么都没留下...