我的应用程序中有一个可搜索的ttk.Treeview,它根据搜索词设置选择(突出显示)。
为此,我将要选择的项目收集到以空格分隔的字符串中,如下所示:
"item_a item_b item_c"
我将此字符串传递给selection_set
方法。
我遇到的问题是,即使据我所知它们具有相同的python版本(2.7.10),这在某些计算机上也无法使用。
我收到如下错误消息:
"item_a item_b item_c": Item not found
好像它正在搜索具有该巨型名称的一个物品。
我可以通过创建一个列表并对其进行遍历,然后对每个项目调用selection_add
来实现相同的目标,但这要慢得多。
我想系统Tcl / Tk版本可能有所不同,可能与python安装有所不同,但是我不确定,我也不知道如何验证。
但是,即使是那样的情况,我仍然很难找到任何有关此方面的好的文档。我发现的任何文档中都没有使用空格分隔的字符串的想法,我只是在其他没有源的StackOverflow帖子中看到了使用它的想法。 (例如here)
因此,我正在寻找与版本无关的(或至少是一种检测版本并执行其他操作的方法)解决方案,以使用项列表调用selection_set
。如果有人能告诉我该怎么做或指向可以帮助我理解该方法的文档,我将不胜感激。
答案 0 :(得分:2)
用空格分隔的字符串起作用的原因是因为tkinter只是tcl / tk解释器的薄包装,tcl会接受以空格分隔的字符串作为列表。 set_selection
将列表作为参数,因此当您将其传递为以空格分隔的字符串时,tcl将根据其内部规则拆分该字符串。
调用set_selection
的正确方法是传递正确的python列表,tkinter会为您将其转换为tcl列表。
下面是一个简短的示例,该示例说明了如何通过将包含三个元素的列表传递给set_selection
来选择树中的子集:
import tkinter as tk
from tkinter import ttk
root = tk.Tk()
tree = ttk.Treeview(root)
tree.pack(fill="both", expand=True)
items = []
for i in range(10):
item = tree.insert("", "end", text="Item {}".format(i+1))
items.append(item)
items_to_select = items[2:5]
tree.selection_set(items_to_select)
root.mainloop()
上面的代码将导致一个如下所示的窗口:
答案 1 :(得分:0)
要在Python 2中使用selection_set
,您需要传递一个元组来选择。您可以使用内置的tuple
函数将列表轻松转换为元组。
如果您可以升级到Python 3,则可以直接使用列表,并且可能会更好。
这是一个简单的测试程序,它使用几种不同的方法在TreeView中选择项目。这应该在Python 2和3上都可以使用,因此您可以查看哪些方法可以使用。
try:
import Tkinter as tk
import ttk
except ImportError:
import tkinter as tk
import tkinter.ttk as ttk
import platform
class TestWindow:
def __init__(self):
self.top = tk.Tk()
self.top.title("Test TreeView selection")
self.top.minsize(450, 600)
self.root_frame = ttk.Frame(self.top, padding=5)
self.root_frame.pack(fill=tk.BOTH, expand=True)
self.python_version_label = ttk.Label(self.root_frame, text="Python Version: " + platform.python_version())
self.python_version_label.pack(fill=tk.X, expand=False)
self.version_label = ttk.Label(self.root_frame, text="TCL Version: " + tk.Tcl().eval('info patchlevel'))
self.version_label.pack(fill=tk.X, expand=False)
self.controls_frame = ttk.Frame(self.root_frame, padding=5)
self.controls_frame.pack(fill=tk.X, expand=False)
self.select_space_button = ttk.Button(self.controls_frame, text="Select Space", command=self.select_space)
self.select_space_button.pack(side=tk.LEFT, fill=tk.X, expand=True)
self.select_loop_button = ttk.Button(self.controls_frame, text="Select Loop", command=self.select_loop)
self.select_loop_button.pack(side=tk.LEFT, fill=tk.X, expand=True)
self.select_list_button = ttk.Button(self.controls_frame, text="Select List", command=self.select_list)
self.select_list_button.pack(side=tk.LEFT, fill=tk.X, expand=True)
self.select_tuple_button = ttk.Button(self.controls_frame, text="Select Tuple", command=self.select_tuple)
self.select_tuple_button.pack(side=tk.LEFT, fill=tk.X, expand=True)
self.clear_button = ttk.Button(self.controls_frame, text="Clear", command=self.clear)
self.clear_button.pack(side=tk.LEFT, fill=tk.X, expand=True)
self.tree_frame = ttk.Frame(self.root_frame, padding=5)
self.tree_frame.pack(fill=tk.BOTH, expand=True)
self.tree_view = ttk.Treeview(self.tree_frame, padding=5)
self.ysb = ttk.Scrollbar(self.tree_frame, orient='vertical', command=self.tree_view.yview)
self.tree_view.configure(yscroll=self.ysb.set)
self.tree_view.pack(expand=True, fill=tk.BOTH, side=tk.LEFT)
self.ysb.pack(side=tk.RIGHT, fill=tk.Y)
self.tree_view.heading("#0", text="Test Item")
for i in range(0, 100):
name = "Item " + str(i)
item_id = self.tree_view.insert("", tk.END, str(i), text=name, open=True)
self.tree_view.insert(item_id, tk.END, str(i) + "a", text=name + ": A")
self.tree_view.insert(item_id, tk.END, str(i) + "b", text=name + ": B")
self.tree_view.insert(item_id, tk.END, str(i) + "c", text=name + ": C")
self.tree_view.insert(item_id, tk.END, str(i) + "d", text=name + ": D")
self.items = []
for i in range(4, 41):
self.items.append(str(i))
self.items.append(str(i) + "a")
self.items.append(str(i) + "b")
self.items.append(str(i) + "d")
def select_space(self):
self.tree_view.selection_set(" ".join(self.items))
def select_loop(self):
for item in self.items:
self.tree_view.selection_add(item)
def select_list(self):
self.tree_view.selection_set(self.items)
def select_tuple(self):
self.tree_view.selection_set(tuple(self.items))
def clear(self):
self.tree_view.selection_remove(self.tree_view.selection())
def run(self):
self.top.mainloop()
if __name__ == "__main__":
window = TestWindow()
window.run()
我已经在Windows 10,macOS 10.14和Debian Buster(Python 2和3)上对此进行了测试。“选择空间”在任何地方都不起作用,“选择循环”始终有效,但是速度很慢,“选择列表” ”仅适用于Python 3,“选择元组”始终有效。如果您被锁定在2.7.10中,这似乎是解决方案。