我有三个字典,一个提供所有可用选项的列表,另外两个提供选择的子集(一个用于默认设置,一个用于用户选择)。我使用python内置的JSON解析器获得了三个字典。
我想在UI中在左边显示一棵基于字典中键的树,在右边我想显示一个组合框,一个按钮,一个列表框或一些其他适当的小部件来处理数据那把钥匙。我需要这棵树,因为我实际上是在做一份字典,并且我想允许折叠。
到目前为止,我已经研究了tkinter,tkinter的ttk和tix库,它们似乎允许树,但不允许在右边显示可配置列表。我还看到了一些从python的IDLE借来树的示例。
如果GUI工具包是跨平台兼容的(*
nix和win),并且在可能的情况下可以免费分发,我会更喜欢它。出于兴趣,这里没有关于使用tk创建自定义窗口小部件的教程,我尝试过查找,但是我一直直接针对tk的窗口小部件使用,而不是窗口小部件设计:s
作为一个最小的示例,我暂时放弃了额外的命令,并具有以下内容:
import json
import tkinter as tk
from tkinter import ttk
from pprint import pprint as pprint
def JSONTree(Tree, Parent, Dictionery, TagList = []):
for key in Dictionery :
if isinstance(Dictionery[key],dict):
Tree.insert(Parent, 'end', key, text = key)
TagList.append(key)
JSONTree(Tree, key, Dictionery[key], TagList)
pprint(TagList)
elif isinstance(Dictionery[key],list):
Tree.insert(Parent, 'end', key, text = key) # Still working on this
else :
Tree.insert(Parent, 'end', key, text = key, value = Dictionery[key])
if __name__ == "__main__" :
# Setup the root UI
root = tk.Tk()
root.title("JSON editor")
root.columnconfigure(0, weight=1)
root.rowconfigure(0, weight=1)
# Setup Data
Data = {"firstName": "John",
"lastName": "Smith",
"gender": "man",
"age": 32,
"address": {"streetAddress": "21 2nd Street",
"city": "New York",
"state": "NY",
"postalCode": "10021"},
"phoneNumbers": [{ "type": "home", "number": "212 555-1234" },
{ "type": "fax", "number": "646 555-4567" }]}
# Setup the Frames
TreeFrame = ttk.Frame(root, padding = "3")
TreeFrame.grid(row = 0, column = 0, sticky = tk.NSEW)
# Setup the Tree
tree = ttk.Treeview(TreeFrame, columns = ('Values'))
tree.column('Values', width = 100, anchor = 'center')
tree.heading('Values', text = 'Values')
JSONTree(tree, '', Data)
tree.pack(fill=tk.BOTH, expand = 1)
# Limit windows minimum dimensions
root.update_idletasks()
root.minsize(root.winfo_reqwidth(),root.winfo_reqheight())
root.mainloop()
好吧,所以它不是很漂亮,将这样的代码投入生产也不会感到很好,但是它确实可以工作。为了使其更加理智和提高生产质量,我可能将JSONTree设置为一个类,并将所有这些代码包装到方法中。这样可以简化和清除代码,并减少将对象传递给事件处理程序的过程。
import json
import tkinter as tk
from tkinter import ttk
from pprint import pprint as pprint
# opt_name: (from_, to, increment)
IntOptions = {
'age': (1.0, 200.0, 1.0),
}
def close_ed(parent, edwin):
parent.focus_set()
edwin.destroy()
def set_cell(edwin, w, tvar):
value = tvar.get()
w.item(w.focus(), values=(value,))
close_ed(w, edwin)
def edit_cell(e):
w = e.widget
if w and len(w.item(w.focus(), 'values')) > 0:
edwin = tk.Toplevel(e.widget)
edwin.protocol("WM_DELETE_WINDOW", lambda: close_ed(w, edwin))
edwin.grab_set()
edwin.overrideredirect(1)
opt_name = w.focus()
(x, y, width, height) = w.bbox(opt_name, 'Values')
edwin.geometry('%dx%d+%d+%d' % (width, height, w.winfo_rootx() + x, w.winfo_rooty() + y))
value = w.item(opt_name, 'values')[0]
tvar = tk.StringVar()
tvar.set(str(value))
ed = None
if opt_name in IntOptions:
constraints = IntOptions[opt_name]
ed = tk.Spinbox(edwin, from_=constraints[0], to=constraints[1],
increment=constraints[2], textvariable=tvar)
else:
ed = tk.Entry(edwin, textvariable=tvar)
if ed:
ed.config(background='LightYellow')
#ed.grid(column=0, row=0, sticky=(tk.N, tk.S, tk.W, tk.E))
ed.pack()
ed.focus_set()
edwin.bind('<Return>', lambda e: set_cell(edwin, w, tvar))
edwin.bind('<Escape>', lambda e: close_ed(w, edwin))
def JSONTree(Tree, Parent, Dictionery, TagList=[]):
for key in Dictionery :
if isinstance(Dictionery[key], dict):
Tree.insert(Parent, 'end', key, text=key)
TagList.append(key)
JSONTree(Tree, key, Dictionery[key], TagList)
pprint(TagList)
elif isinstance(Dictionery[key], list):
Tree.insert(Parent, 'end', key, text=key) # Still working on this
else:
Tree.insert(Parent, 'end', key, text=key, value=Dictionery[key])
if __name__ == "__main__" :
# Setup the root UI
root = tk.Tk()
root.title("JSON editor")
root.columnconfigure(0, weight=1)
root.rowconfigure(0, weight=1)
# Setup Data
Data = {
"firstName": "John",
"lastName": "Smith",
"gender": "man",
"age": 32,
"address": {
"streetAddress": "21 2nd Street",
"city": "New York",
"state": "NY",
"postalCode": "10021"},
"phoneNumbers": [
{ "type": "home", "number": "212 555-1234" },
{ "type": "fax", "number": "646 555-4567" },
]}
# Setup the Frames
TreeFrame = ttk.Frame(root, padding="3")
TreeFrame.grid(row=0, column=0, sticky=tk.NSEW)
# Setup the Tree
tree = ttk.Treeview(TreeFrame, columns=('Values'))
tree.column('Values', width=100, anchor='center')
tree.heading('Values', text='Values')
tree.bind('<Double-1>', edit_cell)
tree.bind('<Return>', edit_cell)
JSONTree(tree, '', Data)
tree.pack(fill=tk.BOTH, expand=1)
# Limit windows minimum dimensions
root.update_idletasks()
root.minsize(root.winfo_reqwidth(), root.winfo_reqheight())
root.mainloop()
以下是相关的更新代码位。正如用户carmickr所建议的,我使用DefaultListModel来处理地址簿HashMap中的数据。 然后在UserInterface构造函数内部:
如何使用AngularJS正确显示键值对? 这是我的HTML: 以下是JSON数据: 以下是输出: 我想要:
我正在用TreeView和用户控件让自己陷入困境;我是WPF的新手,所以请提前道歉。 提要 我有我的TreeView项目的VM类的集合。因此,TreeView绑定到[父]VM实例的集合,每个实例都有一个[子]ren的集合,每个[子]都有其他数据和其他集合(我不会让你厌烦)。 TreeView位于窗体的左侧,在右侧,我有一个用户控件,该控件只能根据所选的TreeViewItem类型可见。 因此,如果
问题内容: 我曾经使用过i18n。我想将服务用于模块化语言密钥作为延迟加载。我也想为此使用解决选项。 现在该怎么做?是否可以为我添加代码示例? 谢谢 问题答案: 我找到解决方案并解决我的问题。 在配置中: 在索引中: 并在: 在工厂: 并且请注意,您应该像这样在所有参数中添加和作为参数:
我创建了一个名为EmployeeGUI的类,它能够创建任意数量的user Employee对象并将它们添加到ArrayList中。我遇到的问题是,在GUI底部有一个JTable,我希望显示我创建的所有对象,但在我的情况下,GUI每次通过包含对象细节的for循环时都会创建一个新的Table对象,但随着for循环的进行,新的细节会覆盖旧的细节,而不是添加到JTable的底部。有人能帮我调试错误吗? 这
首先,我读过这个问题,但它并没有解决我的问题。 这会给我带来以下错误: InvalidReferenceException:以下内容的计算结果为null或缺失:==>bean[colName][在模板“front.ftl”第46行,第35列中] 提示:导致这个错误的是最后[]步骤,而不是之前的步骤。 提示:如果已知失败表达式在法律上引用的内容有时为null或缺少,则可以指定默认值,如myoptio