2017-03-08 101 views
7

我正在使用函數以電子表格樣式格式顯示熊貓數據框。我希望能夠添加一些功能來根據它們的內容來格式化樹視圖的各個單元,例如,如果它們包含的子字符串「X」,或者如果他們的值大於Y.在tkinter ttk treeview中格式化單個單元格/項目而不是整個行

目前較高的執行了升級功能如下:

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() 

任何人都可以確認,你可以在事實上編輯在單個單元格t檢討?

如果是,是否有任何想法如何可以實施?

+0

我不認爲這是可能的。是否有任何理由不想製作簡單的Label或Entry小部件網格? – Novel

+0

我使用自定義類來創建,顯示,添加滾動條,使用顯示數據上的綁定鍵更新和執行復雜的排序和過濾器。在這一點上,我不確定我可以重新構建框架。如果這是不可能的,我想我將不得不重新考慮功能。 – user3535074

回答

1

無法在Treeview中設置單個單元格的樣式;只有整行可以使用標籤屬性。

如果你只是想要一個值表,那麼我建議你只使用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() 
+0

在傳統的ttk中,看起來不可能做到我想要的東西。所以我接受喬納森的答案,詳細提出了一種替代解決方案。 – user3535074

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) 
+0

這可能與ttk Treeview一起使用嗎?或者我需要從頭開始使用Gtk構建GUI? – user3535074

+0

是的這個cellrenderer需要一個Gtk.Treeview。我不知道它是否也可以與ttk一起工作,但我認爲不是。 – 2017-03-19 18:16:02

相關問題