Problem with variable for if statement in tkinter - python

Hy everyone, i've a problem with my script, because when i launch it for testing and press the L0 button i receive this error message:
Exception in Tkinter callback
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/tkinter/init.py", line 1705, in call
return self.func(*args)
File "nucleo.py", line 33, in spegni
value = int(previous_state.get()) UnboundLocalError: local variable 'previous_state' referenced before assignment
I show my full code:
import serial
import random
import time
from tkinter import *
from tkinter import messagebox
import os
previuos_state=0
def accendi():
if previous_state == 0:
TimeDelay = random.randrange(10,20)
time.sleep(TimeDelay)
ser.write('L1'.encode())
previous_state = 1
USER_TIME = list(ser.read(5).decode("utf8"))
if USER_TIME[0] == 'T':
USER_TIME = str(USER_TIME[1])+str(USER_TIME[2])+str(USER_TIME[3])+str(USER_TIME[4])
print(str(int(USER_TIME,16))+" ms")
else:
print("Errore in ricezione")
else:
messagebox.showwarning("Attenzione", "Spegnere led per iniziare un nuovo test")
def spegni():
if previous_state == 1:
TimeDelay = random.randrange(10,20)
time.sleep(TimeDelay)
ser.write('L0'.encode())
previous_state = 0
USER_TIME = list(ser.read(5).decode("utf8"))
if USER_TIME[0] == 'T':
USER_TIME = str(USER_TIME[1])+str(USER_TIME[2])+str(USER_TIME[3])+str(USER_TIME[4])
print(str(int(USER_TIME,16))+" ms")
else:
print("Errore in ricezione")
else:
messagebox.showwarning("Attenzione", "Accendere led per iniziare un nuovo test")
finestra=Tk()
finestra.geometry("520x230")
finestra.title("Misuratore di riflessi")
testo=Label(finestra, text="Premere il pulsante L0 se il LED è acceso\nPremere il pulsante L1 se il LED è spento\nPremere EXIT per uscire")
testo.grid(row=0, column=0, columnspan=3)
tasto1=Button(finestra, text="L0", command=spegni)
tasto1.grid(row=3, column=0)
tasto2=Button(finestra, text="L1", command=accendi)
tasto2.grid(row=3, column=2)
lista=Listbox(finestra)
lista.insert(END, "uno", "due", "tre", "quattro", "cinque", "sei", "sette", "otto")
lista.grid(row=0, column= 3, columnspan=5, rowspan=5)
tasto3=Button(finestra, text="EXIT", command=exit)
tasto3.grid(row=4, column=1)
finestra.mainloop()
I don't understand why i can't use the variable "previuous_state", in the functions.

previous state is misspelled in its initial declaration
import serial
import random
import time
from tkinter import *
from tkinter import messagebox
import os
previuos_state=0
This makes your checks at the start of your functions fail as the variable is not declared

The right code:
import serial
import random
import time
from tkinter import *
from tkinter import messagebox
import os
previous_state=0
def stampa():
print(previous_state)
def accendi():
if previous_state == 0:
TimeDelay = random.randrange(10,20)
time.sleep(TimeDelay)
ser.write('L1'.encode())
previous_state = 1
USER_TIME = list(ser.read(5).decode("utf8"))
if USER_TIME[0] == 'T':
USER_TIME = str(USER_TIME[1])+str(USER_TIME[2])+str(USER_TIME[3])+str(USER_TIME[4])
print(str(int(USER_TIME,16))+" ms")
else:
print("Errore in ricezione")
else:
messagebox.showwarning("Attenzione", "Spegnere led per iniziare un nuovo test")
def spegni():
if previous_state == 1:
TimeDelay = random.randrange(10,20)
time.sleep(TimeDelay)
ser.write('L0'.encode())
previous_state = 0
USER_TIME = list(ser.read(5).decode("utf8"))
if USER_TIME[0] == 'T':
USER_TIME = str(USER_TIME[1])+str(USER_TIME[2])+str(USER_TIME[3])+str(USER_TIME[4])
print(str(int(USER_TIME,16))+" ms")
else:
print("Errore in ricezione")
else:
messagebox.showwarning("Attenzione", "Accendere led per iniziare un nuovo test")
finestra=Tk()
finestra.geometry("520x230")
finestra.title("Misuratore di riflessi")
testo=Label(finestra, text="Premere il pulsante L0 se il LED è acceso\nPremere il pulsante L1 se il LED è spento\nPremere EXIT per uscire")
testo.grid(row=0, column=0, columnspan=3)
tasto1=Button(finestra, text="L0", command=spegni)
tasto1.grid(row=3, column=0)
tasto2=Button(finestra, text="L1", command=accendi)
tasto2.grid(row=3, column=2)
lista=Listbox(finestra)
lista.insert(END, "uno", "due", "tre", "quattro", "cinque", "sei", "sette", "otto")
lista.grid(row=0, column= 3, columnspan=5, rowspan=5)
tasto3=Button(finestra, text="EXIT", command=exit)
tasto3.grid(row=4, column=1)
tastoo=Button(finestra, text="STAMPA", command=stampa)
tastoo.grid(row=1, column=1)
finestra.mainloop()
I continue to try but i can't use the variable for the if

Related

Youtube playlist is unrecognized

Im trying to set a radio and youtube playlist player
my code works with radio and single youtube link but with playlist it says that the link is unrecognized, can somoene help?
import os
from os import path
from random import randrange
from tkinter.ttk import Combobox
import pafy
import requests
import vlc
import time
from tkinter import *
from tkinter import messagebox,PhotoImage
from bs4 import BeautifulSoup
root = Tk()
global phplay,phpause,phstop
global pausevar
pausevar = ""
phplay = PhotoImage(file=r'img/play.png')
phpause = PhotoImage(file=r'img/pause.png')
phstop = PhotoImage(file=r'img/stop.png')
frmradio = LabelFrame(root, text="Radio Player", padx=5, pady=5, highlightbackground="black", highlightthickness=2)
frmradio.grid(row=0, column=0, sticky=NW, pady=2)
def getradiolist():
var1 = open("Confs/lstradios.txt", "r").readlines()
data = []
for line in var1:
if len(line) > 1:
estacao, url, = line.split('<=>')
data.append(estacao)
return data
valradio = StringVar()
imp_radio = Combobox(frmradio, textvariable=valradio, height=10, width=47)
imp_radio['values'] = getradiolist()
imp_radio['state'] = 'readonly'
imp_radio.grid(row=1, column=0,columnspan=5, pady=2, sticky="ew")
# define VLC instance
instance = vlc.Instance('--input-repeat=-1', '--fullscreen')
# Define VLC player
player = instance.media_player_new()
instance.log_unset()
def startplayer(pausevar):
if pausevar == "sim":
pausevar=""
player.pause()
player.stop()
esta = imp_radio.get()
if len(esta)>1:
var1 = open("Confs/lstradios.txt", "r").readlines()
for line in var1:
if len(line) > 1:
if esta in line:
estacao, url, = line.split('<=>')
break
if "youtube" in estacao:
playlist = pafy.get_playlist(url)
items = playlist["items"]# getting playlist items
def loop_play():
item = items[randrange(len(items))]
i_pafy = item['pafy']
y_url = i_pafy.watchv_url
video = pafy.new(y_url)
best = video.getbest()
media = instance.media_new(best.y_url.strip()) # por testar ainda
player.set_media(media)
frmradio.config(text=str(playlist["title"]))
player.play()
loop_play()
else:
media = instance.media_new(url.strip())
player.set_media(media)
player.play()
frmradio.config(text=str("Radio Player : Playing: " + estacao))
def stopplauyer():
player.stop()
frmradio.config(text=str("Radio Player"))
def pauseplauyer():
global pausevar
pausevar = "sim"
player.pause()
frmradio.config(text=str("Radio Player : Pause!"))
Button(frmradio, width="150",height="28", text="Play", image=phplay, command=lambda pausevar=pausevar: startplayer(pausevar)).grid(row=0, column=0, sticky=N + S + E + W)
Button(frmradio, width="100",height="28", text="Pause", image=phpause, command=lambda: pauseplauyer()).grid(row=0, column=1, sticky=N + S + E + W)
Button(frmradio, width="100",height="28", text="Stop", image=phstop,command=lambda: stopplauyer()).grid(row=0, column=2, sticky=N + S + E + W)
if __name__ == '__main__':
root.mainloop()
getting this error:
Exception in Tkinter callback Traceback (most recent call last):
File
"/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/tkinter/init.py",
line 1892, in call
return self.func(*args) File "/Users/ricardosimoes/PycharmProjects/OCPP/yplayer.py", line 105, in
Button(frmradio, width="150",height="28", text="Play", image=phplay, command=lambda pausevar=pausevar:
startplayer(pausevar)).grid(row=0, column=0, sticky=N + S + E + W)
File "/Users/ricardosimoes/PycharmProjects/OCPP/yplayer.py", line 70,
in startplayer
playlist = pafy.get_playlist2(url) File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/pafy/playlist.py",
line 316, in get_playlist2
return Playlist.from_url(playlist_url, basic, gdata, size, callback) File
"/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/pafy/playlist.py",
line 175, in from_url
t = cls(url, basic, gdata, size, callback) File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/pafy/playlist.py",
line 146, in init
raise ValueError(err % playlist_url) ValueError: Unrecognized playlist url:
https://www.youtube.com/playlist?list=PLr5JVJSLVg79UpgS6gdrcINWt86npzXkz
Listaradios.txt is
youtube <=> https://www.youtube.com/playlist?list=PLr5JVJSLVg79UpgS6gdrcINWt86npzXkz
Mega Hits <=> http://19553.live.streamtheworld.com:80/MEGA_HITS_SC

Python: calling function inside if statement from another File

I have an error in my program: "Taula_G3110 ()
NameError: name 'Taula_G3110' is not defined"
My question is:
I want to call a function that is inside an IF loop.This function is in another file. I have tried everything with imports:
"from Kleben_Tabelle import Taula_G3110, Taula_G3111.
import Kleben_Tabelle ", but there is no way.
Does anyone have an idea what I'm doing wrong?
Code:
from tkinter import *
from PIL import Image, ImageTk
from tkinter import ttk
from tkinter import messagebox
#from Kleben_Tabelle import *
import serial
import time
import PIL.Image
import Kleben_Tabelle
root = Tk()
root.geometry("1000x600")
# root.resizable (False,False)
root.title("Combobox")
arduino = serial.Serial("COM7", 9600)
time.sleep(0.1) # reducir el uso de la CPU.Prueba con diferentes valores (0.01 a 0.1)
def cambiar():
mes = combo.get()
if mes == "G3110":
label_resultat.configure(text=txt)
Taula_G3110()
if mes == "G3111":
label_resultat.configure(text=txt2)
Taula_G3111()
if mes == "G3112":
messagebox.showinfo("Mes", "Marzo")
def apagarLED():
arduino.write(b'4')
time.sleep(1)
def cerrarInterfaz():
# cerrar comunicación Serial
global raiz
arduino.close()
# cerrar ventana
root.destroy()
image = Image.open ('Edifici_Knauer_blau.png')
photo_image = ImageTk.PhotoImage(image)
label = Label(root, image=photo_image)
label.pack()
frame_resultat = Frame(root, width=400, height=100, relief="flat", highlightbackground="blue", highlightthickness=1)
frame_resultat.place(x=250, y=200)
label_resultat = Label(root, text="", bg="yellow", borderwidth=0, relief="groove", width=20, height=2, justify='left',
highlightbackground="blue", highlightthickness=1)
label_resultat.place(x=80, y=200)
etiqueta = Label(root, text="Zelle: Kleben")
etiqueta.place(x=100, y=40)
combo = ttk.Combobox(root, state="readonly")
combo.place(x=100, y=70)
combo["values"] = ("G3110", "G3111", "G3112", "1")
combo.current(0)
boton = Button(root, text="Cambiar mes", command=cambiar)
boton.place(x=100, y=100)
# boton de apagado del LED
btnApagar = ttk.Button(root, text="Reset", command=apagarLED)
# btnApagar = ttk.Button(raiz,text ="Reset",command = clearTextInput)
btnApagar.place(x=420, y=450)
# boton de Cerrar interfaz
btnCerrar = ttk.Button(root, text="Cerrar", command=cerrarInterfaz)
btnCerrar.place(x=420, y=480)
txt = ("G3110 Frontabdeckung")
txt2 = ("G3111 Frontabdeckung")
root.mainloop()
and this ist my other File with this Module-Function:(File: Kleben_Tabelle.py)
def Taula_G3110():
arduino.write(bytes(b'T'))
arbol = ttk.Treeview(frame_resultat,columns=("Bauteile","Regal","Lager"))
arbol.column ('#0',width=100)
arbol.column ('Bauteile',width=100)
arbol.column ('Regal',width=80)
arbol.column ('Lager',width=80)
arbol.insert("",END,text="G3110",values=("P6400","K2.0001.01","Regal 2"))
arbol.insert("",END,text="G3110",values=("P6406XA","K1.0004.01"))
arbol.insert("",END,text="G3110",values=("P6403XA","K1.0003.01"))
arbol.heading("#0",text="Model")
arbol.heading("Bauteile",text="Bauteile")
arbol.heading("Regal",text="Regal")
arbol.place(x=100,y=70)
arbol.pack()
In order to call a function in a module that you've imported, you need to reference the module and function like so:
import Kleben_Tabelle
...
def cambiar():
mes = combo.get()
if mes == "G3110":
label_resultat.configure(text=txt)
Kleben_Tabelle.Taula_G3110()

How to specify Tkinter correct label?

So, I've made some code which has 2 functions: A clock and a countdown timer (simultaneously).
But, they show each other simultaneously as well, but what I need is only one of them at a time: For this example below, while the countdown timer starts at 60 seconds and goes to 0, it has to show on the screen, and when it reaches 0, switch back to the clock.
What is currently happening is both of them showing all the time, I just need to know how to specify something like an if countdown > 0, show countdown timer... if countdown = 0, show clock
Can anybody help me?
import tkinter as tk
from tkinter import *
import time
root = Tk()
root.attributes("-fullscreen", True)
root.config(cursor="none")
display = Label(root, font=('helvetica', 180, 'bold'), bg='black', fg='white')
display.pack(fill=BOTH, expand=1)
hora = 0
tempo = 60
def clock():
global hora
hora = time.strftime('%H:%M:%S')
display['text'] = hora
root.after(100, clock)
clock()
def countdown():
global tempo
display['text'] = ('{0:02d}:{1:02d}'.format(*divmod(tempo, 60)))
if tempo > 0:
tempo = tempo - 1
root.after(1000, countdown)
countdown()
root.mainloop()
If you use a single function then you won't have to worry about it fighting itself :)
import tkinter as tk
from tkinter import *
import time
root = Tk()
root.attributes("-fullscreen", True)
root.config(cursor="none")
display = Label(root, font=('helvetica', 180, 'bold'), bg='black', fg='white')
display.pack(fill=BOTH, expand=1)
tempo = 60
def tick():
global tempo
if tempo > 0:
# countdown mode
display['text'] = ('{0:02d}:{1:02d}'.format(*divmod(tempo, 60)))
tempo = tempo - 1
else:
# clock mode
hora = time.strftime('%H:%M:%S')
display['text'] = hora
root.after(1000, tick)
tick()
root.mainloop()

Tkinter, try to keep using the program on while executing

How can I maintain the execution of my program whilst the following loop is executing?
def callback():
var=OpenHour.get()
var1=CloseHour.get()
actual = 0
if not validateDate(var, var1):
tkMessageBox.showinfo("Error","Datos o formato incorrecto, deberia ser hh:mm")
else:
while var != actual:
actual = datetime.datetime.now().time().strftime('%H:%M')
print "ya acabe voy al second while"
while var1 != actual:
actual = datetime.datetime.now().time().strftime('%H:%M')
tkMessageBox.showinfo("Exito","Se ha terminado el ciclo")
#tkMessageBox.showinfo("Exito","La programacion se ha \nrealizado de la manera correcta")
b = Button(VentanaPersiana, text="Programar", width=10, command=callback)
b.pack()
You can use root.after(miliseconds, function_name, argument) to execute function with delay and root.mainloop() (and program) will work normally.
You can use datetime to convert text to datetime object, substract two dates and get difference in milliseconds.
try:
import tkinter as tk
import tkinter.messagebox as tkMessageBox
print("Python 3")
except:
import Tkinter as tk
import tkMessageBox
print("Python 2")
from datetime import datetime as dt
# --- functions ---
def callback():
var_open = open_hour.get()
var_close = close_hour.get()
if not validateDate(var_open, var_close):
tkMessageBox.showinfo("Error", "Incorrect times")
else:
# current date and time
current = dt.now()
print('current:', current)
# convert strings to `time` object
time_open = dt.strptime(var_open, '%H:%M').time()
time_close = dt.strptime(var_close, '%H:%M').time()
print('time_open:', time_open)
print('time_close:', time_close)
# combine `current date` with `time`
today_open = dt.combine(current, time_open)
today_close = dt.combine(current, time_close)
print('today_open:', today_open)
print('today_close:', today_close)
# substract dates and get milliseconds
milliseconds_open = (today_open - current).seconds * 1000
milliseconds_close = (today_close - current).seconds * 1000
print('milliseconds_open:', milliseconds_open)
print('milliseconds_close:', milliseconds_close)
# run functions with delay
root.after(milliseconds_open, show_open_message, var_open)
root.after(milliseconds_close, show_close_message, var_close)
def validateDate(time1, time2):
# TODO: check dates
return True
def show_open_message(arg):
tkMessageBox.showinfo("Info", "Open time: " + arg)
def show_close_message(arg):
tkMessageBox.showinfo("Info", "Close time: " + arg)
# --- main ---
root = tk.Tk()
open_hour = tk.StringVar()
close_hour = tk.StringVar()
e1 = tk.Entry(root, textvariable=open_hour)
e1.pack()
e2 = tk.Entry(root, textvariable=close_hour)
e2.pack()
b = tk.Button(root, text="Start", command=callback)
b.pack()
root.mainloop()

tkinter.entry and NameErrors.

I am currently coding a GUI for a palindrome-detector but I have run into some problems. I can launch the program and the GUI appears to be fine. All buttons work except the essential one: Testa Palindrom (translates to Test Palindrome).
Whenever I click that button, I get a NameError: global name 'palindromentry' is not defined.
Below you will find the entire code but first a quick explanation of what it does.
def ordnaText lowers the text and fixes it for the check.
def testap tests whether it is a palindrome or not using a for-loop.
def visaResultat shows the result (this can be see in the label1.config).
My question is: Why am I getting this error? I cannot figure it out for the life of me.
import tkinter
import tkinter.messagebox
def main():
gui()
tkinter.mainloop()
def gui():
main_window = tkinter.Tk()
top_frame = tkinter.Frame()
mid_frame = tkinter.Frame()
bottom_frame = tkinter.Frame()
main_window.title("Palindromdetektor")
main_window.geometry("400x400")
label1 = tkinter.Label(top_frame, text = "Skriv in ett palindrom nedan för att testa det!",
bg = "green", width = 60, height = 6)
button1 = tkinter.Button(mid_frame, text = "Testa palindrom", height = 3, width = 22,
bg = "Purple", command = mainaction)
button2 = tkinter.Button(bottom_frame, text= "Instruktioner", height = 3, width = 22,
bg = "Purple", command = messagebox)
button3 = tkinter.Button(bottom_frame, text ="Spara palindrom", height = 3, width = 22,
bg = "Purple") #command = sparapalindrom)
button4 = tkinter.Button(bottom_frame, text ="Avsluta programmet", height = 3, width = 22,
bg = "Purple", command=main_window.destroy)
palindromentry = tkinter.Entry(mid_frame, width = 67)
palindromentry.pack()
top_frame.pack()
mid_frame.pack()
bottom_frame.pack()
label1.pack()
button1.pack()
button2.pack()
button3.pack()
button4.pack()
def ordnaText(text):
nytext = ("")
fixadText = text.lower()
for i in fixadText:
if i.isalnum():
nytext = (nytext + i)
return nytext
def testap(nytext):
palindrom = True
for i in range (0, len(nytext)):
if (nytext[i]) != (nytext[len(nytext)-i-1]):
palindrom = False
return palindrom
def visaResultat(palindrom):
if palindrom:
label1.config(text="Ja, detta är ett palindrom!", bg="green")
else:
label1.config(text="Nej, detta är inte ett palindrom!", bg="red")
def messagebox():
tkinter.messagebox.showinfo("Hjälp", "Detta är ett program som testar vare sig en text är ett palindrom eller inte.\n \
Skriv in din text i rutan och tryck på Testa Palindrom-knappen så får du se ditt resultat högst upp.\n \
Om du vill avsluta programmet klickar du på knappen som heter Avsluta programmet.\n \
Detta program är kodat av Olof Unge som nås via mail: olofunge#hotmail.com.\n \
Tack för att du använder detta program!")
#def sparapalindrom():
# try:
# if palindrom:
# myfile = open("palindrom.txt", "a")
# myfile.write(text\n)
# myfile.close()
# else:
# label1.config(text="Du kan bara spara godkända palindrom.")
# except IOError:
# label1.config(text="Kunde inte hitta / skapa filen.")
def mainaction():
global text
text = palindromentry.get()
ordnaText(text)
testap(ordnaText(text))
visaResultat(testap(ordnaText(text)))
main()
I would appreciate very much if you could stick to topic and not comment anything else because everything else works fine. Thank you very much!
Best regards.
THIS IS CODED IN PYTHON 3.0
palindromentry is defined in the gui function. As such, it's scope is limited to that single function. When you click the button, the mainaction function is called, but it knows nothing of the gui function's scope.
There are a few options here (in order of my preferences):
Make all of this stuff a class so that you can share the state between function calls
move the definition of mainaction into the gui function (It needs to be defined before the button which does the action ...).
declare palindromentry as global in gui

Categories