標籤:

Tkinter中的mainloop應該如何理解?

今天糊塗了,目前的糊塗的理解是:

root

……

root.pack()

之間的帶入主循環

但是今天的一個特例,告訴我不是這樣子,mainloop應該如何理解,它又是把哪些帶入主循環的呢?(幾乎所有的教材都是這一句,實際上很想了解背後機制,因為這個決定了上面的程序段,可以如何的自由發揮)


很簡單。你把滑鼠一個按上會變成手型。或者你在知乎回答問題的文本框里輸入文字。甚至你看到的電腦屏幕內容。看上去是動態的。其實和動畫電影原理差不多。

現在你滑鼠的移動,鍵盤的按鍵。都是實實在在輸入。這裡我們叫做事件。譬如有滑鼠移動事件,單擊事件,F5按下的事件。

以回答問題 按鈕&<發布回答&>左側的匿名勾選框為例。你單擊一次,就綠色小勾表示選中。再單擊就去掉了小勾。現在你這樣想。實際上有兩幅圖(有勾和無勾的)。你單擊滑鼠移動滑鼠就觸發了事件,會把你滑鼠的坐標和單擊這個行為捕獲。那假設你單擊了,滑鼠坐標又在那個框框區域內,我們就把一張圖用另外一張圖代替,同時後台表示是否匿名的某個變數取反。

root到root.pack()之間,無非就是設計你的部件的類型,尺寸,樣式,位置,然後綁定一個事件。

mainloop就進入到事件(消息)循環。一旦檢測到事件,就刷新組件。譬如你輸入一個字元,就要立即在游標那個位置顯示出來(前提是你選中了文本框,也就是滑鼠在文本框這個圖案的範圍內單擊過)。又譬如你點了首頁這個按鈕(就是在這個圖形的區域附近單擊)那麼就要清除你瀏覽器里的全部部件,然後重新繪製(按照主頁設計的布局和內容)。

再給你打個比方。你設計的程序中間有個按鈕,你設計的時候就要把一個按鈕放到中間去。這個按鈕有一個屬性(假設和變數x關聯,x表示按鈕上文字的顏色,如果是1就黑色,0就灰色)。你按一下按鈕,文字顏色就會切換。root到root.pack()你就相當於在那裡放按鈕(其實按鈕就是多幅圖,某一時刻顯示其中一張),具體顏色看x取值。現在到了mainloop。一旦有事件,就又在那裡放按鈕(不妨直接覆蓋原來的圖)。所以在那個位置單擊滑鼠才是觸發某個你想要的程序行為的要素,那個按鈕的刷新,不過是其中一項程序行為。有沒有按鈕你都可以點擊那個區域觸發。但是除了設計者,誰知道呢?無法是視覺效果罷了。

PS:如果你知道連環畫,你可以理解為,每個部件都是連環畫。root到root.pack()就是你設計連環畫。mainloop就是去翻它!實際上不是有很多程序有一個選項就是 動畫效果么,關閉可以減少資源消耗。無非就是連環畫的頁數多。快速翻閱就有動感。如果只有兩頁,看上去很唐突而已。

pps:前面也說了,你看到電腦屏幕也是如此,是不停在刷新的。一般是50-60hz每秒。遊戲里不有一個fps么,楨率 就是畫面的刷新頻率,太慢不就會卡頓么(和網路卡不是一回事)。然後屏幕還有局部刷新的技術,不一定每次都刷新整塊屏幕。設計的程序也是。你可以所有組件每次事件都重新畫。也可以只是畫你需要的部分。


直接理解重新繪製對應Widget實例中的所有內容。

例如你重置了listbox的list內容,在調用listbox.mainloop()前真正顯示出來的list其實並沒有什麼區別,同理之前看有人說過一個所謂的bug:

如果不把canvas的create_image()和mainloop()寫進一個域就無法顯示圖片

其實直接在create_image()後緊接著調用canvas的mainloop()方法就可以正常刷出來。


Mainloop,重建啊,多看源代碼吧,有些東西必須多看


推薦閱讀:

TAG:Python | tkinter |