tkinter 树视图行显示值与下划线的差异 [英] tkinter treeview row display value discrepancy with underscore

查看:28
本文介绍了tkinter 树视图行显示值与下划线的差异的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a treeview display of invoice related data. The invoice identifiers have underscores. I have noticed the underscore displays correctly in the GUI however the invoice number value obtained from the tree row data omits the underscore. I am currently doing a substitution of - for _ before inserting the data in the full application to handle the issue.

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

Is the way I am using the treeview or retrieving the row data the user selected causing the issue? Or, is there another explanation for the discrepancy between GUI display and the retrieved values that have underscore characters?

我使用的是 python 3.6 和 tkinter 8.6

I am using python 3.6 and 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').

tl;dr: Instead of doing item(row_selected)['values'], do item(row_selected, option='values').

我认为这实际上是 tkinter 中的一个错误,解决方法实际上依赖于另一个错误,所以我将两者都提交为 bpo#34447.但让我们看看那边的 tkinter 专家怎么说.

I think this is actually a bug in tkinter, and the workaround is actually relying on another bug, so I filed both as b.p.o. #34447. But let's see what the tkinter experts over there say.

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

Meanwhile, you hopefully want to understand why that makes a difference, right?

如果您查看 的文档项目:

If you look at the docs for item:

查询或修改指定项的选项.

Query or modify the options for the specified item.

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

If no options are given, a dict with options/values for the item is returned. If option is specified then the value for that option is returned. Otherwise, sets the options to the corresponding values as given by kw.

因此,如果您请求 values 选项,您将获得 values 选项的值.

So, if you ask for the values option, you get the values option's value.

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

But if you don't ask for anything, tkinter tries to get clever and give you a dict with all of the options.

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

The problem is that, under the covers, tkinter is a wrapper around Tcl/Tk. In Tcl, everything is a string (it's more like, say, bash in this regard than Python); there's no difference between the number 123 and the string '123'. It's perfectly legal to store ints in TreeView items, but they get stored exactly the same way as strings.

Tcl 代码返回的用于获取项目的所有选项的是 Tcl 键值对的 Tcl 列表,其中所有值都是 Tcl 字符串.Tkinter 不知道哪些应该是字符串,哪些应该是 int.2 所以它试图猜测:任何可以使用 int<转换为 int 的字符串/code> 构造函数是一个 int,其他任何东西都是一个字符串.1 而你的字符串可以转换为 int3,所以它是.

And what's returned by the Tcl code to get all of the options for an item is a Tcl list of Tcl key-value pairs where all of the values are Tcl strings. Tkinter has no idea which ones were supposed to be strings, and which were supposed to be ints.2 So it tries to guess: any string that can be converted to an int with the int constructor is an int, anything else is a string.1 And your string can be converted to an int3, so it is.

当然,这很hacky,但它通常会做你想做的事情,而且当它做的时候它会让事情变得更方便,并且非常hacky但通常可以方便地做你想做的事情"几乎是 tkinter 的定义.

Of course this is pretty hacky, but it usually does what you want, and it makes things more convenient when it does, and "pretty hacky but usually does what you want conveniently" is almost the definition of tkinter.

然而,我认为它应该认识到,虽然 '123_456' 是一个完全有效的 Python 整数文字,它不是一个可以由 Tcl 创建的字符串对于一个整数,所以它不应该尝试解析它.

However, I think it ought to recognize that, while '123_456' is a perfectly valid Python integer literal, it's not a string that could ever be created by Tcl for an integer, so it shouldn't try to parse that.

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

If you want to see the code that does this: ttk.TreeView.item calls ttk._val_or_dict, which calls tkinter._splitdict with ttk._tclobj_to_py as a value-converter.

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

But why doesn't _val_or_dict run the converter over a single key-value pair? I can't honestly see a good reason for this. But it doesn't, so we can take advantage of that fact to work around the problem.

1.如果一个值应该是一个浮点数呢?嗯,这在 TreeView 中并不经常出现,所以 tkinter 不会打扰那个;你只是得到你的浮点数的字符串表示.但是在其他类型中,例如 LabeledScale,浮点数更有用/更常见,它使用不同的函数尝试 float 而不是 int 如果有' 字符串中的 ..

1. What if a value was supposed to be a float? Well, that doesn't come up very often in TreeViews, so tkinter doesn't bother with that one; you just get the string representation of your float. But in other types, like LabeledScale, where floats are more useful/common, it uses a different function that tries float instead of int if there' a . in the string.

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 的一种完全有效的方式,这就是您得到的.

3. In earlier versions of Python, 180618_24 wasn't a valid int literal, so you'd still get a string. But in 3.6, underscores are allowed as group separators, so 180618_24 is a perfectly valid way to spell 18061824, so that's what you get.

这篇关于tkinter 树视图行显示值与下划线的差异的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆