2012-11-10 19 views
18

क्या किसी के पास कोई उदाहरण है कि टिथरर टेक्स्ट विजेट में लॉगऑन में लॉगिंग कैसे सेट करें? मैंने इसे कई ऐप्स में उपयोग किया है लेकिन लॉग फ़ाइल के अलावा लॉगिंग को निर्देशित करने का तरीका नहीं समझ सकता है।पाइथन टिंकर टेक्स्ट विजेट पर लॉगिंग

उत्तर

9

आप logging.Handler उपवर्ग चाहिए, जैसे:

import logging 
from Tkinter import INSERT 

class WidgetLogger(logging.Handler): 
    def __init__(self, widget): 
     logging.Handler.__init__(self) 
     self.widget = widget 

    def emit(self, record): 
     # Append message (record) to the widget 
     self.widget.insert(INSERT, record + '\n') 
6

मैं यूरी के विचार पर बनाया गया है, लेकिन कुछ परिवर्तन करने की जरूरत बातें काम कर पाने के:

import logging 
import Tkinter as tk 

class WidgetLogger(logging.Handler): 
    def __init__(self, widget): 
     logging.Handler.__init__(self) 
     self.setLevel(logging.INFO) 
     self.widget = widget 
     self.widget.config(state='disabled') 

    def emit(self, record): 
     self.widget.config(state='normal') 
     # Append message (record) to the widget 
     self.widget.insert(tk.END, self.format(record) + '\n') 
     self.widget.see(tk.END) # Scroll to the bottom 
     self.widget.config(state='disabled') 

ध्यान दें कि राज्य वापस टॉगल और 'सामान्य' से 'अक्षम' से आगे Text विजेट केवल पढ़ने के लिए आवश्यक है।

1

फोर्ड के उत्तर पर आगे बढ़ना, यहां एक स्क्रॉलिंग टेक्स्ट विजेट है जो लॉग को पूंछ करता है। logging_handler सदस्य वह है जो आप अपने लॉगर में जोड़ते हैं।

import logging 
from Tkinter import END, N, S, E, W, Scrollbar, Text 
import ttk 

class LoggingHandlerFrame(ttk.Frame): 

    class Handler(logging.Handler): 
     def __init__(self, widget): 
      logging.Handler.__init__(self) 
      self.setFormatter(logging.Formatter("%(asctime)s: %(message)s")) 
      self.widget = widget 
      self.widget.config(state='disabled') 

     def emit(self, record): 
      self.widget.config(state='normal') 
      self.widget.insert(END, self.format(record) + "\n") 
      self.widget.see(END) 
      self.widget.config(state='disabled') 

    def __init__(self, *args, **kwargs): 
     ttk.Frame.__init__(self, *args, **kwargs) 

     self.columnconfigure(0, weight=1) 
     self.columnconfigure(1, weight=0) 
     self.rowconfigure(0, weight=1) 

     self.scrollbar = Scrollbar(self) 
     self.scrollbar.grid(row=0, column=1, sticky=(N,S,E)) 

     self.text = Text(self, yscrollcommand=self.scrollbar.set) 
     self.text.grid(row=0, column=0, sticky=(N,S,E,W)) 

     self.scrollbar.config(command=self.text.yview) 

     self.logging_handler = LoggingHandlerFrame.Handler(self.text) 
0

फोर्ड पर भी बिल्डिंग लेकिन रंगीन टेक्स्ट जोड़ना!

class WidgetLogger(logging.Handler): 
    def __init__(self, widget): 
     logging.Handler.__init__(self) 
     self.setLevel(logging.DEBUG) 
     self.widget = widget 
     self.widget.config(state='disabled') 
     self.widget.tag_config("INFO", foreground="black") 
     self.widget.tag_config("DEBUG", foreground="grey") 
     self.widget.tag_config("WARNING", foreground="orange") 
     self.widget.tag_config("ERROR", foreground="red") 
     self.widget.tag_config("CRITICAL", foreground="red", underline=1) 

     self.red = self.widget.tag_configure("red", foreground="red") 
    def emit(self, record): 
     self.widget.config(state='normal') 
     # Append message (record) to the widget 
     self.widget.insert(tk.END, self.format(record) + '\n', record.levelname) 
     self.widget.see(tk.END) # Scroll to the bottom 
     self.widget.config(state='disabled') 
     self.widget.update() # Refresh the widget 
5

ऊपर जवाब के अलावा: भले ही यह (यहाँ और this other thread में भी) के लिए प्रस्तावित समाधान का एक बहुत देखते हैं, मैं इस अपने आप को काम करने के लिए काफ़ी संघर्ष कर रहा था। आखिर में मैं this text handler class by Moshe Kaplan में भाग गया, जो ScrolledText विजेट का उपयोग करता है (जो स्क्रॉलबार विधि से शायद आसान है)।

मुझे यह पता लगाने में कुछ समय लगा कि वास्तव में थ्रेडेड एप्लिकेशन में मोशी कक्षा का उपयोग कैसे किया जाए। अंत में मैंने एक न्यूनतम डेमो स्क्रिप्ट बनाई जो दिखाती है कि इसे सभी काम कैसे करें। क्योंकि यह दूसरों के लिए सहायक हो सकता है मैं इसे नीचे साझा कर रहा हूं। मेरे विशेष मामले में मैं दोनों GUI और एक टेक्स्ट फ़ाइल पर लॉग इन करना चाहता था; यदि आपको इसकी आवश्यकता नहीं है तो फ़ाइल नामलॉगिंग.बासिक कॉनफिग में विशेषता को हटा दें।

import time 
import threading 
import logging 
try: 
    import tkinter as tk # Python 3.x 
    import tkinter.scrolledtext as ScrolledText 
except ImportError: 
    import Tkinter as tk # Python 2.x 
    import ScrolledText 

class TextHandler(logging.Handler): 
    # This class allows you to log to a Tkinter Text or ScrolledText widget 
    # Adapted from Moshe Kaplan: https://gist.github.com/moshekaplan/c425f861de7bbf28ef06 

    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 emit(self, record): 
     msg = self.format(record) 
     def append(): 
      self.text.configure(state='normal') 
      self.text.insert(tk.END, msg + '\n') 
      self.text.configure(state='disabled') 
      # Autoscroll to the bottom 
      self.text.yview(tk.END) 
     # This is necessary because we can't modify the Text from other threads 
     self.text.after(0, append) 

class myGUI(tk.Frame): 

    # This class defines the graphical user interface 

    def __init__(self, parent, *args, **kwargs): 
     tk.Frame.__init__(self, parent, *args, **kwargs) 
     self.root = parent 
     self.build_gui() 

    def build_gui(self):      
     # Build GUI 
     self.root.title('TEST') 
     self.root.option_add('*tearOff', 'FALSE') 
     self.grid(column=0, row=0, sticky='ew') 
     self.grid_columnconfigure(0, weight=1, uniform='a') 
     self.grid_columnconfigure(1, weight=1, uniform='a') 
     self.grid_columnconfigure(2, weight=1, uniform='a') 
     self.grid_columnconfigure(3, weight=1, uniform='a') 

     # Add text widget to display logging info 
     st = ScrolledText.ScrolledText(self, state='disabled') 
     st.configure(font='TkFixedFont') 
     st.grid(column=0, row=1, sticky='w', columnspan=4) 

     # Create textLogger 
     text_handler = TextHandler(st) 

     # Logging configuration 
     logging.basicConfig(filename='test.log', 
      level=logging.INFO, 
      format='%(asctime)s - %(levelname)s - %(message)s')   

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

def worker(): 
    # Skeleton worker function, runs in separate thread (see below) 
    while True: 
     # Report time/date at 2-second intervals 
     time.sleep(2) 
     timeStr = time.asctime() 
     msg = 'Current time: ' + timeStr 
     logging.info(msg) 

def main(): 

    root = tk.Tk() 
    myGUI(root) 

    t1 = threading.Thread(target=worker, args=[]) 
    t1.start() 

    root.mainloop() 
    t1.join() 

main() 

Github सार ऊपर कोड यहाँ के लिए लिंक:

https://gist.github.com/bitsgalore/901d0abe4b874b483df3ddc4168754aa

+0

आप में से जो ** 'TclStackFree हो रही के लिए: गलत freePtr' ** त्रुटि, जवाब के ऊपर इस को हल करती है। 'Self.widget.after (0, function_to_execute) का उपयोग करके' यह सुनिश्चित करता है कि विजेट को उस थ्रेड द्वारा संशोधित किया गया है जो इससे संबंधित है। – Felix

संबंधित मुद्दे