簡體   English   中英

Tkinter,如何調整 treeview 壓痕大小和指示箭頭圖像

[英]Tkinter, how to adjust treeview indentation size and indicator arrow image

我有一個 treeview 小部件,您可以放大和縮小字體大小。 問題是縮進在放大時與正常時不成比例。 有沒有辦法調整壓痕寬度? 下面是兩張圖片,一張是正常的,另一張是放大的。 我也想知道是否有辦法改變指標圖像?

更新:感謝下面的jasonharper評論,我已經解決了縮進問題。 我仍然需要更改指示箭頭圖像似乎在 web 上找不到任何信息。

圖像1

圖2

縮進

正如 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)
  • 換行以遵守 PEP 標准 79 字符行長度
  • 縮進右括號以希望使代碼更具可讀性。

變化的核心是新的 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

這是最終結果:

mserve open close triangles.png

暫無
暫無

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

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