簡體   English   中英

更改 window.columnconfigure() 后 Tkinter 窗口未更新

[英]Tkinter window not updating after changing the window.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, column=0, sticky="nsew")


    def start(self):
        self.root.mainloop()
        
Main().start()

問題是當我按下退出鍵時,什么也沒有發生。 但是,當我通過單擊並拖動窗口來移動窗口時,它會突然更新並以我想要的方式顯示窗口。 所以代碼似乎正在運行,但由於某種原因窗口沒有更新。

我不知道我能做些什么。 我發現它確實更新了左側和中心框架的網格位置,但是grid_configure()在不移動窗口的情況下似乎不會更新。

有沒有辦法更新框架或以其他方式實現框架切換?

編輯:

問題已經通過在每一幀添加一個按鈕來解決。 現在框架不再是空的,它似乎有效。 我還toggle_left_menu()編輯了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", padx=10, pady=5)
    self.test_button2.grid(row=0, column=0)

    self.test_button3 = Button(self.right_menu, text="right", padx=10, 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.thisself.root.that都是不必要的。 此外,您無論如何都必須這樣做,除非您打算將整個 gui 內容轉儲到您的init_gui方法中。 如果您的應用程序很大,那么跟蹤將是一場噩夢。 作為額外的獎勵,我使整個toggle_menu方法動態化,因此它可以切換任一菜單。 您可以將鍵綁定更改為任何內容。 我使用Escape then l用於left_menuEscape 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, master, **kwargs)
        self.grid(row=row, column=column, sticky='nswe')
        
        
class RightMenu(Frame):
    @property
    def minsize(self):
        return 250
        
    def __init__(self, master, row=0, column=0, **kwargs):
        Frame.__init__(self, master, **kwargs)
        self.grid(row=row, column=column, sticky='nswe')
       

class Center(Frame):
    def __init__(self, master, row=0, column=0, **kwargs):
        Frame.__init__(self, master, **kwargs)
        self.grid(row=row, column=column, 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, 0, 0, bg="#333")
        self.center     = Center(self, 0, 1, bg="white")
        self.right_menu = RightMenu(self, 0, 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()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM