0

I am trying to insert a variable named 'Variable A' from 'Class_A' class into a Listbox which is at another class named 'App(tk)'. Can anyone help me?

The result should look like this:Ideal Result.

However when using the code I have and after hitting the 'Run' button, it opens up a new window (which is identical as the main window) instead of inserting 'Variable A' into 'positive' Listbox at the existing window. Actual Result and I also receive an error: AttributeError: '_tkinter.tkapp' object has no attribute 'myListbox_01'

Here is the code:

from tkinter import *
import tkinter.messagebox as tkMessageBox
import tkinter.filedialog as tkFileDialog


class class_A(object):
    def __init__(self, isON = False):
        self.isOn = False
    def turnOn(self):
        self.isOn = True
        tkMessageBox.showinfo(title = 'On', message = 'It is on')
        x = 'favorable'
        if x == 'favorable':
            temp_App = App()
            temp_App.myListbox_01.insert(END, 'Variable A')
        else:
            temp_App.myListbox_02.insert(END, 'Variable A')

    def turnOff(self):
        self.isOn = False
        tkMessageBox.showinfo(title = 'Off', message = 'It is off')


class App(Tk):
    def __init__(self):
        Tk.__init__(self)

        def toggle():

            if button.config('text')[-1] == 'Run':
                A = class_A()
                A.turnOn()
                button.config(text='Stop')
            else:
                button.config(text='Run')

                A = class_A()
                A.turnOff()


        Frame_0 = Frame(self, bg = 'Black', borderwidth = 2, relief = GROOVE)
        Frame_0.pack(side = TOP, padx = 10, pady = 2.5)

        # Positive
        Frame_title01 = Frame(Frame_0, bg="white", height = 10, width = 300, borderwidth = 2, relief=GROOVE)
        Frame_title01.grid(row = 0, column = 0, padx=5, pady=5)
        Label(Frame_title01, text="positive").pack(padx=2, pady=2)

        Frame_01 = Frame(Frame_0, bg="white", height = 200, width = 300, borderwidth = 2, relief=GROOVE)
        Frame_01.grid(row = 1, column = 0, padx=5, pady=5)

        myListbox_01 = Listbox(Frame_01, bg = 'white', width = 15, height = 10, font = ('times', 14), borderwidth=0)
        myListbox_01.grid(row = 0, column = 0, padx = 80, pady = 5)

        # Negative
        Frame_title02 = Frame(Frame_0, bg="white", height = 10, width = 300, borderwidth = 2, relief=GROOVE)
        Frame_title02.grid(row = 0, column = 1, padx=2, pady=2)
        Label(Frame_title02, text="Negative").pack(padx=2, pady=2)

        Frame_02 = Frame(Frame_0, bg="white", height = 200, width = 300, borderwidth = 2, relief=GROOVE)
        Frame_02.grid(row = 1, column = 1, padx=5, pady=5)

        myListbox_02 = Listbox(Frame_02, bg = 'white', width = 15, height = 10, font = ('times', 14), borderwidth=0)
        myListbox_02.grid(row = 0, column = 0, padx = 80, pady = 5)

        # Button        
        Frame_1 = Frame(self, bg = 'white', borderwidth = 2, relief = FLAT)
        Frame_1.pack(side = TOP)

        button = Button(Frame_1, text = 'Run', command = toggle)
        button.pack(pady = 10)



if __name__ == "__main__":
    app = App()
    app.geometry("800x300+51+51")
    app.title("GUI")
    app.mainloop()
2
  • Can you give us a sample output and why it does not work? Is it giving you an error, not producing the correct output, or doing something else? You've given us a good code sample; please also provide some output and what the problem is. Commented Jul 10, 2016 at 22:37
  • @Alex, I have updated the post with the sample output and the problem. Commented Jul 10, 2016 at 22:56

1 Answer 1

1

You're getting a new window because your class_A instance creates a new App instance in turnOn. Probably you want to pass the existing App to the class at some point (either to the constuctor, or to turnOn itself).

Here's a quick and dirty fix. A better version would probably keep the app value in a instance variable in class_A, rather than passing it to turnOn only (you might also want your App to keep a single instance of class_A, rather than creating a new one each time the button is pressed):

class class_A(object):
    def __init__(self, isON = False):
        self.isOn = False
    def turnOn(self, app):              # new app arg!!!
        self.isOn = True
        tkMessageBox.showinfo(title = 'On', message = 'It is on')
        x = 'favorable'
        if x == 'favorable':
            app.myListbox_01.insert(END, 'Variable A')   # use new arg here
        else:
            app.myListbox_02.insert(END, 'Variable A')   # and here

    def turnOff(self):
        self.isOn = False
        tkMessageBox.showinfo(title = 'Off', message = 'It is off')

class App(Tk):
    def __init__(self):
        Tk.__init__(self)

        def toggle():

            if button.config('text')[-1] == 'Run':
                A = class_A()
                A.turnOn(self)                  # pass self as app arg!
                button.config(text='Stop')
            else:
                button.config(text='Run')

                A = class_A()
                A.turnOff()

        # ...
Sign up to request clarification or add additional context in comments.

3 Comments

Thanks. I try running your code but it gives me an error (AttributeError: '_tkinter.tkapp' object has no attribute 'myListbox_01'). Still it is unable to find the Listbox.
Hmm, that issue should have been happening in your original code too, just on the newer window rather than on the original one. You're not assigning your widgets to instance variables in App.__init__, only to local variables. Assign them to attributes on self (like self.myListbox_01) to make them instance variables.
It works! Thank you for your help and your explanations are very effective.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.