1

Good evening everybody,

I started to use Tkinter some weeks ago (so I haven't understood it really) and I'm currently working on a counter programme: it should increase the variable i by pressing a certain button and reset it with another (which then counts the number of resets). A third button shall be used to write the current counter variables to a txt file.

I first wrote it without the __init__ method, which might be not elegant, but it works:

from Tkinter import *

root = Tk()

global i, k
i = 0
k = 0

count = open('count.txt', 'w')
count.write("i   k\n")

output = Label(root, text="")
output.pack(side=RIGHT)


def nextnum():
        global i, k
        i += 1
        output.config(text="i=" + str(i) + ", k=" + str(k))


def reset():
        global i, k
        i = 0
        k += 1
        output.config(text="i=" + str(i) + ", k=" + str(k))


def write():
     count.write(str(i) + "   " + str(k) + "\n")


nextb = Button(root, text="next", command=nextnum)
nextb.pack(side=LEFT)

resetb = Button(root, text="reset i", command=reset)
resetb.pack(side=LEFT)

writeb = Button(root, text="write", command=write)
writeb.pack(side=LEFT)

root.mainloop() 

Is there any other method than using global variables? I tried to use the return command, but I have the problem, that with each press of a counter button the global dictionary is not updated. Such, I always just get the first round printed, but not the counting variable. Is there any way to get it running that way?

And what if I want to save strings in the txt file? Doing it with global variables seems to work, but again it seems unelegant.

I furthermore tried it with the __init__ method, with problems. It tells me, that my defined subfunctions are static, which seems to come from the output.config() command, but I'm not too sure on that (I think it has something to do with it, since it tells me output and count are unresolved references). It also can't do the .write() command into my txt file.

import Tkinter as Tk


class MainApp(Tk.Frame):
    def __init__(self, parent):
        Tk.Frame.__init__(self, parent)
        self.root = parent
        self.root.title("Main frame")
        self.frame = Tk.Frame(parent)
        self.frame.pack()

        global i, k
        i = 0
        k = 0

        count = open('count.txt', 'w')
        count.write("i   k\n")

        nextb = Tk.Button(self.frame, text="Next number", command=self.nextnum)
        nextb.pack()

        resetb = Tk.Button(self.frame, text="Reset i", command=self.reset)
        resetb.pack()

        writeb = Tk.Button(self.frame, text="Write to file", command=self.write)
        writeb.pack()

        output = Tk.Label(self.frame, text="i=" + str(i) + ", k=" + str(k))
        output.pack()

    def nextnum(self):
        global i
        i += 1
        output.config(text="i=" + str(i) + ", k=" + str(k))

    def reset(self):
        global i, k
        i = 0
        k += 1
        output.config(text="i=" + str(i) + ", k=" + str(k))

    def write(self):
        count.write(str(i) + "   " + str(k) + "\n")


if __name__ == "__main__":
    root = Tk.Tk()
    app = MainApp(root)
    root.mainloop() 

Can anyone tell, what is wrong here and why it won't accept the defined labels in other subfunctions? what should I do instead to update the output? Or do I need to call that label I want to change in every subfunction?

Thanks for any suggestions.

p.s.: In fact, this is just a test programme for a bigger application, where I need to give the uses a certain information, when she/he presses a Button and write data, read out from an instrument, to a file when pressing another button.

1 Answer 1

2

You need to learn about variable scope. You define output inside the __init__ method, so it is local to that method only; once that finishes, the variable is destroyed, and it isn't available from anywhere else.

But __init__ and the other methods are all part of the same class; one of the whole points of classes is that you can set instance variables. In this case, you want to assign to self.output, and reference that inside nextnum and reset.

Really, you should do the same with i and k, then you don't need any global declarations at all.

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

1 Comment

Thanks for the answer, I think I got, what you mean.

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.