我目前正在使用函数以电子表格样式格式显示pandas数据框。我希望能够根据其内容添加一些功能来格式化树视图的各个单元格,例如如果它们包含子串'X'或它们的值高于Y。
目前实施的更新功能如下:
def updateTree(self, dataframe):
'''
Updates the treeview with the data in the dataframe
parameter
'''
#Remove any nan values which may have appeared in the dataframe parameter
df = dataframe.replace(np.nan,'', regex=True)
#Currently displayed data
self.treesubsetdata = dataframe
#Remove existing items
for item in self.tree.get_children(): self.tree.delete(item)
#Recreate from scratch the columns based on the passed dataframe
self.tree.config(columns= [])
self.tree.config(columns= list(dataframe.columns))
#Ensure all columns are considered strings and write column headers
for col in dataframe.columns:
self.tree.heading(col,text=str(col))
#Get number of rows and columns in the imported script
self.rows,self.cols = dataframe.shape
#Populate data in the treeview
for row in dataframe.itertuples():
self.tree.insert('', 'end',values = tuple(row[1:]))
#Minimise first column
self.tree.column('#0',width=0)
self.tree.update()
任何人都可以确认您实际上可以在treview中编辑单个单元格吗?
如果是,是否有任何关于如何实施这一点的想法?
答案 0 :(得分:1)
无法在Treeview中设置单个单元格的样式;只有整行可以使用tag属性。
如果您只想要一个值表,那么我建议您只使用ttk.Label小部件,您可以通过多种方式进行格式化。例如:
import Tkinter as tk
import ttk
import pandas as pd
from random import randrange
PADDING = dict(padx=3, pady=3)
class GridView(tk.Frame):
def __init__(self, master=None, **kwargs):
tk.Frame.__init__(self, master, **kwargs)
self.labels = []
style = ttk.Style()
style.configure("red.TLabel", background='red')
style.configure("green.TLabel", background='green')
style.configure("header.TLabel", font = '-weight bold')
def set(self, df):
self.clear()
for col, name in enumerate(df.columns):
lbl = ttk.Label(self, text=name, style='header.TLabel')
lbl.grid(row=0, column=col, **PADDING)
self.labels.append(lbl)
for row, values in enumerate(df.itertuples(), 1):
for col, value in enumerate(values[1:]):
lbl = ttk.Label(self, text=value, style=self.get_style(value))
lbl.grid(row=row, column=col, **PADDING)
self.labels.append(lbl)
@staticmethod
def get_style(value):
if value > 70:
return "red.TLabel"
elif value < 30:
return "green.TLabel"
else:
return None
def clear(self):
for lbl in self.labels:
lbl.grid_forget()
self.labels = []
class GUI(tk.Frame):
def __init__(self, master=None, **kwargs):
tk.Frame.__init__(self, master, **kwargs)
self.table = GridView(self)
self.table.pack()
btn = ttk.Button(self, text="populate", command=self.populate)
btn.pack()
btn = ttk.Button(self, text="clear", command=self.table.clear)
btn.pack()
def populate(self):
self.table.set(new_rand_df())
def main():
root = tk.Tk()
win = GUI(root)
win.pack()
root.mainloop()
def new_rand_df():
width = 5
height = 5
return pd.DataFrame([[randrange(100) for _ in range(width)] for _ in range(height)], columns = list('abcdefghijklmnopqrstuvwxyz'[:width]))
if __name__ == '__main__':
main()
答案 1 :(得分:1)
这可以使用Gtk3中的自定义cellrenderer,例如:
import gi
gi.require_version( 'Gtk', '3.0' )
from gi.repository import Gtk, GObject
class My_CellRendererText( Gtk.CellRendererText ):
def __init__( self ):
super().__init__()
def do_render( self, cr, widget, background_area, cell_area, flags ):
cell_text = self.props.text
self.props.underline = ( "X" in cell_text )
self.props.weight = 700 if ( cell_text.isdigit() and int( cell_text ) > 3 ) else 400
return Gtk.CellRendererText.do_render( self, cr, widget, background_area, cell_area, flags )
GObject.type_register( My_CellRendererText )