tkinter treeview行显示值与下划线不符

时间:2018-08-21 03:43:09

标签: python tkinter

我有一个发票相关数据的树状视图显示。发票标识符带有下划线。我注意到下划线在GUI中正确显示,但是从树行数据获取的发票编号值省略了下划线。 我目前正在将_替换为_,然后再将数据插入完整的应用程序以处理该问题。

是我使用树状视图还是检索用户选择的导致问题的行数据的方式?或者,对于GUI显示和带有下划线字符的检索值之间的差异,还有另一种解释吗?

我正在使用python 3.6和tkinter 8.6

这里是一个例子。

谢谢。

import tkinter as tk
from tkinter import ttk

DATA = [('180518-23', '23/06/18'),
        ('180618_24', '27/06/18')]
def invoice_selected(event):
    row_selected = event.widget.focus()
    values = event.widget.item(row_selected)['values']
    invoicenumber = values[0]
    print('invoice number', invoicenumber)

ROOT = tk.Tk()
header = ('Invoice', 'Due')
tree = ttk.Treeview(columns=header,
                    show="headings",
                    height=5)
tree.grid()
for col, text in enumerate(header):
    tree.heading(col, text=text)
tree.bind('<<TreeviewSelect>>', invoice_selected)

for record in DATA:
    tree.insert('', 'end', values=record)
ROOT.mainloop()

1 个答案:

答案 0 :(得分:1)

tl; dr:不要执行item(row_selected)['values'],而是执行item(row_selected, option='values')


我认为这实际上是tkinter中的一个错误,解决方法实际上是依赖于另一个错误,因此我将两者都称为b.p.o. #34447。但是,让我们看看那里的tkinter专家怎么说。


同时,您希望希望理解为什么会有所作为,对吗?

如果您查看item的文档:

  

查询或修改指定项目的选项。

     

如果没有给出选项,则返回带有该项目的选项/值的字典。如果指定了 option ,则返回该选项的值。否则,将选项设置为 kw 给定的相应值。

因此,如果您要求使用values选项,则会获得values选项的值。

但是,如果您不要求任何内容,则tkinter会尝试变得聪明,并为您提供所有选项的字典。

问题在于,在幕后,tkinter是Tcl / Tk的包装。在Tcl中,一切都是字符串(在这方面,它更像是bash,而不是Python);数字123和字符串'123'之间没有区别。将整数存储在TreeView项中是完全合法的,但是它们的存储方式与字符串完全相同。

Tcl代码返回以获取某项的所有选项的是Tcl键值对的Tcl列表,其中所有值都是Tcl字符串。 Tkinter不知道哪个应该是字符串,哪些应该是整数。 2 因此,它试图猜测:可以使用int转换为int的任何字符串。构造函数是一个int,其他任何东西都是一个字符串。 1 您的字符串可以转换为int 3

当然这是很棘手的,但是它通常可以满足您的要求,并且使事情变得更加方便,而“相当hacky但通常可以方便地满足您的需求”几乎tkinter的定义。

但是,我认为应该认识到,尽管'123_456'是一个完全有效的Python整数文字,但它不是 一个可以由Tcl为整数创建的字符串,因此它不应该尝试解析它。

如果您想查看执行此操作的代码:ttk.TreeView.item调用ttk._val_or_dict,后者以tkinter._splitdict作为值转换器调用ttk._tclobj_to_py


但是_val_or_dict为什么不对单个键值对运行转换器?老实说,我看不出有什么充分的理由。但是事实并非如此,因此我们可以利用这一事实来解决问题。


1。如果值应该是浮点数怎么办?好吧,这种情况在TreeView中很少出现,因此tkinter不会为那一个烦恼。您只获得浮点数的字符串表示形式。但是在其他类型(例如LabeledScale)中,浮点数更有用/更常见,它使用不同的函数尝试使用float而不是int,如果其中包含.字符串。

2。如果您想知道它的外观,即使在Tcl列表已解析之后,也请尝试打印tree.tk.call(tree._w, 'item', row_selected)tree.tk.call(tree._w, 'item', row_selected, '-values')的结果。

3。在Python的早期版本中,180618_24不是有效的int文字,因此您仍然会得到一个字符串。但是在3.6中,下划线可以用作组分隔符,因此180618_24是拼写18061824的一种非常有效的方法,因此您可以得到。