I'm creating a GUI with tkinter that will handle starting/stopping/and logging events for a web-scraper (scraper not created yet).
The current code is working... but I've been gathering my information from so many different sources I'm sort of lost in the mire on how to improve it. The biggest problem right now is that I feel like the loop
and stop
functions should be removed from the class they are currently in (maybe put in a new class?) but I'm really not sure. Eventually they will be starting/stopping the scraper.
This is essentially a learning experience for me since I'm new to Python and learn best by doing (I know scrapers don't need GUIs). Any suggestions or recommendations on how I can best organize it currently to prepare for later is appreciated as well.
The TextHandler
code and comments are from what I found here.
import tkinter as tk
import tkinter.scrolledtext as tkst
from tkinter import ttk
import logging
def popupmsg(msg):
popup = tk.Tk()
popup.wm_title("!")
label = ttk.Label(popup, text=msg)
label.pack(side="top", fill="x", pady=10)
b1 = ttk.Button(popup, text="Okay", command=popup.destroy)
b1.pack()
popup.mainloop()
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 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 Menu(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
container = tk.Frame(self)
container.pack(side="top", fill="both", expand=True)
container.grid_rowconfigure(0, weight=1)
container.grid_columnconfigure(0, weight=1)
menubar = tk.Menu(container)
filemenu = tk.Menu(menubar, tearoff=0)
filemenu.add_command(label="Save settings", command=lambda: popupmsg("Not supported just yet!"))
filemenu.add_separator()
filemenu.add_command(label="Exit", command=quit)
menubar.add_cascade(label="File", menu=filemenu)
tk.Tk.config(self, menu=menubar)
class HomePage(tk.Frame):
def __init__(self, parent):
tk.Frame.__init__(self, parent)
bottomframe = tk.Frame(root)
bottomframe.pack(side=tk.BOTTOM)
topframe = tk.Frame(root)
topframe.pack(side=tk.TOP)
topframe = tk.Frame(root)
topframe.pack(side=tk.TOP)
st = tkst.ScrolledText(topframe, state='disabled')
st.configure(font='TkFixedFont')
st.pack()
# Create textLogger
text_handler = TextHandler(st)
# Add the handler to logger
logger = logging.getLogger()
logger.addHandler(text_handler)
root.flag = True
def stop():
root.flag = False
def loop():
if root.flag:
logger.error("error")
root.after(1000, loop)
else:
logger.error("Loop stopped")
root.flag = True
return
startButton = tk.Button(bottomframe, text="Start", command=loop)
startButton.pack()
stopButton = tk.Button(bottomframe, text="Stop", command=stop)
stopButton.pack()
exitButton = tk.Button(bottomframe, text="Exit", command=quit)
exitButton.pack()
if __name__ == "__main__":
root = Menu()
root.wm_title("Scraper")
HomePage(root)
root.mainloop()