![]() |
Multi windows in tkinter buttons not responding correctly - Printable Version +- Python Forum (https://python-forum.io) +-- Forum: Python Coding (https://python-forum.io/forum-7.html) +--- Forum: GUI (https://python-forum.io/forum-10.html) +--- Thread: Multi windows in tkinter buttons not responding correctly (/thread-3826.html) Pages:
1
2
|
Multi windows in tkinter buttons not responding correctly - curtjohn86 - Jun-28-2017 My apologies I am new to forums and new to coding, I am sure I'm doing everything completely backwards. I am trying to use my RPI 3b for home automation. I am using Python 3 and tkinter as a GUI. I have reduced my program drastically to try and assist in easier troubleshooting, currently only showing different page and only one button under "main level" page. Recently I only had one tkinter window with many buttons to toggle pins on my IO pi plus, at this point everything worked well. Just this week I switched over to multiple pages to give it a smoother appearance. The problem I am encountering currently is my GUI buttons do not show indication of the pins state of which they are toggling, on or off. The error I get is " ToggleButton1["text"] = ("Fireplace On") NameError: name 'toggleButton1' is not defined " I am assuming this has something to do with classes (which I'm currently trying to comprehend) or even placement. FYI if you try to run program you will need to change to gpio rather than looking for i2c bus. Thank you in advance for any insight you may have resolve my issue import logging import datetime import tkinter from queue import Queue from ABE_helpers import ABEHelpers from ABE_IoPi import IoPi import RPi.GPIO as GPIO import time from time import sleep, localtime, strftime import http.client, urllib from tkinter import* import tkinter as tk import io import base64 from urllib.request import urlopen import math import threading import _thread import os from tkinter import font as tkfont GPIO.setwarnings(False) GPIO.setmode(GPIO.BOARD) pinList = [29, 31, 33, 35, 37, 32, 36, 38, 40] for i in pinList: GPIO.setup(i, GPIO.OUT) GPIO.output(i, GPIO.HIGH) class SampleApp(tk.Tk): def __init__(self, *args, **kwargs): tk.Tk.__init__(self, *args, **kwargs) self.title_font = tkfont.Font(family='Helvetica', size=18, weight="bold", slant="italic") self.title_font2 = tkfont.Font(family='Helvetica', size=10, weight="bold") self.title_font3 = tkfont.Font(family='Helvetica', size=12, weight="bold") self.title_font4 = tkfont.Font(family='Helvetica', size=10, weight="bold") container = tk.Frame(self) container.pack(side="top", fill="both", expand=True) container.grid_rowconfigure(0, weight=1) container.grid_columnconfigure(0, weight=1) self.frames = {} for F in (StartPage, Mainfloor, Upstairs, Basement, Yard): page_name = F.__name__ frame = F(parent=container, controller=self) self.frames[page_name] = frame frame.grid(row=0, column=0, sticky="nsew") self.show_frame("StartPage") def show_frame(self, page_name): '''Show a frame for the given page name''' frame = self.frames[page_name] frame.tkraise() ##################################### #Fireplace class Fireplace(): def __init__(self): if (bus1.read_pin(15) == 1): bus1.write_pin(15, 0) toggleButton1["text"] = ("Fireplace On") else: bus1.write_pin(15, 1) toggleButton1["text"] = ("Fireplace Off") #################################### class StartPage(tk.Frame): def __init__(self, parent, controller): tk.Frame.__init__(self, parent) self.controller = controller controller.attributes('-zoomed', True) label2 = tk.Label(self, text= "Select a Page to View", font=controller.title_font4) label2.place(x=290, y=60) button1 = tk.Button(self, text="Main Floor", width=15, height=5, font=controller.title_font2, bg= 'white', command=lambda: controller.show_frame("Mainfloor")) button2 = tk.Button(self, text="Upstairs", width=15, height=5, font=controller.title_font2, bg= 'white', command=lambda: controller.show_frame("Upstairs")) button3 = tk.Button(self, text="Basement", width=15, height=5, font=controller.title_font2, bg= 'white', command=lambda: controller.show_frame("Basement")) button4 = tk.Button(self, text="Yard Lighting", width=15, height=5, font=controller.title_font2, bg= 'white', command=lambda: controller.show_frame("Yard")) button1.place(x=200, y=100) button2.place(x=200, y=200) button3.place(x=400, y=100) button4.place(x=400, y=200) class Mainfloor(tk.Frame): def __init__(self, parent, controller): tk.Frame.__init__(self, parent) self.controller = controller label = tk.Label(self, text="Main Floor View", font=controller.title_font) label.pack(side="top", fill="x", pady=10) button0 = tk.Button(self, text="Home Page", width=15, font=controller.title_font2, bg= 'white', command=lambda: controller.show_frame("StartPage")) button1 = tk.Button(self, text="Main Floor", width=15, font=controller.title_font2, bg= 'black', fg= 'yellow', command=lambda: controller.show_frame("Mainfloor")) button2 = tk.Button(self, text="Upstairs", width=15, font=controller.title_font2, bg= 'white', command=lambda: controller.show_frame("Upstairs")) button3 = tk.Button(self, text="Basement", width=15, font=controller.title_font2, bg= 'white', command=lambda: controller.show_frame("Basement")) button4 = tk.Button(self, text="Yard Lighting", width=15, font=controller.title_font2, bg= 'white', command=lambda: controller.show_frame("Yard")) ##############fireplace button toggleButton1 = Button(self, text=("Fireplace"), width=7, height=3, bg= 'white', font=controller.title_font3, relief="raised", command=Fireplace) button0.place(x=5, y=105) button1.place(x=5, y=135) button2.place(x=5, y=165) button3.place(x=5, y=195) button4.place(x=5, y=225) toggleButton1.place(x=355,y=140) class Upstairs(tk.Frame): def __init__(self, parent, controller): tk.Frame.__init__(self, parent) self.controller = controller label = tk.Label(self, text="Upstairs View", font=controller.title_font) label.pack(side="top", fill="x", pady=10) button0 = tk.Button(self, text="Home Page", width=15, font=controller.title_font2, bg= 'white', command=lambda: controller.show_frame("StartPage")) button1 = tk.Button(self, text="Main Floor", width=15, font=controller.title_font2, bg= 'white', command=lambda: controller.show_frame("Mainfloor")) button2 = tk.Button(self, text="Upstairs", width=15, font=controller.title_font2, bg= 'black', fg= 'yellow', command=lambda: controller.show_frame("Upstairs")) button3 = tk.Button(self, text="Basement", width=15, font=controller.title_font2, bg= 'white', command=lambda: controller.show_frame("Basement")) button4 = tk.Button(self, text="Yard Lighting", width=15, font=controller.title_font2, bg= 'white', command=lambda: controller.show_frame("Yard")) button0.place(x=5, y=105) button1.place(x=5, y=135) button2.place(x=5, y=165) button3.place(x=5, y=195) button4.place(x=5, y=225) class Basement(tk.Frame): def __init__(self, parent, controller): tk.Frame.__init__(self, parent) self.controller = controller label = tk.Label(self, text="Basement View", font=controller.title_font) label.pack(side="top", fill="x", pady=10) button0 = tk.Button(self, text="Home Page", width=15, font=controller.title_font2, bg= 'white', command=lambda: controller.show_frame("StartPage")) button1 = tk.Button(self, text="Main Floor", width=15, font=controller.title_font2, bg= 'white', command=lambda: controller.show_frame("Mainfloor")) button2 = tk.Button(self, text="Upstairs", width=15, font=controller.title_font2, bg= 'white', command=lambda: controller.show_frame("Upstairs")) button3 = tk.Button(self, text="Basement", width=15, font=controller.title_font2, bg= 'black', fg= 'yellow', command=lambda: controller.show_frame("Basement")) button4 = tk.Button(self, text="Yard Lighting", width=15, font=controller.title_font2, bg= 'white', command=lambda: controller.show_frame("Yard")) button0.place(x=5, y=105) button1.place(x=5, y=135) button2.place(x=5, y=165) button3.place(x=5, y=195) button4.place(x=5, y=225) class Yard(tk.Frame): def __init__(self, parent, controller): tk.Frame.__init__(self, parent) self.controller = controller label = tk.Label(self, text="Yard View", font=controller.title_font) label.place(x=350, y=40) button0 = tk.Button(self, text="Home Page", width=15, font=controller.title_font2, bg= 'white', command=lambda: controller.show_frame("StartPage")) button1 = tk.Button(self, text="Main Floor", width=15, font=controller.title_font2, bg= 'white', command=lambda: controller.show_frame("Mainfloor")) button2 = tk.Button(self, text="Upstairs", width=15, font=controller.title_font2, bg= 'white', command=lambda: controller.show_frame("Upstairs")) button3 = tk.Button(self, text="Basement", width=15, font=controller.title_font2, bg= 'white', command=lambda: controller.show_frame("Basement")) button4 = tk.Button(self, text="Yard Lighting", width=15, font=controller.title_font2, bg= 'black', fg= 'yellow', command=lambda: controller.show_frame("Yard")) button0.place(x=5, y=105) button1.place(x=5, y=135) button2.place(x=5, y=165) button3.place(x=5, y=195) button4.place(x=5, y=225) if __name__ == "__main__": app = SampleApp() app.mainloop() RE: Multi windows in tkinter buttons not responding correctly - Barrowman - Jun-28-2017 I'm finding it hard to follow your code because there is no indentation within it as it's displayed here. So it may be that when you are doing ToggleButton1["text"] = ("Fireplace On")It cannot see where you have defined ToggleButton1 also I think there is a syntax error anyway. I think it should be ToggleButton1["text"] = "Fireplace On"I'm a long way from being an expert but it seems there are many errors in the code. for example in a case where you use def in this part of the code I have shown the indentation I would expect class SampleApp(tk.Tk): def __init__(self, *args, **kwargs): tk.Tk.__init__(self, *args, **kwargs) self.title_font = tkfont.Font(family='Helvetica', size=18, weight="bold", slant="italic") self.title_font2 = tkfont.Font(family='Helvetica', size=10, weight="bold") self.title_font3 = tkfont.Font(family='Helvetica', size=12, weight="bold") self.title_font4 = tkfont.Font(family='Helvetica', size=10, weight="bold")but I have no idea if the self.title_font = tkfont.Font(family='Helvetica', size=18, weight="bold", slant="italic") self.title_font2 = tkfont.Font(family='Helvetica', size=10, weight="bold") self.title_font3 = tkfont.Font(family='Helvetica', size=12, weight="bold") self.title_font4 = tkfont.Font(family='Helvetica', size=10, weight="bold")part should be indented to be part of the class itself. No doubt someone who is far more conversant with this will help. RE: Multi windows in tkinter buttons not responding correctly - curtjohn86 - Jun-28-2017 Sorry, for some reason when I copied and pasted I lost all indentations. I will try to edit it. RE: Multi windows in tkinter buttons not responding correctly - curtjohn86 - Jun-28-2017 This should be the correct indentation toggleButton1["text"] = ("Fireplace On") NameError: name 'toggleButton1' is not defined import logging import datetime import tkinter from queue import Queue from ABE_helpers import ABEHelpers from ABE_IoPi import IoPi import RPi.GPIO as GPIO import time from time import sleep, localtime, strftime import http.client, urllib from tkinter import* import tkinter as tk import io import base64 from urllib.request import urlopen import math import threading import _thread import os from tkinter import font as tkfont GPIO.setwarnings(False) GPIO.setmode(GPIO.BOARD) pinList = [29, 31, 33, 35, 37, 32, 36, 38, 40] for i in pinList: GPIO.setup(i, GPIO.OUT) GPIO.output(i, GPIO.HIGH) class SampleApp(tk.Tk): def __init__(self, *args, **kwargs): tk.Tk.__init__(self, *args, **kwargs) self.title_font = tkfont.Font(family='Helvetica', size=18, weight="bold", slant="italic") self.title_font2 = tkfont.Font(family='Helvetica', size=10, weight="bold") self.title_font3 = tkfont.Font(family='Helvetica', size=12, weight="bold") self.title_font4 = tkfont.Font(family='Helvetica', size=10, weight="bold") container = tk.Frame(self) container.pack(side="top", fill="both", expand=True) container.grid_rowconfigure(0, weight=1) container.grid_columnconfigure(0, weight=1) self.frames = {} for F in (StartPage, Mainfloor, Upstairs, Basement, Yard): page_name = F.__name__ frame = F(parent=container, controller=self) self.frames[page_name] = frame frame.grid(row=0, column=0, sticky="nsew") self.show_frame("StartPage") def show_frame(self, page_name): '''Show a frame for the given page name''' frame = self.frames[page_name] frame.tkraise() ##################################### #Fireplace class Fireplace(): def __init__(self): if (bus1.read_pin(15) == 1): bus1.write_pin(15, 0) toggleButton1["text"] = ("Fireplace On") else: bus1.write_pin(15, 1) toggleButton1["text"] = ("Fireplace Off") #################################### class StartPage(tk.Frame): def __init__(self, parent, controller): tk.Frame.__init__(self, parent) self.controller = controller controller.attributes('-zoomed', True) label2 = tk.Label(self, text= "Select a Page to View", font=controller.title_font4) label2.place(x=290, y=60) button1 = tk.Button(self, text="Main Floor", width=15, height=5, font=controller.title_font2, bg= 'white', command=lambda: controller.show_frame("Mainfloor")) button2 = tk.Button(self, text="Upstairs", width=15, height=5, font=controller.title_font2, bg= 'white', command=lambda: controller.show_frame("Upstairs")) button3 = tk.Button(self, text="Basement", width=15, height=5, font=controller.title_font2, bg= 'white', command=lambda: controller.show_frame("Basement")) button4 = tk.Button(self, text="Yard Lighting", width=15, height=5, font=controller.title_font2, bg= 'white', command=lambda: controller.show_frame("Yard")) button1.place(x=200, y=100) button2.place(x=200, y=200) button3.place(x=400, y=100) button4.place(x=400, y=200) class Mainfloor(tk.Frame): def __init__(self, parent, controller): tk.Frame.__init__(self, parent) self.controller = controller label = tk.Label(self, text="Main Floor View", font=controller.title_font) label.pack(side="top", fill="x", pady=10) button0 = tk.Button(self, text="Home Page", width=15, font=controller.title_font2, bg= 'white', command=lambda: controller.show_frame("StartPage")) button1 = tk.Button(self, text="Main Floor", width=15, font=controller.title_font2, bg= 'black', fg= 'yellow', command=lambda: controller.show_frame("Mainfloor")) button2 = tk.Button(self, text="Upstairs", width=15, font=controller.title_font2, bg= 'white', command=lambda: controller.show_frame("Upstairs")) button3 = tk.Button(self, text="Basement", width=15, font=controller.title_font2, bg= 'white', command=lambda: controller.show_frame("Basement")) button4 = tk.Button(self, text="Yard Lighting", width=15, font=controller.title_font2, bg= 'white', command=lambda: controller.show_frame("Yard")) ##############fireplace button toggleButton1 = Button(self, text=("Fireplace"), width=7, height=3, bg= 'white', font=controller.title_font3, relief="raised", command=Fireplace) button0.place(x=5, y=105) button1.place(x=5, y=135) button2.place(x=5, y=165) button3.place(x=5, y=195) button4.place(x=5, y=225) toggleButton1.place(x=355,y=140) class Upstairs(tk.Frame): def __init__(self, parent, controller): tk.Frame.__init__(self, parent) self.controller = controller label = tk.Label(self, text="Upstairs View", font=controller.title_font) label.pack(side="top", fill="x", pady=10) button0 = tk.Button(self, text="Home Page", width=15, font=controller.title_font2, bg= 'white', command=lambda: controller.show_frame("StartPage")) button1 = tk.Button(self, text="Main Floor", width=15, font=controller.title_font2, bg= 'white', command=lambda: controller.show_frame("Mainfloor")) button2 = tk.Button(self, text="Upstairs", width=15, font=controller.title_font2, bg= 'black', fg= 'yellow', command=lambda: controller.show_frame("Upstairs")) button3 = tk.Button(self, text="Basement", width=15, font=controller.title_font2, bg= 'white', command=lambda: controller.show_frame("Basement")) button4 = tk.Button(self, text="Yard Lighting", width=15, font=controller.title_font2, bg= 'white', command=lambda: controller.show_frame("Yard")) button0.place(x=5, y=105) button1.place(x=5, y=135) button2.place(x=5, y=165) button3.place(x=5, y=195) button4.place(x=5, y=225) class Basement(tk.Frame): def __init__(self, parent, controller): tk.Frame.__init__(self, parent) self.controller = controller label = tk.Label(self, text="Basement View", font=controller.title_font) label.pack(side="top", fill="x", pady=10) button0 = tk.Button(self, text="Home Page", width=15, font=controller.title_font2, bg= 'white', command=lambda: controller.show_frame("StartPage")) button1 = tk.Button(self, text="Main Floor", width=15, font=controller.title_font2, bg= 'white', command=lambda: controller.show_frame("Mainfloor")) button2 = tk.Button(self, text="Upstairs", width=15, font=controller.title_font2, bg= 'white', command=lambda: controller.show_frame("Upstairs")) button3 = tk.Button(self, text="Basement", width=15, font=controller.title_font2, bg= 'black', fg= 'yellow', command=lambda: controller.show_frame("Basement")) button4 = tk.Button(self, text="Yard Lighting", width=15, font=controller.title_font2, bg= 'white', command=lambda: controller.show_frame("Yard")) button0.place(x=5, y=105) button1.place(x=5, y=135) button2.place(x=5, y=165) button3.place(x=5, y=195) button4.place(x=5, y=225) class Yard(tk.Frame): def __init__(self, parent, controller): tk.Frame.__init__(self, parent) self.controller = controller label = tk.Label(self, text="Yard View", font=controller.title_font) label.place(x=350, y=40) button0 = tk.Button(self, text="Home Page", width=15, font=controller.title_font2, bg= 'white', command=lambda: controller.show_frame("StartPage")) button1 = tk.Button(self, text="Main Floor", width=15, font=controller.title_font2, bg= 'white', command=lambda: controller.show_frame("Mainfloor")) button2 = tk.Button(self, text="Upstairs", width=15, font=controller.title_font2, bg= 'white', command=lambda: controller.show_frame("Upstairs")) button3 = tk.Button(self, text="Basement", width=15, font=controller.title_font2, bg= 'white', command=lambda: controller.show_frame("Basement")) button4 = tk.Button(self, text="Yard Lighting", width=15, font=controller.title_font2, bg= 'black', fg= 'yellow', command=lambda: controller.show_frame("Yard")) button0.place(x=5, y=105) button1.place(x=5, y=135) button2.place(x=5, y=165) button3.place(x=5, y=195) button4.place(x=5, y=225) if __name__ == "__main__": app = SampleApp() app.mainloop() RE: Multi windows in tkinter buttons not responding correctly - Larz60+ - Jun-29-2017 My word, Please fix your indentation. You will get a more responses to your questions RE: Multi windows in tkinter buttons not responding correctly - Barrowman - Jun-29-2017 Can you post the full error message rather than what you think is the important part please? RE: Multi windows in tkinter buttons not responding correctly - curtjohn86 - Jun-30-2017 (Jun-29-2017, 09:42 PM)Barrowman Wrote: Can you post the full error message rather than what you think is the important part please? Barrowman this is the full error I am receiving, sorry i did not realize I missed some of it. Exception in Tkinter callback Traceback (most recent call last): File "/usr/lib/python3.4/tkinter/__init__.py", line 1536, in __call__ return self.func(*args) File "/home/pi/Desktop/Programs is Use/multi window attempt.py", line 77, in __init__ toggleButton1["text"] = ("Fireplace On") NameError: name 'toggleButton1' is not defined (Jun-29-2017, 01:20 AM)Larz60+ Wrote: My word, Please fix your indentation. You will get a more responses to your questions Larz60 I posted the correct indentation above your reply (Jun-28-2017, 10:39 PM)curtjohn86 Wrote: This should be the correct indentation RE: Multi windows in tkinter buttons not responding correctly - Barrowman - Jun-30-2017 I haven't been using classes myself but looking at this and other ( working ) examples of code I think you need a change: class Fireplace() def __init__(self): if (bus1.read_pin(15) == 1): bus1.write_pin(15, 0) toggleButton1["text"] = ("Fireplace On") else: bus1.write_pin(15, 1) toggleButton1["text"] = ("Fireplace Off")to this: class Fireplace@ def __init__(self): if (bus1.read_pin(15) == 1): bus1.write_pin(15, 0) Mainfloor.toggleButton1["text"] = ("Fireplace On") else:Mainfloor bus1.write_pin(15, 1) Mainfloor.toggleButton1["text"] = ("Fireplace Off")Of course I may be wrong as I usually am ![]() RE: Multi windows in tkinter buttons not responding correctly - nilamo - Jun-30-2017 (Jun-30-2017, 06:07 PM)Barrowman Wrote: I haven't been using classes myself but looking at this and other ( working ) examples of code I think you need a change: Quote:Theclass Fireplace@ class keyword starts a definition block, and like all other block structures (def, if, for), it uses a colon at the end of the line, not an @.Quote:The Mainfloor class, itself, does not have a toggleButton1, but it's instances do. So that would throw an error as you're trying to modify something that doesn't exist.Mainfloor.toggleButton1["text"] = ("Fireplace On") Nice try, though :) RE: Multi windows in tkinter buttons not responding correctly - nilamo - Jun-30-2017 toggleButton1 only exists in the MainFloor class. You're trying to change it from within the Fireplace class. A nice way to handle this would be using events or signals (something frequently done in game programming, and is how something like the physics code will do most of it's communication). But that'd be a whole lot of changes.You currently pass each object a controller object, but the Fireplace doesn't keep track of it. If you do, then you can crawl into the controller and manipulate it's frames to get to the MainFloor to do what you're trying to do. So, Fireplace would then look like this: class Fireplace(): def __init__(self, controller): self.controller = controller main_floor = self.controller.frames["MainFloor"] if (bus1.read_pin(15) == 1): bus1.write_pin(15, 0) main_floor.toggleButton1["text"] = ("Fireplace On") else: bus1.write_pin(15, 1) main_floor.toggleButton1["text"] = ("Fireplace Off") |