python tkinter entry input divided by label input from optionMenu - python

I need a bit off help..
In the example below I have two optionsMenus, two entries, and some labels.
What I'm trying to do, is to divide my input from the entry by the labels value, choosen from the optionsMenu, and then show the new value in the next column. But I'm a bit stuck now and can't get it to work.
from tkinter import *
class App(Frame):
def __init__(self, root=None):
Frame.__init__(self, root)
self.materialPrice = {'Brick': 70, 'Rockwool': 50, 'Concrete': 20}
materialvariable1 = StringVar(self, root)
materialvariable1.set("Choose material")
materialvariable2 = StringVar(self, root)
materialvariable2.set("Choose materiale")
self.w1 = OptionMenu(root, materialvariable1, *self.materialPrice, command=self.displayPrice).grid(row=2,
column=0,
columnspan=1,
sticky='WE')
self.w2 = OptionMenu(root, materialvariable2, *self.materialPrice, command=self.displayPrice2).grid(row=3,
column=0,
columnspan=1,
sticky='WE')
self.var = IntVar()
self.var.set(float(0.00))
self.var2 = IntVar()
self.var2.set(float(0.00))
self.entry1 = Entry(root, textvariable=self.var).grid(row=2, column=1)
self.entry2 = Entry(root, textvariable=self.var2).grid(row=3, column=1)
self.priceVarLabel1 = IntVar()
self.priceVarLabel1.set(float(0.00))
self.priceVarLabel2 = IntVar()
self.priceVarLabel2.set(float(0.00))
self.priceVarValue1 = Label(root, textvariable=self.priceVarLabel1, relief='sunken').grid(row=2,
column=2,
columnspan=1,
sticky='WE')
self.priceVarValue2 = Label(root, textvariable=self.priceVarLabel2, relief='sunken').grid(row=3,
column=2,
columnspan=1,
sticky='WE')
self.label1 = Label(root, textvariable=self.displayResult).grid(row=2, column=3)
self.label2 = Label(root, textvariable=self.displayResult2).grid(row=3, column=3)
def displayPrice(self, value):
self.priceVarLabel1.set(self.materialPrice[value])
def displayPrice2(self, value):
self.priceVarLabel2.set(self.materialPrice[value])
def displayResult(self):
self.label1.set(self.entry1 / self.priceVarValue1)
def displayResult2(self):
self.label1.set(self.entry1 / self.priceVarValue1)
root = Tk()
app = App(root)
root.title("help")
root.mainloop()

Just add the division to your function:
def displayPrice(self, value):
self.priceVarLabel1.set(self.materialPrice[value] / self.var.get())
You may want to change the starting value to 1 so that you don't get a ZeroDivisionError right off the bat.
BTW, initializing a widget and laying it out on the same line is a well known bug source. Always use 2 lines.
# very bad:
self.entry1 = Entry(root, textvariable=self.var).grid(row=2, column=1)
# good:
self.entry1 = Entry(root, textvariable=self.var)
self.entry1.grid(row=2, column=1)

Related

Object of Class inheriting LabelFrame doesnt show up (tkinter)

Basically I have a class that inherits from LabelFrame, I want it to show up on the window itself, but I don't see it at all, it doesn't even show up on the window no matter what I do
from tkinter import *
root = Tk()
root['bg'] = 'white'
root.state('zoomed')
class CharacterFrame(LabelFrame):
def __init__(self, master, skin_img, requirement, desc):
super().__init__(master=master, bg='grey29')
self.desc = Label(self, text=desc)
default_char_frame = CharacterFrame(master=root, desc='Default Character.', requirement=0, skin_img='')
default_char_frame.grid(row=0, column=0, sticky='nse')
root.mainloop()
ok, so i was stupid for not implementing the actual code itself, but ill do it now (This isnt actual source code, just the important code, still has same error as actual code):
from tkinter import *
root = Tk()
root['background'] = 'white'
root.state('zoomed')
class SkinFrame(LabelFrame):
def __init__(self, master, skin_img, requirement, desc):
super().__init__(master=master, bg='grey29')
self.desc = Label(self, text=desc)
self.desc.pack()
def show_chars():
button_grid.grid_forget()
skin_lib.grid(row=1, column=0, sticky='nws')
button_skin0 = Button(skin_lib, text="Skin1", relief="flat", width=15, fg="white", bg="darkgrey", command=lambda: show_char_frame(prev, default_char_frame), font=("Arial", 29, "italic"))
button_skin0.grid(row=0, column=0, pady=(0,10))
back = Button(skin_lib, text="Back", width=15, relief="flat", fg="white", bg="maroon", font=("Arial",29,"italic"),
command=lambda: [skin_lib.grid_forget(), button_grid.grid(row=1, column=0, sticky='nws')])
back.grid(row=100, column=0)
def show_char_frame(prev, char_frame):
skin_lib.grid_forget()
default_char_frame.grid(row=1, column=1, sticky='nse')
default_char_frame = SkinFrame(master=root, desc='Default Skin.', requirement=0, skin_img='')
Label(root, text="Game Title", width=68, relief="flat", bg="white", fg="grey", font=("Arial",26,"italic")).grid(row=0, column=0, sticky='n')
button_grid = LabelFrame(root, bg='grey29', relief="groove", pady=10, padx=10)
button_grid.grid(row=1, column=0, sticky='nws')
skin_lib = LabelFrame(root, bg='grey29', relief="groove", pady=10, padx=10)
skins = Button(button_grid, text="Skins", width=15, relief="flat", fg="white", bg="navy", command=show_chars, font=("Arial", 29, "italic"))
skins.grid(row=2, column=0, pady=(0,10))
previous_skinframe
root.mainloop()
you missed to pack() label to add in control
self.desc.pack()
this is complete code
from tkinter import *
root = Tk()
root['bg'] = 'white'
root.state('zoomed')
class CharacterFrame(LabelFrame):
def __init__(self, master, skin_img, requirement, desc):
super().__init__(master=master, bg='grey29')
self.desc = Label(self, text=desc)
self.desc.pack()
default_char_frame = CharacterFrame(master=root, desc='Default Character.', requirement=0, skin_img='')
default_char_frame.grid(row=0, column=0, sticky='nse')
root.mainloop()
in this code what I add self.desc.pack() to show
this is output

Python/Tkinter: How to display a blank bottom frame when the application is run first?

When the application is run first, the last frame's widgets are displayed on the screen. What i wanted to do is, displaying the related frames when the user clicks their buttons. So, i want to display a blank frame with the top buttons. In order to do that, what should i do? (I removed the button functions, because they are not related to the question.) Thanks in advance.
import tkinter as tk
class TopFrame(tk.Frame):
def __init__(self, master=None):
tk.Frame.__init__(self, master)
self.grid(row=0, column=0, sticky="nsew")
self.BottomFrame = tk.Frame(master=master)
self.BottomFrame.grid(row=1, column=0, sticky="nsew")
self.f1 = tk.Frame(master=self.BottomFrame)
self.f2 = tk.Frame(master=self.BottomFrame)
self.f3 = tk.Frame(master=self.BottomFrame)
for f in (self.f1, self.f2, self.f3):
f.grid(row=0, column=0, sticky="nsew")
self.b1 = tk.Button(master=self, text="Add Words")
self.b2 = tk.Button(master=self, text="Add From File")
self.b3 = tk.Button(master=self, text="Change Words")
self.add_button = tk.Button(master=self.f1, text="Add")
self.open_button = tk.Button(master=self.f2, text="Open File")
self.change_button = tk.Button(master=self.f3, text="Change")
self.l1 = tk.Label(master=self.f1, text="English")
self.l2 = tk.Label(master=self.f1, text="Turkish")
self.l3 = tk.Label(master=self.f3, text="Old word")
self.l4 = tk.Label(master=self.f3, text="New word")
self.e1 = tk.Entry(master=self.f1)
self.e2 = tk.Entry(master=self.f1)
self.e3 = tk.Entry(master=self.f3)
self.e4 = tk.Entry(master=self.f3)
self.configure_buttons()
self.configure_labels()
self.configure_entries()
def configure_buttons(self):
self.b1.grid(row=0, column=0)
self.b1.configure(command=lambda: self.f1.tkraise())
self.b2.grid(row=0, column=1)
self.b2.configure(command=lambda: self.f2.tkraise())
self.b3.grid(row=0, column=2)
self.b3.configure(command=lambda: self.f3.tkraise())
self.add_button.grid(row=2, columnspan=2)
#self.add_button.configure(command=self.add_word)
self.open_button.pack(side="top")
#self.open_button.configure(command=self.add_from_file)
self.change_button.grid(row=2, columnspan=2)
def configure_labels(self):
self.l1.grid(row=0, column=0)
self.l2.grid(row=0, column=1)
self.l3.grid(row=0, column=0)
self.l4.grid(row=0, column=1)
def configure_entries(self):
self.e1.grid(row=1, column=0)
self.e2.grid(row=1, column=1)
self.e3.grid(row=1, column=0)
self.e4.grid(row=1, column=1)
if __name__ == "__main__":
root = tk.Tk()
example = TopFrame(master=root)
example.mainloop()
Instead of having 3 widgets in the same location, it's better to have only the one you need.
First, get rid of this code:
for f in (self.f1, self.f2, self.f3):
f.grid(row=0, column=0, sticky="nsew")
Now the frame will start in a blank state.
Then, instead of calling .tkraise() on the frames, we will remove the current frame (if any) and add another one in its place. So
self.b1.configure(command=lambda: self.f1.tkraise())
self.b2.configure(command=lambda: self.f2.tkraise())
self.b3.configure(command=lambda: self.f3.tkraise())
becomes:
self.b1.configure(command=lambda: self._activate(self.f1))
self.b2.configure(command=lambda: self._activate(self.f2))
self.b3.configure(command=lambda: self._activate(self.f3))
with
def _activate(self, frame):
# remove the current frame
for child in self.BottomFrame.winfo_children():
child.grid_forget()
# add the new frame in its place
frame.grid(row=0, column=0, sticky='nsew')

__init__() missing argument: 'checkbutton' - Python

I'm having issues with my constructor. I get the error __init__() missing 1 required positional argument: 'checkbutton'
Update:
this is my main file:
from GUI_Rootmodule import GUI_Root
gui_root = GUI_Root()
this is my rootmodule file:
from GUI_Unitmodule import Unit
from tkinter import *
class GUI_Root:
def __init__(self):
print("hoi")
window = Tk()
window.title("Project: Embedded Systems")
rootframe = Frame(window, width=1800, height=750)
rootframe.pack()
Unit(rootframe)
window.mainloop()
this is my Unitmodule:
from tkinter import *
class Unit:
def __init__(self, master, checkbutton):
self.frame1 = Frame(master) #Frame voor labels, buttons, entries
self.frame1.pack()
# Checkbutton #
print("test frame")
self.var1 = IntVar()
self.checkbutton = checkbutton(self.frame1, text="Automatisch", variable=self.var1, onvalue= 1, offvalue= 0, pady=20).grid(row=0, column=0, sticky=E)
print("test checkbutton")
# Labels #
self.Extend_Label = Label(self.frame1, text="Uitrol afstand", pady=20).grid(row=2, column=0, sticky=E)
self.Retract_Label = Label(self.frame1, text="Inrol afstand", pady=20).grid(row=3, column=0, sticky=E)
self.Temperture_Label = Label(self.frame1, text="Temperatuur Trigger", pady=20).grid(row=4, column=0, sticky=E)
self.LightIntensity_Label = Label(self.frame1, text="Lichtintensiteit Trigger", pady=20).grid(row=5, column=0, sticky=E)
print("test label")
# Entry #
self.Extend_Entry = Entry(self.frame1).grid(row=2, column=1, sticky=E)
self.Retract_Entry = Entry(self.frame1).grid(row=3, column=1, sticky=E)
self.Temperture_Entry = Entry(self.frame1).grid(row=4, column=1, sticky=E)
self.LightIntensity_Entry = Entry(self.frame1).grid(row=5, column=1, sticky=E)
print("test entry")
# Buttons
self.A = Button(self.frame1, text ="Inrollen", padx=10, pady=20).grid(row=6, column=0)
self.B = Button(self.frame1, text ="Uitrollen", padx=10, pady=20).grid(row=6, column=1)
print("test button")
I've tried to run in it, but it keeps saying that I'm missing an argument which i've put in init(self, master, checkbutton)
Can someone explain what I'm missing here and/or doing wrong ?
Update 2: Without the checkbutton code, the rest works and shows a simple GUI. It's still not clear where exactly i'm missing the argument for checkbutton
You didn't supply all of the required input parameters on this line:
Unit(rootframe)
You supplied master, but are missing checkbutton. The class should be instantiated with all of the required input parameters:
Unit(master, checkbutton)
Alternatively, you can provide default values for the inputs and adjust the code in the function accordingly:
class Unit(master=None,checkbutton=None):
...
However, it looks like maybe you don't intend to pass in a checkbutton variable at all and meant to simply include a tkinter Checkbutton. If that's what you're after, I've included code for that below. I avoided the star import from tkinter import * so the source of the objects is more clear. I also combined things into the same module so the whole thing runs as-is.
import tkinter as tk
def main():
gui_root = GUI_Root()
class GUI_Root:
def __init__(self):
print("hoi")
window = tk.Tk()
window.title("Project: Embedded Systems")
rootframe = tk.Frame(window, width=1800, height=750)
rootframe.pack()
Unit(rootframe)
window.mainloop()
class Unit:
def __init__(self, master):
self.frame1 = tk.Frame(master) #Frame voor labels, buttons, entries
self.frame1.pack()
# Checkbutton #
print("test frame")
self.var1 = tk.IntVar()
self.checkbutton = tk.Checkbutton(self.frame1, text="Automatisch", variable=self.var1, onvalue= 1, offvalue= 0, pady=20).grid(row=0, column=0, sticky=tk.E)
print("test checkbutton")
# Labels #
self.Extend_Label = tk.Label(self.frame1, text="Uitrol afstand", pady=20).grid(row=2, column=0, sticky=tk.E)
self.Retract_Label = tk.Label(self.frame1, text="Inrol afstand", pady=20).grid(row=3, column=0, sticky=tk.E)
self.Temperture_Label = tk.Label(self.frame1, text="Temperatuur Trigger", pady=20).grid(row=4, column=0, sticky=tk.E)
self.LightIntensity_Label = tk.Label(self.frame1, text="Lichtintensiteit Trigger", pady=20).grid(row=5, column=0, sticky=tk.E)
print("test label")
# Entry #
self.Extend_Entry = tk.Entry(self.frame1).grid(row=2, column=1, sticky=tk.E)
self.Retract_Entry = tk.Entry(self.frame1).grid(row=3, column=1, sticky=tk.E)
self.Temperture_Entry = tk.Entry(self.frame1).grid(row=4, column=1, sticky=tk.E)
self.LightIntensity_Entry = tk.Entry(self.frame1).grid(row=5, column=1, sticky=tk.E)
print("test entry")
# Buttons
self.A = tk.Button(self.frame1, text ="Inrollen", padx=10, pady=20).grid(row=6, column=0)
self.B = tk.Button(self.frame1, text ="Uitrollen", padx=10, pady=20).grid(row=6, column=1)
print("test button")
if __name__ == '__main__':
main()

How to get input and give an output after calculation

I'm beginner for python and I tried to make a BMI calculator
but i have some problems with the input and output
I want to get input from self.Heighttypeand self.Weighttypeand give a output at self.BMI
And some tips to simply my coding?
from tkinter import *
import tkinter.messagebox
root = Tk()
root.resizable(0,0)
class win1:
def __init__(self, master):
self.master = master
master.title("BMI Calculator")
#
self.he = IntVar()
self.we = IntVar()
self.height = Label(master, text="ENTER Your Height(cm) Here:")
self.Heighttype = Entry(master, textvariable=self.he) #here
self.weight = Label(master,text="ENTER Your Weight(kg) Here:")
self.Weighttype = Entry(master, textvariable=self.we) #and here
#
self.ans = IntVar()
self.BMI = Label(master, textvariable=self.ans) #output here
self.credit = Button(master, text="Credit", command=self.credit_show)
self.result = Button(master, text="Result", command=self.calculation)
root.protocol('WM_DELETE_WINDOW', self.ask_quit)
self.close = Button(master, text="Close", command=self.ask_quit)
self.height.grid(sticky=E, padx=2, pady=4)
self.Heighttype.grid(row=0, column=1, columnspan=2, padx=2)
self.weight.grid(sticky=E, padx=2, pady=4)
self.Weighttype.grid(row=1, column=1, columnspan=2, padx=2)
self.BMI.grid(row=2, column=1, columnspan=2, padx=2)
self.credit.grid(row=3, sticky=W, padx=4 , pady=4)
self.result.grid(row=3, column=1, pady=4, sticky=W+E, padx=4)
self.close.grid(row=3, column=2, pady=4, sticky=W+E, padx=1)
def calculation(self):
# i want to get the user input from top and make calculation
# and make a output self.BMI = Label
def credit_show(self):
tkinter.messagebox.showinfo("Credit","Created by BlackLotus")
def ask_quit(self):
if tkinter.messagebox.askokcancel("Quit", "Do you want to Quit?"):
root.destroy()
apps = win1(root)
root.mainloop()
Someone help me please. Thanks a lot.
Use .get() and .set() on the IntVars to get the parameters and set the result:
def calculation(self):
m = self.we.get()
l = self.he.get()
bmi = # calculate the bmi here
self.ans.set(bmi)
Also, while it seems to work with an IntVar as well, it seems more reasonable to make ans a DoubleVar, i.e.:
self.ans = DoubleVar()

Adding a scrollbar to a frame using Tkinter (Python)

I've a simple GUI thats shows the users some options, after putting the number of the initial options to be shown. In this case, 4:
By clicking on Add row you can add a row to the GUI. The thing is that if the user wants 100 options, the GUI becomes extra big and all the options are not shown.
So I would like to have a scrollbar only on the options space, not the rest parts. Sorry for the bad Photoshop, but I would like to have something like this:
The options space is the FrameTwo, so I would like to have the entire FrameTwo inside of scrollbar like the image above.
# -*- coding: utf-8 -*-
from Tkinter import *
import Image
import ImageTk
import tkFileDialog
import datetime
class Planificador(Frame):
def __init__(self,master):
Frame.__init__(self, master)
self.master = master
self.initUI()
def initUI(self):
self.master.title("Plan")
self.frameOne = Frame(self.master)
self.frameOne.grid(row=0,column=0)
self.frameTwo = Frame(self.master)
self.frameTwo.grid(row=1, column=0)
self.frameThree = Frame(self.master)
self.frameThree.grid(row=2, column=0)
# Borrar esto?
self.txt = Text(self)
self.txt.pack(fill=BOTH, expand=1)
self.piezastext = Label(self.frameOne, text = " Amount of pieces ", justify="center")
self.piezastext.grid(row=1, column=0)
self.entrypiezas = Entry(self.frameOne,width=3)
self.entrypiezas.grid(row=2, column=0, pady=(5,5))
self.aceptarnumpiezas = Button(self.frameOne,text="Click me", command=self.aceptar_piezas,width=8)
self.aceptarnumpiezas.grid(row=6, column=0, pady=(5,5))
def aceptar_piezas(self):
try:
val = int(self.entrypiezas.get())
self.aceptar_piezas_ok()
except ValueError:
showerror('Error', "Introduce un numero")
def aceptar_piezas_ok(self):
self.num_piezas = self.entrypiezas.get()
self.piezastext.grid_remove()
self.entrypiezas.grid_remove()
self.aceptarnumpiezas.grid_remove()
self.optionmenus_piezas = list()
self.numpiezas = []
self.numerolotes = []
self.optionmenus_prioridad = list()
self.lotes = list()
self.mispiezas = ['One', 'Two', 'Three', 'Four', 'Five']
self.n = 1
while self.n <= int(self.num_piezas):
self.textopieza = Label(self.frameTwo, text = "Pieza: ", justify="left")
self.textopieza.grid(row=self.n, column=0)
var = StringVar()
menu = OptionMenu(self.frameTwo, var, *self.mispiezas)
menu.config(width=10)
menu.grid(row=self.n, column=1)
var.set("One")
self.optionmenus_piezas.append((menu, var))
self.numpiezastext = Label(self.frameTwo, text = "Numero de piezas: ", justify="center")
self.numpiezastext.grid(row=self.n, column=2, padx=(10,0))
self.entrynumpiezas = Entry(self.frameTwo,width=6)
self.entrynumpiezas.grid(row=self.n, column=3, padx=(0,10))
self.entrynumpiezas.insert(0, "0")
self.textoprioridad = Label(self.frameTwo, text = "Prioridad: ", justify="center")
self.textoprioridad.grid(row=self.n, column=4)
var2 = StringVar()
menu2 = OptionMenu(self.frameTwo, var2, "Normal", "Baja", "Primera pieza", "Esta semana")
menu2.config(width=10)
menu2.grid(row=self.n, column=5)
var2.set("Normal")
self.optionmenus_prioridad.append((menu2, var2))
self.lotestext = Label(self.frameTwo, text = "Por lotes?", justify="center")
self.lotestext.grid(row=self.n, column=6, padx=(10,0))
self.var1 = IntVar()
self.entrynumlotes = Checkbutton(self.frameTwo, variable=self.var1)
self.entrynumlotes.grid(row=self.n, column=7, padx=(5,10))
self.lotes.append(self.var1)
self.numpiezas.append(self.entrynumpiezas)
self.n += 1
self.anadirpiezas = Button(self.frameThree, text="Add row", command=self.addpieza, width=10)
self.anadirpiezas.grid(row=0, column=2, pady=(10,10))
self.calculotext = Label(self.frameThree, text = "Other stuff ")
self.calculotext.grid(row=1, column=2, padx=(10,0), pady=(10,10))
self.graspbutton = Button(self.frameThree, text="OPT 1", width=10)
self.graspbutton.grid(row=2, column=1)
self.parettobutton = Button(self.frameThree, text="OPT 2",width=10)
self.parettobutton.grid(row=2, column=2, pady=(10,10), padx=(10,0))
self.parettoEvolbutton = Button(self.frameThree, text="OPT 2", width=10)
self.parettoEvolbutton.grid(row=2, column=3, pady=(10,10), padx=(10,0))
def addpieza(self):
self.textopiezanuevo = Label(self.frameTwo, text = "Pieza: ", justify="left")
self.textopiezanuevo.grid(row=int(self.num_piezas)+1, column=0)
var = StringVar()
menu = OptionMenu(self.frameTwo, var, *self.mispiezas)
menu.grid(row=self.n, column=1)
menu.config(width=10)
menu.grid(row=int(self.num_piezas)+1, column=1)
var.set("One")
self.optionmenus_piezas.append((menu, var))
self.numpiezastext = Label(self.frameTwo, text = "Numero de piezas: ", justify="center")
self.numpiezastext.grid(row=int(self.num_piezas)+1, column=2, padx=(10,0))
self.entrynumpiezas = Entry(self.frameTwo,width=6)
self.entrynumpiezas.grid(row=int(self.num_piezas)+1, column=3, padx=(0,10))
self.entrynumpiezas.insert(0, "0")
self.textoprioridad = Label(self.frameTwo, text = "Prioridad: ", justify="center")
self.textoprioridad.grid(row=int(self.num_piezas)+1, column=4)
var2 = StringVar()
menu2 = OptionMenu(self.frameTwo, var2, "Normal", "Baja", "Primera pieza", "Esta semana")
menu2.config(width=10)
menu2.grid(row=int(self.num_piezas)+1, column=5)
var2.set("Normal")
self.optionmenus_prioridad.append((menu2, var2))
self.lotestext = Label(self.frameTwo, text = "Por lotes?", justify="center")
self.lotestext.grid(row=int(self.num_piezas)+1, column=6, padx=(10,0))
self.var1 = IntVar()
self.entrynumlotes = Checkbutton(self.frameTwo, variable=self.var1)
self.entrynumlotes.grid(row=int(self.num_piezas)+1, column=7, padx=(5,10))
self.lotes.append(self.var1)
self.numpiezas.append(self.entrynumpiezas)
self.num_piezas = int(self.num_piezas)+1
if __name__ == "__main__":
root = Tk()
aplicacion = Planificador(root)
root.mainloop()
FrameOne is used to put an image I removed to make this example more simple. And FrameThree are the buttons you can see at the bottom of the GUI.
So it would be very helpful if someone could give me a hand and tell me how to put the entire FrameTwo inside of a scrollbar as you can see on the third image.
Thanks in advance.
One of your problems, is that "frameTwo" has no limits to it's size. If you don't limit it's size, any scrollbar you add, never will act. But limiting the size of you frame have the inconvenient of limit the number of lines you can grid, making the scrollbar useless again.
A solution is creating a frame inside the "frameTwo", to receive the pieces you create. This way, by one hand, allow you to limit the size of "frameTwo" and attach the scrollbar to it, and by other hand, allow you to grid the pieces you add to the frame located inside "frameTwo", named, let's say, "ListFrame". when "ListFrame" size becomes bigger than "frameTwo" size, you can now make the scrollbar work.
I change your code with the changes mentioned above. Check it out.
The changes are commented in the code.
Sorry for the short explanation, but i'm a bit hurry. I may edit this answer when I have more time.
PS: Sorry if my english is not the best
# -*- coding: utf-8 -*-
from Tkinter import *
import Image
import ImageTk
import tkFileDialog
import datetime
class Planificador(Frame):
def __init__(self,master):
Frame.__init__(self, master)
self.master = master
self.initUI()
def initUI(self):
self.master.title("Plan")
self.frameOne = Frame(self.master)
self.frameOne.grid(row=0,column=0)
self.frameTwo = Frame(self.master)
self.frameTwo.grid(row=1, column=0)
#Creating of a new frame, inside of "frameTwo" to the objects to be inserted
#Creating a scrollbar
#The reason for this, is to attach the scrollbar to "FrameTwo", and when the size of frame "ListFrame" exceed the size of frameTwo, the scrollbar acts
self.canvas=Canvas(self.frameTwo)
self.listFrame=Frame(self.canvas)
self.scrollb=Scrollbar(self.master, orient="vertical",command=self.canvas.yview)
self.scrollb.grid(row=1, column=1, sticky='nsew') #grid scrollbar in master, but
self.canvas['yscrollcommand'] = self.scrollb.set #attach scrollbar to frameTwo
self.canvas.create_window((0,0),window=self.listFrame,anchor='nw')
self.listFrame.bind("<Configure>", self.AuxscrollFunction)
self.scrollb.grid_forget() #Forget scrollbar because the number of pieces remains undefined by the user. But this not destroy it. It will be "remembered" later.
self.canvas.pack(side="left")
self.frameThree = Frame(self.master)
self.frameThree.grid(row=2, column=0)
# Borrar esto?
self.txt = Text(self)
self.txt.pack(fill=BOTH, expand=1)
self.piezastext = Label(self.frameOne, text = " Amount of pieces ", justify="center")
self.piezastext.grid(row=1, column=0)
self.entrypiezas = Entry(self.frameOne,width=3)
self.entrypiezas.grid(row=2, column=0, pady=(5,5))
self.aceptarnumpiezas = Button(self.frameOne,text="Click me", command=self.aceptar_piezas,width=8)
self.aceptarnumpiezas.grid(row=6, column=0, pady=(5,5))
def AuxscrollFunction(self,event):
#You need to set a max size for frameTwo. Otherwise, it will grow as needed, and scrollbar do not act
self.canvas.configure(scrollregion=self.canvas.bbox("all"),width=600,height=500)
def aceptar_piezas(self):
#IMPORTANT!!! All the objects are now created in "ListFrame" and not in "frameTwo"
#I perform the alterations. Check it out
try:
val = int(self.entrypiezas.get())
self.aceptar_piezas_ok()
self.scrollb.grid(row=1, column=1, sticky='nsew') #grid scrollbar in master, because user had defined the numer of pieces
except ValueError:
showerror('Error', "Introduce un numero")
def aceptar_piezas_ok(self):
self.num_piezas = self.entrypiezas.get()
self.piezastext.grid_remove()
self.entrypiezas.grid_remove()
self.aceptarnumpiezas.grid_remove()
self.optionmenus_piezas = list()
self.numpiezas = []
self.numerolotes = []
self.optionmenus_prioridad = list()
self.lotes = list()
self.mispiezas = ['One', 'Two', 'Three', 'Four', 'Five']
self.n = 1
while self.n <= int(self.num_piezas):
self.textopieza = Label(self.listFrame, text = "Pieza: ", justify="left")
self.textopieza.grid(row=self.n, column=0)
var = StringVar()
menu = OptionMenu(self.listFrame, var, *self.mispiezas)
menu.config(width=10)
menu.grid(row=self.n, column=1)
var.set("One")
self.optionmenus_piezas.append((menu, var))
self.numpiezastext = Label(self.listFrame, text = "Numero de piezas: ", justify="center")
self.numpiezastext.grid(row=self.n, column=2, padx=(10,0))
self.entrynumpiezas = Entry(self.listFrame,width=6)
self.entrynumpiezas.grid(row=self.n, column=3, padx=(0,10))
self.entrynumpiezas.insert(0, "0")
self.textoprioridad = Label(self.listFrame, text = "Prioridad: ", justify="center")
self.textoprioridad.grid(row=self.n, column=4)
var2 = StringVar()
menu2 = OptionMenu(self.listFrame, var2, "Normal", "Baja", "Primera pieza", "Esta semana")
menu2.config(width=10)
menu2.grid(row=self.n, column=5)
var2.set("Normal")
self.optionmenus_prioridad.append((menu2, var2))
self.lotestext = Label(self.listFrame, text = "Por lotes?", justify="center")
self.lotestext.grid(row=self.n, column=6, padx=(10,0))
self.var1 = IntVar()
self.entrynumlotes = Checkbutton(self.listFrame, variable=self.var1)
self.entrynumlotes.grid(row=self.n, column=7, padx=(5,10))
self.lotes.append(self.var1)
self.numpiezas.append(self.entrynumpiezas)
self.n += 1
self.anadirpiezas = Button(self.frameThree, text="Add row", command=self.addpieza, width=10)
self.anadirpiezas.grid(row=0, column=2, pady=(10,10))
self.calculotext = Label(self.frameThree, text = "Other stuff ")
self.calculotext.grid(row=1, column=2, padx=(10,0), pady=(10,10))
self.graspbutton = Button(self.frameThree, text="OPT 1", width=10)
self.graspbutton.grid(row=2, column=1)
self.parettobutton = Button(self.frameThree, text="OPT 2",width=10)
self.parettobutton.grid(row=2, column=2, pady=(10,10), padx=(10,0))
self.parettoEvolbutton = Button(self.frameThree, text="OPT 2", width=10)
self.parettoEvolbutton.grid(row=2, column=3, pady=(10,10), padx=(10,0))
def addpieza(self):
self.textopiezanuevo = Label(self.listFrame, text = "Pieza: ", justify="left")
self.textopiezanuevo.grid(row=int(self.num_piezas)+1, column=0)
var = StringVar()
menu = OptionMenu(self.listFrame, var, *self.mispiezas)
menu.grid(row=self.n, column=1)
menu.config(width=10)
menu.grid(row=int(self.num_piezas)+1, column=1)
var.set("One")
self.optionmenus_piezas.append((menu, var))
self.numpiezastext = Label(self.listFrame, text = "Numero de piezas: ", justify="center")
self.numpiezastext.grid(row=int(self.num_piezas)+1, column=2, padx=(10,0))
self.entrynumpiezas = Entry(self.listFrame,width=6)
self.entrynumpiezas.grid(row=int(self.num_piezas)+1, column=3, padx=(0,10))
self.entrynumpiezas.insert(0, "0")
self.textoprioridad = Label(self.listFrame, text = "Prioridad: ", justify="center")
self.textoprioridad.grid(row=int(self.num_piezas)+1, column=4)
var2 = StringVar()
menu2 = OptionMenu(self.listFrame, var2, "Normal", "Baja", "Primera pieza", "Esta semana")
menu2.config(width=10)
menu2.grid(row=int(self.num_piezas)+1, column=5)
var2.set("Normal")
self.optionmenus_prioridad.append((menu2, var2))
self.lotestext = Label(self.listFrame, text = "Por lotes?", justify="center")
self.lotestext.grid(row=int(self.num_piezas)+1, column=6, padx=(10,0))
self.var1 = IntVar()
self.entrynumlotes = Checkbutton(self.listFrame, variable=self.var1)
self.entrynumlotes.grid(row=int(self.num_piezas)+1, column=7, padx=(5,10))
self.lotes.append(self.var1)
self.numpiezas.append(self.entrynumpiezas)
self.num_piezas = int(self.num_piezas)+1
if __name__ == "__main__":
root = Tk()
aplicacion = Planificador(root)
root.mainloop()
You have option menus, labels, entry boxes, and checkbuttons in FrameTwo. How would you expect a scrollbar for the entire frame would work? Would it scroll all widgets at the same time? Tkinter scrollbars are generally attached to listboxes, canvases, entry widgets, and text fields. http://effbot.org/zone/tkinter-scrollbar-patterns.htm Come up with a simple example that illustrates the problem for further help.

Categories