क्या किसी के पास कोई उदाहरण है कि टिथरर टेक्स्ट विजेट में लॉगऑन में लॉगिंग कैसे सेट करें? मैंने इसे कई ऐप्स में उपयोग किया है लेकिन लॉग फ़ाइल के अलावा लॉगिंग को निर्देशित करने का तरीका नहीं समझ सकता है।पाइथन टिंकर टेक्स्ट विजेट पर लॉगिंग
उत्तर
आप 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')
मैं यूरी के विचार पर बनाया गया है, लेकिन कुछ परिवर्तन करने की जरूरत बातें काम कर पाने के:
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
विजेट केवल पढ़ने के लिए आवश्यक है।
फोर्ड के उत्तर पर आगे बढ़ना, यहां एक स्क्रॉलिंग टेक्स्ट विजेट है जो लॉग को पूंछ करता है। 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)
फोर्ड पर भी बिल्डिंग लेकिन रंगीन टेक्स्ट जोड़ना!
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
ऊपर जवाब के अलावा: भले ही यह (यहाँ और 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
आप में से जो ** 'TclStackFree हो रही के लिए: गलत freePtr' ** त्रुटि, जवाब के ऊपर इस को हल करती है। 'Self.widget.after (0, function_to_execute) का उपयोग करके' यह सुनिश्चित करता है कि विजेट को उस थ्रेड द्वारा संशोधित किया गया है जो इससे संबंधित है। – Felix