I´m having a problem with my interface using Tkinter in Python. I would like to put the phrase "Primeira cesta" and the button "Aplicar", at the top of the interface, not at the bottom. After that, I would like that comes the dropdown.
Can anybody help me, please?
Code
from tkinter import*
class Application():
def init(self, master):
mainframe = Frame(root)
mainframe.grid(column=0, row=0,sticky=(N,W,E,S))
mainframe.columnconfigure(0, weight = 1)
mainframe.rowconfigure(0, weight = 1)
mainframe.pack(pady = 100, padx = 100)
#color1
self.widget1 = Frame(master)
self.widget1.pack(side=TOP)
self.msg = Label(self.widget1, text="Primeira cesta")
self.msg["font"]=("Times New Roman", "12", "italic", "bold")
self.msg.pack()
self.aplicar=Button(self.widget1)
self.aplicar["text"]="Aplicar"
self.aplicar["font"]=("Calibri","10")
self.aplicar["width"]=5
self.aplicar["command"]=self.mudarTexto
self.aplicar.pack()
#Dropdown1
# Create a Tkinter variable
tkvar = StringVar(root)
tkvar2 = StringVar(root)
# Dictionary with options
cores = { 'Amarelo','Azul','Verde','Vermelho'}
formatos = {'2x1','2x2','2x3','2x4'}
tkvar.set('Cores') # set the default option
tkvar2.set('Formatos')
popupMenu = OptionMenu(mainframe, tkvar, *cores)
label1=Label(mainframe, text="Escolha uma cor")
label1.grid(row=1, column=1)
popupMenu.grid(row = 2, column =1)
popupMenu2 = OptionMenu(mainframe, tkvar2, *formatos)
label2=Label(mainframe, text="Escolha um formato")
label2.grid(row=3,column=1)
popupMenu2.grid(row = 4, column =1)
# on change dropdown value
def change_dropdown(*args):
print( tkvar.get() )
def change_dropdown2(*args):
print( tkvar2.get() )
# link function to change dropdown
tkvar.trace('w', change_dropdown)
tkvar2.trace('w', change_dropdown2)
def mudarTexto(self):
if self.msg["text"]=="Primeira cesta":
self.msg["text"]="A primeira cesta foi configurada"
else:
self.msg["text"]="Primeira cesta"
root=Tk()
Application(root)
root.mainloop()
enter image description here
I'm developing a GUI where the idea is to add some values to a treeview (as a billing system) and then get the result or sum of all items' prices.
The button "Agregar" (Add in English) get the Entries' data and add them to the treevew; one of them if the amount of money to pay.
Now what I want, and haven't been able to get, is the sum of the values given in the treeview to be shown in the field or entry which is below the treeview when "Generar" (Generate in English) button is pressed.
Next, the code I got:
#!/usr/bin/python
#-*- coding:utf-8 -*-
from Tkinter import*
from ttk import Combobox, Treeview
from tkMessageBox import*
import MySQLdb
from controller import *
import math
class Gastos(Frame):
def __init__(self, parent, controller):
Frame.__init__(self, parent)
#INSTANCIAS
global cc, nombre, pago, ref, cod, desc, valor
#INSTANCIAS DE LOS WIDGETS
global e1, e2, e3, e4, e5, tree, l8
cc = IntVar()
nombre = StringVar()
pago = StringVar()
ref = StringVar()
cod = StringVar()
desc = StringVar()
valor = DoubleVar()
tbancos = ['Bancolombia', "Banco Bogotá", "Banco Agrario", "Banco Occidente"]
lupa = PhotoImage(file='img/lupa.png')
tbanktype = ['Corriente','Ahorro']
fpago = ['Efectivo','Transferencia']
resultado = DoubleVar()
#BUSQUEDA = ["Nombre","CC/Nit"]
busqueda = StringVar()
busqueda.trace("w", lambda name, index, mode: buscar())
dato = StringVar()
#WIDGETS
#========================= HEADER ==============================
self.titleL = Label(self, text="GASTOS", font="bold")
self.titleL.pack(pady=20, side=TOP)
#========================== WRAPPER ============================
self.wrapper = Frame (self)
self.wrapper.pack(side=LEFT, fill=Y)
#Esto centro el wrapper
#self.wrapper.pack(side=LEFT, fill=BOTH, expand=True)
#======================== BENEFICIARIO =======================
self.lf1 = LabelFrame(self.wrapper, text="Beneficiario")
self.lf1.pack(fill=X, ipady=5)
self.f0 = Frame(self.lf1)
self.f0.pack(pady=5, fill=X)#-----------------------------------
l1 = Label(self.f0, text='CC/Nit:')
l1.pack(side=LEFT)
e1 = Entry(self.f0, textvariable=cc)
e1.pack(side=LEFT)
b0 = Button(self.f0, text='Buscar:', image=lupa, command=buscarB)
b0.pack(side=LEFT)
l2 = Label(self.f0, text='Nombre:')
l2.pack(side=LEFT)
e2 = Entry(self.f0, textvariable=nombre)
e2.pack(side=LEFT, fill=X, expand=1)
self.f1 = Frame(self.lf1)
self.f1.pack(pady=5, fill=X)#-----------------------------------
l3 = Label(self.f1, text='Forma de Pago:')
l3.pack(side=LEFT)
Cbx = Combobox(self.f1, textvariable=pago, values=fpago, width=15)
Cbx.set('Efectivo')
Cbx.pack(side=LEFT)
l4 = Label(self.f1, text='Ref. Bancaria:')
l4.pack(side=LEFT)
e3 = Entry(self.f1, textvariable=ref)
e3.pack(side=LEFT, fill=X, expand=1)
b1 = Button(self.f1, text='Buscar:', image=lupa)
b1.image=lupa
b1.pack(side=LEFT)
#======================== CONCEPTO ========================
self.lf2 = LabelFrame(self.wrapper, text="Concepto")
self.lf2.pack(fill=X, ipady=5)
self.f2 = Frame(self.lf2)
self.f2.pack(pady=5, fill=X)#-------------------------------
l5 = Label(self.f2, text='Código:')
l5.pack(side=LEFT)
e4 = Entry(self.f2, textvariable=cod)
e4.pack(side=LEFT)
b2 = Button(self.f2, text='Buscar:', image=lupa, command=buscarC)
b2.pack(side=LEFT)
self.f3 = Frame(self.lf2)
self.f3.pack(pady=5, fill=X)#-------------------------------
l6 = Label(self.f3, text='Descripción:')
l6.pack(side=LEFT)
e5 = Entry(self.f3, textvariable=desc, state=DISABLED)
e5.pack(side=LEFT, fill=X, expand=1)
l7 = Label(self.f3, text='Valor:')
l7.pack(side=LEFT)
e6 = Entry(self.f3, width=15, textvariable=valor)
e6.pack(side=LEFT)
b3 = Button(self.f3, text='Agregar:', command=agregar)
b3.pack(side=LEFT)
#-------------------------- TREEVIEW ---------------------------
self.f4 = Frame(self.wrapper)
self.f4.pack(pady=5,fill=X)
tree = Treeview(self.f4, height=4, show="headings", columns=('col1','col2','col3'))
tree.pack(side=LEFT, fill=X, expand=1)
tree.column('col1', width=20, anchor='center')
tree.column('col2', width=200, anchor='center')
tree.column('col3', width=10, anchor='center')
tree.heading('col1', text='Código')
tree.heading('col2', text='Concepto')
tree.heading('col3', text='Valor')
scroll = Scrollbar(self.f4,orient=VERTICAL,command=tree.yview)
tree.configure(yscrollcommand=scroll.set)
#--------------------------------------------------------------
self.f5 = Frame(self.wrapper)
self.f5.pack(pady=5,fill=X)#-------------------
#RESULT MUST BE SHOWN HERE
l8 = Label(self.f5, text=resultado, fg="red", bg="white", anchor='e', font="bold, 22", relief= SUNKEN)
l8.pack(fill=X, side=RIGHT, expand=1)
#l8.set("link")
self.fBtn = Frame(self.wrapper)
self.fBtn.pack()#-------------------------------
clean = Button(self.fBtn, text='Cancelar', bg='navy', foreground='white', activebackground='red3', activeforeground='white', command=limpiar)
clean.pack(side=RIGHT)
update = Button(self.fBtn, text='Actualizar', bg='navy', foreground='white', activebackground='red3', activeforeground='white', state=DISABLED)
update.pack(side=RIGHT)
add = Button(self.fBtn, text='Generar', bg='navy', foreground='white', activebackground='red3', activeforeground='white', command=generar)
add.pack(side=RIGHT)
#========================= ASIDE ===========================
self.aside = Frame(self)
self.aside.pack(side=TOP, fill=BOTH)
self.wrap1 = Frame(self.aside)
self.wrap1.pack()
self.viewer = Label(self.wrap1, text="LISTA DE GASTOS")
self.viewer.pack()
scroll = Scrollbar(self.wrap1, orient=VERTICAL)
scroll.pack(side=RIGHT, fill=Y)
lb = Listbox(self.wrap1, yscrollcommand=scroll.set, height=20, width=30)
scroll.config (command=lb.yview)
lb.pack(fill=BOTH)
lb.bind("<Double-Button-1>", callback)
self.wrap2 = Frame(self.aside)
self.wrap2.pack()
load = Button(self.wrap2, text='Cargar lista', bg='navy', foreground='white', activebackground='red3', activeforeground='white', command=cargar_lista)
load.pack(fill=X)
delete = Button(self.wrap2, text='Borrar', bg='navy', foreground='white', activebackground='red3', activeforeground='white', command=borrar)
delete.pack(fill=X)
edit = Button(self.wrap2, text='Modificar', bg='navy', foreground='white', activebackground='red3', activeforeground='white', command=modificar)
edit.pack(fill=X)
buscador = Label(self.wrap2, text="Buscar por Número:")
buscador.pack()
E = Entry(self.wrap2, textvariable=busqueda, width=24)
E.pack()
E.bind("<KeyRelease>", caps)
def cargar_lista():
try:
connect.commit()
display = "SELECT g_num FROM detalles order by g_num;"
cursor.execute(display)
registros = cursor.fetchall()
lb.delete(0, END)
for item in registros:
#print item
num = item[0]
lb.insert(END, num)
except:
showerror("Mensaje", "Ha ocurrido un error")
# NUEVO / CANCELAR
def limpiar():
tree.delete(*tree.get_children())
pass
def agregar():
v1 = cc.get()
v2 = None
v3 = cod.get()
v4 = desc.get()
v5 = valor.get()
tree.insert('', 0, values=(v3,v4,v5))
#FUNCTION THAT GIVE THE VALUES
def generar():
children = tree.get_children()#OBTIENE LOS iid DE LOS ITEMS
for child in children:
i = tree.item(child, 'values')[2]#OBTIENE LOS VALORES DE LOS ITEMS
print i
def borrar():
pass
def bloquear():
pass
def callback(event):
llenar_campos()
def llenar_campos():
pass
def habilitar():
pass
def modificar():
pass
def actualizar():
pass
def buscar():
pass
def buscarB():
connect.commit()
try:
v = cc.get()
sql = "SELECT b_nombre from beneficiarios WHERE b_cc='%d';" % (v)
cursor.execute(sql)
query = cursor.fetchone()
for n in query:
nombre.set(n)
except TypeError, e:
showerror("Error", e)
except MySQLdb.IntegrityError, e:
showerror("Error", e)
def buscarC():
connect.commit()
try:
v = cod.get()
sql = "SELECT cg_nombre from concepto_gastos WHERE cg_cod='%s';" % (v)
cursor.execute(sql)
query = cursor.fetchone()
for n in query:
desc.set(n)
except TypeError, e:
showerror("Error", e)
except MySQLdb.IntegrityError, e:
showerror("Error", e)
except:
showerror ("Mensaje", "No se encuentra!")
# CONVIERTE LA ENTRADA DE LOS ENTRIES EN MAYÚSCULA
def caps(event):
pass
The code is not finished, that's why it has so much info. But next function is what give me the values I need to be sum:
def generar():
children = tree.get_children()#OBTIENE LOS iid DE LOS ITEMS
for child in children:
i = tree.item(child, 'values')[2]#OBTIENE LOS VALORES DE LOS ITEMS
print i
By the way, this file is called by another (home.py) to interact with it.
If anyone could give me a hand this problem, you'll save a life. Thanks for your time, look on this, and anything you could answer. Sorry for my English if it is not good.
You have to convert string to float and then you can add to variable ie. total
def generar():
total = 0.0
for child in tree.get_children():
total += float(tree.item(child, 'values')[2])
print total
But you could add value even in agregar to get total with using button
# create global variables
total = 0.0
# or
total_var = DoubleVar()
def agregar():
# inform function to use external/global variable when you use `+=`
global total
v1 = cc.get()
v2 = None
v3 = cod.get()
v4 = desc.get()
v5 = valor.get()
total += v5
# or
total_var.set(total_var.get() + v5)
tree.insert('', 0, values=(v3,v4,v5))
Full working example
import Tkinter as tk
import ttk
# --- functions ---
def agregar(v3, v4, v5):
tree.insert('', 0, values=(v3,v4,v5))
def generar():
total = 0.0
for child in tree.get_children():
total += float(tree.item(child, 'values')[2])
print total
result['text'] = 'Total: {}'.format(total)
# --- main ---
root = tk.Tk()
tree = ttk.Treeview(root, height=4, show="headings", columns=('col1','col2','col3'))
tree.pack()
tree.heading('col1', text='Código')
tree.heading('col2', text='Concepto')
tree.heading('col3', text='Valor')
add = tk.Button(root, text='Generar', command=generar)
add.pack()
result = tk.Label(root, text='Total: 0')
result.pack()
agregar("1", "AAA", 1.11)
agregar("2", "BBB", 2.22)
agregar("3", "CCC", 3.33)
root.mainloop()
The reason you are getting PY_VAR240 is because your code is trying to display an object instead of a value.
There is already an answer here that hints at the issue as well: Python Tkinter Treeview - Iterating 'get_children' output
Also here is how I get the values from a row:
rowItem = treeSomeTree.item(itemID)
itemDictionary = rowItem['values']
someVariable = itemDictionary[0]
Note the item id variable represents row item identifier which may or may not be a number and must be unique. The treeview .insert defaults to None (iid=None) if not specified.
By specifying the iid as an integer value as you inert rows you will always know which row you have (or need to get) to summarize.
I have a problem that i still cant solve, specifically involving tkinter.
Eventhough some parts of the code are written in spanish I hope its not a problem.
When trying to calculate the hypotenuse of a triangle with Vel_in_y as the opposing side.
import tkinter
import math
window= tkinter.Tk()
frame = tkinter.Frame(window)
frame.pack()
Velocidad_in =tkinter.IntVar()
Angulo_desp = tkinter.IntVar()
Altura_max = tkinter.IntVar()
Alcan = tkinter.IntVar()
Temp = tkinter.IntVar()
Vel_in_y= tkinter.IntVar()
Vel_in_x= tkinter.IntVar()
var = [Velocidad_in,Angulo_desp ,Altura_max,Alcan,Temp,Vel_in_y,Vel_in_x]
opciones_de_Vel = ['Velocidad Inicial en X','Velocidad Inicial en Y','Modulo de Velocidad']
def Velocidad_Inicial(root):
for (tipo,var) in ((' La Velocidad Inicial en X',Vel_in_x),(' La Velocidad Inicial en Y',Vel_in_y),(' El Modulo de Velocidad',Velocidad_in)):
label = tkinter.Label(frame,text= 'Inserte '+ tipo)
label.pack()
entry= tkinter.Entry(frame,textvariable = var)
entry.pack()
def Angulo_Despegue(root):
label = tkinter.Label(frame,text='Inserte el Angulo de despegue')
label.pack()
entry= tkinter.Entry(frame,textvariable = Angulo_desp)
entry.pack()
def Altura_Maxima(root):
label = tkinter.Label(frame,text='Inserte la Altura Maxima')
label.pack()
entry= tkinter.Entry(frame,textvariable = Altura_max)
entry.pack()
def Alcance(root):
label = tkinter.Label(frame,text='Inserte el Alcance')
label.pack()
entry= tkinter.Entry(frame,textvariable = Alcan)
entry.pack()
def Tiempo(root):
label = tkinter.Label(frame,text='Inserte el Tiempo')
label.pack()
entry= tkinter.Entry(frame,textvariable = Temp)
entry.pack()
def calcular_modulo(root):
modulo = Vel_in_y* math.sin(Angulo_desp)
label = tkinter.Label(frame,textvariable=modulo)
label.pack()
if modulo == 0:
modulo = math.sqrt(Vel_in_x**2+ Vel_in_y**2)
label = tkinter.Label(frame,textvariable=modulo)
label.pack()
button = tkinter.Button(frame,text='respuesta' ,command = lambda: calcular_modulo(window))
button.pack()
menubar = tkinter.Menu(window)
option_menu =tkinter.Menu(menubar)
option_menu.add_command(label= 'Velocidad Inicial',command=lambda:Velocidad_Inicial(window))
option_menu.add_command(label= 'Angulo de Despegue',command=lambda:Angulo_Despegue(window))
option_menu.add_command(label= 'Altura Maxima',command=lambda:Altura_Maxima(window))
option_menu.add_command(label= 'Alcance',command=lambda:Alcance(window))
option_menu.add_command(label= 'Tiempo', command=lambda:Tiempo(window))
menubar.add_cascade(label= 'Tipo de Variable',menu=option_menu)
window.config(menu=menubar)
window.mainloop()
If you spot an error,Ill apreciate all feedback!
BTW when I run this code I get an error saying :
TypeError: a float is required
modulo = Vel_in_y* math.sin(Angulo_desp.get())
math.sin has no idea what to do with an IntVar ... you must get the value
the same applies everywhere else you are trying to access the value of the variables
I don't understand why you use IntVal instead int .
You need to convert IntVal type to int type by use the get function .
Here is your code , it was fixed :
def calcular_modulo(root):
modulo = Vel_in_y.get()* math.sin(Angulo_desp.get())
label = tkinter.Label(frame,textvariable=modulo)
label.pack()
if modulo == 0:
modulo = math.sqrt(Vel_in_x.get()**2+ Vel_in_y.get()**2)
label = tkinter.Label(frame,textvariable=modulo)
label.pack()
I need a scrollbar to roll under the elements, see that when create more than 30 elements from first window the screen dont fill in correct mode:
import numpy as np
import matplotlib.pyplot as plt
from Tkinter import *
import tkMessageBox
import tkSimpleDialog
from matplotlib import pylab
prefixo = "vetor"
def makeWidgets():
global entries
window = Tk()
window.title('Vetores')
form = Frame(window)
form.pack()
entries = {}
numero = tkSimpleDialog.askinteger("Vetores", "Digite o numero de vetores a serem usados:")
for ix in range(numero):
label = "%s %s" % (prefixo , ix + 1)
lab = Label(form, text=label)
ent = Entry(form)
lab.grid(row=ix, column=0)
ent.grid(row=ix, column=1)
entries[label] = ent
Button(window, text="Histograma", command=histograma).pack(side=LEFT)
Button(window, text="Media", command=media).pack(side=LEFT)
Button(window, text="Mediana", command=mediana).pack(side=LEFT)
window.mainloop()
def pegavalores():
valores = []
for chave, entrada in sorted(entries.items()):
valores.append(entrada.get())
valores = np.asarray(valores, dtype=np.float64)
return valores
def histograma():
histograma = pegavalores()
pylab.grid(True)
plt.hist(histograma)
plt.show()
def media():
media = pegavalores()
elementos = len(media)
valormedio = np.sum(media)/elementos
tkMessageBox.showinfo("Media", valormedio)
def mediana():
mediana = pegavalores()
resultado = np.median(mediana)
tkMessageBox.showinfo("Mediana", resultado)
window = makeWidgets()
You have to use the Scrollbar widget (http://effbot.org/tkinterbook/scrollbar.htm).
Unfortunately it doesn’t work pretty straight forward with frames. When I was working with Tkinter I found this extension quite useful:
http://tkinter.unpythonic.net/wiki/VerticalScrolledFrame
If you include it in your script it is easy to put your widgets in the interior frame to get the vertical scrollbar like:
window.title('Vetores')
form = VerticalScrolledFrame(window)
form.pack(fill=BOTH, expand=1)
entries = {}
numero = tkSimpleDialog.askinteger("Vetores", "Digite o numero de vetores a serem usados:")
for ix in range(numero):
label = "%s %s" % (prefixo , ix + 1)
lab = Label(form.interior, text=label)
ent = Entry(form.interior) ...
Please, help me. This is very strange.
Look at this:
#!/usr/bin/env python
from Tkinter import *
import database
def insertBook():
insertWindow = Tk()
insertWindow.title("Inserisci un nuovo romanzo nel database")
checkvars = []
checkvars.append(IntVar())
checkvars.append(IntVar())
Checkbutton(insertWindow, text = 'male', variable=checkvars[0]).pack()
Checkbutton(insertWindow, text = 'female', variable=checkvars[1]).pack()
Button(insertWindow, text= 'show', command=lambda: show(checkvars)).pack()
insertWindow.mainloop()
def show(checkvars):
print checkvars[0].get()
print checkvars[1].get()
class AppBase:
def __init__(self, parent):
self.quadro1 = Frame(parent)
self.quadro1.pack()
self.welcolmeLabel = Label(self.quadro1, text = "Benvenuto nel database dei romanzi di Lory")
self.welcolmeLabel.pack()
self.insertButton = Button(self.quadro1, command = insertBook);
self.insertButton["borderwidth"] = 1
self.insertButton["text"] = "Inserisci un libro nel database"
self.insertButton["background"] = "pink"
self.insertButton.pack(side = "left")
self.quadro2 = Frame(parent)
self.quadro2.pack()
self.searchButton = Button(self.quadro1);
self.searchButton["borderwidth"] = 1
self.searchButton["text"] = "Ricerca nel database"
self.searchButton["background"] = "blue"
self.searchButton.pack(side = "left")
self.showButton = Button(self.quadro1);
self.showButton["borderwidth"] = 1
self.showButton["text"] = "Mostra i generi di libro"
self.showButton["background"] = "violet"
self.showButton.pack(side = "left")
self.exitButton = Button(self.quadro2, text = "Uscita", borderwidth = 1, background = "red", command = self.quadro1.quit)
self.exitButton.pack(side = RIGHT, pady = 20)
if __name__ == '__main__':
mainFinestra = Tk()
mainFinestra.title('Database di Romanzi')
app = AppBase(mainFinestra)
listvars = []
listvars.append(IntVar())
listvars.append(IntVar())
Checkbutton(mainFinestra, text = 'male', variable=listvars[0]).pack()
Checkbutton(mainFinestra, text = 'female', variable=listvars[1]).pack()
Button(mainFinestra, text= 'show', command=lambda: show(listvars)).pack()
mainFinestra.mainloop()
It seems that checkbuttons variables are set only in the mainFinestra.
If I create checkbuttons in another new window (such as insertWindow), the variables in checkvars are always 0, even if the buttons are checked. Instead if I try to check the checkbutton in the mainFinestra, the function "show" returns 1 if they are checked. What's the difference? Please, this project is important to me.
Thanks
You're doing something that Tkinter isn't designed to do -- you're creating two instances of the class Tk. You should only ever create one instance, and only ever start one event loop.
If you need multiple windows, create instances of Tkinter.Toplevel.