2016-04-02 35 views
0

我有一個ScrolledText小部件,其中輸出所有日誌消息。由於有很多,並且這個程序運行了幾個小時,它會被超載。限制作爲日誌工作的ScrolledText中的行數

我需要一種限制行數的方式,比如400行。

我試圖清除文字是這樣的:

self.mytext.delete(1.0, END) 

但它不會做任何事情。

我的繼承人設置:

class XStatusFrame: 

    def __init__(self, master, window): 
     self.frame = Frame(master, relief="raised", width=950) 
     self.frame.grid(row=4,column=0,sticky=(E,W),columnspan=20,rowspan=2) 

     self.clear_btn = Button(self.frame,text="Clear Log", command=lambda: self.clear_log()) 
     self.clear_btn.pack(side=TOP, anchor=W) 

     # text widget 
     self.mytext = ScrolledText(self.frame, undo=True,state="disabled", fg="white", bg="black") 
     #self.mytext = Text(self.frame, state="disabled", fg="white", bg="black") 
     self.mytext.pack(fill=X) 

     # Create textLogger 
     text_handler = TextHandler(self.mytext) 

     # Add the handler to logger 
     self.logger = logging.getLogger() 
     self.logger.addHandler(text_handler) 

    def clear_log(self): 
     self.mytext.delete(1.0, END) 



class TextHandler(logging.Handler): 

    def __init__(self, text): 
     # run the regular Handler __init__ 
     logging.Handler.__init__(self) 
     # Store a reference to the Text it will log to 
     self.text = text 

    def num_lines(self): 
     return int(self.text.index('end').split('.')[0]) - 1 

    def emit(self, record): 
     msg = self.format(record) 
     def append(): 
      self.text.configure(state='normal') 
      self.text.insert(END, "["+self.timestamp()+"]["+str(self.num_lines())+"] "+msg + '\n') 
      self.text.configure(state='disabled') 
      # Autoscroll to the bottom 
      self.text.yview(END) 
     # This is necessary because we can't modify the Text from other threads 
     self.text.after(0, append) 

     # MY Try at limiting number of lines, which doesnt work... 
     if self.num_lines() > 5: 
      self.text.delete("1.0", END) 

    def timestamp(self): 
     ts = time.time() 
     return datetime.datetime.fromtimestamp(ts).strftime('%Y-%m-%d %H:%M:%S') 

回答

1

您需要設置文本小到正常的狀態,您嘗試刪除該行之前,然後再禁用它,就像你做當你添加一行。您的clear_log功能應爲:

def clear_log(self): 
    self.mytext.configure(state='normal') 
    self.mytext.delete(1.0, END) 
    self.mytext.configure(state='disabled') 
1

下面是我通常使用和減少是相關的,並應(希望)是有用的日誌顯示的變形例。我刪除了保存/打開日誌文件的部分。如果您需要轉儲/保存日誌文件,我也可以更新部件。我不熟悉logging,所以我簡單地說明了在達到上限時刪除文本內容。

from queue import Queue, Empty 
import tkinter as tk 
from tkinter import ttk, scrolledtext as stxt 
import threading, time 

MESSAGES = Queue() 
UPPER_BOUND = 400 

#Just to randomly have some data so you can see deleting etc 
for i in range(10000): 
    MESSAGES.put(i) 

class Log(tk.Frame): 

    def __init__(self, master): 

     tk.Frame.__init__(self, master) 
     self.log = stxt.ScrolledText(self, bg="black", fg="green2") 
     self.log.pack(side=tk.TOP, fill=tk.BOTH, expand=1) 
     thread = threading.Thread(target=self.update) 
     thread.daemon = 1 
     thread.start() 

    def check_range(self): 

     if float(self.log.index("end-1c")) == UPPER_BOUND: 
      self.log.delete("1.0", "end-1c") 
      #sleep to pause so you can see it did indeed delete 
      time.sleep(5) 

    def update(self): 

     #I change states here since you typically want it to be read only 
     try: 
      self.log['state'] = 'normal' 
      while True: 
       self.check_range() 
       data = MESSAGES.get_nowait() 
       if not isinstance(data, str): 
        data = str(data) 
       self.log.insert(tk.END, data+"\n") 
       self.log.see(tk.END) 
       self.update_idletasks() 
     except Empty: 
      self.log['state'] = 'disabled' 
     self.after(100, self.update) 

if __name__ == "__main__": 

    root = tk.Tk() 
    log = Log(root) 
    log.pack(fill=tk.BOTH, side=tk.TOP, expand=1) 
    root.mainloop() 

另外,您可以使用位於另一行計數方法here