I'm trying to create a menu in tkinter, in which there will be different conditions. One of them will be the date choice. Now you need to enter the date manually. I want to make a calendar. I thought to use the answer to this question and the code to which there is a link. But I do not know how to use it with my code.
Below is the code of my menu:
import numpy as np
items5 = np.arange(1,14)
items6 = np.arange(1, 28)
items7 = np.arange(4, 28)
choose_y_n = ['yes', 'no']
items12 = np.arange(50, 100)
items13 = np.arange(0,15)
from tkinter import*
class MyOptionMenu(OptionMenu):
def __init__(self, master, status, *options):
self.var = StringVar(master)
self.var.set(status)
OptionMenu.__init__(self, master, self.var, *options)
self.config(font=('Arial',(10)),bg='white',width=20)
self['menu'].config(font=('Arial',(10)),bg='white')
root = Tk()
optionList5 = items5
optionList6 = items6
optionList7 = items7
optionList8 = choose_y_n
optionList12 = items12
optionList13 = items13
lab = Label(root, text="Enter the date in the format 'dd.mm.yyyy'", font="Arial 10", anchor='w')
ent1 = Entry(root,width=20,bd=3)
lab5 = Label(root, text="condition №1", font="Arial 10", anchor='w')
mymenu5 = MyOptionMenu(root, '2', *optionList5)
lab6 = Label(root, text="condition №2", font="Arial 10", anchor='w')
mymenu6 = MyOptionMenu(root, '12', *optionList6)
lab7 = Label(root, text="condition №3", font="Arial 10", anchor='w')
mymenu7 = MyOptionMenu(root, '13', *optionList7)
lab8 = Label(root, text="condition №4", font="Arial 10", anchor='w')
mymenu8 = MyOptionMenu(root, 'yes', *optionList8)
lab12 = Label(root, text="condition №5", font="Arial 10", anchor='w')
mymenu12 = MyOptionMenu(root, '80', *optionList12)
lab13 = Label(root, text="condition №6", font="Arial 10", anchor='w')
mymenu13 = MyOptionMenu(root, '9', *optionList13)
labels = [lab, lab5, lab6, lab7, lab8, lab12, lab13]
mymenus = [ent1, mymenu5, mymenu6, mymenu7, mymenu8, mymenu12, mymenu13]
def save_selected_values():
global values1
values1 = [ent1.get(), mymenu5.var.get(), mymenu6.var.get(), mymenu7.var.get(), mymenu8.var.get(),
mymenu12.var.get(), mymenu13.var.get()]
print(values1)
def close_window():
root.destroy()
button = Button(root, text="Ok", command=save_selected_values)
button1 = Button(root, text="Quit", command=close_window)
for index, (lab, mymenu) in enumerate(zip(labels, mymenus)):
lab.grid(row=index, column=0)
mymenu.grid(row=index, column=1)
button.grid(row=index, column=2)
button1.grid(row=index, column=3)
root.mainloop()
For me, it's important to save the date in a variable.
I will be very grateful for any recommendations!
UPD
My new code is below.
It seems that my code doesn't save the date at all.
I just don't understand how to get the date as a variable. What am I doing wrong?
import numpy as np
items5 = np.arange(1,14)
items6 = np.arange(1, 28)
items7 = np.arange(4, 28)
choose_y_n = ['yes', 'no']
items12 = np.arange(50, 100)
items13 = np.arange(0,15)
from tkinter import*
import tkinter.font as tkFont
from tkinter import ttk
def get_calendar(locale, fwday):
# instantiate proper calendar class
if locale is None:
return calendar.TextCalendar(fwday)
else:
return calendar.LocaleTextCalendar(fwday, locale)
class Calendar(ttk.Frame):
# XXX ToDo: cget and configure
datetime = calendar.datetime.datetime
timedelta = calendar.datetime.timedelta
def __init__(self, master=None, **kw):
"""
WIDGET-SPECIFIC OPTIONS
locale, firstweekday, year, month, selectbackground,
selectforeground
"""
# remove custom options from kw before initializating ttk.Frame
fwday = kw.pop('firstweekday', calendar.MONDAY)
year = kw.pop('year', self.datetime.now().year)
month = kw.pop('month', self.datetime.now().month)
locale = kw.pop('locale', None)
sel_bg = kw.pop('selectbackground', '#ecffc4')
sel_fg = kw.pop('selectforeground', '#05640e')
self._date = self.datetime(year, month, 1)
self._selection = None # no date selected
ttk.Frame.__init__(self, master, **kw)
self._cal = get_calendar(locale, fwday)
self.__setup_styles() # creates custom styles
self.__place_widgets() # pack/grid used widgets
self.__config_calendar() # adjust calendar columns and setup tags
# configure a canvas, and proper bindings, for selecting dates
self.__setup_selection(sel_bg, sel_fg)
# store items ids, used for insertion later
self._items = [self._calendar.insert('', 'end', values='')
for _ in range(6)]
# insert dates in the currently empty calendar
self._build_calendar()
# set the minimal size for the widget
self._calendar.bind('<Map>', self.__minsize)
def __setitem__(self, item, value):
if item in ('year', 'month'):
raise AttributeError("attribute '%s' is not writeable" % item)
elif item == 'selectbackground':
self._canvas['background'] = value
elif item == 'selectforeground':
self._canvas.itemconfigure(self._canvas.text, item=value)
else:
ttk.Frame.__setitem__(self, item, value)
def __getitem__(self, item):
if item in ('year', 'month'):
return getattr(self._date, item)
elif item == 'selectbackground':
return self._canvas['background']
elif item == 'selectforeground':
return self._canvas.itemcget(self._canvas.text, 'fill')
else:
r = ttk.tclobjs_to_py({item: ttk.Frame.__getitem__(self, item)})
return r[item]
def __setup_styles(self):
# custom ttk styles
style = ttk.Style(self.master)
arrow_layout = lambda dir: (
[('Button.focus', {'children': [('Button.%sarrow' % dir, None)]})]
)
style.layout('L.TButton', arrow_layout('left'))
style.layout('R.TButton', arrow_layout('right'))
def __place_widgets(self):
# header frame and its widgets
hframe = ttk.Frame(self)
lbtn = ttk.Button(hframe, style='L.TButton', command=self._prev_month)
rbtn = ttk.Button(hframe, style='R.TButton', command=self._next_month)
self._header = ttk.Label(hframe, width=15, anchor='center')
# the calendar
self._calendar = ttk.Treeview(show='', selectmode='none', height=7)
# pack the widgets
hframe.pack(in_=self, side='top', pady=4, anchor='center')
lbtn.grid(in_=hframe)
self._header.grid(in_=hframe, column=1, row=0, padx=12)
rbtn.grid(in_=hframe, column=2, row=0)
self._calendar.pack(in_=self, expand=1, fill='both', side='bottom')
def __config_calendar(self):
cols = self._cal.formatweekheader(3).split()
self._calendar['columns'] = cols
self._calendar.tag_configure('header', background='grey90')
self._calendar.insert('', 'end', values=cols, tag='header')
# adjust its columns width
font = tkFont.Font()
maxwidth = max(font.measure(col) for col in cols)
for col in cols:
self._calendar.column(col, width=maxwidth, minwidth=maxwidth,
anchor='e')
def __setup_selection(self, sel_bg, sel_fg):
self._font = tkFont.Font()
self._canvas = canvas = tkinter.Canvas(self._calendar,
background=sel_bg, borderwidth=0, highlightthickness=0)
canvas.text = canvas.create_text(0, 0, fill=sel_fg, anchor='w')
canvas.bind('<ButtonPress-1>', lambda evt: canvas.place_forget())
self._calendar.bind('<Configure>', lambda evt: canvas.place_forget())
self._calendar.bind('<ButtonPress-1>', self._pressed)
def __minsize(self, evt):
width, height = self._calendar.master.geometry().split('x')
height = height[:height.index('+')]
self._calendar.master.minsize(width, height)
def _build_calendar(self):
year, month = self._date.year, self._date.month
# update header text (Month, YEAR)
header = self._cal.formatmonthname(year, month, 0)
self._header['text'] = header.title()
# update calendar shown dates
cal = self._cal.monthdayscalendar(year, month)
for indx, item in enumerate(self._items):
week = cal[indx] if indx < len(cal) else []
fmt_week = [('%02d' % day) if day else '' for day in week]
self._calendar.item(item, values=fmt_week)
def _show_selection(self, text, bbox):
"""Configure canvas for a new selection."""
x, y, width, height = bbox
textw = self._font.measure(text)
canvas = self._canvas
canvas.configure(width=width, height=height)
canvas.coords(canvas.text, width - textw, height / 2 - 1)
canvas.itemconfigure(canvas.text, text=text)
canvas.place(in_=self._calendar, x=x, y=y)
# Callbacks
def _pressed(self, evt):
"""Clicked somewhere in the calendar."""
x, y, widget = evt.x, evt.y, evt.widget
item = widget.identify_row(y)
column = widget.identify_column(x)
self.event_generate("<<CalendarChanged>>")
if not column or not item in self._items:
# clicked in the weekdays row or just outside the columns
return
item_values = widget.item(item)['values']
if not len(item_values): # row is empty for this month
return
text = item_values[int(column[1]) - 1]
if not text: # date is empty
return
bbox = widget.bbox(item, column)
if not bbox: # calendar not visible yet
return
# update and then show selection
text = '%02d' % text
self._selection = (text, item, column)
self._show_selection(text, bbox)
def _prev_month(self):
"""Updated calendar to show the previous month."""
self._canvas.place_forget()
self._date = self._date - self.timedelta(days=1)
self._date = self.datetime(self._date.year, self._date.month, 1)
self._build_calendar() # reconstuct calendar
def _next_month(self):
"""Update calendar to show the next month."""
self._canvas.place_forget()
year, month = self._date.year, self._date.month
self._date = self._date + self.timedelta(
days=calendar.monthrange(year, month)[1] + 1)
self._date = self.datetime(self._date.year, self._date.month, 1)
self._build_calendar() # reconstruct calendar
# Properties
#property
def selection(self):
"""Return a datetime representing the current selected date."""
if not self._selection:
return None
year, month = self._date.year, self._date.month
return self.datetime(year, month, int(self._selection[0]))
class MyOptionMenu(OptionMenu):
def __init__(self, master, status, *options):
self.var = StringVar(master)
self.var.set(status)
OptionMenu.__init__(self, master, self.var, *options)
self.config(font=('Arial',(10)),bg='white',width=20)
self['menu'].config(font=('Arial',(10)),bg='white')
root = Tk()
optionList5 = items5
optionList6 = items6
optionList7 = items7
optionList8 = choose_y_n
optionList12 = items12
optionList13 = items13
lab = Label(root, text="Select date", font="Arial 10", anchor='w')
ent1 = Calendar(firstweekday=calendar.SUNDAY)
lab5 = Label(root, text="condition №1", font="Arial 10", anchor='w')
mymenu5 = MyOptionMenu(root, '2', *optionList5)
lab6 = Label(root, text="condition №2", font="Arial 10", anchor='w')
mymenu6 = MyOptionMenu(root, '12', *optionList6)
lab7 = Label(root, text="condition №3", font="Arial 10", anchor='w')
mymenu7 = MyOptionMenu(root, '13', *optionList7)
lab8 = Label(root, text="condition №4", font="Arial 10", anchor='w')
mymenu8 = MyOptionMenu(root, 'yes', *optionList8)
lab12 = Label(root, text="condition №5", font="Arial 10", anchor='w')
mymenu12 = MyOptionMenu(root, '80', *optionList12)
lab13 = Label(root, text="condition №6", font="Arial 10", anchor='w')
mymenu13 = MyOptionMenu(root, '9', *optionList13)
labels = [lab, lab5, lab6, lab7, lab8, lab12, lab13]
mymenus = [ent1, mymenu5, mymenu6, mymenu7, mymenu8, mymenu12, mymenu13]
def save_selected_values():
global values1
values1 = [ent1, mymenu5.var.get(), mymenu6.var.get(), mymenu7.var.get(), mymenu8.var.get(),
mymenu12.var.get(), mymenu13.var.get()]
print(values1)
def on_calendar_changed(event):
date = cal.selection
datestr = "{:%d.%m.%Y}".format(date)
print(datestr)
dateVar.set(datestr)
def close_window():
root.destroy()
button = Button(root, text="Ok", command=save_selected_values)
button1 = Button(root, text="Quit", command=close_window)
for index, (lab, mymenu) in enumerate(zip(labels, mymenus)):
lab.grid(row=index, column=0)
mymenu.grid(row=index, column=1)
button.grid(row=index, column=2)
button1.grid(row=index, column=3)
root.mainloop()
That ttkcalendar.py needs a little help I reckon. You want to perform an action when the calendar widget has a new date selected and to do that you should bind to an event. However it is not generating any at the moment so at the end of the _pressed method add the following line to generate a virtual event you can bind to:
self.event_generate("<<CalendarChanged>>")
You can then add this widget to your UI and bind a function to this CalendarChanged virtual event as shown:
def on_calendar_changed(event):
date = cal.selection
datestr = "{:%d.%m.%Y}".format(date)
print(datestr)
dateVar.set(datestr)
cal.bind("<<CalendarChanged>>", on_calendar_changed)
Here I set a StringVar named dateVar as the textvariable of the ent1 widget. Now when the calendar selection changes, it puts the properly formatted string into your entry widget.
You would do well to convert from the OptionMenu widget to ttk.Combobox widgets and generally use ttk widgets in preference to the older Tk widgets.
Related
I want to display a row that matches the entry from all of my entry boxes into the treeview. How can I get the values of the treeview and check if it matches the entry from one of the boxes and display the whole row. Here is my treeview code
tree = ttk.Treeview()
books_data = pandas.read_csv("List of Books - Sheet1 (3).csv")
df_column = books_data.columns.values
print(len(df_column))
print(df_column)
tree["column"] = list(books_data.columns)
tree["show"] = "headings"
for column in tree['column']:
tree.heading(column,text=column)
df_rows = books_data.to_numpy().tolist()
for row in df_rows:
tree.insert("","end",values=row)
tree.grid(column=0,row=4,columnspan=8)
The short solution
import tkinter as tk
import tkinter.ttk as ttk
import sys
import pandas
# https://gist.githubusercontent.com/netj/8836201/raw/6f9306ad21398ea43cba4f7d537619d0e07d5ae3/iris.csv
df = pandas.read_csv('./iris.csv')
df.head()
class main_window:
def __init__(self, root):
self.root = root
root.title("Treeview Search Example")
# INITIALIZE TREEVIEW + SCROLLVIEW
self.tree = ttk.Treeview(root, columns=list(df.columns.values), show='headings')
self.tree.grid(row=1, column=0, sticky='nsew')
# https://stackoverflow.com/a/41880534/5210078
vsb = ttk.Scrollbar(root, orient="vertical", command=self.tree.yview)
vsb.grid(row=1, column=1, sticky='ns')
self.tree.configure(yscrollcommand=vsb.set)
for column in self.tree['column']:
self.tree.heading(column,text=column)
df_rows = df.to_numpy().tolist()
for row in df_rows:
self.tree.insert("","end",values=row)
# ADD SEARCH BOXES
search_frame = tk.Frame(root)
search_frame.grid(row=0, column=0, columnspan=2, sticky='nsew')
tk.Label(search_frame, text="sepal.length:").grid(row=0, column=0)
tk.Label(search_frame, text="sepal.width:").grid(row=0, column=2)
tk.Label(search_frame, text="petal.length:").grid(row=0, column=4)
tk.Label(search_frame, text="petal.width:").grid(row=0, column=6)
tk.Label(search_frame, text="variety:").grid(row=0, column=8)
# Add Search boxes
self.sepal_length_ent = tk.Entry(search_frame)
self.sepal_length_ent.grid(row=0, column=1)
self.sepal_width_ent = tk.Entry(search_frame)
self.sepal_width_ent.grid(row=0, column=3)
self.petal_length_ent = tk.Entry(search_frame)
self.petal_length_ent.grid(row=0, column=5)
self.petal_width_ent = tk.Entry(search_frame)
self.petal_width_ent.grid(row=0, column=7)
self.variety_ent = tk.Entry(search_frame)
self.variety_ent.grid(row=0, column=9)
tk.Button(search_frame, text="Search", command=self.search).grid(row=0, column=10)
def search(self):
# https://stackoverflow.com/a/27068344/5210078
self.tree.delete(*self.tree.get_children())
build_query = ""
# https://stackoverflow.com/a/56157729/5210078
if self.sepal_length_ent.get():
build_query += f'& {self.sepal_length_ent.get()} == `sepal.length` '
if self.sepal_width_ent.get():
build_query += f'& {self.sepal_width_ent.get()} == `sepal.width` '
if self.petal_length_ent.get():
build_query += f'& {self.petal_length_ent.get()} == `petal.length` '
if self.petal_width_ent.get():
build_query += f'& {self.petal_width_ent.get()} == `petal.width` '
if self.variety_ent.get():
build_query += f'& "{self.variety_ent.get()}" in `variety`'
if build_query:
print(build_query)
queried_df = df.query(build_query[1:])
else:
queried_df = df
df_rows = queried_df.to_numpy().tolist()
for row in df_rows:
self.tree.insert("","end",values=row)
if __name__ == '__main__':
main = tk.Tk()
main_window(main)
main.mainloop()
sys.exit()
The explanation of the solution
import tkinter as tk
import tkinter.ttk as ttk
import sys
import pandas
Obviously importing all the needed programs.
# https://gist.githubusercontent.com/netj/8836201/raw/6f9306ad21398ea43cba4f7d537619d0e07d5ae3/iris.csv
df = pandas.read_csv('./iris.csv')
df.head()
Loading the csv dataset. I used the IRIS dataset because it is easily accessible.
Jump ahead to:
if __name__ == '__main__':
main = tk.Tk()
main_window(main)
main.mainloop()
sys.exit()
Here we load the main_window class into our main tkinter window (makes your code look neater)
The self-explanatory bit (added a ttk treeview with scrollbar):
class main_window:
def __init__(self, root):
self.root = root
root.title("Treeview Search Example")
# INITIALIZE TREEVIEW + SCROLLVIEW
self.tree = ttk.Treeview(root, columns=list(df.columns.values), show='headings')
self.tree.grid(row=1, column=0, sticky='nsew')
# https://stackoverflow.com/a/41880534/5210078
vsb = ttk.Scrollbar(root, orient="vertical", command=self.tree.yview)
vsb.grid(row=1, column=1, sticky='ns')
self.tree.configure(yscrollcommand=vsb.set)
for column in self.tree['column']:
self.tree.heading(column,text=column)
df_rows = df.to_numpy().tolist()
for row in df_rows:
self.tree.insert("","end",values=row)
# ADD SEARCH BOXES
search_frame = tk.Frame(root)
search_frame.grid(row=0, column=0, columnspan=2, sticky='nsew')
tk.Label(search_frame, text="sepal.length:").grid(row=0, column=0)
tk.Label(search_frame, text="sepal.width:").grid(row=0, column=2)
tk.Label(search_frame, text="petal.length:").grid(row=0, column=4)
tk.Label(search_frame, text="petal.width:").grid(row=0, column=6)
tk.Label(search_frame, text="variety:").grid(row=0, column=8)
# Add Search boxes
self.sepal_length_ent = tk.Entry(search_frame)
self.sepal_length_ent.grid(row=0, column=1)
self.sepal_width_ent = tk.Entry(search_frame)
self.sepal_width_ent.grid(row=0, column=3)
self.petal_length_ent = tk.Entry(search_frame)
self.petal_length_ent.grid(row=0, column=5)
self.petal_width_ent = tk.Entry(search_frame)
self.petal_width_ent.grid(row=0, column=7)
self.variety_ent = tk.Entry(search_frame)
self.variety_ent.grid(row=0, column=9)
tk.Button(search_frame, text="Search", command=self.search).grid(row=0, column=10)
def search(self):
# https://stackoverflow.com/a/27068344/5210078
self.tree.delete(*self.tree.get_children())
Delete all the rows in the table
build_query = ""
# https://stackoverflow.com/a/56157729/5210078
if self.sepal_length_ent.get():
build_query += f'& {self.sepal_length_ent.get()} == `sepal.length` '
if self.sepal_width_ent.get():
build_query += f'& {self.sepal_width_ent.get()} == `sepal.width` '
if self.petal_length_ent.get():
build_query += f'& {self.petal_length_ent.get()} == `petal.length` '
if self.petal_width_ent.get():
build_query += f'& {self.petal_width_ent.get()} == `petal.width` '
if self.variety_ent.get():
build_query += f'& "{self.variety_ent.get()}" in `variety`'
Build a search query. Use == for integers/floats and use in when searching inside strings. If you want to read more about queries, read this. If you wanted to do something wacky, like make one of your entries a "lower than" box for integers, you could even substitute in a < or >. It basically makes our life much easier here! Because we can do a query, based off a dynamically changing string!
if build_query:
print(build_query)
queried_df = df.query(build_query[1:])
else:
queried_df = df
If there is no build_query (no inputs in entry boxes), just reload the table with the data from the df. (if build_query: is shorthand for if build_query != '':)
If there is query data, do a query with the query terms.
df_rows = queried_df.to_numpy().tolist()
for row in df_rows:
self.tree.insert("","end",values=row)
Reload the treeview with the data from the "new" queried df!
If you wanted a solution relate to your actual csv and interface, I'd recommend sharing an example of your csv and the gui design.
What the solution became
def search():
# clear the tree of data
tree.delete(*tree.get_children())
entries = [
title_entry,
author_entry,
subject_category_entry,
publication_date_entry
]
build_df = books_data
if entries[0].get():
build_df = build_df[build_df.TITLE.str.contains(entries[0].get())]
if entries[1].get():
build_df = build_df[build_df.AUTHOR.str.contains(entries[1].get())]
if entries[2].get():
build_df = build_df[build_df.SUBJECT_CATEGORY.str.contains(entries[2].get())]
if entries[3].get():
build_df = build_df[build_df.PUBLICATION_DATE == (entries[3].get())]
df_rows = build_df.to_numpy().tolist()
for row in df_rows:
tree.insert("","end",values=row)
I have two issues.
One:
I can't figure out how to calculate days left until a specific date which the user inputs in a calendar interface.
Secondly:
I want to use the numbers that the user has input in the interface to do some calculations with, and to watch what is going on I print some of the input to the terminal - however, the .value attribute returns "0" and I don't understand why.
Below the #PROXIMITY comment in the code you will find the calendar/date. I just want to subtract the date today from the date specified by the user in the calendar interface and output the days left.
Below the #VALUE is the calculation that prints "0" when i print the .value attribute.
Full code:
from tkcalendar import * # Calendar module
import tkinter.messagebox # Import the messagebox module
import datetime
import pickle
task_list = []
task_types = ['Sparetime', 'School', 'Work']
class Task:
def __init__(self, n, type_, i, m, p, h, v): #(w=8, p, u, n, v):
self.name = n
self.type = type_
self.impact = i
self.manageability = m
self.proximity = p
self.hours = h
self.value = v
#self.connectivity = c
##self.work = w ##hours of work per day
##self.urgency = u
##self.note = n
##self.value = v
def show_tasks():
# DELETED: for task in task_list:
# REPLACED WITH: task = task_list[-1]
task = task_list[-1]
#print(
#'Task:'+task.name + '\n' +
#'Impact:' + task.impact + '\n' +
#'Manageability:' + task.manageability + '\n' +
#'Hours:' + task.hours + '\n'
#'Value:' + task.value +'\n'
#)
print('Task:')
print(task.name)
print('\n')
print('Impact:')
print(task.impact)
print('\n')
print('manageability:')
print(task.manageability)
print('\n')
print('Hours')
print(task.hours)
print('\n')
print('Value:')
print(task.value)
def open_add_task():
taskwin = Toplevel(root)
taskwin.focus_force()
#TITLE
titlelabel = Label(taskwin, text='Title task concisely:', font=('Roboto',11,'bold')).grid(column=1, row=0)
name_entry = Entry(taskwin, width=40, justify='center')
name_entry.grid(column=1, row=1)
#TYPE
typelabel = Label(taskwin, text='Type', font=('Roboto',10)).grid(column=0, row=2)
type_var = StringVar(value=task_types[0])
OptionMenu(taskwin, type_var, *task_types).grid(column=0, row=3, sticky='nsew')
#IMPACT
impactlabel = Label(taskwin, text='Impact', font=('Roboto',10)).grid(column=1, row=2)
imp_var = StringVar(value=0)
OptionMenu(taskwin, imp_var, *range(0, 10+1)).grid(column=1, row=3, sticky='ns')
#MANAGEABILITY
manlabel = Label(taskwin, text='Manageability', font=('Roboto',10)).grid(column=2, row=2)
man_var = StringVar(value=0)
OptionMenu(taskwin, man_var, *range(0, 10+1)).grid(column=2, row=3, sticky='nsew')
#PROXIMITY
proximity_label = Label(taskwin, text = 'Choose a deadline', font=('Roboto',10), justify='center')
proximity_label.grid(column=1, row=4)
cal = Calendar(taskwin, selectmode='day', year=2021, month=4, day=27)
cal.grid(column=1, row=5)
def get_date():
proximity_output_date.config(text=cal.get_date()) ##the .config didn't work until i did .grid(column=, row=) on seperate lines
#HOURS(required)
hourlabel = Label(taskwin, text='Whole hours \n required', font=('Roboto',10)).grid(column=1, row=16)
hour_entry = Entry(taskwin, width=4, justify='center')
hour_entry.grid(column=1, row=17)
#CONNECTIVITY
#for index, task in enumerate(task_list):
#Checkbutton(taskwin, **options).grid(column=0, row=index)
C_lab = Label(taskwin,text="Check tasks this task is related to").grid(column=1, row=18)
placement=19
for task in task_list:
Checkbutton(taskwin, text=(task.name)).grid(column=1, row=placement, sticky="w")
placement+=1
#VALUE
val_var = (int(imp_var.get()))+ (int(man_var.get()))
def add_task():
if name_entry.get() != '': # If textbox inputfield is NOT empty do this:
task_list.append(Task(name_entry.get(), type_var.get(), imp_var.get(), man_var.get(), cal.get_date(), hour_entry.get(), val_var))
show_tasks()
listbox_tasks.insert(tkinter.END, name_entry.get())
name_entry.delete(0, tkinter.END)
taskwin.destroy()
else:
tkinter.messagebox.showwarning(title='Whoops', message='You must enter a task')
next_button = Button(taskwin, text='Next', font=('Roboto',10), command=add_task).grid(column=2, row=placement, sticky="e")
placement+=1
def sort_tasks():
pass
def delete_task():
try:
task_index = listbox_tasks.curselection()[0]
listbox_tasks.delete(task_index)
except:
tkinter.messagebox.showwarning(title='Error', message='You must select a task to delete')
def save_tasks():
pass
#tasks = listbox_tasks.get(0, listbox_tasks.size())
#pickle.dump(tasks, open('tasks.dat', 'wb'))
root = Tk()
task_frame = Frame()
# Create UI
your_tasks_label = Label(root, text='THESE ARE YOUR TASKS:', font=('Roboto',10, 'bold'), justify='center')
your_tasks_label.pack()
scrollbar_tasks = tkinter.Scrollbar(root)
scrollbar_tasks.pack(side=tkinter.RIGHT, fill=tkinter.Y)
listbox_tasks = tkinter.Listbox(root, height=10, width=50, font=('Roboto',10), justify='center') # tkinter.Listbox(where it should go, height=x, width=xx)
listbox_tasks.pack()
listbox_tasks.config(yscrollcommand=scrollbar_tasks.set)
scrollbar_tasks.config(command=listbox_tasks.yview)
try:
#tasks = pickle.load(open('tasks.dat', 'rb'))
listbox_tasks.delete(0, tkinter.END)
for task in task_list:
listbox_tasks.insert(tkinter.END, task)
except:
tkinter.messagebox.showwarning(title='Phew', message='You have no tasks')
#BUTTONS
Add_Button = Button(root, text='Add New', width=42, command=open_add_task)
Add_Button.pack()
button_delete_task = Button(root, text='Delete task', width=42, command=delete_task)
button_delete_task.pack()
button_save_tasks = Button(root, text='Save tasks', width=42, command=save_tasks)
button_save_tasks.pack()
#sort_type = StringVar(value='All')
#OptionMenu(btn_frame, sort_type, 'All', *task_types).grid(column=0, row=0, sticky='nsew')
#sort_imp = StringVar(value='Any')
#OptionMenu(btn_frame, sort_imp,'Any', *range(0, 10+1)).grid(column=1, row=0, sticky='nsew')
#Button(btn_frame, text='Sort', command=sort_tasks).grid(column=1, row=1, sticky='nsew')
root.mainloop()
how to calculate days left until a specific date
You might subtract datetime.date from datetime.date to get datetime.timedelta object holding numbers of days, consider following example
import datetime
d1 = datetime.date(2021, 1, 1) # year, month, day
d2 = datetime.date(2021, 1, 10)
diff21 = (d2-d1).days
diff12 = (d1-d2).days
print(diff21)
print(diff12)
output
9
-9
For getting current date you might use datetime.date.today().
For your first issue, you can use cal.selection_get() to return the selected date in datetime.date type. Then you can calculate the days left easily:
selected = cal.selection_get()
delta = (selected - datetime.date.today()).days
status = "overdue" if delta <= 0 else f"{delta} days left"
print(f"{selected} ({status})")
For second issue, you need to move the line val_var = (int(imp_var.get()))+ (int(man_var.get())) into add_task() function:
def add_task():
if name_entry.get() != '':
val_var = int(imp_var.get()) + int(man_var.get())
...
else:
...
Note that you need to do some validations on the values returned by imp_var.get() and man_var.get() to avoid exception due to invalid values.
from tkinter import Tk, Frame, Button, Label, Entry, ttk, StringVar, messagebox
import datetime
# Main Window
class WINDOW(Tk):
def __init__(self, master):
Tk.__init__(self, master)
self.master = master
frame1 = Frame1(self)
frame1.grid(row=0,column=0)
class Frame1(Frame):
def __init__(self, master):
Frame.__init__(self, master,height=master.winfo_screenheight(),
width=master.winfo_screenwidth())
self.master = master
var = StringVar()
label = Label(self, text="DATA", font=('calibre', 10, 'bold'))
entry = Entry(self, textvariable=var,width=10, font=('calibre', 10, 'normal'))
label.grid(row=0, column=1)
entry.grid(row=1, column=1)
# Log data sheet
NewTree = ttk.Treeview(self, height=23, columns=("Time","Time Diff", "DATA"))
NewTree['show'] = 'headings'
NewTree['columns'] = ("Time","Time Diff", "DATA")
NewTree.column("Time", width=180)
NewTree.column("Time Diff", width=150)
NewTree.column("DATA", width=150)
NewTree.heading("Time",text='TIME')
NewTree.heading("Time Diff",text='TimeDIfference')
NewTree.heading("DATA",text='DATA')
NewTree.grid(row=5, columnspan=4)
def insert_data():
if entry.get()=='':
messagebox.showerror("","Please insert data")
else:
NewTree.insert('', 'end',values=(datetime.datetime.now(),"",entry.get()))
entry.delete(0, 'end')
submit_button = Button(self, text="SUBMIT", command=insert_data)
submit_button.grid(row=3, column=4)
root = WINDOW(None)
root.geometry(f'{root.winfo_screenwidth()}x{root.winfo_screenheight()}')
root.title("ADD DATA")
root.mainloop()
Please refer the image:
there is time difference between submitting the 11 and 12, 12 and 24 and so on.
i need to calculate that time and want to add in time difference column.
it is like how much time it takes to add next data
I am not quite sure with what you are comparing the value, but my guess is the previous time.
you can use relativedelta to get the time difference.
In the beginning, assign both currenttime = previoustime = datetime.datetime.now(). Then when ever the user calls update again assign currenttime=datetime.datetime.now() find the time difference, display the data in the treeview and then update previoustime=currenttime
Here is an example.
from tkinter import ttk,Tk
import datetime
from dateutil.relativedelta import relativedelta
def diff(t_a, t_b):
t_diff = relativedelta(t_b, t_a)
return ' {h}h {m}m {s}s {ms}ms'.format(h=abs(t_diff.hours), m=abs(t_diff.minutes), s=abs(t_diff.seconds), ms=abs(round(t_diff.microseconds*0.001, 2)))
def update():
global currenttime, previoustime, timediff
currenttime= datetime.datetime.now()
timediff = diff(currenttime, previoustime)
curr = tree.insert('','end',values=(currenttime,timediff))
previoustime = currenttime
tree.selection_set(curr)
tree.see(curr)
root = Tk()
tree = ttk.Treeview(root, height = 20, columns = 2)
tree['show']='headings'
tree['columns'] = ('one','two')
tree.column('one', width = 250)
tree.column('two', width = 250)
tree.heading('one', text = 'TIME')
tree.heading('two', text = 'TIME Difference')
tree.grid(row = 0, column = 0)
currenttime= datetime.datetime.now()
previoustime= currenttime
timeBtn = ttk.Button(root, text='Update', command=update)
timeBtn.grid(row=1, column=0)
root.geometry("500x500")
root.mainloop()
Update after OP's request:
class Frame1(Frame):
def __init__(self, master):
...
NewTree.grid(row=5, columnspan=4)
self.currenttime = None
self.previoustime = None
self.timediff = None
def diff(t_a, t_b):
t_diff = relativedelta(t_b, t_a)
return ' {h}h {m}m {s}s {ms}ms'.format(h=abs(t_diff.hours), m=abs(t_diff.minutes), s=abs(t_diff.seconds), ms=abs(round(t_diff.microseconds*0.001, 2)))
def update_time():
if entry.get()=='':
messagebox.showerror("","Please insert data")
else:
self.currenttime= datetime.datetime.now()
if self.previoustime is None:
self.previoustime = self.currenttime
self.timediff = diff(self.currenttime, self.previoustime)
curr = NewTree.insert('','end',values=(datetime.datetime.now(), self.timediff ,entry.get()))
self.previoustime = self.currenttime
NewTree.selection_set(curr)
NewTree.see(curr)
submit_button = Button(self, text="SUBMIT", command=update_time)
...
After changing the font size of the widget text increases , how to make it static?
I'm giving you all the code so you can run the program. So do not swear
from tkinter import*
import tkinter as tk
from tkinter import Toplevel, Listbox, StringVar, BooleanVar, TclError
from tkinter import filedialog, scrolledtext,Menu,END,messagebox
from tkinter.ttk import Checkbutton, Frame, Label, Button, Scrollbar, Style, Entry
from tkinter.font import families, Font
from locale import getdefaultlocale
import PIL
from PIL import Image, ImageTk
__version__ = "2.0.2"
# --- translation
EN = {"Cancel": "Cancel", "Bold": "Bold", "Italic": "Italic",
"Underline": "Underline", "Overstrike": "Strikethrough"}
FR = {"Cancel": "Annuler", "Bold": "Gras", "Italic": "Italique",
"Underline": "Souligné", "Overstrike": "Barré"}
LANGUAGES = {"fr": FR, "en": EN}
if getdefaultlocale()[0][:2] == "fr":
TR = LANGUAGES["fr"]
else:
TR = LANGUAGES["en"]
class FontChooser(Toplevel):
""".Font chooser dialog."""
def __init__(self, master, font_dict={}, text="Abcd", title="Font Chooser",
**kwargs):
"""
Create a new FontChooser instance.
Arguments:
master: master window
font_dict: dictionnary, like the one returned by the .actual
method of a Font object:
{'family': 'DejaVu Sans',
'overstrike': False,
'size': 12,
'slant': 'italic' or 'roman',
'underline': False,
'weight': 'bold' or 'normal'}
text: text to be displayed in the preview label
title: window title
**kwargs: additional keyword arguments to be passed to
Toplevel.__init__
"""
Toplevel.__init__(self, master, **kwargs)
self.title(title)
self.resizable(False, False)
self.protocol("WM_DELETE_WINDOW", self.quit)
self._validate_family = self.register(self.validate_font_family)
self._validate_size = self.register(self.validate_font_size)
# --- variable storing the chosen font
self.res = ""
style = Style(self)
style.configure("prev.TLabel", background="white")
bg = style.lookup("TLabel", "background")
self.configure(bg=bg)
# --- family list
self.fonts = list(set(families()))
self.fonts.append("TkDefaultFont")
self.fonts.sort()
for i in range(len(self.fonts)):
self.fonts[i] = self.fonts[i].replace(" ", "\ ")
max_length = int(2.5 * max([len(font) for font in self.fonts])) // 3
self.sizes = ["%i" % i for i in (list(range(6, 17)) + list(range(18, 32, 2)))]
# --- font default
font_dict["weight"] = font_dict.get("weight", "normal")
font_dict["slant"] = font_dict.get("slant", "roman")
font_dict["underline"] = font_dict.get("underline", False)
font_dict["overstrike"] = font_dict.get("overstrike", False)
font_dict["family"] = font_dict.get("family",
self.fonts[0].replace('\ ', ' '))
font_dict["size"] = font_dict.get("size", 10)
# --- creation of the widgets
# ------ style parameters (bold, italic ...)
options_frame = Frame(self, relief='groove', borderwidth=2)
self.font_family = StringVar(self, " ".join(self.fonts))
self.font_size = StringVar(self, " ".join(self.sizes))
self.var_bold = BooleanVar(self, font_dict["weight"] == "bold")
b_bold = Checkbutton(options_frame, text=TR["Bold"],
command=self.toggle_bold,
variable=self.var_bold)
b_bold.grid(row=0, sticky="w", padx=4, pady=(4, 2))
self.var_italic = BooleanVar(self, font_dict["slant"] == "italic")
b_italic = Checkbutton(options_frame, text=TR["Italic"],
command=self.toggle_italic,
variable=self.var_italic)
b_italic.grid(row=1, sticky="w", padx=4, pady=2)
self.var_underline = BooleanVar(self, font_dict["underline"])
b_underline = Checkbutton(options_frame, text=TR["Underline"],
command=self.toggle_underline,
variable=self.var_underline)
b_underline.grid(row=2, sticky="w", padx=4, pady=2)
self.var_overstrike = BooleanVar(self, font_dict["overstrike"])
b_overstrike = Checkbutton(options_frame, text=TR["Overstrike"],
variable=self.var_overstrike,
command=self.toggle_overstrike)
b_overstrike.grid(row=3, sticky="w", padx=4, pady=(2, 4))
# ------ Size and family
self.var_size = StringVar(self)
self.entry_family = Entry(self, width=max_length, validate="key",
validatecommand=(self._validate_family, "%d", "%S",
"%i", "%s", "%V"))
self.entry_size = Entry(self, width=4, validate="key",
textvariable=self.var_size,
validatecommand=(self._validate_size, "%d", "%P", "%V"))
self.list_family = Listbox(self, selectmode="browse",
listvariable=self.font_family, highlightthickness=0, exportselection=False, width=max_length)
self.list_size = Listbox(self, selectmode="browse",
listvariable=self.font_size, highlightthickness=0, exportselection=False, width=4)
scroll_family = Scrollbar(self, orient='vertical', command=self.list_family.yview)
scroll_size = Scrollbar(self, orient='vertical', command=self.list_size.yview)
self.preview_font = Font(self, **font_dict)
if len(text) > 30:
text = text[:30]
self.preview = Label(self, relief="groove", style="prev.TLabel", text=text, font=self.preview_font, anchor="center")
self.list_family.configure(yscrollcommand=scroll_family.set)
self.list_size.configure(yscrollcommand=scroll_size.set)
self.entry_family.insert(0, font_dict["family"])
self.entry_family.selection_clear()
self.entry_family.icursor("end")
self.entry_size.insert(0, font_dict["size"])
try:
i = self.fonts.index(self.entry_family.get().replace(" ", "\ "))
except ValueError:
i = 0
self.list_family.selection_clear(0, "end")
self.list_family.selection_set(i)
self.list_family.see(i)
try:
i = self.sizes.index(self.entry_size.get())
self.list_size.selection_clear(0, "end")
self.list_size.selection_set(i)
self.list_size.see(i)
except ValueError:
pass
self.entry_family.grid(row=0, column=0, sticky="ew", pady=(10, 1), padx=(10, 0))
self.entry_size.grid(row=0, column=2, sticky="ew", pady=(10, 1), padx=(10, 0))
self.list_family.grid(row=1, column=0, sticky="nsew", pady=(1, 10), padx=(10, 0))
self.list_size.grid(row=1, column=2, sticky="nsew", pady=(1, 10), padx=(10, 0))
scroll_family.grid(row=1, column=1, sticky='ns', pady=(1, 10))
scroll_size.grid(row=1, column=3, sticky='ns', pady=(1, 10))
options_frame.grid(row=0, column=4, rowspan=2, padx=10, pady=10, ipadx=10)
self.preview.grid(row=2, column=0, columnspan=5, sticky="eswn", padx=10, pady=(0, 10), ipadx=4, ipady=4)
button_frame = Frame(self)
button_frame.grid(row=3, column=0, columnspan=5, pady=(0, 10), padx=10)
Button(button_frame, text="Ok", command=self.ok).grid(row=0, column=0, padx=4, sticky='ew')
Button(button_frame, text=TR["Cancel"], command=self.quit).grid(row=0, column=1, padx=4, sticky='ew')
self.list_family.bind('<<ListboxSelect>>', self.update_entry_family)
self.list_size.bind('<<ListboxSelect>>', self.update_entry_size, add=True)
self.list_family.bind("<KeyPress>", self.keypress)
self.entry_family.bind("<Return>", self.change_font_family)
self.entry_family.bind("<Tab>", self.tab)
self.entry_size.bind("<Return>", self.change_font_size)
self.entry_family.bind("<Down>", self.down_family)
self.entry_size.bind("<Down>", self.down_size)
self.entry_family.bind("<Up>", self.up_family)
self.entry_size.bind("<Up>", self.up_size)
self.bind_class("TEntry", "<Control-a>", self.select_all)
self.wait_visibility(self)
self.grab_set()
self.entry_family.focus_set()
self.lift()
def select_all(self, event):
event.widget.selection_range(0, "end")
def keypress(self, event):
key = event.char.lower()
l = [i for i in self.fonts if i[0].lower() == key]
if l:
i = self.fonts.index(l[0])
self.list_family.selection_clear(0, "end")
self.list_family.selection_set(i)
self.list_family.see(i)
self.update_entry_family()
def up_family(self, event):
try:
i = self.list_family.curselection()[0]
self.list_family.selection_clear(0, "end")
if i <= 0:
i = len(self.fonts)
self.list_family.see(i - 1)
self.list_family.select_set(i - 1)
except TclError:
self.list_family.selection_clear(0, "end")
i = len(self.fonts)
self.list_family.see(i - 1)
self.list_family.select_set(i - 1)
self.list_family.event_generate('<<ListboxSelect>>')
def up_size(self, event):
"""Navigate in the size listbox with up key."""
try:
s = self.var_size.get()
if s in self.sizes:
i = self.sizes.index(s)
elif s:
sizes = list(self.sizes)
sizes.append(s)
sizes.sort(key=lambda x: int(x))
i = sizes.index(s)
else:
i = 0
self.list_size.selection_clear(0, "end")
if i <= 0:
i = len(self.sizes)
self.list_size.see(i - 1)
self.list_size.select_set(i - 1)
except TclError:
i = len(self.sizes)
self.list_size.see(i - 1)
self.list_size.select_set(i - 1)
self.list_size.event_generate('<<ListboxSelect>>')
def down_family(self, event):
"""Navigate in the family listbox with down key."""
try:
i = self.list_family.curselection()[0]
self.list_family.selection_clear(0, "end")
if i >= len(self.fonts):
i = -1
self.list_family.see(i + 1)
self.list_family.select_set(i + 1)
except TclError:
self.list_family.selection_clear(0, "end")
self.list_family.see(0)
self.list_family.select_set(0)
self.list_family.event_generate('<<ListboxSelect>>')
def down_size(self, event):
"""Navigate in the size listbox with down key."""
try:
s = self.var_size.get()
if s in self.sizes:
i = self.sizes.index(s)
elif s:
sizes = list(self.sizes)
sizes.append(s)
sizes.sort(key=lambda x: int(x))
i = sizes.index(s) - 1
else:
s = len(self.sizes) - 1
self.list_size.selection_clear(0, "end")
if i < len(self.sizes) - 1:
self.list_size.selection_set(i + 1)
self.list_size.see(i + 1)
else:
self.list_size.see(0)
self.list_size.select_set(0)
except TclError:
self.list_size.selection_set(0)
self.list_size.event_generate('<<ListboxSelect>>')
def toggle_bold(self):
"""Update font preview weight."""
b = self.var_bold.get()
self.preview_font.configure(weight=["normal", "bold"][b])
def toggle_italic(self):
"""Update font preview slant."""
b = self.var_italic.get()
self.preview_font.configure(slant=["roman", "italic"][b])
def toggle_underline(self):
"""Update font preview underline."""
b = self.var_underline.get()
self.preview_font.configure(underline=b)
def toggle_overstrike(self):
"""Update font preview overstrike."""
b = self.var_overstrike.get()
self.preview_font.configure(overstrike=b)
def change_font_family(self, event=None):
"""Update font preview family."""
family = self.entry_family.get()
if family.replace(" ", "\ ") in self.fonts:
self.preview_font.configure(family=family)
def change_font_size(self, event=None):
"""Update font preview size."""
size = int(self.var_size.get())
self.preview_font.configure(size=size)
def validate_font_size(self, d, ch, V):
"""Validation of the size entry content."""
l = [i for i in self.sizes if i[:len(ch)] == ch]
i = None
if l:
i = self.sizes.index(l[0])
elif ch.isdigit():
sizes = list(self.sizes)
sizes.append(ch)
sizes.sort(key=lambda x: int(x))
i = min(sizes.index(ch), len(self.sizes))
if i is not None:
self.list_size.selection_clear(0, "end")
self.list_size.selection_set(i)
deb = self.list_size.nearest(0)
fin = self.list_size.nearest(self.list_size.winfo_height())
if V != "forced":
if i < deb or i > fin:
self.list_size.see(i)
return True
if d == '1':
return ch.isdigit()
else:
return True
def tab(self, event):
"""Move at the end of selected text on tab press."""
self.entry_family = event.widget
self.entry_family.selection_clear()
self.entry_family.icursor("end")
return "break"
def validate_font_family(self, action, modif, pos, prev_txt, V):
"""Completion of the text in the entry with existing font names."""
if self.entry_family.selection_present():
sel = self.entry_family.selection_get()
txt = prev_txt.replace(sel, '')
else:
txt = prev_txt
if action == "0":
txt = txt[:int(pos)] + txt[int(pos) + 1:]
return True
else:
txt = txt[:int(pos)] + modif + txt[int(pos):]
ch = txt.replace(" ", "\ ")
l = [i for i in self.fonts if i[:len(ch)] == ch]
if l:
i = self.fonts.index(l[0])
self.list_family.selection_clear(0, "end")
self.list_family.selection_set(i)
deb = self.list_family.nearest(0)
fin = self.list_family.nearest(self.list_family.winfo_height())
index = self.entry_family.index("insert")
self.entry_family.delete(0, "end")
self.entry_family.insert(0, l[0].replace("\ ", " "))
self.entry_family.selection_range(index + 1, "end")
self.entry_family.icursor(index + 1)
if V != "forced":
if i < deb or i > fin:
self.list_family.see(i)
return True
else:
return False
def update_entry_family(self, event=None):
"""Update family entry when an item is selected in the family listbox."""
# family = self.list_family.get("#%i,%i" % (event.x , event.y))
family = self.list_family.get(self.list_family.curselection()[0])
self.entry_family.delete(0, "end")
self.entry_family.insert(0, family)
self.entry_family.selection_clear()
self.entry_family.icursor("end")
self.change_font_family()
def update_entry_size(self, event):
"""Update size entry when an item is selected in the size listbox."""
# size = self.list_size.get("#%i,%i" % (event.x , event.y))
size = self.list_size.get(self.list_size.curselection()[0])
self.var_size.set(size)
self.change_font_size()
def ok(self):
"""Validate choice."""
self.res = self.preview_font.actual()
self.quit()
def get_res(self):
"""Return chosen font."""
return self.res
def quit(self):
self.destroy()
def askfont(master=None, text="Abcd", title="Font Chooser", **font_args):
chooser = FontChooser(master, font_args, text, title)
chooser.wait_window(chooser)
return chooser.get_res()
def edit_font():
font = askfont(root, title="Choose a font")
if font:
font['family'] = font['family'].replace(' ', '\ ')
font_str = "%(family)s %(size)i %(weight)s %(slant)s" % font
if font['underline']:
font_str += ' underline'
if font['overstrike']:
font_str += ' overstrike'
text.configure(font=font_str)
root=tk.Tk()
root.geometry("1423x800")
# added weights so the widget resizes correctly with window
root.rowconfigure(0, weight=1)
root.columnconfigure(0, weight=1)
image = ImageTk.PhotoImage(file="0.png")
lab=tk.Label(root, image = image)
lab.grid(row=0, column=0)
text=tk.Text(root,width = 60,height=15, font=Font(family="Helvetica", size=10))
text.grid(row=0, column=0)
king=tk.Menu(root)
root.config(menu=king)
view=tk.Menu(king, tearoff=0)
view2=tk.Menu(view, tearoff=0)
view2.add_command(label='Font',command=edit_font)
view.add_cascade(label='Text', menu=view2)
king.add_cascade(label='View', menu=view)
root.mainloop()
This is the code you will most likely need to fix my problem:
def askfont(master=None, text="Abcd", title="Font Chooser", **font_args):
chooser = FontChooser(master, font_args, text, title)
chooser.wait_window(chooser)
return chooser.get_res()
def edit_font():
font = askfont(root, title="Choose a font")
if font:
font['family'] = font['family'].replace(' ', '\ ')
font_str = "%(family)s %(size)i %(weight)s %(slant)s" % font
if font['underline']:
font_str += ' underline'
if font['overstrike']:
font_str += ' overstrike'
text.configure(font=font_str)
root=tk.Tk()
root.geometry("1423x800")
# added weights so the widget resizes correctly with window
root.rowconfigure(0, weight=1)
root.columnconfigure(0, weight=1)
image = ImageTk.PhotoImage(file="0.png")
lab=tk.Label(root, image = image)
lab.grid(row=0, column=0)
text=tk.Text(root,width = 60,height=15, font=Font(family="Helvetica", size=10))
text.grid(row=0, column=0)
king=tk.Menu(root)
root.config(menu=king)
view=tk.Menu(king, tearoff=0)
view2=tk.Menu(view, tearoff=0)
view2.add_command(label='Font',command=edit_font)
view.add_cascade(label='Text', menu=view2)
king.add_cascade(label='View', menu=view)
root.mainloop()
This will probably include setting the frame size and frame, as well as banning distribution, one of my friends said. Hope this helps you
If you give the Text widget a fixed height and width and wrap it in a Frame with the same width and height and use grid_propagate(False), when the text is made bigger the Text widget stays the same size.
import tkinter as tk
def fontUp():
text.config(font = ("30"))
root = tk.Tk()
root.geometry("800x800")
frm = tk.Frame(root, height = 500, width = 500)
frm.grid(row = 0, column = 0)
frm.grid_propagate(False)
text = tk.Text(frm, height = 500, width = 500)
text.grid(row = 0, column = 0)
btn = tk.Button(root, text="Font bigger", command = fontUp)
btn.grid(row = 2, column = 0)
I'm trying to do a simple GUI in Tkinter. I have a Listbox there and I want the user to know what kind of data is in the Listbox so I want to set a label for it (upper).
The problem is that when I set a label, this Listbox disappears.
l = Label(multiple_choose_days_listbox, textvariable=label_day_listbox , anchor=NW, justify='center')
l.pack()
The solution is probably obvious but I'm new in Tkinter.
Do you have any advices?
import Tkinter
import tkSimpleDialog
from Tkinter import *
import db
import ttkcalendar
class CalendarDialog(tkSimpleDialog.Dialog):
"""Dialog box that displays a calendar and returns the selected date"""
def __init__(self, master):
self.calendar = ttkcalendar.Calendar(master)
# self.calendar.pack()
#property
def result(self):
return self.calendar.selection
def pack(self,**kwargs):
self.calendar.pack(**kwargs)
states_list = db.get_states()
bought_days_before_list = db.get_bought_days_before()
multiple_choose_length_of_trips_list = db.get_lengths_of_trips()
def main():
root = Tkinter.Tk()
root.wm_title("CalendarDialog Demo")
root.grid_columnconfigure(0, weight=1)
root.grid_rowconfigure(0, weight=1)
root.geometry("1000x500")
top = Frame(root)
bottom = Frame(root)
top.pack(side=TOP)
bottom.pack(side=BOTTOM, fill=BOTH, expand=True)
cd_1 = CalendarDialog(root)
cd_2 = CalendarDialog(root)
cd_1.pack(in_=top, side=LEFT)
cd_2.pack(in_=top, side=LEFT)
multiple_choose_states_listbox = Listbox(root, selectmode=EXTENDED)
multiple_choose_states_listbox.grid(row=20, columns=1)
multiple_choose_days_listbox = Listbox(root, selectmode=EXTENDED)
multiple_choose_length_of_trips_list_listbox = Listbox(root, selectmode=EXTENDED)
label_day_listbox = StringVar()
label_day_listbox.set("LABEL")
l = Label(multiple_choose_days_listbox, textvariable=label_day_listbox , anchor=NW, justify='center')
l.pack()
multiple_choose_days_listbox.pack(in_=top,side=LEFT)
multiple_choose_states_listbox.pack()
multiple_choose_length_of_trips_list_listbox.pack()
for item in states_list:
multiple_choose_states_listbox.insert(END, item)
for item in bought_days_before_list:
multiple_choose_days_listbox.insert(END, item)
def get_result_dict():
date_from = cd_1.result
date_to = cd_2.result
states = [states_list[i] for i in multiple_choose_states_listbox.curselection()]
bought_days_before = [bought_days_before_list[i] for i in multiple_choose_days_listbox.curselection()]
length_of_trip = [states_list[i] for i in multiple_choose_length_of_trips_list.curselection()]
res_dict = {
'date_from': date_from,
'date_to': date_to,
'states': states,
'bought_days_before': bought_days_before,
'length_of_trip': length_of_trip,
}
return res_dict
button = Tkinter.Button(root, text="Generate", command=get_result_dict)
button.pack()
root.update()
root.mainloop()
if __name__ == "__main__":
main()
It should be
l = Tkinter.Label(root, text="Label")