Python 提供带有编辑功能的列表框的标准ttk方式
我需要一个具有多个选择的列表控件,以及用户编辑显示列表的方法 根据判断,Python 提供带有编辑功能的列表框的标准ttk方式,python,ttk,Python,Ttk,我需要一个具有多个选择的列表控件,以及用户编辑显示列表的方法 根据判断,ttk.Treeview是显示列表的新的黑色方式,它取代了Tkinter.Listbox 是否也提供了一些库存/推荐的方法来合并列表编辑 这通常通过控件周围的三个按钮“添加”/“编辑”/“删除”来完成(前两个按钮可能会导致弹出一个带有编辑控件的小窗口),或者列表条目本身成为编辑器,例如双击。手工实现这两种逻辑都不重要。Tk,因此Tkinter只提供基本的小部件;它们的可重用组合超出了它们的范围。这个被废弃的软件包提供了一种机
ttk.Treeview
是显示列表的新的黑色方式,它取代了Tkinter.Listbox
是否也提供了一些库存/推荐的方法来合并列表编辑
这通常通过控件周围的三个按钮“添加”/“编辑”/“删除”来完成(前两个按钮可能会导致弹出一个带有编辑控件的小窗口),或者列表条目本身成为编辑器,例如双击。手工实现这两种逻辑都不重要。Tk,因此Tkinter只提供基本的小部件;它们的可重用组合超出了它们的范围。这个被废弃的软件包提供了一种机制和一个称为“巨型小部件”的集合,但这个想法显然没有流行起来 我是按照以下方式完成的(使用模型视图演示器设计模式) 看起来是这样的:
导入tkinter
从tkinter导入ttk
从特金特进口W,E
类视图\u可编辑列表(对象):
def_uuuinit_uuu(self、root、root_行):
“”列表,带有编辑其内容的按钮。
:param root:父窗口小部件
:param roow_row:root中的行。该节包含2行。
"""
self.list=tkinter.Listbox(root,selectmode=tkinter.EXTENDED)
self.list.grid(row=root\u row,sticky=(W,E))
rootconfigure(root\u行,权重=1)
self.frame=ttk.frame(根)
self.frame.grid(row=root\u row+1,sticky=(W,E))
self.add=ttk.按钮(self.frame,text=“+”,width=5)
self.add.grid(行=0,列=1)
self.edit=ttk.Button(self.frame,text=“*”,width=5)
self.edit.grid(行=0,列=2)
self.del=ttk.按钮(self.frame,text=“-”,width=5)
自删除网格(行=0,列=3)
self.up=ttk.按钮(self.frame,text=u)↑", 宽度=5)
self.up.grid(行=0,列=4)
self.down=ttk.按钮(self.frame,text=u)↓“,宽度=5)
self.down.grid(行=0,列=5)
self.frame.grid\u columnconfigure(0,权重=1)
self.frame.grid\u columnconfigure(6,权重=1)
类演示者\u可编辑列表(对象):
定义初始化(自、视图、根):
"""
:param view:view\u EditableList
:param root:要用作模式窗口的父窗口的根窗口小部件
"""
self.root=根
self.view=view
view.add.configure(命令=self.add)
view.edit.configure(命令=self.edit)
view.del\ux.configure(命令=self.del\ux)
view.up.configure(命令=self.up)
view.down.configure(命令=self.down)
def添加(自我):
w=视图\u AskText(self.root)
self.root.wait_窗口(w.top)
如果w.value:
self.view.list.insert(self.view.list.size(),w.value)
def编辑(自我):
l=self.view.list
尝试:
[索引]=l
除值错误外:
返回
w=视图\ AskText(self.root,l.get(index))
self.root.wait_窗口(w.top)
如果w.value:
l、 删除(索引)
l、 插入(索引,w值)
定义删除(自我):
l=self.view.list
尝试:
[索引]=l
除值错误外:
返回
l、 删除(索引)
l、 选择_集(最大值(索引,l.size()-1))
def up(自我):
l=self.view.list
尝试:
[索引]=l
除值错误外:
返回
如果索引>0:
v=l.get(索引)
l、 删除(索引)
l、 插入(索引-1,v)
l、 选择_集(索引-1)
def关闭(自我):
l=self.view.list
尝试:
[索引]=l
除值错误外:
返回
如果indexI认为使用placer,您可以在列表框项目上覆盖一个条目
,并允许用户编辑其内容,这应该不会太难。尽管是一种不同的技术,但有一点相似之处我认为是有趣的。相关:。它专门讨论了第二个选项。
import tkinter
from tkinter import ttk
from tkinter import W, E
class View_EditableList(object):
def __init__(self,root,root_row):
""" List with buttons to edit its contents.
:param root: parent widget
:param roow_row: row in `root'. The section takes 2 rows.
"""
self.list = tkinter.Listbox(root, selectmode=tkinter.EXTENDED)
self.list.grid(row=root_row, sticky=(W, E))
root.rowconfigure(root_row, weight=1)
self.frame = ttk.Frame(root)
self.frame.grid(row=root_row+1, sticky=(W, E))
self.add = ttk.Button(self.frame, text="+", width=5)
self.add.grid(row=0, column=1)
self.edit = ttk.Button(self.frame, text="*", width=5)
self.edit.grid(row=0, column=2)
self.del_ = ttk.Button(self.frame, text="-", width=5)
self.del_.grid(row=0, column=3)
self.up = ttk.Button(self.frame, text=u"↑", width=5)
self.up.grid(row=0, column=4)
self.down = ttk.Button(self.frame, text=u"↓", width=5)
self.down.grid(row=0, column=5)
self.frame.grid_columnconfigure(0, weight=1)
self.frame.grid_columnconfigure(6, weight=1)
class Presenter_EditableList(object):
def __init__(self,view,root):
"""
:param view: View_EditableList
:param root: root widget to be used as parent for modal windows
"""
self.root = root
self.view = view
view.add.configure(command=self.add)
view.edit.configure(command=self.edit)
view.del_.configure(command=self.del_)
view.up.configure(command=self.up)
view.down.configure(command=self.down)
def add(self):
w=View_AskText(self.root)
self.root.wait_window(w.top)
if w.value:
self.view.list.insert(self.view.list.size(),w.value)
def edit(self):
l=self.view.list
try:
[index]=l.curselection()
except ValueError:
return
w=View_AskText(self.root,l.get(index))
self.root.wait_window(w.top)
if w.value:
l.delete(index)
l.insert(index,w.value)
def del_(self):
l=self.view.list
try:
[index]=l.curselection()
except ValueError:
return
l.delete(index)
l.select_set(max(index,l.size()-1))
def up(self):
l = self.view.list
try:
[index] = l.curselection()
except ValueError:
return
if index>0:
v = l.get(index)
l.delete(index)
l.insert(index-1,v)
l.select_set(index-1)
def down(self):
l = self.view.list
try:
[index] = l.curselection()
except ValueError:
return
if index<l.size()-1:
v = l.get(index)
l.delete(index)
l.insert(index+1,v)
l.select_set(index+1)
def getlist(self):
return [self.view.list.get(i) for i in range(self.view.list.size())]
def setlist(self,list_):
self.view.list.delete(0,tkinter.END)
for i,v in enumerate(list_):
self.view.list.insert(i,v)
# supplemental class; it's in another file in my actual code
class View_AskText(object):
"""
A simple dialog that asks for a text value.
"""
def __init__(self, master, value=u""):
self.value = None
top = self.top = tkinter.Toplevel(master)
top.grab_set()
self.l = ttk.Label(top, text=u"Value:")
self.l.pack()
self.e = ttk.Entry(top)
self.e.pack()
self.b = ttk.Button(top, text='Ok', command=self.save)
self.b.pack()
if value: self.e.insert(0, value)
self.e.focus_set()
top.bind('<Return>', self.save)
def save(self, *_):
self.value = self.e.get()
self.top.destroy()
root = tkinter.Tk()
view = View_EditableList(root, 5)
Presenter_EditableList(view, root)
root.mainloop()