在 tkinter 树视图中将文本换行到行内

tag*_*aga 4 python treeview tkinter

是否可以使用 tkinter treeview 将文本换行?我尝试更改行高,但文本不会换行。基本上我想在行中有多行文本。

这是代码:

from tkinter import*
from tkinter import ttk

myApp = Tk()


NewTree= ttk.Treeview(myApp, height=5)
NewTree['show'] = 'headings'
s = ttk.Style()
s.configure('Treeview', rowheight=40)

NewTree["columns"]=("1","2")

NewTree.column("1", width=60)
NewTree.column("2", width=60)

NewTree.heading("1", text="col a")
NewTree.heading("2", text="col b")

item = NewTree.insert("", "end", values=("i want to wrap this text","and this text"))

NewTree.grid(row=0,column=0)

myApp.mainloop()
Run Code Online (Sandbox Code Playgroud)

这是代码的第二个版本(当您可以在树视图中手动添加项目时),它在我上面发布的代码之前只有一个大功能。我尝试设置不同的值lenght,但结果是相同的(它不会换行):

from tkinter import*
from tkinter import ttk
from tkinter import messagebox

import textwrap

def wrap(string, lenght=15):
    return '\n'.join(textwrap.wrap(string, lenght))

myApp = Tk()

def editact(event):

    def double(event): # funkcija koja kreira celiju kada se klikne dupli klik
        try:            
            if NewTree.identify_region(event.x, event.y) == 'cell':
                # the user clicked on a cell

                def ok(event):
                    """Change item value."""
                    NewTree.set(item, column, entry.get())
                    entry.destroy()

                column = NewTree.identify_column(event.x)  # identify column
                item = NewTree.identify_row(event.y)  # identify item
                x, y, width, height = NewTree.bbox(item, column) 
                value = NewTree.set(item, column)

            elif NewTree.identify_region(event.x, event.y) == 'heading': 
                    # the user clicked on a heading

                def ok(event):
                    """Change heading text."""
                    NewTree.heading(column, text=entry.get())
                    entry.destroy()

                column = NewTree.identify_column(event.x) # identify column
                # tree.bbox work only with items so we have to get the bbox of the heading differently
                x, y, width, _ = NewTree.bbox(NewTree.get_children('')[0], column) # get x and width (same as the one of any cell in the column)
                # get vertical coordinates (y1, y2)
                y2 = y
                # get bottom coordinate
                while NewTree.identify_region(event.x, y2) != 'heading':  
                    y2 -= 1
                # get top coordinate
                y1 = y2
                while NewTree.identify_region(event.x, y1) == 'heading':
                    y1 -= 1
                height = y2 - y1
                y = y1
                value = NewTree.heading(column, 'text')

            elif NewTree.identify_region(event.x, event.y) == 'nothing': 
                column = NewTree.identify_column(event.x) # identify column
                # check whether we are below the last row:
                x, y, width, height = NewTree.bbox(NewTree.get_children('')[-1], column)
                if event.y > y:

                    def ok(event):
                        """Change item value."""
                        # create item
                        item = NewTree.insert("", "end", values=("", ""))
                        NewTree.set(item, column, entry.get())
                        entry.destroy()

                    y += height
                    value = ""
                else:
                    return
            else:
                return

            # display the Entry   
            entry = ttk.Entry(NewTree)  # create edition entry
            entry.place(x=x, y=y, width=width, height=height, anchor='nw')  # display entry on top of cell
            entry.insert(0, value)  # put former value in entry
            entry.bind('<FocusOut>', ok)  #validate when you click on other cell

            entry.focus_set()

        except IndexError:

            Error=messagebox.showinfo("Error!","You have 0 rows. Please add a new row.")
            sys.exit() #za resavalje greske`
            pass

    NewTree.bind('<Double-Button-1>', double) #create new cell with double click


NewTree= ttk.Treeview(myApp, height=5)
NewTree['show'] = 'headings'

s = ttk.Style()
s.configure('Treeview', rowheight=60)

NewTree["columns"]=("1","2")

NewTree.column("1", width=100, anchor="center")
NewTree.column("2", width=100, anchor="w")

NewTree.heading("1", text="Col A")
NewTree.heading("2", text="Col B")


item = NewTree.insert("", "end", values=(wrap(""),wrap("")))
NewTree.item(item, tags=item)
NewTree.bind('<1>', editact)

NewTree.grid(row=0,column=0, columnspan=5, padx=5)

myApp.mainloop()
Run Code Online (Sandbox Code Playgroud)

jed*_*rds 6

以下代码使用该<B1-Motion>事件动态换行文本(因此支持调整列大小,并且文本将相应地“换行”)。

from tkinter import Tk, ttk
from tkinter.font import Font
from functools import partial

myApp = Tk()

NewTree= ttk.Treeview(myApp, height=5)
NewTree['show'] = 'headings'
s = ttk.Style()
s.configure('Treeview', rowheight=50)

NewTree["columns"]=("1","2")

NewTree.column("1", width=80, anchor="nw")
NewTree.column("2", width=80, anchor="nw")

NewTree.heading("1", text="col a")
NewTree.heading("2", text="col b")

item = NewTree.insert("", "end", values=("i want to wrap this text","and this text"))
print(item)

NewTree.grid(row=0,column=0)

def motion_handler(tree, event):
    f = Font(font='TkDefaultFont')
    # A helper function that will wrap a given value based on column width
    def adjust_newlines(val, width, pad=10):
        if not isinstance(val, str):
            return val
        else:
            words = val.split()
            lines = [[],]
            for word in words:
                line = lines[-1] + [word,]
                if f.measure(' '.join(line)) < (width - pad):
                    lines[-1].append(word)
                else:
                    lines[-1] = ' '.join(lines[-1])
                    lines.append([word,])

            if isinstance(lines[-1], list):
                lines[-1] = ' '.join(lines[-1])

            return '\n'.join(lines)

    if (event is None) or (tree.identify_region(event.x, event.y) == "separator"):
        # You may be able to use this to only adjust the two columns that you care about
        # print(tree.identify_column(event.x))

        col_widths = [tree.column(cid)['width'] for cid in tree['columns']]

        for iid in tree.get_children():
            new_vals = []
            for (v,w) in zip(tree.item(iid)['values'], col_widths):
                new_vals.append(adjust_newlines(v, w))
            tree.item(iid, values=new_vals)


NewTree.bind('<B1-Motion>', partial(motion_handler, NewTree))
motion_handler(NewTree, None)   # Perform initial wrapping

myApp.mainloop()
Run Code Online (Sandbox Code Playgroud)

分隔符左移 分隔符右移