Using tkinter IntVar to update a label - python

Having taken a class on C and Assembly, I decided I wanted to learn python. This is my first attempt with it so please excuse any abuse of notation.
The following is the portion of my GUI I have created to control a grow cycle. I am having an issue with the use IntVar. I have created a countdown to the end-of-cycle (see countdown method). I have tried including the self.remaining label within Countdown, it does show the countdown but the label showing the countdown does not destroy with the cancel button and time_state label at end-of-cycle. With the self.remaining label put in the init using IntVar, it shows the initial countdown in days,hours, mins,secs but stays with that initial value and does not update as countdown is repeated. Shouldn't using IntVar this way update the day_val, hour_val, min_val, and sec_val in the self.remaining label?
from tkinter import *
import time
class Grow_Cycle():
def __init__(self):
self.time_state = Label(app, text = ("You have selected:\n "+str(day_val)+" days,\n "+str(hour_val)+" hours,\n "+str(min_val)+" minutes"))
self.time_state.grid(column = 1, row =1)
self.bttn_3 = Button(app, text = "Cancel", command = self.cancel)
self.bttn_3.configure(bg = "red")
self.bttn_3.grid(row = 2, column = 0,
ipadx = 50, ipady = 20,
padx = 20, pady = 100)
self.temp1 = (day_val * 86400)+(hour_val * 3600)+(min_val * 60)
self.countdown()
self.remaining = Label(app, text = ("You have remaining:\n"+str(day_lef.get())+" days,\n"
+str(hour_lef.get())+" hours,\n"
+str(min_lef.get())+" minutes,\n"
+str(sec_lef.get())+" seconds"),
textvariable = (day_lef, hour_lef, min_lef, sec_lef))
self.remaining.grid(column = 1, row = 2)
def cancel(self):
self.remaining.destroy()
self.bttn_3.destroy()
self.time_state.destroy()
self.temp1 = 0
def countdown(self):
if self.temp1 > 0:
self.temp1 -= 1
global day_lef
day_lef = IntVar()
day_lef.set(int(self.temp1 / 86400))
day_rem = self.temp1 % 86400
global hour_lef
hour_lef = IntVar()
hour_lef.set(int(day_rem / 3600))
hour_rem = day_rem % 3600
global min_lef
min_lef = IntVar()
min_lef.set(int(hour_rem / 60))
min_rem = hour_rem % 60
global sec_lef
sec_lef = IntVar()
sec_lef.set(int(min_rem % 60))
clock.after(1000, self.countdown)
else:
self.cancel()
def tick():
global time1
time2 = time.strftime('%H:%M:%S\n\n%m-%d-%Y')
if time2 != time1:
time1 = time2
clock.config(text=time2)
clock.after(200, tick)
def grow():
# Grow Time set window
set_grow_time = Toplevel(app)
set_grow_time.title("Enter Cycle Time")
set_grow_time.geometry("240x400")
# Set Day
set_day_grow = Spinbox(set_grow_time, from_ = 0, to_ = 10)
set_day_grow.grid(column = 0, row =0,
padx = 20, pady = 20)
set_day_grow.config(width = 10)
set_day_lbl = Label(set_grow_time, text = "Set Day: 0 to 10")
set_day_lbl.grid(column = 1, row = 0)
# Set Hour
set_hour_grow = Spinbox(set_grow_time, from_ = 0, to_ = 23)
set_hour_grow.grid(column = 0, row = 1,
padx = 20, pady = 20)
set_hour_grow.config(width = 10)
set_hour_lbl = Label(set_grow_time, text = "Set Hour: 0 to 23")
set_hour_lbl.grid(column = 1, row = 1)
# Set Minute
set_min_grow = Spinbox(set_grow_time, from_ = 0, to_ = 59)
set_min_grow.grid(column = 0, row = 2,
padx = 20, pady = 20)
set_min_grow.config(width = 10)
set_hour_lbl = Label(set_grow_time, text = "Set Minute: 0 to 59")
set_hour_lbl.grid(column = 1, row = 2)
# Confirm Selection
def fetch_time():
global day_val
day_val = int(set_day_grow.get())
global hour_val
hour_val = int(set_hour_grow.get())
global min_val
min_val = int(set_min_grow.get())
Grow_Cycle()
confirm_grow_time = Button(set_grow_time, text = "OK", command = lambda: (fetch_time(), set_grow_time.destroy()))
confirm_grow_time.grid(column = 0, row = 3)
cancel_grow_time = Button(set_grow_time, text = "Cancel", command = set_grow_time.destroy)
cancel_grow_time.grid(column = 1, row = 3)
def clean():
pass # will finish later
def cancel():
pass # will finish later
# main
# Main Loop Begin
root = Tk()
root.title("Grower")
root.geometry("1280x720")
app = Frame(root)
app.grid()
time1 = ''
clock = Label(app)
clock.config(font = ("Impact", 20))
clock.grid(column = 1, row = 0,
ipadx = 20, ipady = 20,
padx = 50, pady =50)
# Button Setup
bttn_1 = Button(app, text = "Grow", command = grow)
bttn_1.configure(bg = "light green")
bttn_1.grid(column = 0, row = 0,
ipadx = 50, ipady = 20,
padx = 20, pady = 100)
bttn_2 = Button(app, text = "Clean", command = clean)
bttn_2.configure(bg = "cyan")
bttn_2.grid(row = 1, column = 0,
ipadx = 50, ipady = 20,
padx = 20, pady = 100)
tick()
root.mainloop()

After reviewing your code I have made some changes to how you are formatting your strings and how you are apply strings to your labels.
Your class def was not working for me so I rewrote it with a standard method I use to create a tkinter class.
I don't believe you can have both a text = "string' and a textvariable = StringVar() at the same time. So I have formatted the data into your string var.
The way you had it set up it would not work for a few reason. You cant use multiple IntVar()'s in a textvariable so you need to first combine them into a string variable and then use that as your update method to the label.
I have changed your string concatination removing the + method and using format() instead as this is the correct method currently.
I also added self.string_var.set to your countdown() method so we can keep this updated with the countdown.
Take a look at this code and let me know if you have any question.
import tkinter as tk
class Grow_Cycle(tk.Frame):
def __init__(self, master, *args, **kwargs):
tk.Frame.__init__(self, master, *args, **kwargs)
self.master = master
self.day_val = 1
self.hour_val = 0
self.min_val = 0
self.day_lef = tk.IntVar()
self.day_lef.set(1)
self.hour_lef = tk.IntVar()
self.hour_lef.set(0)
self.min_lef = tk.IntVar()
self.min_lef.set(0)
self.sec_lef = tk.IntVar()
self.sec_lef.set(0)
self.day_rem = 0
self.hour_rem = 0
self.min_rem = 0
self.string_var = tk.StringVar()
self.string_var2 = tk.StringVar()
self.string_var.set(
"You have remaining:\n{} days,\n{} hours,\n{} minutes,\n{} seconds".format(self.day_lef.get(), self.hour_lef.get(), self.min_lef.get(), self.sec_lef.get()))
self.time_state = tk.Label(self.master, text = (
"You have selected:\n {} days,\n {} hours,\n {} minutes").format(self.day_val, self.hour_val, self.min_val))
self.time_state.grid(row = 1, column = 1)
self.bttn_3 = tk.Button(self.master, bg = "red", text = "Cancel", command = self.cancel)
self.bttn_3.grid(row = 2, column = 0, ipadx = 50, ipady = 20, padx = 20, pady = 100)
self.temp1 = (self.day_val * 86400)+(self.hour_val * 3600)+(self.min_val * 60)
self.remaining = tk.Label(self.master, textvariable = self.string_var)
self.remaining.grid(column = 1, row = 2)
self.countdown()
def cancel(self):
self.remaining.destroy()
self.bttn_3.destroy()
self.time_state.destroy()
self.temp1 = 0
def countdown(self):
self.string_var.set(
"You have remaining:\n{} days,\n{} hours,\n{} minutes,\n{} seconds".format(self.day_lef.get(), self.hour_lef.get(), self.min_lef.get(), self.sec_lef.get()))
if self.temp1 > 0:
self.temp1 -= 1
self.day_lef.set(int(self.temp1 / 86400))
self.day_rem = self.temp1 % 86400
self.hour_lef.set(int(self.day_rem / 3600))
self.hour_rem = self.day_rem % 3600
self.min_lef.set(int(self.hour_rem / 60))
self.min_rem = self.hour_rem % 60
self.sec_lef.set(int(self.min_rem % 60))
root.after(1000, self.countdown)
else:
self.cancel()
if __name__ == "__main__":
root = tk.Tk()
Grow_Cycle(root)
root.mainloop()

Related

Checkbutton is not clickable after adding an image to it

I started working with tkinter recently and I have the following problem, I need to make the check box bigger but that is only possible with adding an image. The problem is that whenever I add an image to a button it becomes unclickable and the image is not displayed, here is my source code (part of a bigger project). My goal is to display some information and let the user decide which option he gets to keep using the check button. Any help is appreciated.
import tkinter as tk
import tkcalendar as tkc
LARGE_FONT = ("HELVETICA", 32, 'bold')
NORMAL_FONT = ("calibri", 18)
class ConstituireDosar(tk.Toplevel):
def __init__(self, controller):
tk.Toplevel.__init__(self)
self.update_idletasks()
# self.dosar = dosar
self.controller = controller
self.minsize(651, 569)
# self.maxsize(651, 569)
frame_titlu = tk.Frame(self)
frame_titlu.grid(row = 0, column = 0)
frame_continut = tk.Frame(self)
frame_continut.grid(row = 1, column = 0, sticky = "w")
frame_acte = tk.Frame(self)
frame_acte.grid(row = 2, column = 0)
titlu = tk.Label(frame_titlu, font = LARGE_FONT, text = "Constituire Dosar")
titlu.grid(row = 0 , column = 0, padx = 10, pady = 15)
data_emiterii = tk.Label(frame_continut, font = NORMAL_FONT,text = "Data emiterii documentului:")
data_emiterii.grid(row = 1, column = 0, padx = 10, pady = 5, sticky = "w")
self.cal = tkc.DateEntry(frame_continut, date_pattern = "DD/MM/YYYY", width = 20)
self.cal.grid(row = 2, column = 0, padx = 10, pady = 5, sticky = "w")
debitori_label = tk.Label(frame_continut, font = NORMAL_FONT, text = "Selecteaza debitorii.")
debitori_label.grid(row = 3, column = 0, padx = 10, pady = 5, sticky = "w")
debitori = []
tip_debitori = []
for i in range(2):
debitori.append("Person %s " % str(i))
tip_debitori.append("Person %s type" % str(i))
for i in range(len(debitori)):
print(debitori[i])
row_i = 4
self.vars_debitori = []
on_image = tk.PhotoImage(width=48, height=24)
off_image = tk.PhotoImage(width=48, height=24)
on_image.put(("green",), to=(0, 0, 23,23))
off_image.put(("red",), to=(24, 0, 47, 23))
for i in range(len(debitori)):
var = tk.IntVar(frame_continut, value = 0)
interior = debitori[i] + " - " + tip_debitori[i]
# Checkbutton(ws, image=switch_off, selectimage=switch_on, onvalue=1, offvalue=0, variable=cb1, indicatoron=False, command=switchState)
checkbuton = tk.Checkbutton (frame_continut, bd = 5, image = off_image, selectimage = on_image, indicatoron = False, onvalue = 1, offvalue = 0, variable = var, state = tk.ACTIVE, command = lambda: self.toggle(var))
checkbuton.grid(row = row_i, column = 0, padx = 20, pady = 5, sticky = "nw")
checkbuton.image = off_image
# checkbuton.select()
self.vars_debitori.append(var)
row_i += 1
self.vars_acte = []
acte = ["Acte de Procedura", "Incheiere de Admitere", "Cerere de Incuviintare", "Instiintare Creditor"]
for i in range(4):
v = tk.IntVar()
check = tk.Checkbutton(frame_acte, font = NORMAL_FONT, text = acte[i], variable = v)
check.grid(row = row_i, column = 0, padx = 10, pady = 5)
check.select()
self.vars_acte.append(v)
row_i += 1
emite_acte = tk.Button(frame_acte, font = NORMAL_FONT, text = "Emite acte.", command = self.emite_acte)
emite_acte.grid(row = row_i, column = 1, padx = 15, pady = 30, ipadx = 70, ipady = 10)
emite_acte.configure(bg = '#218838', fg = '#FFFFFF')
buton_cancel = tk.Button(frame_acte, font = NORMAL_FONT, text = "Cancel", command = lambda: self.destroy())
buton_cancel.grid(row = row_i, column = 0, padx = 15, pady = 30, ipadx = 70, ipady = 10)
buton_cancel.configure(bg = "red", fg = '#FFFFFF')
def emite_acte(self):
print(self.cal.get_date().strftime("%d/%m/%y"))
print(self.winfo_height(), self.winfo_width())
if __name__ == "__main__":
root = tk.Tk()
app = ConstituireDosar(root)
app.protocol("WM_DELETE_WINDOW", root.destroy)
root.withdraw()
root.mainloop()
I tried some options that I saw on the forum, in another file they worked fine but when I tried to implement it in the project itself the checkbutton is still unclickable and it doesn't display the images either. tkinter checkbutton different image I tried to replicate Bryan's answer, but no luck there. Also didn't receive any console error message.
As #furas pointed in the comments above, the problem got fixed with keeping the images as member variables of the class, also the button became clickable after removing the self.toggle(var) command from checkbutton

How to avoid resetting a value by pressing a button again

The buttonGuess runs numRandom function when it's pressed and it also runs remainingAttemps function. The problem is if user presses the buttonGues, Attemps value is reasigned again.
import tkinter
import random
window = tkinter.Tk()
window.geometry('600x500')
x = random.randint(1,10)
remainingTime = True
Attempts = 4
def countdown (time_left):
global remainingTime
if remainingTime == True:
lblCrono.configure(text = str(time_left))
if time_left > 0:
time_left = time_left - 1
window.after(1000, countdown, time_left)
else:
remainingTime = False
lblCrono.configure(text = 0)
return remainingTime, gameOver()
else:
return
def numRamdom():
global Attempts
numWritten = int(entryWriteNumber.get())
if numWritten > x:
lblClue.configure(text = 'Its a smaller number')
return remainingAttempts(Attempts)
if numWritten < x:
lblClue.configure(text = 'Its a bigger number')
return remainingAttempts(Attempts)
if numWritten == x:
lblClue.configure(text = 'Congratulations ;)')
remainingTime = False
return remainingTime, countdown(0)
def gameOver():
if remainingTime == False and Attempts != 0:
lblClue.configure(text = '¡Time\'s up!')
else:
lblClue.configure(text = 'No attempts')
def remainingAttempts(countAtempts):
Attempts = countAtempts
if Attempts == 0:
return remainingTime, countdown(0), Attempts, gameOver()
else:
Attempts = Attempts - 1
entryWriteNumber = tkinter.Entry(window)
entryWriteNumber.grid(column = 0, row = 1, padx = 10, pady = 10)
lblNumber = tkinter.Label(window, text = 'Number', font = 'Comic 13 bold')
lblNumber.grid(column = 0, row = 0, padx = 10, pady = 10, sticky = tkinter.W )
buttonGuess = tkinter.Button(window, text = 'Guess', bg = 'light grey', padx = 20, command = numRamdom)
buttonGuess.grid(column = 0, row = 2, sticky = tkinter.W, padx = 10, pady = 10)
lblClue = tkinter.Label(window, text = 'Clue', font = 'Comic 13 bold')
lblClue.grid(column = 0, row = 3, padx = 10, pady = 10, sticky = tkinter.W )
lblCrono = tkinter.Label(window, text = '', bg = 'white', fg = 'red', font = 'Comic 20', padx = 50, pady = 5)
lblCrono.grid(column = 1, row = 5, sticky = tkinter.S, padx = 100, pady = 150)
countdown(30)
window.mainloop()
It's all much easier to manage when you get rid of everything that either isn't doing anything or is unnecessary. All your returns are doing nothing. Creating a remainingTime variable when you have a counter is unnecessary. Giving your widgets and functions a bunch of complicated and/or misleading names, isn't helping. You were calling countdown(0) which calls gameOver() and then calling gameOver().
You never put something on row=4, but you put your timer on row=5. This is visibly no different than putting it on 4. You had very repetitive grid options so I homogenized them in a dict and used that dict as **kwargs. Writing your arguments like this -> func(arg1 = value1, arg2 = value2, ...) has no benefit. There's no reason to keep a reference to lblNumber or buttonGuess. You never modify or further reference either, in any way. If you don't specify a column, tkinter will assume you mean column=0. If you don't specify a row, tkinter will assume you mean 1 row greater than the total current rows, regardless of column. Importing tkinter without an alias just gives you more to type.
Below is my edit of your game based on everything I just wrote.
import tkinter as tk
import random
root = tk.Tk()
root.geometry('600x500')
x = random.randint(1,10)
remaining = 4
def countdown(time_left):
global process
chrono['text'] = str(time_left)
if time_left:
process = root.after(1000, countdown, time_left-1)
else:
gameOver()
def check():
global remaining
n = int(guess.get())
if n == x:
gameOver(True)
return
else:
clue['text'] = f'Its a {"smaller" if n > x else "bigger"} number'
remaining -= 1
if not remaining:
gameOver()
def gameOver(win=False):
root.after_cancel(process)
if not win:
clue['text'] = '¡Time\'s up!' if remaining else 'No attempts remain'
else:
clue['text'] = 'Congratulations ;)'
grid = dict(padx=10, pady=10, sticky=tk.W)
tk.Label(root, text='Number', font='Comic 13 bold').grid(**grid)
guess = tk.Entry(root)
guess.grid(**grid)
tk.Button(root, text='Guess', bg='light grey', padx=20, command=check).grid(**grid)
clue = tk.Label(root, text='Clue', font='Comic 13 bold', width=20, anchor='w')
clue.grid(**grid)
chrono = tk.Label(root, text='', bg='white', fg='red', font='Comic 20', padx=50, pady=5)
chrono.grid(column=1, **grid)
countdown(30)
root.mainloop()

Tkinter: keep update a variable

I really need help, my brain is melting because of this problem. I've studied python for 2 months maybe and I'm not very expert in programming. I've got an issue... I'm using tkinter on this program; in this small GUI I'd like to always keep updated the global variable "temp", and its value should change everytime I click on the button. I know that mainloop() is a blocking method, so it is possible to do something like this?
import tkinter as tk
class App:
def __init__(self):
super().__init__()
self.screen = tk.Tk()
self.screen.geometry("400x400")
self.screen.title("Modifica temperatura ambiente")
self.screen.grid_columnconfigure(0, weight = 1)
self.label = tk.Label(self.screen, text="ENTER TEMPERATUR VALUE", fg = "black", font = ("Calibri", 10) )
self.label.grid(row = 0, column = 0, sticky = "N", pady = 10)
self.input_ = tk.Entry(self.screen)
self.input_.grid(row = 1, column = 0, sticky = "WE", pady = 5, padx = 20)
self.button = tk.Button(self.screen, text = "INVIA", command = self.getvalue)
self.button.grid(row = 2, column = 0, sticky = "WE", pady = 5, padx = 10)
def getvalue(self):
self.temp = self.input_.get()
temperatura_label = tk.Label(self.screen, text = "Last input value is " + self.temp + " degrees", fg = "red")
temperatura_label.grid(row = 3, column = 0, sticky = "S")
return self.temp
app = App()
temp = app.getvalue()
print(temp)
app.screen.mainloop()
Thank for the help!
If you want to print it in the terminal, modify your getvalue function.
Code:
import tkinter as tk
screen = tk.Tk()
screen.geometry("400x400")
screen.title("Modifica temperatura ambiente")
screen.grid_columnconfigure(0, weight = 1)
class App:
def __init__(self, master):
super().__init__()
self.master = master
self.label = tk.Label(master, text="ENTER TEMPERATUR VALUE", fg = "black", font = ("Calibri", 10) )
self.label.grid(row = 0, column = 0, sticky = "N", pady = 10)
self.input_ = tk.Entry(master)
self.input_.grid(row = 1, column = 0, sticky = "WE", pady = 5, padx = 20)
def getvalue(self):
self.temp = self.input_.get()
temperatura_label = tk.Label(self.master, text = "Last input value is " + self.temp + " degrees", fg = "red")
temperatura_label.grid(row = 3, column = 0, sticky = "S")
if self.temp == None:
print()
else:
return self.temp
app = App(screen)
def main_loop():
global app
temp = app.getvalue()
print(temp)
button = tk.Button(screen, text = "INVIA", command = main_loop)
button.grid(row = 2, column = 0, sticky = "WE", pady = 5, padx = 10)
screen.mainloop()

Why does the entry widget not work in this case i put it in a frame, tkinter-python

So this is a basic clock and alarm that i am creating, and in the process i want the user to type in what hour and minute they want to set for the alarm. But the entry widget here is not responding.
import time
import tkinter as tk
current_date, current_time = 0, 0
def current_info(timeinfo): #function to get the current time and date
global current_date, current_time
# current time
current_time = time.strftime('%H:%M:%S')
current_date = time.strftime(r'%m/%d/%Y')
clock.after(200, timeinfo)
#Initialise the window
clock = tk.Tk()
clock.title('Easy CLock')
clock.configure(bg='#121212')
clock.columnconfigure(0, weight = 1)
clock.columnconfigure(1, weight = 1)
clock.columnconfigure(2, weight = 1)
clock.columnconfigure(3, weight = 1)
border_effects = {
"flat": tk.FLAT,
"sunken": tk.SUNKEN,
"raised": tk.RAISED,
"groove": tk.GROOVE,
"ridge": tk.RIDGE,
}
#Logo will be under the main parent
logo = tk.PhotoImage(file = r'C:\Users\User\VSC\Alarm\Logo1.png')
logo_size = logo.subsample(5)
#Time and Date function
def time_date():
current_info(time_date)
#Displays the time
c_time = tk.Label(f_time, text = current_time, fg='white', bg='#121212', font=('Verdana', 30))
c_date = tk.Label(f_time, text = current_date, font=('Verdana', 10), fg='white', bg='#121212')
c_time.grid(column=0, row=0)
c_date.grid(column=0, row=1)
#alarm button command
def alarm_func():
current_info(alarm_func)
c_time = tk.Label(f_alarm, text = current_time, fg='white', bg='#121212', font=('Verdana', 10))
c_date = tk.Label(f_alarm, text = current_date, font=('Verdana', 10), fg='white', bg='#121212')
def pressed_enter(): #Command for the enter button
set_label = tk.Label(f_alarm, text = f'Alarm has been set for {time_set}', fg ='white', bg = '#121212', borderwidth = 1, relief = border_effects['sunken'])
set_label.grid(column = 4, row = 0, sticky = 'W')
# Set the time and date for the alarm
set_time = tk.StringVar()
alarm_entry = tk.Entry(clock, textvariable = set_time)
set_time.set('H : M')
time_set = alarm_entry.get()
#label and entry to set alarm / Enter Button
c_label = tk.Label(f_alarm, text = 'Set Alarm: ', font = ('Verdana', 10), fg= 'white', bg ='#121212' )
alarm_enter = tk.Button(f_alarm, text = 'Enter', font = ('Verdana', 7), width = 5, command = pressed_enter)
#Pack the widgets
c_time.grid(row = 0, column = 0)
c_date.grid(column = 1 , row = 0)
alarm_enter.grid(row = 2, column = 3)
c_label.grid(row = 2, sticky = 'W')
alarm_entry.grid(row = 2, column = 1)
#configure the empty columns
f_alarm.columnconfigure(2, minsize = 10)
def recall_frame(event):
if event == f_alarm:
event.grid_forget()
f_time.grid(column=0, row =1, columnspan = 4, sticky = 'N')
elif event == f_time:
event.grid_forget()
f_alarm.grid(column=0, row=1, columnspan = 4, sticky = 'W')
def back_func():
pass
#Creating Frames
f_time = tk.Frame(clock) #Clock Button
f_alarm = tk.Frame(clock) #Alarm Buttton
#configure the frames
f_time.configure(bg = '#121212')
f_alarm.configure(bg = '#121212')
#Setting label in the frame
f_lbl = tk.Label(clock, text= ' Simplistic Clock', image = logo_size, font=('Verdana', 30), fg='white', bg='#121212', compound = tk.LEFT, padx = 35)
time_but = tk.Button(clock, text='Clock', command= lambda :[time_date(), recall_frame(f_alarm)], bg='#f39c12', relief = border_effects['ridge'], pady = 7)
alarm_but = tk.Button(clock, text = 'Alarm', command = lambda :[alarm_func(), recall_frame(f_time)], bg='#f39c12', relief = border_effects['ridge'], pady = 7)
quit_but = tk.Button(clock, text='Exit', command = clock.quit, bg='#f39c12', relief = border_effects['ridge'], pady = 7)
back_but = tk.Button(clock, text = 'Back ', command = back_func, bg='#f39c12', relief = border_effects['ridge'], pady = 7)
f_lbl.config(borderwidth = 4, relief = border_effects['sunken'])
#Putting it on the frames
f_lbl.grid(column = 0, row = 0, columnspan = 5, sticky = 'EW')
time_but.grid(column = 0, row = 3, sticky = 'EW')
alarm_but.grid(column = 1, row = 3, sticky = 'EW')
quit_but.grid(column = 3, row = 3, sticky = 'EW')
back_but.grid(column = 2, row = 3, sticky = 'EW')
clock.mainloop()
i tried testing an entry widget outside the frame and the entry widget was able to work, is it because the frame f_alarm is not looping constantly in the background?
When someone clicks on your button which activates the pressed_enter() function, it will call that function again every time which will set the time to H:M and it will get that value as the set_time.get() is called immediately after.
You're also creating a new Entry every time the button is being clicked because you put alarm_entry = tk.Entry(clock, textvariable=set_time)
in there as well. You should only put the set_time.get inside of that button so that it gets the value that is currently filled in into the Entry. The other things like
set_time = tk.StringVar()
alarm_entry = tk.Entry(clock, textvariable=set_time)
set_time.set('H : M')
Should be put outside of that function so they don't get called every time someone clicks on the button.

create a mathematis matrix with python

Well, I've looked a lot in the web before asking, so here's the thing.
I'm not really experienced in Python and I need to develop this Matrix Generator. Yes, it is a mathematics matrix. I'm using Tkinter and Python 3.3.
First i ask the Number of Rows and Columns and then I fill each field and the code transforms it in a notepad for other programs to read.
I used the grid method so i'm having trouble with large scale matrices. The thing is I need to apply a scrollbar. I have read that I can use frame and a friend of mine showed me a scrollbar he made using frames. Can you help me? ;D
Every time I refer to linhas is the same as rows and colunas is the same as columns.
import tkinter
class DropDown:
def __init__(self):
self._list_window = tkinter.Tk();
self._row_var = tkinter.StringVar(self._list_window)
self._col_var = tkinter.StringVar(self._list_window)
self._row_var.set(0)
self._col_var.set(0)
self._rows = None
self._columns = None
self._row_label = tkinter.Label(
master = self._list_window,
text = 'Number of rows: ')
self._row_label.grid(
row = 0, column = 0, padx = 5, pady = 5,
sticky = tkinter.NE)
self._row_entry = tkinter.Entry(self._list_window, width=1)
self._row_entry.grid(
row = 0, column = 1, padx = 5, pady = 5,
sticky = tkinter.EW)
self._column_label = tkinter.Label(
master = self._list_window,
text = 'Number of columns: ')
self._column_label.grid(
row = 1, column = 0, padx = 5, pady = 5,
sticky = tkinter.NE)
self._column_entry = tkinter.Entry(self._list_window)
self._column_entry.grid(
row = 1, column = 1, padx = 5, pady = 5,
sticky = tkinter.EW)
self._list_window.columnconfigure(1, weight = 1)
self._OK_button = tkinter.Button(
master = self._list_window, text = "OK",
command = self.get_dimensions)
self._OK_button.grid(
row = 2, column = 0, columnspan = 2,
padx = 5, pady = 5)
def get_dimensions(self):
self._rows = self._row_entry.get()
self._columns = self._column_entry.get()
self._list_window.destroy()
def show(self):
self._list_window.mainloop()
if self._rows != None and self._columns != None:
return (int(self._rows), int(self._columns))
else:
return (None, None)
class matrix:
def __init__(self, linhas, colunas):
self.linhas=linhas
self.colunas=colunas
self.mwindow=tkinter.Tk()
self.vars = [[] for x in range(self.linhas) ]
for i in range(self.linhas):
for j in range(self.colunas):
v=tkinter.StringVar()
self.vars[i].append(v)
entry = tkinter.Entry(master = self.mwindow, textvariable = self.vars[i][j])
entry.grid(row = i, column = j, padx = 10, pady = 10)
self.botOK=tkinter.Button(master=self.mwindow, text="OK", command=self.OK)
self.botOK.grid(row=self.linhas+1, column=(self.colunas//2)-1, columnspan=2, padx=5, pady=5)
def Start(self):
self.mwindow.mainloop()
return self.lista
def OK(self):
self.lista = []
for i in range(self.linhas):
for j in range(self.colunas):
self.lista.append(self.vars[i][j].get())
self.mwindow.destroy()
dimensoes= DropDown().show()
#print (dimensoes)
if dimensoes[0]<dimensoes[1]:
diag=dimensoes[0]
else:
diag=dimensoes[1]
matriz=matrix(dimensoes[0], dimensoes[1]).Start()
with (open("notepadmatrix.txt", "w")) as arquivo:
arquivo.write(str(dimensoes[0]*dimensoes[1])+"\n")
arquivo.write(str(dimensoes[0])+"\n")
arquivo.write(str(dimensoes[1])+"\n")
arquivo.write(str(diag)+"\n")
for i in matriz:
arquivo.write(i+"\n")
arquivo.write("fim")
and here goes the code he gave me to the scroll bar.
class Earnings():
def __init__(self, Ticker, EPS, Time):
self._root_window = tkinter.Tk()
self.canvas = tkinter.Canvas(master = self._root_window, background = '#8989E0')
self.canvas.config(scrollregion=[0,0,600,10000])
self.frame = tkinter.Frame(master = self.canvas)
self.scrollbar = tkinter.Scrollbar(master = self._root_window, orient = tkinter.VERTICAL)
self.frame.pack(side = tkinter.LEFT, fill = tkinter.BOTH, expand = tkinter.TRUE)
self.canvas.create_window((0,0), window=self.frame, anchor=tkinter.NW)
self.scrollbar.pack(side = tkinter.RIGHT, fill = tkinter.BOTH, expand = tkinter.TRUE)
self.canvas.pack(side = tkinter.TOP, fill = tkinter.BOTH, expand = tkinter.TRUE)
self.scrollbar.config(command = self.canvas.yview)
self.canvas.config(yscrollcommand = self.scrollbar.set)
self.ticker = Ticker
self.EPS = EPS
self.time = Time
for i in range(len(self.ticker)):
self.TickerButton = tkinter.Button(
master = self.frame,
text = self.ticker[i],
command = lambda i=i: self.search_ticker(self.ticker[i]))
self.TickerButton.grid(row = i+1, column = 0, padx = 10, pady = 10,
sticky = tkinter.W)
self.EPSLabel = tkinter.Label(
master = self.frame,
text = self.EPS[i])
self.EPSLabel.grid(row = i+1, column = 1, padx = 10, pady = 10,
sticky = tkinter.W)
self.TimeLabel = tkinter.Label(
master = self.frame,
text = self.time[i])
self.TimeLabel.grid(row = i+1, column = 2, padx = 10, pady = 10,
sticky = tkinter.W)
TkInter is long in the tooth, I'd use Kivy Grid layout instead:
http://kivy.org/docs/api-kivy.uix.gridlayout.html?highlight=grid

Categories