Tkinter window destroyed but program doesn't terminate - python

While creating a tkinter GUI application, I created a window with a button to close the program and terminate the script, but when I used it, the program did close but the script was still running in the background and I was unable to start the program again.
I have tried several different functions to close the program, but nothing has worked. Here are some of my attempts:
def Cerrar():
summary.destroy()
No = customtkinter.CTkButton(summary, text="Cerrar", command=Cerrar,width=10)
or
No = customtkinter.CTkButton(summary, text="Cerrar", command=lambda:Cerrar(),width=10)
or
No = customtkinter.CTkButton(summary, text="Cerrar", command=lambda:summary.destroy(),width=10)
here is the window im having a problem with:
def Analisis():
global resumen,cuantia,summary,refuerzo
Denom_Malla = "{}-{}".format(Malla.get(),Separacion.get())
denominacion_mallas = ["4-25","4-20","4-15","4.5-15","5-15","5.5-15",
"6-15","6.5-15","7-15","7.5-15","8-15","8.5-15",
"4-12.5","4-10","4-7.5","4.5-7.5","5-7.5","5.5-7.5",
"6-7.5","6.5-7.5","7-7.5","7.5-7.5","8-7.5","8.5-7.5"]
if Denom_Malla in denominacion_mallas:
fc = int(Fc.get())
fy_malla = int(Fy_Malla.get())
fy_barra = int(Fy_Barra.get())
mu = float(Mu.get())
H = float(h.get())
Rec = float(rec.get())
malla = Malla.get()
separacion = Separacion.get()
denom_barra = int(Denom_Barra.get())
resumen, cuantia_calculada, d, Rn, cuantia_min, cuantia_diseño, As,Sep_Barra = Calculo_Losa(fc, fy_malla, fy_barra, mu, H, Rec, malla, separacion, denom_barra)
root.destroy()
if resumen == None:
root_losas(lista_fc.index(str(fc)),lista_fy.index(str(fy_malla)),lista_fy.index(str(fy_barra)),lista_mallas.index(malla),lista_denombarra.index(str(denom_barra)),mu,H,Rec,lista_separacion.index(str(separacion)))
else:
summary = customtkinter.CTk()
summary.title("Resumen")
summary.minsize(width=300,height=150)
customtkinter.CTkLabel(summary, text="Momento Último calculado es de: {} KN-m".format(mu)).grid(row=0,column=0,columnspan=2)
customtkinter.CTkLabel(summary, text="La cuantía calculada es de: {}".format(round(cuantia_diseño,4))).grid(row=1,column=0,columnspan=2)
customtkinter.CTkLabel(summary, text="Para la losa se necesita una malla {}".format(resumen)).grid(row=2,column=0,columnspan=2)
customtkinter.CTkLabel(summary, text="Desea realizar otro análisis?").grid(row=3,column=0,columnspan=2)
customtkinter.CTkLabel(summary, text="En que tipo de refuerzo desea guardar: ").grid(row=2,column=3)
refuerzo = customtkinter.StringVar(value=lista_refuerzo[0])
refuerzo_Box = customtkinter.CTkOptionMenu(summary, variable=refuerzo, values=lista_refuerzo, width=100)
refuerzo_Box.grid(row=3,column=3,padx=15)
refuerzo_Box.configure(cursor="hand2")
Yes = customtkinter.CTkButton(summary, text="Analizar", command=lambda:Siguiente(fc,fy_malla,fy_barra,malla,denom_barra,mu,H,Rec,separacion),width=10)
Yes.grid(row=4,column=0)
Yes.configure(cursor="hand2")
Guardar = customtkinter.CTkButton(summary, text="Guardar", command=lambda:Save(fc,fy_malla,mu,1,H,Rec,d,Rn,cuantia_calculada,cuantia_min,cuantia_diseño,As,malla,separacion,denom_barra,Sep_Barra,resumen))
Guardar.grid(row=4,column=3,pady=15)
Guardar.configure(cursor="hand2")
No = customtkinter.CTkButton(summary, text="Cerrar", command=Cerrar,width=10)
No.grid(row=4,column=1)
No.configure(cursor="hand2")
summary.mainloop()
else:
tk.messagebox.showerror(title="Error Malla", message="La denominacion de la malla elegida no está registrada.")
`

Related

Unable to complete operation on element with key none

I'm practicing with an algorithm that generates a random number that the user needs, then keeps trying until it hits. But PySimpleGUI produces an error saying: Unable to complete operation on element with key None.
import randomimport PySimpleGUI as sg
class ChuteONumero:
def init(self):
self.valor_aleatorio = 0
self.valor_minimo = 1
self.valor_maximo = 100
self.tentar_novamente = True
def Iniciar(self):
# Layout
layout = [
[sg.Text('Seu chute', size=(39, 0))],
[sg.Input(size=(18, 0), key='ValorChute')],
[sg.Button('Chutar!')],
[sg.Output(size=(39, 10))]
]
# Criar uma janela
self.janela = sg.Window('Chute o numero!', Layout=layout)
self.GerarNumeroAleatorio()
try:
while True:
# Receber valores
self.evento, self.valores = self.janela.Read()
# Fazer alguma coisa com os vaalores
if self.evento == 'Chutar!':
self.valor_do_chute = self.valores['ValorChute']
while self.tentar_novamente == True:
if int(self.valor_do_chute) > self.valor_aleatorio:
print('Chute um valor mais baixo')
break
elif int(self.valor_do_chute) < self.valor_aleatorio:
print('Chute um valor mais alto!')
break
if int(self.valor_do_chute) == self.valor_aleatorio:
self.tentar_novamente = False
print('Parabéns, você acertou!')
break
except:
print('Não foi compreendido, apenas digite numeros de 1 a 100')
self.Iniciar()
def GerarNumeroAleatorio(self):
self.valor_aleatorio = random.randint(
self.valor_minimo, self.valor_maximo)
chute = ChuteONumero()
chute.Iniciar()
I expected a layout to open, but it does not open.
Revised your code ...
import random
import PySimpleGUI as sg
class ChuteONumero:
def __init__(self):
self.valor_aleatorio = 0
self.valor_minimo = 1
self.valor_maximo = 100
self.tentar_novamente = True
def Iniciar(self):
# Layout
layout = [
[sg.Text('Your kick', size=(39, 0))],
[sg.Input(size=(18, 0), key='ValorChute')],
[sg.Button('Kick!')],
[sg.Output(size=(39, 10))]
]
# Create a window
self.janela = sg.Window('Guess The Number!', layout)
self.GerarNumeroAleatorio()
while True:
# Receive amounts
evento, valores = self.janela.read()
if evento == sg.WIN_CLOSED:
break
# Do something with the values
elif evento == 'Kick!':
try:
valor_do_chute = int(valores['ValorChute'])
except ValueError:
print('Not understood, just type numbers from 1 to 100')
continue
if valor_do_chute > self.valor_aleatorio:
print('Guess a lower value')
elif valor_do_chute < self.valor_aleatorio:
print('Kick a higher value!')
if valor_do_chute == self.valor_aleatorio:
sg.popup_ok('Congratulations, you got it right!')
break
self.janela.close()
def GerarNumeroAleatorio(self):
self.valor_aleatorio = random.randint(self.valor_minimo, self.valor_maximo)
chute = ChuteONumero()
chute.Iniciar()

How to add a progress bar while executing process in tkinter?

I'm building a little app to generate a word document with several tables, since this process takes a little long to finish I'd like to add a progress bar to, make it a little less boring the wait for the user, so far I manage to make the following method:
def loading_screen(self,e,data_hold=None):
"""
Generates a progress bart to display elapset time
"""
loading = Toplevel()
loading.geometry("300x50")
#loading.overrideredirect(True)
progreso = Progressbar(loading,orient=HORIZONTAL,length=280,mode="determinate")
progreso.pack()
progreso.start(10)
#progreso.destroy()
This method is supposed to run right after the user clicks a button of the next Toplevel.
def validate_data(self):
"""
genera una venta para validar los datos ingresadados y hacer cualquier correccion
previa a la generacion de los depositos finales
"""
if self.datos:
venta = Toplevel()
venta.title("Listado de depositos por envasadora")
venta.geometry("600x300")
columnas = ["ID","Banco","Monto","Envasadora"]
self.Tree_datos = ttk.Treeview(venta,columns=columnas,show="headings")
self.Tree_datos.pack()
for i in columnas:
self.Tree_datos.heading(i,text=i)
for contact in self.datos:
self.Tree_datos.insert('', END, values=contact)
self.Tree_datos.column("ID",width=20)
#Tree_datos.column("Banco",width=100)
imprimir_depositos = Button(venta,text="Generar Depositos",command=self.generar_depositos)
imprimir_depositos.pack(fill=BOTH,side=LEFT)
editar_deposito = Button(venta,text="Editar seleccion",command=self.edit_view)
editar_deposito.pack(fill=BOTH,side=RIGHT)
imprimir_depositos.bind("<Button-1>",self.loading_screen)
#return get_focus ()
def get_focus(e):
self.valor_actualizado = self.Tree_datos.item(self.Tree_datos.focus()) ["values"]
self.Tree_datos.bind("<ButtonRelease-1>",get_focus)
else:
messagebox.showinfo(message="No hay datos que mostra por el momento",title="No hay datos!")
The command that generates the doc file is this (along with other methods that are not relevant for now I guess):
def generar_depositos(self):
documento = Document()
add_style = documento.styles ["Normal"]
font_size = add_style.font
font_size.name = "Calibri"
font_size.size = Pt(9)
table_dict = {"BPD":self.tabla_bpd,"BHD":self.tabla_bhd,"Reservas":self.tabla_reservas}
self.tabla_bhd(documento,"La Jagua","2535")
#for banco,env,deposito in datos_guardados:
#table_dict [banco] (documento,env,deposito)
# documento.add_paragraph()
self.set_doc_dimx(documento,margen_der=0.38,margen_izq=0.9,margen_sup=0.3,margen_infe=1)
sc = documento.sections
for sec in sc:
print(sc)
documento.save("depositos.docx")
So basically what I want is to display the animated progress bar while this method is running, I read about threading but I don't how to implement it on my code.

Scrapy using loops in Python

I want an activity to scrapy a web page. The part of data web is route_data.
route_data = ["javascript:mostrarFotografiaHemiciclo( '/wc/htdocs/web/img/diputados/peq/215_14.jpg', '/wc/htdocs/web', 'Batet Lamaña, Meritxell (Presidenta del Congreso de los Diputados)', 'Diputada por Barcelona', 'G.P. Socialista' ,'','');",
"javascript:mostrarFotografiaHemiciclo( '/wc/htdocs/web/img/diputados/peq/168_14.jpg', '/wc/htdocs/web', 'Rodríguez Gómez de Celis, Alfonso (Vicepresidente Primero)', 'Diputado por Sevilla', 'G.P. Socialista' ,'','');",]
I create a dictionary with empty values.
dictionary_data = {"Nombre":None, "Territorio":None, "Partido":None, "url":None}
I have to save in dictionary_data each one line:
url = /wc/htdocs/web/img/diputados/peq/215_14.jpg
Nombre = Batet Lamaña, Meritxell
Territorio = Diputada por Barcelona
Partido = G.P. Socialista
For thus, and I loop over route_data.
for i in route_data:
text = i.split(",")
nombre = text[2:4]
territorio = text[4]
partido = text[5]
But the output is:
[" 'Batet Lamaña", " Meritxell (Presidenta del Congreso de los Diputados)'"] 'Diputada por Barcelona' 'G.P. Socialista'
[" 'Rodríguez Gómez de Celis", " Alfonso (Vicepresidente Primero)'"] 'Diputado por Sevilla' 'G.P. Socialista'
How can it get put correct in dictionary?
A simple solution would be:
all_routes = []
for i in route_data:
text = re.findall("'.+?'", i)
all_routes.append(
{"Nombre": re.sub('\(.*?\)', '', text[2]).strip(),
"Territorio": text[3],
"Partido": text[-2],
"Url": text[0]})

Python tkinter - auto click on selected item from Treeview

I have a treeview widget that displays a simple list from a table.
I want to automatically highlight one of the items on the list. (this works perfectly).
Now, I want this item to automatically receive a mouse click (without any action from the user). according to the documentation, use the command Rec_list.event_generate ('<ButtonRelease-1>' .format (button-1), when = "now")
but without results.
# coding:utf-8
#version 3.x python
from tkinter import *
from tkinter.ttk import *
from tkinter import ttk
def Load_Recette_Contenu():
Load_Recette = tk.Toplevel()
Load_Recette.title("Ouvrit une recette SAF")
Load_Recette.geometry("325x178+0+0")
Load_Recette.resizable(width=False, height=False)
# Fenêtre verrouillée
Load_Recette.attributes("-toolwindow", 1)
# Supprime les boutons Réduire/Agrandir
Load_Recette.attributes("-topmost", 1)
# au premier plan
# ==================================================
# TreeView
# ==================================================
# --- Insertion Table Nom HV dans TreeView
def DisplayData():
for i in Recette_DB_BackEnd.loadRecord():
# print("Nom de la recette --> ", i[0])
Rec_list.insert('', 'end', text=i[0], values=(i[0]))
# --- Insertion Scrollbar
scrollbar_y = Scrollbar(Recette_TreView, orient='vertical') # Ascenseur Vertical
scrollbar_y.place(x=299, y=0, height=169)
Rec_list = ttk.Treeview(Recette_TreView, selectmode="browse", columns=(1), show="headings", yscrollcommand=scrollbar_y.set)
# --- En-tête
Rec_list.heading('#1', text="Recettes")
# --- Largeur Colonnes
Rec_list.column('#1', width=300, minwidth=40, stretch=OFF)
Rec_list.place(x=0, y=0, width=301, height=168)
scrollbar_y.config(command=Rec_list.yview) # Ascenseur Vertical
DisplayData()
def selectionItem(a):
# === [Sélection - Widget Treeview] ===
curItem = Rec_list.focus()
Liste = Rec_list.item(curItem)["values"]
# print("winfo_name()", Rec_list.winfo_name()) # ID widget Treeview -- Exemple : winfo_name() !treeview
# print("Liste - TreeView - Recette sélectionnée", Liste) # Affiche la sélection contenu de la liste
# print("Liste - TreeView - Colonne Nom -->", Liste[0])
# for child in Rec_list.get_children(): # Listing du contenu de la Treeview -- Exemple : ['Recette_2020.05_8_30.5_NoName']
# print(Rec_list.item(child)["values"])
# print("Rec_list.item(curItem)[","values","][0] ", Rec_list.item(curItem)["values"][0]) # Affiche Nom recette depuis Treeview -- Exemple : Recette_2020.05_8_30.5_NoName
# print("Rec_list.get_children()", Rec_list.get_children()) # iid -- Renvoie un tuple des valeurs iid des enfants de l'élément spécifié par l'argument élément. S'il est omis, vous obtenez un tuple contenant les valeurs iid des éléments de niveau supérieur. --- exemple : Rec_list.get_children() ('I001', 'I002', 'I003', 'I004')
# print("Rec_list.get_children()[0]", Rec_list.get_children()[0])
# print("Rec_list.get_children()", Rec_list.get_children([Rec_list.item(curItem)["values"][0]])) ????????????????????
z = -1
for child in Rec_list.get_children():
z = z +1
time.sleep(1)
Rec_list.update()
Rec_list.selection_set(Rec_list.get_children()[z])
# Rec_list.event_generate('<ButtonRelease-1>'.format(button-1), when="now")
Rec_list.focus_force()
Rec_list.focus_set()
Rec_list.focus(Rec_list.get_children()[z])
Rec_list.update()
# -- Identifie le type de bouton activé --
# un bouton pressé(event.type = 4)
# un bouton relaché(event.type = 5)
# un bouton pressé en mouvement(event.type = 6)
print("\ntype :", a.type)
# -- Identifie quel bouton pressé --
# clic gauche(Bouton 1): event.num = 1
# clic droit(Bouton 3): event.num = 3
print("num :", a.num)
# Load_Recette.update()
# Rec_list.event_generate('<ButtonPress-1>')
# Load_Recette.update()
# ==================================================
# Evénement Treeview
# ==================================================
# via souris
Rec_list.bind('<ButtonRelease-1>', selectionItem) # Le bouton de la souris a été relâché
how to activate a mouse click without user intervention?
Thank you for your time, have good day
Auto Selection Item
This is a slightly nonprofessional route, but using a library such as py-game can automatically click or select with the mouse, you would have to take in to account screen resolution though. You can also try to see if there is a property to auto-select, check the Tkinter reference guide for help, Link 1
i find solution
import tkinter as tk
import tkinter.ttk as ttk
import time
tree = ttk.Treeview()
for i in range(10):
iid = tree.insert('', 'end', text=i)
tree.pack()
def event_test(iid):
t['text'] = iid
print("iid", iid)
def move_bottom():
iid = tree.get_children('')[-1]
time.sleep(1)
if iid != tree.focus():
iid = tree.get_children('')[5]
tree.focus(iid)
tree.selection_set(iid)
print("iid", iid)
tree.event_add('<<Declenche>>', '<ButtonRelease-1>')
tree.after(1000, lambda: tree.event_generate('<<Declenche>>'))
tree.bind('<<Declenche>>', event_test(iid))
t = tk.Label()
t.pack()
tk.Button(text='move', command=move_bottom).pack()
tree.mainloop()
To automate the selection I found this solution: in insert for loop where the data is from a table of a database, I use 1 particular db-data as value (better an unique id). I get the iid with get_children method using the loop index. In the for I insert data into a dictionary where the key is the iid and the value is the value (unique data) form the db.
If the goal to change data in the row and send that back into the database, you can make a query selection to find the first unchanged row, and select only the unique id, unique data of this row (or use the main autoincremented rowid). Use that id for having the iid of that row, than make focus and selection with that iid. After the binding that selection to an event you can run that calling event to run your method without clicking on any row.
def calling(event):
selectedRow = tree.item(tree.focus())
datas = selectedRow['values']
var1 = datas[0]
var2 = datas[1]
yourMethod(var1, var2)
def keyGetter(val, lib):
for key, value in lib.items():
if val == value:
return key
return "key doesn't exist"
index = 0
iidLibrary = dict()
for row in rows:
tree.insert("", index, values = (row[0], row[1], row[2))
iid = tree.get_children()[index]
iidLibrary[iid] = row[3]
curs.execute(
"SELECT id_of_row FROM table WHERE something=? ORDER BY rowid ASC LIMIT 1", (variable, )
firstUnclosed = curs.fetchall()
iidActual = keyGetter(firstUnclosed[0][0], iidLibrary)
tree.focus(iidActual)
tree.selection_set(iidActual)
tree.bind('<<TreeviewSelect>>', calling)

Python - calculation of surplus

I am trying to develop an application to calculate the surplus value on the IRPJ. It consists of, if the value of the IRPJ is greater than 60k, calculate 10% over the excess of 60k, but I am not able to put the second value as a variable, it gives the following error:
l_calcirpj = Label(calc, text='O valor a ser pago de IRPJ é de: {:.2f}'.format(irpj2))
UnboundLocalError: local variable 'irpj2' referenced before assignment
Follow the code below:
from tkinter import *
# ---
calc = Tk()
calc.title('mikaelson')
calc.geometry('350x350')
# ---
l_receita = Label(text='Receita')
l_receita.place(x=15, y=15)
e_receita = Entry(calc)
e_receita.place(x=100, y=15)
# ---
def calcular():
receita = float(e_receita.get())
# ---
irpj = receita * 32 / 100
if irpj > 60000:
irpj2 = (irpj - 60000) * 10 / 100
else:
print('menor que 60k')
l_calcirpj = Label(calc, text='O valor a ser pago de IRPJ é de: {:.2f}'.format(irpj2))
l_calcirpj.place(x=15, y=60)
# ---
e_receita.delete(0, END)
bt = Button(calc, text='Calcular', command=calcular)
bt.place(x=15, y=95)
calc.mainloop()
The variable irpj2 is only created if irpj>60000. Try creating the variable and initialising it to a sensible default (e.g. 0) outside of the if statement.

Categories

Resources