Search code examples
pythontkinterattributeerror

Python AttributeError instance has no attribute


I'm getting the following error:-

AttributeError: PageOne instance has no attribute 'scann'

I'm trying to run a bash script (runfocus). Still not being able to figure out why I'm getting this error. My code is as follow:-

class PageOne(tk.Frame):

    def __init__(self, parent, controller):

        running = False  # Global flag

        tk.Frame.__init__(self, parent)
        self.controller = controller

        button = tk.Button(self, text="Go to the start page",
                           command=lambda: controller.show_frame("StartPage"))
        strt = tk.Button(self, text="Start Scan", command=self.start)
        stp = tk.Button(self, text="Stop", command=self.stop)

        button.pack()       
        strt.pack()
        stp.pack()
        self.after(1000, self.scann)  # After 1 second, call scanning

    def scann(self):
        if running:
          sub.call(['./runfocus'], shell=True)

        self.after(1000, self.scann)

    def start(self):
        """Enable scanning by setting the global flag to True."""
        global running
        running = True

    def stop(self):
        """Stop scanning by setting the global flag to False."""
        global running
        running = False

Please provide your valuable suggestions.


Solution

  • I can't reproduce the AttributeError: PageOne instance has no attribute 'scann' error, but your script has other issues, due to that running flag. You should avoid using modifiable globals, and when you've already got a class, there's absolutely no need to use a separate global. Just create an attribute as the flag.

    Here's a runnable repaired version of your code. I've replaced the sub.call(['./runfocus'], shell=True) call with a simple print call so that we can see that start and stop behave correctly.

    import tkinter as tk
    
    class PageOne(tk.Frame):
        def __init__(self, parent, controller):
            self.running = False
    
            tk.Frame.__init__(self, parent)
            self.controller = controller
    
            button = tk.Button(self, text="Go to the start page",
                               command=lambda: controller.show_frame("StartPage"))
            strt = tk.Button(self, text="Start Scan", command=self.start)
            stp = tk.Button(self, text="Stop", command=self.stop)
    
            button.pack()
            strt.pack()
            stp.pack()
            self.after(1000, self.scann)  # After 1 second, call scanning
    
        def scann(self):
            if self.running:
                #sub.call(['./runfocus'], shell=True)
                print("calling runfocus")
    
            self.after(1000, self.scann)
    
        def start(self):
            """Enable scanning by setting the flag to True."""
            self.running = True
    
        def stop(self):
            """Stop scanning by setting the flag to False."""
            self.running = False
    
    
    root = tk.Tk()
    frame = PageOne(root, root)
    frame.pack()
    root.mainloop()