Python 如何在tkinter中向从csv读取的表的每一行添加复选按钮?
我有一个表,其中有4列是从csv读取的,并使用tkinter显示。我想在名为“已送达”的列中每行的末尾添加一个复选按钮。然而,我没有得到一个复选按钮,而是得到了“.”。!镶框的“但是” 这是我的密码:Python 如何在tkinter中向从csv读取的表的每一行添加复选按钮?,python,python-3.x,tkinter,Python,Python 3.x,Tkinter,我有一个表,其中有4列是从csv读取的,并使用tkinter显示。我想在名为“已送达”的列中每行的末尾添加一个复选按钮。然而,我没有得到一个复选按钮,而是得到了“.”。!镶框的“但是” 这是我的密码: from tkinter import * from tkinter import ttk from ttkthemes import ThemedStyle import tkinter.font as font import csv root = Tk() root.title("A") #
from tkinter import *
from tkinter import ttk
from ttkthemes import ThemedStyle
import tkinter.font as font
import csv
root = Tk()
root.title("A") #title shown in bar
root.iconbitmap(r'C:/Users/...') #icon shown in bar
TableMargin = ttk.Frame(root)
TableMargin.grid(column=0, row=0, sticky=(N, W, E, S))
root.columnconfigure(0, weight=1)
root.rowconfigure(0, weight=1)
root.state('zoomed') #fullscreen
# Setting Theme
style = ThemedStyle(TableMargin)
style.set_theme("black")
#Heading
label = ttk.Label(TableMargin, text='Orders')
label['font'] = font.Font(size=20, weight="bold")
label.grid(row=0, sticky=(N),pady=5)
#Designing of Table
style = ttk.Style()
style.configure("Treeview.Heading", font=(None, 13))
# scrollbarx = Scrollbar(TableMargin, orient=HORIZONTAL)
# scrollbary = Scrollbar(TableMargin, orient=VERTICAL)
tree = ttk.Treeview(TableMargin, columns=("Table No.", "Order", "Time", "Served"), height=400, selectmode="extended") #, yscrollcommand=scrollbary.set, xscrollcommand=scrollbarx.set
# scrollbary.config(command=tree.yview)
# scrollbary.pack(side=RIGHT, fill=Y)
# scrollbarx.config(command=tree.xview)
# scrollbarx.pack(side=BOTTOM, fill=X)
tree.heading('Table No.', text="Table No.", anchor=W)
tree.heading('Order', text="Order", anchor=W)
tree.heading('Time', text="Time", anchor=W)
tree.heading('Served', text="Served", anchor=W)
tree.column('#0', stretch=NO, minwidth=0, width=0)
tree.column('#1', stretch=NO, minwidth=0, width=100)
tree.column('#2', stretch=NO, minwidth=0, width=600)
tree.column('#3', stretch=NO, minwidth=0, width=100)
tree.column('#4', stretch=NO, minwidth=0, width=100)
tree.grid(row=0, pady=50,padx=190,sticky=(N, E, S))
with open('C:/Users/...', encoding = "utf-8-sig") as f:
reader = csv.DictReader(f, delimiter=',')
for row in reader:
table = row['Table']
order = row['Order']
time = row['Time']
var = IntVar()
served = ttk.Checkbutton(TableMargin, text="", variable=var)
served.grid()
tree.insert("", 1, values=(table, order, time, served))
您可以使用复选框中的图像来完成此操作。首先,我使用行布局将图像置于右侧:
style.layout('cb.Treeview.Row',
[('Treeitem.row', {'sticky': 'nswe'}),
('Treeitem.image', {'side': 'right', 'sticky': 'e'})])
然后,我在每个树项目上使用标记“checked”和“unchecked”来控制复选框的图像(参见下面的代码)
我还将项目的id作为标记添加到每个项目中,以便将此标记绑定到按钮单击。当有点击时,我用identification\u列(event.x)
检查点击是否在“serviced”列中,如果是,我使用标签切换复选框的状态
以下是完整的代码:
import tkinter as tk
from tkinter import ttk
root = tk.Tk()
class CbTreeview(ttk.Treeview):
def __init__(self, master=None, **kw):
kw.setdefault('style', 'cb.Treeview')
kw.setdefault('show', 'headings') # hide column #0
ttk.Treeview.__init__(self, master, **kw)
# create checheckbox images
self._im_checked = tk.PhotoImage('checked',
data=b'GIF89a\x0e\x00\x0e\x00\xf0\x00\x00\x00\x00\x00\x00\x00\x00!\xf9\x04\x01\x00\x00\x00\x00,\x00\x00\x00\x00\x0e\x00\x0e\x00\x00\x02#\x04\x82\xa9v\xc8\xef\xdc\x83k\x9ap\xe5\xc4\x99S\x96l^\x83qZ\xd7\x8d$\xa8\xae\x99\x15Zl#\xd3\xa9"\x15\x00;',
master=self)
self._im_unchecked = tk.PhotoImage('unchecked',
data=b'GIF89a\x0e\x00\x0e\x00\xf0\x00\x00\x00\x00\x00\x00\x00\x00!\xf9\x04\x01\x00\x00\x00\x00,\x00\x00\x00\x00\x0e\x00\x0e\x00\x00\x02\x1e\x04\x82\xa9v\xc1\xdf"|i\xc2j\x19\xce\x06q\xed|\xd2\xe7\x89%yZ^J\x85\x8d\xb2\x00\x05\x00;',
master=self)
style = ttk.Style(self)
style.configure("cb.Treeview.Heading", font=(None, 13))
# put image on the right
style.layout('cb.Treeview.Row',
[('Treeitem.row', {'sticky': 'nswe'}),
('Treeitem.image', {'side': 'right', 'sticky': 'e'})])
# use tags to set the checkbox state
self.tag_configure('checked', image='checked')
self.tag_configure('unchecked', image='unchecked')
def tag_add(self, item, tags):
new_tags = tuple(self.item(item, 'tags')) + tuple(tags)
self.item(item, tags=new_tags)
def tag_remove(self, item, tag):
tags = list(self.item(item, 'tags'))
tags.remove(tag)
self.item(item, tags=tags)
def insert(self, parent, index, iid=None, **kw):
item = ttk.Treeview.insert(self, parent, index, iid, **kw)
self.tag_add(item, (item, 'unchecked'))
self.tag_bind(item, '<ButtonRelease-1>',
lambda event: self._on_click(event, item))
def _on_click(self, event, item):
"""Handle click on items."""
if self.identify_row(event.y) == item:
if self.identify_column(event.x) == '#4': # click in 'Served' column
# toggle checkbox image
if self.tag_has('checked', item):
self.tag_remove(item, 'checked')
self.tag_add(item, ('unchecked',))
else:
self.tag_remove(item, 'unchecked')
self.tag_add(item, ('checked',))
tree = CbTreeview(root, columns=("Table No.", "Order", "Time", "Served"),
height=400, selectmode="extended")
tree.heading('Table No.', text="Table No.", anchor='w')
tree.heading('Order', text="Order", anchor='w')
tree.heading('Time', text="Time", anchor='w')
tree.heading('Served', text="Served", anchor='w')
tree.column('#1', stretch='no', minwidth=0, width=100)
tree.column('#2', stretch='no', minwidth=0, width=600)
tree.column('#3', stretch='no', minwidth=0, width=100)
tree.column('#4', stretch='no', minwidth=0, width=70)
tree.pack(fill='both')
for i in range(5):
tree.insert('', 'end', values=(i, i, i))
root.mainloop()
将tkinter作为tk导入
从tkinter导入ttk
root=tk.tk()
CbTreeview类(ttk.Treeview):
def _初始功率(自,主=无,**kw):
kw.setdefault('style','cb.Treeview')
kw.setdefault('show','headers')#隐藏列#0
ttk.Treeview.\uuuu初始值\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
#创建复选框图像
self.\u im\u checked=tk.PhotoImage('checked',
10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x04\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\0\0\0\x00\0\0\0\0\\0\0\0\\0\0\0\0\\\0\\x15\x00;',
主(自我)
self.\u im\u unchecked=tk.PhotoImage('unchecked',
data=b'GIF89a\x0e\x00\x0e\x00\x00\x00\x00\x00\x00\x00!\xf9\x04\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0e\x00\x00\x00\x00\x02\x1e\x04\x82\x79\x79\x81\xcf“| i\xc2j\x19\xce\xAE\x02\x02\x02\x02\x85\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x00,
主(自我)
style=ttk.style(自)
style.configure(“cb.Treeview.Heading”,font=(无,13))
#把图像放在右边
style.layout('cb.Treeview.Row',
[('Treeitem.row',{'sticky':'nswe'}),
('Treeitem.image',{'side':'right','sticky':'e'})
#使用标记设置复选框状态
self.tag\u configure('checked',image='checked')
self.tag\u configure('unchecked',image='unchecked')
def标签添加(自身、项目、标签):
新标签=元组(self.item(item,'tags'))+元组(tags)
self.item(item,tags=new_tags)
def标签_移除(自身、项目、标签):
tags=list(self.item(item,'tags'))
标记。删除(标记)
self.item(item,tags=tags)
def插入(自身、父项、索引、iid=无,**kw):
item=ttk.Treeview.insert(自、父、索引、iid,**kw)
self.tag_add(项,(项,'unchecked'))
自标记绑定(项目“”,
lambda事件:自。\单击(事件、项目))
单击时定义(自身、事件、项目):
“”“处理单击项目。”“”
如果自识别行(事件y)=项目:
如果self.identification_列(event.x)='#4':#单击“服务”列
#切换复选框图像
如果self.tag_有('checked',项):
self.tag_移除(项目“已选中”)
self.tag_add(项,('unchecked',))
其他:
self.tag_删除(项目“未选中”)
self.tag_add(项,('checked',))
tree=CbTreeview(根,列=(“表号”,“订单”,“时间”,“送达”),
高度=400,选择mode=“扩展”)
树标题('Table No.,text=“Table No.”,anchor='w')
树标题('Order',text=“Order”,anchor=“w”)
tree.heading('Time',text=“Time”,anchor='w')
tree.heading('Served',text=“Served”,anchor='w')
tree.column('#1',stretch='no',minwidth=0,width=100)
tree.column('#2',stretch='no',minwidth=0,width=600)
tree.column('#3',stretch='no',minwidth=0,width=100)
tree.column('#4',stretch='no',minwidth=0,width=70)
tree.pack(fill='both')
对于范围(5)中的i:
插入(“”,'end',value=(i,i,i))
root.mainloop()
这是否回答了您的问题:可以在不同的列中添加多个复选框?@Jmm86否,不使用此解决方案,因为我使用项目的图像创建复选框,而项目只有一个图像。@Jmm86可以使用
tree.bbox将attk.Checkbutton
放置在给定单元格中(项目,列)
获取其坐标。图像是否已选中和未选中是内置的,还是程序员必须在Gimp中创建它们?是否有一个半选中的图像,用于当父项选中了一些但不是所有子项时检查?@wineunuchs2unix,如果您想要树形结构(不是像这里这样的表),它将更适合于查看(或使用CheckboxTreeview
from)有部分复选框的位置。在这两种情况下,复选框都是用图片制作的,但在这个答案中,我从字符串(tk.PhotoImage(…,data=)
)加载它们,以使代码更易于为任何人运行。