我有一个发票相关数据的树状视图显示。发票标识符带有下划线。我注意到下划线在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()
答案 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
的一种非常有效的方法,因此您可以得到。