Okay, my problem goes as follows.

I've been writing a small program in python (an adventure game) which has hitherto run via the console. I'm now working on giving it a full interface, which is requiring a lot of changes to my rather simplistic/archaic structure and generally making things something of a pain.

Specifically, I've got a class called App, with an instance called app (so app = App(root) and root = Tk()). When I reference variables or functions in app in my main file I can change them fine. However, when I use functions with imported files and vice versa it doesn't work. So for example, I import other.py into my main file, and then I can't use the app.output function in any functions within other.py and I can't change app.(variable) by directly referencing it either.

Is there a way round this that's simple, or do I have to either pass & return a lot more data from each function in other (so I get the functions to return all the strings I want outputted, then print them), or just put all my functions in one file (which would make for a very convolutedly large file)?

Hopefully that makes some sense as a query, any help much appreciated!

Recommended Answers

All 5 Replies

Could you post short code example with this problem, to make it more clear what you mean?

In main.py, I've imported other.py and then define app:

class App:

    def __init__(self, master):

        frame = Frame(master)
        frame.grid()

        self.scrollbar = Scrollbar(frame)
        self.scrollbar.grid(row=1, column=2)

        self.button = Button(frame, text="QUIT", fg="red", command=frame.quit)
        self.button.grid(row=2, column=1)

        self.hi_there = Text(frame, font='Arial', yscrollcommand=self.scrollbar.set)
        self.hi_there.grid(row=1, column=1)
        self.hi_there.config(state=DISABLED)
        self.scrollbar.config(command=self.hi_there.yview)

        self.textfield = Entry(frame, font='Arial')
        self.textfield.grid(row=2, column=1)

        self.dostuff = Button(frame, text="Hello", command=self.handlermain)
        self.dostuff.grid(row=2, column=2)
        #
        # Variable assignments
        #
        self.location = 1
        self.loctype = 0 # 0 are villages or indoors, 1 are town side-streets, 2 are forests, 3 are rural, 4 are mountains, 5 are roads. These only need changing when moving from setting to setting.
        self.prelocation = 1
        self.game = 1
        self.actionfixed = 'HELP'
      **(NB snipped out a ton of game variables here for posting)**
        #
        #
        self.newgame = 1
        self.startup = 1
        self.promptype = 1

    def output (self, string):
        self.hi_there.config(state=NORMAL)
        stringy = string
        self.hi_there.insert(INSERT, stringy + "\n")
        self.hi_there.see(END)
        self.hi_there.config(state=DISABLED)
        print(string)

    def inputstuff (self, event=0, outfile=0):
        if outfile != 0:
            outfill = str(outfile)
            self.output(outfill)
        string = self.textfield.get()
        stringup = str.upper(string)
        self.output(stringup)
        return stringup

    def handlermain(self, event=0):
        if promptype == 00:
            print('WTF')
        elif promptype == 10:
            string = self.textfield.get()
            stringup = str.upper(string)
            navigationmain(stringup)
        elif promptype == 20:
            string = self.textfield.get()
            stringup = str.upper(string)
            combat(stringup)
        self.textfield.delete(0, END)


root = Tk()

app = App(root)
root.bind("<Return>", app.handlermain)

Then later in the same file, in a function outside the class, I do:

other.printstuff('Attack!')

In other.py:

    def printstuff (value):
        value = value + ' is shouted loudly!'
        app.output(value)

And get an error, whereas if I use app.output within the same file as the class it does work.
(Hopefully that helps - no idea if the formatting is working right here, sorry)

You left out the part of other.py where you import main, but if you didn't use the from main import ... form of import, you'll have to refer to main's variables, functions and classes as main.app etc. instead of just app.

I had indeed failed to import main into other - or rather, I hadn't done because I correctly reasoned that this would mess things up as the main file contained the executable mainloop stuff. Now moved the mainloop into a new file and importing main into other, so it works fine.

Thanks, all!

If you want a given portion of a file to only execute when the file is run directly and not when the file is imported, you can put the code in an if __name__ == "__main__": block. That condition is true if the file is run directly, and false if it's imported from somewhere else.

Of course moving the code into another file works too.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.