python - tkinter treeview 行显示值与下划线的差异
问题描述
我有发票相关数据的树视图显示。发票标识符有下划线。我注意到下划线在 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()
解决方案
tl; dr:与其做item(row_selected)['values']
,不如做item(row_selected, option='values')
。
我认为这实际上是 tkinter 中的一个错误,解决方法实际上是依赖于另一个错误,所以我将两者都归档为bpo #34447。但是让我们看看那边的 tkinter 专家怎么说。
同时,您希望了解为什么会有所作为,对吗?
如果您查看以下文档item
:
查询或修改指定项的选项。
如果没有给出选项,则返回一个带有项目选项/值的字典。如果指定了选项,则返回该选项的值。否则,将选项设置为kw给出的相应值。
因此,如果您要求该values
选项,您将获得该values
选项的价值。
但是,如果您不要求任何东西,tkinter 会尝试变得聪明,并为您提供包含所有选项的 dict。
问题在于,在幕后,tkinter 是 Tcl/Tk 的包装器。在 Tcl 中,一切都是字符串(在这方面它更像是 bash,而不是 Python);123
number和 string之间没有区别'123'
。在TreeView
项目中存储整数是完全合法的,但它们的存储方式与字符串完全相同。
Tcl 代码为获取项目的所有选项返回的是一个 Tcl 键值对的 Tcl 列表,其中所有值都是 Tcl 字符串。Tkinter 不知道哪些应该是字符串,哪些应该是整数。2所以它试图猜测:任何可以使用int
构造函数转换为 int 的字符串都是 int,其他任何字符串都是字符串。1你的字符串可以转换为int
3,就是这样。
当然,这很 hacky,但它通常会做你想做的事,而且这样做会让事情变得更方便,而“相当 hacky 但通常可以方便地做你想做的事”几乎是 tkinter 的定义。
然而,我认为它应该认识到,虽然'123_456'
它是一个完全有效的 Python 整数文字,但它不是Tcl 可以为整数创建的字符串,所以它不应该尝试解析它。
如果您想查看执行此操作的代码:ttk.TreeView.item
calls ttk._val_or_dict
,它调用tkinter._splitdict
withttk._tclobj_to_py
作为值转换器。
但是为什么不在_val_or_dict
单个键值对上运行转换器呢?老实说,我看不出有什么好的理由。但事实并非如此,因此我们可以利用这一事实来解决问题。
1. 如果一个值应该是一个浮点数怎么办?好吧,这在 s 中并不经常出现TreeView
,因此 tkinter 不会打扰那个;你只是得到你的浮点数的字符串表示。但是在其他类型中,例如LabeledScale
,其中浮点数更有用/更常见,它使用不同的函数来尝试float
而不是字符串中int
是否存在 a .
。
2. 如果你好奇这是什么样子,即使在 Tcl 列表已经被解析之后,尝试打印tree.tk.call(tree._w, 'item', row_selected)
vs.的结果tree.tk.call(tree._w, 'item', row_selected, '-values')
。
3. 在早期版本的 Python 中,180618_24
不是一个有效的 int 字面量,所以你仍然会得到一个字符串。但是在 3.6 中,允许使用下划线作为组分隔符,因此180618_24
拼写 是一种完全有效的方式18061824
,所以这就是你得到的。
推荐阅读
- go - Golang Nacl Secretbox 中的 Bip32 密钥加密
- php - 使用gradereport_user_get_grade_items 的moodle web 服务
- r - .pmmlDataDictionary(field,transformed = transforms)中的错误:特性不支持 nmatrix.2 类
- javascript - 无法通过弹出窗口将对象传递给控制器方法
- mysql - 我们如何连接两个数据库表。用 PHP 简单的方法
- r - 运行 1000 次模拟,并存储 LASSO 的输出
- python - 我可以使用 Raspberry Pi 3(B 型)中的 AUX 端口插入麦克风以获取音频信号吗?
- c# - 编写单元测试
- dart - 在没有 pub 的情况下在 Windows 上运行时出现 webdev 错误
- java - 如何在 Dagger 2.16 中为工作类实现 Dagger?('android.arch.work:work-runtime')