2016-04-02 90 views
0

私はすべてのログメッセージを出力するScrolledTextウィジェットを持っています。たくさんあり、このプログラムは何時間も実行されているので、過負荷になります。ログとして機能するScrolledText内の行数を制限する

私は、行数を制限する方法、たとえば400行を必要とします。

self.mytext.delete(1.0, END) 

をしかし、それは何もしません。

私はこのようなテキストをクリアしようとしました。

HERESに私のセットアップ:

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

関連する問題