-2

I am trying to run a while loop that changes the variables in my code but instead it just breaks my code. I am not sure what to do. I want X to change when I change T without the command being repeated.

import tkinter
from tkinter import *

code = Tk()

T = 1
X = 0



def printx():
    global X
    print(X);
def teez():
    global T
    T = 0;
def teeo():
    global T
    T = 1;

while T == 1:
    X = 5
else:
    X = 6

button1 = Button(code, text = "Print X", command = printx)
button1.pack()
button2 = Button(code, text = "T = 0", command = teez)
button2.pack()
button2 = Button(code, text = "T = 1", command = teeo)
button2.pack()

code.mainloop()

P.S. It is in python 3.7

PLP124
  • 9
  • 2
  • The reason it breaks your code is that it is an infinite loop. I'm not sure what you are trying to do. – khelwood Sep 12 '18 at 13:51
  • Also you need to have an `if...else` inside your while loop. Insert a break statement as well – SmitM Sep 12 '18 at 13:53
  • @khelwood I want it to change x when I change T but I don't want it to be inside the function. – PLP124 Sep 12 '18 at 13:54
  • I would step back a minute and ask why you don't want to change X inside the function? The while loop as written never lets your code get to the tkinter button definitions. – Adrian Keister Sep 12 '18 at 14:03
  • I think you are trying to do a if statement. If you can tell us what are you trying to achieve with the while loop we can help you fixing the issue – Sreeram TP Sep 12 '18 at 14:11
  • @AdrianKeister Because I'll essentially have multiple functions that essentially change "T" and use the same set of code. I didn't want to use the same if loop in every function. I thought their might be a more concise way. – PLP124 Sep 12 '18 at 17:48
  • There's a way to call a function with arguments from a button push in tkinter. That would simplify your code somewhat. Go here for the syntax: https://stackoverflow.com/questions/6920302/how-to-pass-arguments-to-a-button-command-in-tkinter#6921225. – Adrian Keister Sep 12 '18 at 18:33

1 Answers1

1

First lets correct your imports.

You do not need to import Tkinter twice and it is preferred you do not use *.

The best way to import Tkinter is like this:

import tkinter as tk

Then simply use the tk. prefix for Tkinter widgets.

Now to address your looping issue. Tkinter comes with a cool method called after(). Keep in mind the after() method uses a number to represent milliseconds so 1000 is 1 second. So in the below code we are running the check_t function 1000 times a second. You may wish to change that depending on your needs. We can use this method and a function to check the status of your variables and make the needed changes without affecting the mainloop() like a while statement will.

import tkinter as tk

root = tk.Tk()

T = 1
X = 0

def printx():
    global X
    print(X)

def teez():
    global T
    T = 0

def teeo():
    global T
    T = 1
def check_t():
    global T, X
    if T == 1:
        X = 5
        root.after(1, check_t)
    else:
        X = 6
        root.after(1, check_t)

button1 = tk.Button(root, text = "Print X", command = printx)
button1.pack()
button2 = tk.Button(root, text = "T = 0", command = teez)
button2.pack()
button2 = tk.Button(root, text = "T = 1", command = teeo)
button2.pack()

check_t()

root.mainloop()

The above code will do exactly what you are trying to do without freezing the mainloop(). That said I really don't like using lots of global statements and prefer the OOP route. The below code is a reworked version of your code that is in OOP.

import tkinter as tk

class MyApp(tk.Tk):
    def __init__(self):
        tk.Tk.__init__(self)
        self.t = 1 # changed to lower case name as UPPER case is used for constants
        self.x = 0
        tk.Button(self, text="Print X", command=self.printx).pack()
        tk.Button(self, text="T = 0", command=self.teez).pack()
        tk.Button(self, text="T = 1", command=self.teeo).pack()
        self.check_t()

    def printx(self):
        print(self.x)

    def teez(self):
        self.t = 0

    def teeo(self):
        self.t = 1

    def check_t(self):
        if self.t == 1:
            self.x = 5
            self.after(1, self.check_t)
        else:
            self.x = 6
            self.after(1, self.check_t)

MyApp().mainloop()
Mike - SMT
  • 14,784
  • 4
  • 35
  • 79