1
\$\begingroup\$

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()
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.