Erase widgets from window - python

So in my program, whenever I put the grid_remove() function it usually deletes the widget. Whenever I run the program for the first time (that is, not losing any points by guessing wrongly), it deletes most of the widgets. However, whenever I guess wrong and get points taken away (which works fine), the widgets lazily remain on the window. Any help?
Here's the code: (I think that the error occurs somewhere after def numright and def wordguess)
import random
from tkinter import *
from tkinter import messagebox
text_doc = open("test.txt", "r")
text = text_doc.read()
numbOfletters = len(text)
random_letter = random.randint(0,numbOfletters-1)
letter = text[random_letter]
points = 50
username = ""
is_there = 0
class GUIFramework(Frame):
def __init__(self,master=None):
Frame.__init__(self,master)
self.master.title("Window")
self.master.geometry("420x75")
self.grid(padx=10,pady=10)
self.CreateWidgets()
def CreateWidgets(self):
self.lbText = Label(self, text="Would you like to play \"Find the secret letter?\"", font="Verdana")
self.lbText.grid(row=0, column=0, columnspan = 3)
self.button = Button(self, text="Yes, please", command=self.next, background = "green")
self.button.grid(row=1, column=0)
self.btnDisplay = Button(self, text="No, thanks", command = self.window, background = "red")
self.btnDisplay.grid(row=1, column=1)
def window(self):
self.tl = Toplevel(self)
self.master.destroy()
def next(self):
self.lbText.grid_remove()
self.button.grid_remove()
self.btnDisplay.grid_remove()
self.lbText = Label(self, text="You're currently playing \"Find the secret letter\"", font="Verdana")
self.lbText.grid(row=0, column=0, columnspan = 10)
self.username = Label(self, text="Enter your username")
self.username.grid(row=1, column=0)
self.enText = Entry(self)
self.enText.grid(row=1, column=2, columnspan=5)
self.ok = Button(self, text="OK", command = self.wordguess)
self.ok.grid(row=1, column=8)
def wordguess(self):
global username
self.master.geometry("420x90")
username = self.enText.get()
self.username.grid_remove()
self.enText.grid_remove()
self.word = Label(self, text="You have {0} points, enter a word?".format(50))
self.word.grid(row=1, column=0)
self.entry = Entry(self)
self.entry.grid(row=1, column=1, columnspan=4)
self.ok = Button(self, text="OK", command = self.numright)
self.ok.grid(row=1, column=8)
def numright(self):
global points
global is_there
word = self.entry.get()
word = word.lower()
is_there = word.count(letter)
self.lbText.grid_remove()
self.word.grid_remove()
self.entry.grid_remove()
self.enText.grid_remove()
self.ok.grid_remove()
if is_there > 4:
self.master.geometry("200x70")
self.done = Label(self, text = "Congradulations, you have won!")
self.done.grid(row = 0, column = 0)
self.ok = Button(self, text="OK", command = self.window)
self.ok.grid(row=1, column=0)
else:
if (is_there < 5) and (is_there > 0):
points = points - 5
else:
points = points - 10
self.lbText = Label(self, text="You're currently playing \"Find the secret letter\"", font="Verdana")
self.lbText.grid(row=0, column=0, columnspan = 10)
self.numright = Label(self, text="That word has {} secret letters".format(is_there))
self.numright.grid(row=2, column=0)
self.word = Label(self, text="You have {0} points, enter a word?".format(points))
self.word.grid(row=1, column=0)
self.entry = Entry(self)
self.entry.grid(row=1, column=1, columnspan=4)
def scores(self):
output = open("names.txt", "a")
output.write("{0:2} {1} \n".format(str(points), username))
output.close()
output = open("names.txt", "r")
if __name__ == "__main__":
guiFrame = GUIFramework()
guiFrame.mainloop()

Your problem is the lines (in the else clause of the numright method):
self.numright = Label(self, text="That word has {} secret letters".format(is_there))
self.numright.grid(row=2, column=0)
self.numright is a method in your GUIFramework class, which you stomp on here and reassign it to a Label field. Also you probably have to put the self.ok button back onto the page since you grid_removed it above. I added the lines:
self.ok = Button(self, text="OK", command = self.numright)
self.ok.grid(row=1, column=8)
to the end of the numright method to put the OK button back. I then fiddled about by making a different method which just called self.numright which is how I caught the reassignment bug.

Related

Passing variables through classes and using .get() in Tkinter to find users input

class Menu():
def __init__(self):
pass
def menuWindow(self):
menu = Tk()
menu.title("Menu")
menu.geometry("300x250")
menuFrame = Frame(menu)
menuFrame.pack()
menu = Menu()
menuLabel = Label(menuFrame, font="Helvetica 18 bold", text="MENU")
menuLabel.grid(row=0, column=0, sticky=W)
cDirF = TaskWindowMaker()
cDir = Button(menuFrame, text="Create Directory", command=cDirF.cDirWindow, height=2,width=20)
cDir.grid(row=2, column=0, sticky=W)
cProfF = TaskWindowMaker()
cProf = Button(menuFrame, text="Create Profiles", command=cProfF.cProfWindow, height=2,width=20)
cProf.grid(row=3, column=0, sticky=W)
dProfF = TaskWindowMaker()
dProf = Button(menuFrame, text="Delete Profiles", command=dProfF.dProfWindow, height=2,width=20)
dProf.grid(row=6, column=0, sticky=W)
mSenderF = TaskWindowMaker()
mSender = Button(menuFrame, text="Make Sender", command=mSenderF.mSenderWindow, height=2,width=20)
mSender.grid(row=8, column=0, sticky=W)
sendParcelF = TaskWindowMaker()
sParcel = Button(menuFrame, text="Send Parcel", command=sendParcelF.sendParcelWindow, height=2,width=20)
sParcel.grid(row=10, column=0, sticky=W)
class ProfileDeveloper(object):
def __init__(self,):
pass
def create_folder_profiles(self):
global directoryNamecProfWindow
y = False
while y == False:
path = os.getcwd()
print(path)
y = numbercProfWindow.get()#int(input("Number of profiles: "))
print(y)
#y = int(y)
p = os.getcwd()+("\profiles")#Reading number file in profiles
n = ("number")
d = os.path.join(p,n)
try:
dirName = directoryNamecProfWindow.get()#input("Directory name :")
print(dirName+"OO")
path = os.getcwd()+("\profiles")
folderDir = os.path.join(path, dirName)
with open(folderDir+"profile.txt","x") as f:
print("Opened.")
except FileNotFoundError:
print("File not found.")
except FileExistsError:
messagebox.showerror("Error","File already exists.")
for a in range(y):
with open(d+".txt","r") as z:
num = z.read()
num = int(num)
newNum = (int(num)+1)
numProf = ("profile"+str(newNum))
with open(d+".txt","w") as file:
file.write(str(newNum))
path = os.getcwd()+("\profiles")
folderDir = os.path.join(path, dirName,numProf)
with open(folderDir+".txt","x") as f:
print("Created '"+numProf+"'.")
y = True
#except:
print("Saved to "+folderDir+"\n")
class TaskWindowMaker(object):
def __init__(self):
pass
def cProfWindow(self):
global numbercProfWindow
cProf = Tk()
cProf.title("Create Profiles")
cProf.geometry("300x250")
cProfFrame = Frame(cProf)
cProfFrame.pack()
titleLabel = Label(cProfFrame, font="Helvetica 18 bold", text="Create Profiles")
titleLabel.grid(row=0, column=0, sticky=W)
menuLabel = Label(cProfFrame, text="Folder Name")
menuLabel.grid(row=1, column=0, sticky=W)
directoryNamecProfWindow = StringVar()
cDirEntry = Entry(cProfFrame, textvariable=directoryNamecProfWindow)
cDirEntry.grid(row=1, column=1, sticky=W)
menuLabel = Label(cProfFrame, text="Number of Profiles")
menuLabel.grid(row=2, column=0, sticky=W)
numbercProfWindow = StringVar()
cDirEntry = Entry(cProfFrame, textvariable=numbercProfWindow)
cDirEntry.grid(row=2, column=1, sticky=W)
cProfF = ProfileDeveloper(directoryNamecProfWindow)
cDir = Button(cProfFrame, text="Enter", command=cProfF.create_folder_profiles, height=2,width=20)
cDir.grid(row=3, column=0, sticky=W)
start = Menu()
start.menuWindow()
This is my code. I'm opening multiple Windows. Then when I enter in an input box in
numbercProfWindow = StringVar()
cDirEntry = Entry(cProfFrame, textvariable=numbercProfWindow)
cDirEntry.grid(row=2, column=1, sticky=W)
I'm then using the button:
cProfF = ProfileDeveloper(directoryNamecProfWindow)
cProf = Button(cProfFrame, text="Enter", command=cProfF.create_folder_profiles, height=2,width=20)
cProf.grid(row=3, column=0, sticky=W)
To send the input to ProfileDeveloper.create_folder_profiles
When it's sent to ProfileDeveloper.create_folder_profiles the program doesn't recognise the input, as in it's not '.get()ing it'.
I'm quite new so don't know how to pass variables between different functions and using the .get() function or global variables.
The main aim of the program is creating a profiles (txt files) in a specified folder. Instead of it being a script in shell I'm trying to add a Tkinter GUI.
Hopefully this explains it as I've asked before and people just get too confused. There's still a lot of code which I don't show but the confusion between passing variables continues throughout the code so not sure. The code was really long and just running in Shell then I added the Tkinter GUI and it's complicated it all by doubling variables and now this, so any help is greatly appreciated.
Thanks :)
Does this example help You understand better what You can do:
from tkinter import Tk, Entry, Button
root = Tk()
class UserInput:
def __init__(self, master):
self.master = master
self.entry = Entry(self.master)
self.entry.pack()
self.button = Button(self.master, text='Submit', command=self.submit)
self.button.pack()
def submit(self):
entry_var = self.entry.get()
print(entry_var)
user_input = UserInput(root)
root.mainloop()

How to add "equal to" sign to a tkinter calculator GUI?

Background: I am a newbie doing projects to get familiar with python.
Problem: I would like to add an "equal to" sign in my calculator I made using tkinter. How can I do this?
My idea: I commented out the attempt I made. Is there anyway to include if statement with an "and" so I can say something like if method is add and equal to then +
Here is my code:
from tkinter import Tk, Label, Button, IntVar, Entry, END, W, E
class Calculator:
def __init__(self, master):
self.total = 0
self.entered_number = 0
self.title_label = Label(master, text="Calculator")
self.total_label_text = IntVar()
self.total_label_text.set(self.total)
self.total_label = Label(master, textvariable=self.total_label_text)
self.label = Label(master, text="Total:")
vcmd = master.register(self.validate)
self.entry = Entry(master, validate="key", validatecommand=(vcmd, "%P"))
self.addition_button = Button(
master, text="Add", command=lambda: self.update("add")
)
self.subtract_button = Button(
master, text="Minus", command=lambda: self.update("minus")
)
self.equalto_button = Button(
master, text="Equals", command=lambda: self.update("equalto")
)
self.reset_button = Button(
master, text="Reset", command=lambda: self.update("reset")
)
self.close_button = Button(master, text="Close", command=master.quit, bg="red")
# LAYOUT
self.label.grid(row=1, column=1, sticky=W)
self.total_label.grid(row=1, column=0, columnspan=2, sticky=E)
self.entry.grid(row=2, column=0, columnspan=2, sticky=W + E)
self.addition_button.grid(row=3, column=0)
self.subtract_button.grid(row=3, column=1)
self.equalto_button.grid(row=3, column=2)
self.reset_button.grid(row=4, column=0, sticky=W + E)
self.close_button.grid(row=4, column=1)
def validate(self, new_text):
if not new_text:
self.entered_number = 0
return True
try:
self.entered_number = int(new_text)
return True
except ValueError:
return False
def update(self, method):
if method == "add":
self.total += self.entered_number
elif method == "minus":
self.total -= self.entered_number
# elif method == "equalto":
# self.total += self.entered_number
else:
self.total = 0
self.total_label_text.set(self.total)
self.entry.delete(0, END)
root = Tk()
my_gui = Calculator(root)
root.mainloop()
In Python, the "equal to" sign is "==", with modifications being made on the first "=" if you want "greater than", "less than", and etc.
Edit: "=" is an assignment whilst "==" is a comparison.

StringVar().get() not returning string

I am trying to get the input of what page number the user wants. They should type in a number, and click the submit button. To test it, I just want to print whatever they typed and then close the window. I've been following: http://effbot.org/tkinterbook/entry.htm as a guide, but I am stumped.
Why does
print(temp)
not print out a number to console?
right now it prints out:
<bound method IntVar.get of <tkinter.IntVar object at 0x000001FBC85353C8>>
I've cleaned up the code a little bit:
import sys
from file import *
from page import *
from view import View
import tkinter as tk
from tkinter import *
class ViewGui:
def __init__(self):
#Included in the class, but unrelated to the question:
self._file = File("yankee.txt", 25)
self.pages = self._file.paginate()
self.initial_list = self.pages[0].readpage(self._file.fo)
self.initial_string = ''.join(self.initial_list)
# Create root
self.root = Tk()
self.root.wm_title("yankee.txt - page 1")
# Create frame for buttons
self.bframe = Frame(self.root)
self.bframe.pack(side=BOTTOM, fill=X)
self.tbutton = tk.Button(self.bframe, text="Top", command=lambda a="top": self.clicks(a)).pack(side=LEFT, expand=1, fill=X)
self.bbutton = tk.Button(self.bframe, text="Bottom", command=lambda a="bottom": self.clicks(a)).pack(side=LEFT, expand=1, fill=X)
self.ubutton = tk.Button(self.bframe, text="Up", command=lambda a="up": self.clicks(a)).pack(side=LEFT, expand=1, fill=X)
self.dbutton = tk.Button(self.bframe, text="Down", command=lambda a="down": self.clicks(a)).pack(side=LEFT, expand=1, fill=X)
self.pbutton = tk.Button(self.bframe, text="Page", command=lambda a="page": self.pageclicks()).pack(side=LEFT, expand=1, fill=X)
self.qbutton = tk.Button(self.bframe, text="Quit", command=quit).pack(side=LEFT, expand=1, fill=X)
# Create and pack Text
self.T = Text(self.root, height=35, width=60, wrap=NONE)
self.T.pack(side=TOP, fill=X)
# Create and pack Scrollbar
self.S = Scrollbar(self.root, orient=HORIZONTAL, command=self.T.xview)
self.S.pack(side=BOTTOM, fill=X)
# Attach Text to Scrollbar
self.T.insert('1.0', self.initial_string)
self.T.config(xscrollcommand=self.S.set, state=DISABLED)
self.S.config(command=self.T.xview)
def pageclicks(self):
print("pageClicks is getting called at least...")
pop = Tk()
pop.wm_title("Page Number")
pop.label = Label(pop, text="Enter a Page Number:", width=35)
pop.label.pack(side=TOP)
pop.entrytext = IntVar()
Entry(pop, textvariable=pop.entrytext).pack()
pop.submitbuttontext = StringVar()
Button(pop, text="Submit", command=lambda a=pop: self.submitted(a)).pack(side=LEFT, pady=5, padx=40)
pop.cancelbuttontext = StringVar()
Button(pop, text="Cancel", command=pop.destroy).pack(side=LEFT, pady=5, padx=40)
def submitted(self, a):
print('submitted is getting called')
temp = (a.entrytext.get)
print(temp)
def clicks(self, a):
print("you clicked clicks with the " + a)
self.root.wm_title(self._file.filename + " - Page " + self._file.buttonHandler(a))
if __name__ == "__main__":
vg = ViewGui()
vg.root.mainloop()
When you create a new window you should not use Tk(), you must use tk.Toplevel()
Must change:
pop = Tk()
to
pop = tk.Toplevel()
You should also use get(), not just get. Must change:
temp = (a.entrytext.get)
to
temp = a.entrytext.get()
Code:
def pageclicks(self):
print("pageClicks is getting called at least...")
pop = tk.Toplevel()
pop.wm_title("Page Number")
pop.label = Label(pop, text="Enter a Page Number:", width=35)
pop.label.pack(side=TOP)
pop.entrytext = IntVar()
Entry(pop, textvariable=pop.entrytext).pack()
pop.submitbuttontext = StringVar()
Button(pop, text="Submit", command=lambda a=pop: self.submitted(a)).pack(side=LEFT, pady=5, padx=40)
pop.cancelbuttontext = StringVar()
Button(pop, text="Cancel", command=pop.destroy).pack(side=LEFT, pady=5, padx=40)
def submitted(self, a):
print('submitted is getting called')
temp = a.entrytext.get()
print(temp)
Made changes to these two methods and now it is working.
def pageclicks(self):
print("pageClicks is getting called at least...")
pop = Tk()
pop.wm_title("Page Number")
pop.label = Label(pop, text="Enter a Page Number:", width=35)
pop.label.pack(side=TOP)
pop._entry = Entry(pop)
pop._entry.pack()
pop._entry.focus_set()
Button(pop, text="Submit", command=lambda a=pop: self.submitted(a)).pack(side=LEFT, pady=5, padx=40)
Button(pop, text="Cancel", command=pop.destroy).pack(side=LEFT, pady=5, padx=40)
def submitted(self, _pop):
temp = _pop._entry.get()
print(temp)
_pop.destroy()

Python - TKinter "times out"

This is my first post on stackoverflow but I have been using the answers for some time now as I've hit bumps in the code road. The dark day has come where I can't seem to find the answer so please let me know if you can help.
The program is pretty simple I'm using Tkinter to create a widget that just sits on my desktop and tells me how many files are in specific folders. It seems to work pretty well for about 10 minutes and then stops working. It doesn't crash or ping up an error message it just freezes until I realise that somethings wrong and then when I go to click on it or close it down it says it has stopped working.
Here's my code:
import Tkinter as tk
import time
import os
from Tkinter import Tk, Label, BOTH
from ttk import Frame, Style
class SampleApp(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
self.clock = tk.Label(self, text="")
self.clock.pack()
# start the clock "ticking"
self.update_clock()
def update_clock(self):
ptc = len(os.listdir("Folder Dir"))
if ptc != 0:
label1 = Label(self, text="Pre TC", fg="red")
else:
label1 = Label(self, text="Pre TC")
label1.place(x=0, y=0)
if ptc != 0:
label2 = Label(self, text=ptc, fg="red")
else:
label2 = Label(self, text=ptc)
label2.place(x=90, y=0)
pp = len(os.listdir("Folder Dir"))
if pp != 0:
label3 = Label(self, text="PP", fg="red")
else:
label3 = Label(self, text="PP")
label3.place(x=0, y=65)
if pp != 0:
label4 = Label(self, text=pp, fg="red")
else:
label4 = Label(self, text=pp)
label4.place(x=90, y=65)
stc = len(os.listdir("Folder Dir"))
if stc != 0:
label5 = Label(self, text="Super TC", fg="red")
else:
label5 = Label(self, text="Super TC")
label5.place(x=0, y=150)
if stc!= 0:
label6 = Label(self, text=stc, fg="red")
else:
label6 = Label(self, text=stc)
label6.place(x=90, y=150)
wff = len(os.listdir("Folder Dir"))
if wff != 0:
label7 = Label(self, text="WIN FF", fg="red")
else:
label7 = Label(self, text="WIN FF")
label7.place(x=0, y=230)
if wff != 0:
label8 = Label(self, text=wff, fg="red")
else:
label8 = Label(self, text=wff)
label8.place(x=90, y=230)
wa = len(os.listdir("Folder Dir"))
if wa != 0:
label9 = Label(self, text="Wave Agent", fg="red")
else:
label9 = Label(self, text="Wave Agent")
label9.place(x=0, y=315)
if wa != 0:
label10 = Label(self, text=wa, fg="red")
else:
label10 = Label(self, text=wa)
label10.place(x=90, y=315)
bwf = len(os.listdir("Folder Dir"))
if bwf != 0:
label11 = Label(self, text="BWF", fg="red")
else:
label11 = Label(self, text="BWF")
label11.place(x=0, y=395)
if bwf != 0:
label12 = Label(self, text=bwf, fg="red")
else:
label12 = Label(self, text=bwf)
label12.place(x=90, y=395)
swi = len(os.listdir("Folder Dir"))
if swi != 0:
label13 = Label(self, text="Switch", fg="red")
else:
label13 = Label(self, text="Switch")
label13.place(x=0, y=480)
if swi != 0:
label14 = Label(self, text=swi, fg="red")
else:
label14 = Label(self, text=swi)
label14.place(x=90, y=480)
# call this function again in one second
self.after(1000, self.update_clock)
def main():
app = SampleApp()
app.title('Counter')
app.geometry("50x510+1000+8")
app.mainloop()
if __name__== "__main__":
main()
All help would be really apprciated!
Cheers!
Looks like you're creating 14 new widgets every second, but you never destroy any of the old ones. After ten minutes of this, you've got a window that has to keep track of 8,400 elements, which I expect would bog it down considerably.
I see two solutions:
.destroy() all previous widgets before you create more.
create 14 widgets exactly once at the beginning of the program, then .config them to change their text during every update_clock call.

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