[英]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.