[英]Tkinter, how to adjust treeview indentation size and indicator arrow image
我有一個 treeview 小部件,您可以放大和縮小字體大小。 問題是縮進在放大時與正常時不成比例。 有沒有辦法調整壓痕寬度? 下面是兩張圖片,一張是正常的,另一張是放大的。 我也想知道是否有辦法改變指標圖像?
更新:感謝下面的jasonharper評論,我已經解決了縮進問題。 我仍然需要更改指示箭頭圖像似乎在 web 上找不到任何信息。
縮進
正如 jasonharper 和 Daniel Huckson 在評論中所說,縮進可以改變
style.configure('Treeview', indent=100)
指標圖像
可以通過創建自定義主題元素並使用它來替換Treeview.Item
布局中的標准指標來更改指標圖像。
這里的關鍵是要知道打開的項目('user1')和沒有孩子的項目('user2')的狀態名稱,關閉是默認的 state。 因此,打開指示器需要與 state ('user1', '!user2')
中的項目和空圖像映射到 state ('user2', )
中的項目。
我使用 PIL 為指標創建虛擬圖像,但可以直接加載自定義圖像。
from PIL import Image, ImageTk, ImageDraw
import tkinter as tk
from tkinter import ttk
root = tk.Tk()
style = ttk.Style(root)
# custom indicator images
im_open = Image.new('RGBA', (15, 15), '#00000000')
im_empty = Image.new('RGBA', (15, 15), '#00000000')
draw = ImageDraw.Draw(im_open)
draw.polygon([(0, 4), (14, 4), (7, 11)], fill='yellow', outline='black')
im_close= im_open.rotate(90)
img_open = ImageTk.PhotoImage(im_open, name='img_open', master=root)
img_close = ImageTk.PhotoImage(im_close, name='img_close', master=root)
img_empty = ImageTk.PhotoImage(im_empty, name='img_empty', master=root)
# custom indicator
style.element_create('Treeitem.myindicator',
'image', 'img_close', ('user1', '!user2', 'img_open'), ('user2', 'img_empty'),
sticky='w', width=15)
# replace Treeitem.indicator by custom one
style.layout('Treeview.Item',
[('Treeitem.padding',
{'sticky': 'nswe',
'children': [('Treeitem.myindicator', {'side': 'left', 'sticky': ''}),
('Treeitem.image', {'side': 'left', 'sticky': ''}),
('Treeitem.focus',
{'side': 'left',
'sticky': '',
'children': [('Treeitem.text', {'side': 'left', 'sticky': ''})]})]})]
)
tree = ttk.Treeview(root)
tree.pack()
tree.insert('', 'end', text='item 1', open=True)
tree.insert('', 'end', text='item 2')
tree.insert('I001', 'end', text='item 11', open=False)
tree.insert('I001', 'end', text='item 12', open=False)
tree.insert('I004', 'end', text='item 121', open=False)
root.mainloop()
我接受了接受的答案並調整了代碼。 通過使用 treeview 行高作為參數自動計算多邊形坐標,它更短更穩健。
''' Create images for open, close and empty '''
width = row_height-7
im_open, im_close, im_empty = triangle_raw_images(width,
'black', 'LightGrey')
img_open = ImageTk.PhotoImage(im_open)
img_close = ImageTk.PhotoImage(im_close)
img_empty = ImageTk.PhotoImage(im_empty)
# custom indicator
style.element_create('Treeitem.myindicator', 'image', img_close,
('user1', '!user2', img_open), ('user2', img_empty),
sticky='w', width=width)
# replace Treeitem.indicator by custom one
style.layout('Treeview.Item',
[('Treeitem.padding',
{'sticky': 'nswe',
'children': [
('Treeitem.myindicator', {'side': 'left', 'sticky': ''}),
('Treeitem.image', {'side': 'left', 'sticky': ''}),
('Treeitem.focus', {'side': 'left', 'sticky': '','children':
[('Treeitem.text',
{'side': 'left','sticky': ''})]
})
]
})])
以上來自已接受答案的更改:
row_height
與傳遞給 treeview 的變量相同,當使用較大的字體大小時,HiDPI 屏幕需要該變量。ImageTk.PhotoImage(im_open)
用於代替ImageTk.PhotoImage(im_open, name='img_open', master=root)
變化的核心是新的 function:
def triangle_raw_images(hgt, outc, fillc):
from PIL import Image, ImageTk, ImageDraw # Pillow image processing
# For comments in code assume passed hgt = 21
wid = hgt # square image
hgt_off = 4 # top & bottom whitespace
wxy = ( 0, hgt_off, ) # west point x=0, y=4
exy = ( wid-1, hgt_off, ) # east point x=20, y=4
sxy = ( int((hgt-1)/2), hgt-hgt_off, ) # south point x=10, y=17
retn_images = [] # list of three images
# custom indicator images
im_open = Image.new('RGBA', (wid, hgt), (0, 0, 0, 0))
im_empty = Image.new('RGBA', (wid, hgt), (0, 0, 0, 0))
draw = ImageDraw.Draw(im_open)
draw.polygon([ wxy, exy, sxy ], outline=outc, fill=fillc)
im_close= im_open.rotate(90)
return im_open, im_close, im_empty
這是最終結果:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.