Python Forum
tkinter toggle buttons not working
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
tkinter toggle buttons not working
#21
(Jan-18-2022, 12:05 PM)deanhystad Wrote: Indentation in line 64 pushes the for loop outside the scope of the getTemp() method.
Look st your update clock method. How often is getTemp called. Think before you automatically say "Once every 5 seconds"

Thanks for setting me straight on that, I did notice that finally last night. I got the code working as wanted. I will post the code when I get home as I would really appreciate you looking over it to see if I have done things correctly. Honestly, going from VB.NET to Python has been a struggle for me.
Reply
#22
deanhystad, here is my current code. please let me know how this looks and if it looks like the correct way. Thanks

import tkinter as tk
from tkinter import *
from tkinter import messagebox
import requests
import http.client
import time
import json
   
path = ""

SONOFF_Temp  = 'http://192.168.0.113/cm?cmnd=status+10'
sonoff_url = 'NOT_INIT'


class RelayButton(tk.Button):
    """A button that toggles a relay"""
    def __init__(self, parent, url="", on_image=None, off_image=None, **kwargs):
        super().__init__(parent, image=off_image, command=self.toggle)
        self.url = url
        self._on = False
        self.on_image = on_image
        self.off_image = off_image
        self.label = Label(text="", fg="Black", font=("Helvetica", 12))
        self.label.place(x=10,y=15)
        self.update_clock()
        self.templabel = Label(text="temp info", fg="Black", font=("Helvetica", 12))
        self.templabel.place(x=10, y=40)
        self.getTemp()
        #self.master.configure(background='white')  <<< Frame Color
        
    @property
    def on(self):
        """Return state of the relay"""
        return self._on
   
    @on.setter
    def on(self, on):
        """Set state of the relay"""
        self._on = on

        if on:
            requests.post(f"{self.url}cm?cmnd=Power On")
            self["image"] = self.on_image
        else:
            requests.post(f"{self.url}cm?cmnd=Power Off")
            self["image"] = self.off_image
    
    def toggle(self):
        """Toggle state of the relay"""
        self.on = not self.on
        
    def update_clock(self):
        now = time.strftime("%I:%M:%S %p " + ' - ' + "%x")
        self.label.configure(text='Time/Date:  ' + now)
        self.after(1000, self.update_clock)
        
    def getTemp(self):
        sonoff_url = SONOFF_Temp
        sonR1 = requests.get(sonoff_url)
        x = json.loads(sonR1.text)
        status = x["StatusSNS"]
        timestamp = status["Time"]
        device_names = list(status.keys())[1:-1]
        temp_units = status["TempUnit"]
        
        for name in device_names:
            device = status[name]
            #print(f'ID={name}, Temperature={device["Temperature"]} {temp_units}')
            self.templabel.configure(text='Living Room '+f'Temperature={device["Temperature"]} {temp_units}')
            self.after(5000, self.getTemp)
            
   
def new_button(name, url, parent, row, column, **kwargs):
    """Convenience functon that creates a RelayButton"""
    on_image = tk.PhotoImage(file=f"{path}{name}_on.png")
    off_image = tk.PhotoImage(file=f"{path}{name}_off.png")
    button = RelayButton(parent, url, on_image, off_image, **kwargs)
    button.grid(row=row, column=column, padx=50, pady=110)
    return button


   
def main():
    app = tk.Tk()
    app.title('Home Relay Controls')
    buttons = [
        new_button('living', "http://192.168.0.101/", app, 0, 0),
        new_button('front_porch', "http://192.168.0.113/", app, 0, 1)
    ]
    
    for b in buttons:
        b.on = False
    app.mainloop()
    
    
if __name__ == "__main__":
    main()
Reply
#23
When you make a widget you need to specify the parent window. That is not done here:
self.label = Label(text="", fg="Black", font=("Helvetica", 12))
and a few other places. This is probably why you earlier reported some problems with labels not appearing in your windows.

You should not be polluting the namespace by using a wildcard import (from tkinter import *). You can get away with this in toy programs, but it is a bad practice and will cause very confusing and hard to debug problems in larger programs.

RelayButton is a Button. It should act like a button and it should look like a button. It should not be updating a label to show clock time. It should not be updating a label to show the temperature.
Reply
#24
(Jan-20-2022, 05:27 PM)deanhystad Wrote: When you make a widget you need to specify the parent window. That is not done here:
self.label = Label(text="", fg="Black", font=("Helvetica", 12))
and a few other places. This is probably why you earlier reported some problems with labels not appearing in your windows.

You should not be polluting the namespace by using a wildcard import (from tkinter import *). You can get away with this in toy programs, but it is a bad practice and will cause very confusing and hard to debug problems in larger programs.

RelayButton is a Button. It should act like a button and it should look like a button. It should not be updating a label to show clock time. It should not be updating a label to show the temperature.

Thanks deanhystad, can you show me how/where I should properly be doing this?
Reply
#25
No. Do this on your own.

Try writing the program without the buttons and the relays. Make a label that displays the time and another that displays the temperature. Make a function that updates the labels. Call the function periodically using afer. Once you have the program working think about how you could add in some buttons that will open/close relays.
Reply
#26
(Jan-20-2022, 06:04 PM)deanhystad Wrote: No. Do this on your own.

Try writing the program without the buttons and the relays. Make a label that displays the time and another that displays the temperature. Make a function that updates the labels. Call the function periodically using afer. Once you have the program working think about how you could add in some buttons that will open/close relays.

Ok, well stated... I will take on the challenge and report back. Thanks for helping me on this deanhystad
Reply
#27
ok deanhystad, here is my newest code that I slapped together... it is messy and I know that already. It does work, and it does tell me what the current state is of the relay and starts the window with button state ON or OFF based on the status.

from tkinter import *
from tkinter import messagebox
import requests
import time
import os
import json

ws = Tk() 
ws.title('Relay Control')
ws.geometry("600x400")
ws.configure(background='white')

on = PhotoImage(file = "frPorch_on.png")
off = PhotoImage(file = "frPorch_off.png")


shelly01  = 'http://shelly1-483fda82683f/status'
shURL = 'NOT_INIT'


shURL = shelly01
sh01 = requests.get(shURL)
x = json.loads(sh01.text)
status = x["relays"]
a = status
is_on = a[0]['ison']
print(is_on)

  
def Switch():
    global is_on

    
    if is_on:
        button.config(image = off)
        label.config(text = "Switch is Off", fg = "grey", bg='white')
        requests.post('http://shelly1-483fda82683f/relay/0/?turn=off')
        is_on = False
        
    else:
        
        button.config(image = on)
        label.config(text = "Switch is On", fg = "green", bg='white')
        requests.post('http://shelly1-483fda82683f/relay/0/?turn=on')
        is_on = True



if is_on == True:
    button = Button(ws, image = on, bg='white', bd = 0, command = Switch)
    button.pack(pady = 30)
    label = Label(ws, text = "The Switch Is On!", bg='white', fg = "green", font = ("Helvetica", 32)) 
    label.pack(pady = 20)
else:
    button = Button(ws, image = off, bg='white', bd = 0, command = Switch)
    button.pack(pady = 30)
    label = Label(ws, text = "The Switch Is Off!", bg='white', fg = "grey", font = ("Helvetica", 32)) 
    label.pack(pady = 20)


ws.mainloop()
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Using Tkinter inside function not working Ensaimadeta 5 4,864 Dec-03-2023, 01:50 PM
Last Post: deanhystad
  [Tkinter] Radio Buttons Working Bassackwards gw1500se 6 2,256 Dec-07-2021, 07:13 PM
Last Post: menator01
  [Tkinter] Have tkinter button toggle on and off a continuously running function AnotherSam 5 4,920 Oct-01-2021, 05:00 PM
Last Post: Yoriz
  TkInter Binding Buttons ifigazsi 5 4,169 Apr-06-2020, 08:30 AM
Last Post: ifigazsi
  python file(.py) not working with my tkinter project DeanAseraf1 9 6,996 Mar-22-2020, 10:58 PM
Last Post: ifigazsi
  Tkinter scaling windows conten to or with its size not working Detzi 5 4,361 Jan-12-2020, 12:42 PM
Last Post: Detzi
  Issue on tkinter with buttons Reldaing 1 2,417 Jan-07-2020, 08:21 AM
Last Post: berckut72
  Need tkinter help with clicking buttons pythonprogrammer 2 2,402 Jan-03-2020, 04:43 AM
Last Post: joe_momma
  [Tkinter] Mouse click event not working on multiple tkinter window evrydaywannabe 2 3,715 Dec-16-2019, 04:47 AM
Last Post: woooee
  Tkinter Buttons action d3fi 1 1,979 Nov-20-2019, 09:16 PM
Last Post: Larz60+

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020