Python tkinter - auto click on selected item from Treeview - python

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)

Related

Tkinter window destroyed but program doesn't terminate

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.")
`

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.

Generating a table with docx from a dataframe in python

Hellow,
Currently I´m working in a project in which I have to generate some info with docx library in python. I want to know how to generate a docx table from a dataframe in order to have the output with all the columns and rows from de dataframe I've created. Here is my code, but its not working correctly because I can´t reach the final output:
table = doc.add_table(rows = len(detalle_operaciones_total1), cols=5)
table.style = 'Table Grid'
table.rows[0].cells[0].text = 'Nombre'
table.rows[0].cells[1].text = 'Operacion Nro'
table.rows[0].cells[2].text = 'Producto'
table.rows[0].cells[3].text = 'Monto en moneda de origen'
table.rows[0].cells[4].text = 'Monto en moneda local'
for y in range(1, len(detalle_operaciones_total1)):
Nombre = str(detalle_operaciones_total1.iloc[y,0])
Operacion = str(detalle_operaciones_total1.iloc[y,1])
Producto = str(detalle_operaciones_total1.iloc[y,2])
Monto_en_MO = str(detalle_operaciones_total1.iloc[y,3])
Monto_en_ML = str(detalle_operaciones_total1.iloc[y,4])
table.rows[y].cells[0].text = Nombre
table.rows[y].cells[1].text = Operacion
table.rows[y].cells[2].text = Producto
table.rows[y].cells[3].text = Monto_en_MO
table.rows[y].cells[4].text = Monto_en_ML

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.

Unhandled exception in py2neo: Type error

I am writing an application whose purpose is to create a graph from a journal dataset. The dataset was a xml file which was parsed in order to extract leaf data. Using this list I wrote a py2neo script to create the graph. The file is attached to this message.
As the script was processed an exception was raised:
The debugged program raised the exception unhandled TypeError
"(1676 {"titulo":"reconhecimento e agrupamento de objetos de aprendizagem semelhantes"})"
File: /usr/lib/python2.7/site-packages/py2neo-1.5.1-py2.7.egg/py2neo/neo4j.py, Line: 472
I don't know how to handle this. I think that the code is syntactically correct...but...
I dont know if I shoud post the entire code here, so the code is at: https://gist.github.com/herlimenezes/6867518
There goes the code:
+++++++++++++++++++++++++++++++++++
'
#!/usr/bin/env python
#
from py2neo import neo4j, cypher
from py2neo import node, rel
# calls database service of Neo4j
#
graph_db = neo4j.GraphDatabaseService("DEFAULT_DOMAIN")
#
# following nigel small suggestion in http://stackoverflow.com
#
titulo_index = graph_db.get_or_create_index(neo4j.Node, "titulo")
autores_index = graph_db.get_or_create_index(neo4j.Node, "autores")
keyword_index = graph_db.get_or_create_index(neo4j.Node, "keywords")
dataPub_index = graph_db.get_or_create_index(neo4j.Node, "data")
#
# to begin, database clear...
graph_db.clear() # not sure if this really works...let's check...
#
# the big list, next version this is supposed to be read from a file...
#
listaBase = [['2007-12-18'], ['RECONHECIMENTO E AGRUPAMENTO DE OBJETOS DE APRENDIZAGEM SEMELHANTES'], ['Raphael Ghelman', 'SWMS', 'MHLB', 'RNM'], ['Objetos de Aprendizagem', u'Personaliza\xe7\xe3o', u'Perfil do Usu\xe1rio', u'Padr\xf5es de Metadados', u'Vers\xf5es de Objetos de Aprendizagem', 'Agrupamento de Objetos Similares'], ['2007-12-18'], [u'LOCPN: REDES DE PETRI COLORIDAS NA PRODU\xc7\xc3O DE OBJETOS DE APRENDIZAGEM'], [u'Maria de F\xe1tima Costa de Souza', 'Danielo G. Gomes', 'GCB', 'CTS', u'Jos\xe9 ACCF', 'MCP', 'RMCA'], ['Objetos de Aprendizagem', 'Modelo de Processo', 'Redes de Petri Colorida', u'Especifica\xe7\xe3o formal'], ['2007-12-18'], [u'COMPUTA\xc7\xc3O M\xd3VEL E UB\xcdQUA NO CONTEXTO DE UMA GRADUA\xc7\xc3O DE REFER\xcaNCIA'], ['JB', 'RH', 'SR', u'S\xe9rgio CCSPinto', u'D\xe9bora NFB'], [u'Computa\xe7\xe3o M\xf3vel e Ub\xedqua', u'Gradua\xe7\xe3o de Refer\xeancia', u' Educa\xe7\xe3o Ub\xedqua']]
#
pedacos = [listaBase[i:i+4] for i in range(0, len(listaBase), 4)] # pedacos = chunks
#
# lists to collect indexed nodes: is it really useful???
# let's think about it when optimizing code...
dataPub_nodes = []
titulo_nodes = []
autores_nodes = []
keyword_nodes = []
#
#
for i in range(0, len(pedacos)):
# fill dataPub_nodes and titulo_nodes with content.
#dataPub_nodes.append(dataPub_index.get_or_create("data", pedacos[i][0], {"data":pedacos[i][0]})) # Publication date nodes...
dataPub_nodes.append(dataPub_index.get_or_create("data", str(pedacos[i][0]).strip('[]'), {"data":str(pedacos[i][0]).strip('[]')}))
# ------------------------------- Exception raised here... --------------------------------
# The debugged program raised the exception unhandled TypeError
#"(1649 {"titulo":["RECONHECIMENTO E AGRUPAMENTO DE OBJETOS DE APRENDIZAGEM SEMELHANTES"]})"
#File: /usr/lib/python2.7/site-packages/py2neo-1.5.1-py2.7.egg/py2neo/neo4j.py, Line: 472
# ------------------------------ What happened??? ----------------------------------------
titulo_nodes.append(titulo_index.get_or_create("titulo", str(pedacos[i][1]).strip('[]'), {"titulo":str(pedacos[i][1]).strip('[]')})) # title node...
# creates relationship publicacao
publicacao = graph_db.get_or_create_relationships(titulo_nodes[i], "publicado_em", dataPub_nodes[i])
# now processing autores sublist and collecting in autores_nodes
#
for j in range(0, len(pedacos[i][2])):
# fill autores_nodes list
autores_nodes.append(autores_index.get_or_create("autor", pedacos[i][2][j], {"autor":pedacos[i][2][j]}))
# creates autoria relationship...
#
autoria = graph_db.get_or_create_relationships(titulo_nodes[i], "tem_como_autor", autores_nodes[j])
# same logic...
#
for k in range(0, len(pedacos[i][3])):
keyword_nodes.append(keyword_index.get_or_create("keyword", pedacos[i][3][k]))
# cria o relacionamento 'tem_como_keyword'
tem_keyword = graph_db.get_or_create_relationships(titulo_nodes[i], "tem_como_keyword", keyword_nodes[k])
`
The fragment of py2neo which raised the exception
def get_or_create_relationships(self, *abstracts):
""" Fetch or create relationships with the specified criteria depending
on whether or not such relationships exist. Each relationship
descriptor should be a tuple of (start, type, end) or (start, type,
end, data) where start and end are either existing :py:class:`Node`
instances or :py:const:`None` (both nodes cannot be :py:const:`None`).
Uses Cypher `CREATE UNIQUE` clause, raising
:py:class:`NotImplementedError` if server support not available.
.. deprecated:: 1.5
use either :py:func:`WriteBatch.get_or_create_relationship` or
:py:func:`Path.get_or_create` instead.
"""
batch = WriteBatch(self)
for abstract in abstracts:
if 3 <= len(abstract) <= 4:
batch.get_or_create_relationship(*abstract)
else:
raise TypeError(abstract) # this is the 472 line.
try:
return batch.submit()
except cypher.CypherError:
raise NotImplementedError(
"The Neo4j server at <{0}> does not support " \
"Cypher CREATE UNIQUE clauses or the query contains " \
"an unsupported property type".format(self.__uri__)
)
======
Any help?
I have already fixed it, thanks to Nigel Small. I made a mistake as I wrote the line on creating relationships. I typed:
publicacao = graph_db.get_or_create_relationships(titulo_nodes[i], "publicado_em", dataPub_nodes[i])
and it must to be:
publicacao = graph_db.get_or_create_relationships((titulo_nodes[i], "publicado_em", dataPub_nodes[i]))
By the way, there is also another coding error:
keyword_nodes.append(keyword_index.get_or_create("keyword", pedacos[i][3][k]))
must be
keyword_nodes.append(keyword_index.get_or_create("keyword", pedacos[i][3][k], {"keyword":pedacos[i][3][k]}))

Categories

Resources