Tkinter change widgets in a class from external function?
- Make
check_five
,check_two
,check_one
andcheck_toggle
methods ofMyApp
. - Define
self.log = Tk.Text
inMyApp.__init__
. That way, othermethods inMyApp
can referenceself.log
. - In the
if __name__ == "__main__":
part of the script, useapp.check_five
instead ofcheck_five
to referenceapp
'scheck_five
method. And similarly for the othercheck_*
methods.
import Tkinter as Tkimport timeimport RPi.GPIO as GPIOGPIO.setmode(GPIO.BCM)# setup 5 output pinGPIO.setup(11, GPIO.OUT)# setup 2 output pinGPIO.setup(14, GPIO.OUT)# setup 1 output pinGPIO.setup(15, GPIO.OUT)# set low output states on startGPIO.output(11, GPIO.LOW)GPIO.output(14, GPIO.LOW)GPIO.output(15, GPIO.LOW)# setup 5 input pinGPIO.setup(25, GPIO.IN, pull_up_down = GPIO.PUD_DOWN)# setup 2 input pinGPIO.setup(24, GPIO.IN, pull_up_down = GPIO.PUD_DOWN)# setup 1 input pinGPIO.setup(23, GPIO.IN, pull_up_down = GPIO.PUD_DOWN)# setup window toggle pinGPIO.setup(22, GPIO.IN, pull_up_down = GPIO.PUD_DOWN)# out functions light certain led a number of times def fiveTimes_out(): #1 GPIO.output(11, GPIO.HIGH) time.sleep(0.200) GPIO.output(11, GPIO.LOW) time.sleep(0.200) #2 GPIO.output(11, GPIO.HIGH) time.sleep(0.200) GPIO.output(11, GPIO.LOW) time.sleep(0.200) #3 GPIO.output(11, GPIO.HIGH) time.sleep(0.200) GPIO.output(11, GPIO.LOW) time.sleep(0.200) #4 GPIO.output(11, GPIO.HIGH) time.sleep(0.200) GPIO.output(11, GPIO.LOW) time.sleep(0.200) #5 GPIO.output(11, GPIO.HIGH) time.sleep(0.200) GPIO.output(11, GPIO.LOW) time.sleep(0.200)def twoTimes_out(): #1 GPIO.output(14, GPIO.HIGH) time.sleep(0.200) GPIO.output(14, GPIO.LOW) time.sleep(0.200) #2 GPIO.output(14, GPIO.HIGH) time.sleep(0.200) GPIO.output(14, GPIO.LOW) time.sleep(0.200) def oneTimes_out(): #1 GPIO.output(15, GPIO.HIGH) time.sleep(0.200) GPIO.output(15, GPIO.LOW) time.sleep(0.200)########################################################################class OtherFrame(Tk.Toplevel): """""" #---------------------------------------------------------------------- def __init__(self): """Constructor""" Tk.Toplevel.__init__(self) self.geometry("640x480+0+0") self.configure(background = 'yellow') self.title("otherFrame")########################################################################class MyApp(object): """""" #---------------------------------------------------------------------- def __init__(self, parent): """Constructor""" self.root = parent self.root.title("Main frame") self.frame = Tk.Frame(parent) self.frame.pack() btn = Tk.Button(self.frame, text = "Other Window", command = self.openFrame) btn.pack() btn2 = Tk.Button(self.frame, text = "Function test", command = twoTimes_out) btn2.pack() titleLabel = Tk.Label(text = "My Label") titleLabel.place(x = 40, y = 60) insertLabel = Tk.Label(text = "Label") insertLabel.place(x = 170, y = 110) self.log = Tk.Text(state = 'normal', width = 70, height = 10, wrap = 'none') self.log.place(x = 40, y = 160) thanksLabel = Tk.Label(text = "Thank You!") thanksLabel.place(x = 70, y = 350) self.log.insert('1.0', 'here is my text to insert') #---------------------------------------------------------------------- def hide(self): """""" self.root.withdraw() #---------------------------------------------------------------------- def openFrame(self): """""" self.hide() subFrame = OtherFrame() handler = lambda: self.onCloseOtherFrame(subFrame) btn = Tk.Button(subFrame, text = "Close", command = handler) btn.pack() secondPageLabel = Tk.Label(text = "HI") secondPageLabel.place(x = 170, y = 110) #---------------------------------------------------------------------- def onCloseOtherFrame(self, otherFrame): """""" otherFrame.destroy() self.show() #---------------------------------------------------------------------- def show(self): """""" self.root.update() self.root.deiconify() # in functions check if buttons are pushed and run specific functions # also write messages to log def check_five(self): if (GPIO.input(25) == GPIO.HIGH): fiveTimes_out() self.log.insert('1.0', '5 button down') else: self.log.insert('1.0', '5 button up') root.after(10, self.check_five) def check_two(self): if (GPIO.input(24) == GPIO.HIGH): twoTimes_out() self.log.insert('1.0', '2 button down') else: self.log.insert('1.0', '2 button up') root.after(10, self.check_five) def check_one(self): if (GPIO.input(23) == GPIO.HIGH): oneTimes_out() self.log.insert('1.0', '1 button down') else: self.log.insert('1.0', '1 button up') root.after(10, self.check_five) # check if window toggle button is pushed # you reference self in check_toggle, so check_toggle should probably be a method. def check_toggle(self): if (GPIO.input(22) == GPIO.HIGH): self.openFrame() root.after(10, check_toggle)#----------------------------------------------------------------------if __name__ == "__main__": root = Tk.Tk() root.geometry("640x480+0+0") root.configure(background = 'red') app = MyApp(root) root.after(10, app.check_five) root.after(10, app.check_two) root.after(10, app.check_one) root.after(10, app.check_toggle) root.mainloop()
In the __init__
method of MyApp, you'll need to store log
as an instance variable (do self.log = log
) so it it will still be there after leaving __init__
. I would recommend making check_five
be a method of MyApp, in which case you can access log via self.log
. If you want to keep check_five
separate, then you can access it via something like myapp.log
, where you have previously created myapp
by doing myapp = MyApp(root)
. When running a method with after from inside MyApp, you can access it as, e.g. self.check_five
.