如何解决更改窗口后,Tkinter窗口未更新.columnconfigure
我刚开始使用python,我试图制作一个由3帧组成的简单gui。左边一个,右边一个,中间一个。稍后,我想在这些框架中添加按钮和内容,但现在仅此而已。如果要按退出键,希望左框消失或再次出现。为此,我编写了以下代码:
from tkinter import Tk,Button,Label,Frame
class Main:
def __init__(self):
self.root = Tk()
self.init_gui()
def init_gui(self):
self.root.title("Gui Testing")
self.root.minsize(900,600)
self.root.bind("<Escape>",self.toggle_left_menu)
self.root.grid_columnconfigure(0,minsize=200)
self.root.grid_columnconfigure(1,weight=1)
self.root.grid_columnconfigure(2,minsize=250)
self.root.grid_rowconfigure(0,weight=1)
# main 3 panels
self.left_menu_active = True
self.left_menu = Frame(self.root,bg="#333")
self.left_menu.grid(row=0,column=0,sticky="nsew")
self.center = Frame(self.root,bg="white")
self.center.grid(row=0,column=1,sticky="nsew")
self.right_menu = Frame(self.root,bg="#888")
self.right_menu.grid(row=0,column=2,sticky="nsew")
self.toggle_left_menu()
def toggle_left_menu(self,event=None):
if self.left_menu_active == True:
self.left_menu_active = False
self.root.grid_columnconfigure(0,minsize=0)
self.left_menu.grid_forget()
else:
self.left_menu_active = True
self.root.grid_columnconfigure(0,minsize=200)
self.left_menu.grid(row=0,sticky="nsew")
def start(self):
self.root.mainloop()
Main().start()
问题是当我按Escape键时,什么也没发生。但是,当我通过单击并拖动它来移动窗口时,它突然更新,并且以我想要的方式显示该窗口。因此,代码似乎可以正常工作,但是由于某些原因窗口没有更新。
我不知道该怎么办。我发现它确实会更新左侧框架和中央框架的网格位置,但是grid_configure()
似乎不会在不移动窗口的情况下进行更新。
有没有办法更新框架或以其他方式实现框架切换?
编辑:
已通过在每个帧中添加按钮来解决该问题。现在,框架不再是空的了,似乎可以了。我还编辑了toggle_left_menu()
函数。这就是我所做的更改:
添加的按钮:
self.test_button1 = Button(self.left_menu,text="left",padx=10,pady=5)
self.test_button1.grid(row=0,column=0)
self.test_button2 = Button(self.center,text="center",pady=5)
self.test_button2.grid(row=0,column=0)
self.test_button3 = Button(self.right_menu,text="right",pady=5)
self.test_button3.grid(row=0,column=0)
已编辑toggle_left_menu()
:
def toggle_left_menu(self,event=None):
if self.left_menu.winfo_viewable():
self.root.grid_columnconfigure(0,minsize=0)
self.left_menu.grid_remove()
else:
self.root.grid_columnconfigure(0,minsize=200)
self.left_menu.grid()
这对我有用,谢谢!
解决方法
部分问题是minsize
仅影响最小大小。如果左框架可见并且宽度大于零像素,则将minsize
设置为零不会减小该框架。因此,第一步是删除列0的minsize=200
选项。
由于您使用的是grid
,所以隐藏或显示框架的最佳方法是使用grid_remove
删除小部件,然后使用grid
对其进行还原。 grid_remove
将从窗口中删除窗口小部件,但记住其所有设置。当您随后致电.grid()
时,将使用所有以前的设置。
由于您的功能是切换式的,因此您也可以只检查窗口是否可见而无需管理布尔标志。这样可以简化代码。
此外,我认为某些版本的tk(建立tkinter的库)上存在一个错误,该错误会阻止窗口在这种特定类型的情况下刷新。对我有用的是在根窗口上综合生成一个<Configure>
事件。
将所有这些功能一起滚动,此版本的切换功能在OSX上对我有效,而无需对代码进行任何其他修改。
def toggle_left_menu(self,event=None):
if self.left_menu.winfo_viewable():
self.left_menu.grid_remove()
self.root.after_idle(self.root.event_generate,'<Configure>')
else:
self.left_menu.grid()
self.root.after_idle(self.root.event_generate,'<Configure>')
,
扩展Bryan Oakley的示例〜也必须切换minsize
。顺便说一句,我对您的所有GUI进行了分类,并将Main
设为root
。这样,self.root.this
和self.root.that
都不需要。另外,除非您打算将整个gui内容转储到init_gui
方法中,否则您还是必须这样做。如果您的应用很大,那将是一场噩梦。另外,我使整个toggle_menu
方法是动态的,因此它可以切换任一菜单。您可以将键绑定更改为任何值。我将Escape then l
用于left_menu
,将Escape then r
用于right_menu
。
from tkinter import Tk,Button,Label,Frame
class LeftMenu(Frame):
@property
def minsize(self):
return 200
def __init__(self,master,row=0,column=0,**kwargs):
Frame.__init__(self,**kwargs)
self.grid(row=row,column=column,sticky='nswe')
class RightMenu(Frame):
@property
def minsize(self):
return 250
def __init__(self,sticky='nswe')
class Center(Frame):
def __init__(self,sticky='nswe')
class Main(Tk):
def __init__(self):
Tk.__init__(self)
self.bind("<Escape><l>",self.toggle_menu)
self.bind("<Escape><r>",self.toggle_menu)
self.grid_columnconfigure(0,minsize=200)
self.grid_columnconfigure(1,weight=1)
self.grid_columnconfigure(2,minsize=250)
self.grid_rowconfigure(0,weight=1)
# main 3 panels
self.left_menu = LeftMenu(self,bg="#333")
self.center = Center(self,1,bg="white")
self.right_menu = RightMenu(self,2,bg="#888")
self.toggle_menu(menu=self.left_menu)
def toggle_menu(self,event=None,menu=None):
if event and event.char in 'lr':
menu = self.left_menu if event.char == 'l' else self.right_menu
if menu:
if menu.winfo_viewable():
self.grid_columnconfigure(menu.grid_info()['column'],minsize=0)
menu.grid_remove()
else:
menu.grid()
self.grid_columnconfigure(menu.grid_info()['column'],minsize=menu.minsize)
self.after_idle(self.event_generate,'<Configure>')
if __name__ == "__main__":
root = Main()
root.title("Gui Testing")
root.minsize(900,600)
root.mainloop()
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。