ext grid隱藏的列不能修改_Tkinter元件scrollbar高階特性一:自動隱藏
阿新 • • 發佈:2021-01-30
技術標籤:ext grid隱藏的列不能修改
Tkinter元件scrollbar高階特性一:自動隱藏
本文旨在實現 tk.Scrollbar(ttk..Scrollbar)本身沒有且實用的特性:比如 自動隱藏和顯示
簡單示例:
示例1 簡單滾動條的實現程式碼
# -*- coding:utf-8 -*- # Date: 2020/3/13 try: import Tkinter as tk except ImportError: import tkinter as tk try: import ttk except ImportError: import tkinter.ttk as ttk root = tk.Tk() root.geometry("200x300+500+600") hscrollbar = tk.Scrollbar(root) hscrollbar.pack(side=tk.RIGHT, fill="y") test_text = tk.Text(root, wrap=tk.NONE, yscrollcommand=hscrollbar.set) test_text.pack(side=tk.TOP, fill=tk.BOTH, expand=True) test_text.insert(tk.END, "This is tkinter or Tkinter!n"*50) hscrollbar.config(command=test_text.yview) root.mainloop()
特性實現:
佈局管理器grid的實現方式
實現的程式碼如下:
# -*- coding:utf-8 -*- try: import Tkinter as tk except ImportError: import tkinter as tk try: import ttk except ImportError: import tkinter.ttk as ttk class AutoHideScrollbar(ttk.Scrollbar): def set(self,upper,lower): # ❶ if float(upper) <= 0.0 and float(lower) >= 1.0: self.grid_remove() # ❷ else: self.grid() ttk.Scrollbar.set(self,upper,lower) if __name__ == '__main__': root = tk.Tk() root.geometry("200x300+500+600") root.rowconfigure(0, weight=1) root.columnconfigure(0, weight=1) yscrollbar = AutoHideScrollbar(root) yscrollbar.grid(row=0, column=1, sticky=tk.N + tk.S) test_text = tk.Text(root, wrap=tk.NONE, yscrollcommand=yscrollbar.set) test_text.grid(row=0, column=0, sticky=tk.N + tk.E + tk.W + tk.S) test_text.insert(tk.END, "This is tkinter or Tkinter!n"*30) yscrollbar.config(command=test_text.yview) root.mainloop()
註釋❶:繼承ttk.Scrollbar (tk.Scrollbar),重寫覆蓋父類的set()方法,實現自動隱藏滾動條。如下圖所示:
滾動條可以看做一個在0到1之間從上到下的單向座標系,upper 起始值為0,表示滾動條上方在座標系中的值(浮點值表示);lower 表示滾動條最下方在座標系中對應的值,最大為1。
而當upper=0,lower=1時,就表示滾動條佔據了整個空間,此時就可以觸發他的隱藏方法。
註釋❷:需要注意的是,隱藏滾動條元件的方法是用的grid_remove(),而不能使用grid_forget()方法。
具體原因Tkinter中原始碼寫的很清楚:
def grid_forget(self): """Unmap this widget.""" self.tk.call('grid', 'forget', self._w) forget = grid_forget def grid_remove(self): """Unmap this widget but remember the grid options.""" self.tk.call('grid', 'remove', self._w)
效果GIF圖展示
佈局管理器pack的實現方式
如果你說你就喜歡使用 pack 方法實現這個功能,那麼也是可以不過麻煩了一些。因為 pack 中沒有類似於 grid.remove() 這樣既可以移除元件同時又儲存元件的位置資訊的方法(可能之後的版本會有)。
如果使用之前的思路的話,效果如下:
很顯然在這裡是行不通的。
兩種pack實現方法
一:在旁邊放置一個 tk.Frame 元件來裝 滾動條元件。
# -*- coding:utf-8 -*-
try:
import Tkinter as tk
except ImportError:
import tkinter as tk
try:
import ttk
except ImportError:
import tkinter.ttk as ttk
class AutoHideScrollbar(ttk.Scrollbar):
def set(self,upper,lower):
if float(upper) <= 0.0 and float(lower) >= 1.0:
self.pack_forget()
else:
self.pack(side="right", fill="y")
ttk.Scrollbar.set(self,upper,lower)
if __name__ == '__main__':
root = tk.Tk()
root.geometry("200x300+500+600")
frame = tk.Frame(root) # 用於放置scrollbar元件
frame.pack(side="right", fill="y")
vscrollbar = AutoHideScrollbar(frame)
vscrollbar.pack(side=tk.RIGHT, fill="y")
test_text = tk.Text(root, wrap=tk.NONE, yscrollcommand=vscrollbar.set)
test_text.pack(fill=tk.BOTH, expand=True)
vscrollbar.config(command=test_text.yview)
test_text.insert(tk.END, "This is tkinter or Tkinter!n"*26)
root.mainloop()
二:使用canvas 元件來實現
# -*- coding:utf-8 -*-
try:
import Tkinter as tk
except ImportError:
import tkinter as tk
try:
import ttk
except ImportError:
import tkinter.ttk as ttk
class AutoHideScrollbar(ttk.Scrollbar):
def set(self,upper,lower):
if float(upper) <= 0.0 and float(lower) >= 1.0:
self.pack_forget()
else:
if self.cget("orient") == tk.HORIZONTAL:
self.pack(fill=tk.X, side=tk.BOTTOM)
else:
self.pack(fill=tk.Y, side=tk.RIGHT)
ttk.Scrollbar.set(self,upper,lower)
def grid(self, **kw): #
raise AttributeError("{} has no attribute {}".format(AutoHideScrollbar.__name__, "'grid'"))
def place(self, **kw):
raise AttributeError("{} has no attribute {}".format(AutoHideScrollbar.__name__, "'place'"))
if __name__ == '__main__':
root = tk.Tk()
vscrollbar = AutoHideScrollbar(root)
canvas = tk.Canvas(root, yscrollcommand=vscrollbar.set)
canvas.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
vscrollbar.config(command=canvas.yview)
frame = tk.Frame(canvas)
test_text = tk.Text(frame, wrap=tk.NONE)
test_text.pack(fill=tk.BOTH, expand=True)
test_text.insert(tk.END, "This is tkinter or Tkinter!n"*26)
canvas.create_window(0, 0, anchor=tk.NW, window=frame)
frame.update_idletasks()
canvas.config(scrollregion=canvas.bbox("all"))
root.mainloop()
使用 canvas 、canvas.create_window 來實現存在一些小問題,特別是內部使用 tk.Text 元件時。有機會再講,畢竟和本文主題不搭。
推薦使用 grid 方式實現,如果就是要用 pack 實現的話建議使用 pack 的第一種實現方式。
結尾
有疑問歡迎留言詢問
請不要轉載,或者先詢問我
請不要轉載,或者先詢問我