Tkinter application - Task manager for my school year












0












$begingroup$


First of all, I'm Brazillian so forgive me for my bad English, I will try my best.



This is my first fully functional Tkinter Application. Just a simple task manager for my school year.
Basically, I create a task in the left panel and when I set up this as complete, this task will appear in the current subject window (This window is very simple, I'm still working on it).



I just want to know a few bunches of things:
-How is my organization style and what can I improve in my way of code?
How I said before, I'm Brazillian, that's why the interface is in Portuguese. But almost everything that I'm doing in my life I'm using English because I want to improve my writing skills.



I thank the attention :)



"""Componentes Curriculares V0.1. This program is meant to be a task manager to your School Year.
It is composed by various functions such as:
-List of all your tasks and tests, and a complete school report based on these tasks.
You can also add your topics for each subject that you are having along the year.
The main language of the interface is Portuguese and their source code was written in English
Python 3.6 is the current version.
"""

import tkinter as tk
from tkinter import ttk, messagebox
from tkinter.scrolledtext import ScrolledText
from datetime import datetime
import pickle
import getpass

# Standard variables used for multiple widgets.
fontlab_std = 'Tahoma 12 bold'
fontbut_std = 'Tahoma 9'
bg_std = 'cornsilk2'
hover_std = 'Criado por Wilson Cazarré - 3° Mecatrônica. Alpha 0.1'
icon_windows = 'book.ico'

my_subjects = ['LPL',
'Matemática',
'Biologia',
'Geografia',
'História',
'Química',
'Física',
'Filosofia',
'Sociologia',
'Educação Física',
'Inglês',
'Tecnologia de Manufatura 3',
'Linguagem de Programação Aplicada a Mecatrônica',
'Automação e Instrumentação Industrial 3',
'Microcontroladores',
'Tecnologia de Qualidade e processos',
'Robótica e Manufatura Flexível',
'Eletrônica Industrial e de Potência',
'Planejamento e Desenvolvimento do Trabalho de Conclusão de Curso']
grades = ['MB',
'B',
'R',
'I']

days = list(range(1, 32))
mouths = ['Janeiro',
'Fevereiro',
'Março',
'Abril',
'Maio',
'Junho',
'Julho',
'Agosto',
'Setembro',
'Outubro',
'Novembro',
'Dezembro']
years = list(range(2019, 2030))
weekdays = ['Segunda',
'Terça-feira',
'Quarta-feira',
'Quinta-feira',
'Sexta-feira',
'Sábado',
'Domingo']

# ---------------------------------


def load_pickle(file) -> list:
try:
with open(file, 'rb') as infile:
tasks_objects = pickle.load(infile)
tasks_objects.sort(key=lambda task: task.full_date)
return tasks_objects
except FileNotFoundError:
return
except PermissionError:
messagebox.showerror('Acesso Negado', 'Erro ao ler o arquivo. Iniciar como administrador')


def dump_pickle(file, obj):
with open(file, 'wb') as outfile:
pickle.dump(obj, outfile, pickle.HIGHEST_PROTOCOL)

# --------------------------------- Custom Widgets with default options


class MyButton(tk.Button):
"""Create a custom button widget, with default options."""
def __init__(self, master=None, hovertext=None, **kw):
tk.Button.__init__(self, master=master, **kw)
self.configure(font=fontbut_std, relief='groove') # Default options
if hovertext is not None:
self.bind('<Enter>', lambda x: self.on_hover(hovertext))
self.bind('<Leave>', lambda x: self.on_hover(hover_std))

@staticmethod
def on_hover(text):
app.hover_box.configure(text=text)


class MyLabel(tk.Label):
"""Create a custom button widget, with default options."""
def __init__(self, master=None, cnf=None, **kw):
tk.Label.__init__(self, master=master, cnf=cnf, **kw)
self.configure(bg=bg_std)


# --------------------------------- All windows, and the Task Class


class Task:
"""Objects listed in the 'MainWindow.tasks_widget'.

Tasks are saved in the following lists:
list: open_tasks: tasks not completed.
list: ended_tasks: tasks completed.
"""
def __init__(self, subject, title, day, month, year, category, description=None, is_done=False, grade=None):
self.subject = subject
self.title = title
self.day = day
self.month = month
self.year = year
self.description = description
self.is_done = is_done
self.grade = grade
self.category = category
self.full_date = datetime(int(self.year), mouths.index(self.month) + 1, int(self.day))
self.weekday = self.full_date.weekday()

def __str__(self):
return '{} - {}: "{}" para o dia {}/{}/{} ({})'.format(self.subject, self.category, self.title,
self.day, self.month, self.year,
weekdays[self.weekday])

def str_task_complete(self):
return '{}: "{}" Menção: {} - {}/{}/{}'.format(self.category, self.title, self.grade, self.day, self.month,
self.year)


class MainWindow:
"""Create the first window of the program.

self.add_button - invoke AddTaskWindow -> create a task object.
self.done_button - invoke EndTaskWindow -> set the task object as done.
"""
def __init__(self, master):
self.master = master
# Master window configs
master.title('Componentes Curriculares')
master.minsize(width=900, height=520)
master.maxsize(width=900, height=520)
master.geometry('+360+100')
master.iconbitmap(icon_windows)
master.configure(bg=bg_std)

# Setup Widgets
self.title = MyLabel(self.master, text='Componentes Curriculares', font='Tahoma 15 bold', bg=bg_std,
fg='DeepSkyBlue2', anchor='e', width=67)
self.tasks_title = MyLabel(self.master, text='Provas, tarefas e eventos', font='Tahoma 12 bold')

self.tasks_widget = tk.Listbox(self.master, width=100, height=25, relief='solid', highlightthickness=0)

for task in open_tasks:
self.tasks_widget.insert('end', task)

self.tasks_widget.bind('<Enter>', lambda x: MyButton.on_hover('Duplo clique para concluir a tarefa.'))
self.tasks_widget.bind('<Leave>', lambda x: MyButton.on_hover(hover_std))

self.tasks_widget.bind('<Double-Button-1>',
lambda x: EndTaskWindow(tk.Toplevel(), self.tasks_widget.curselection()))

self.add_button = MyButton(self.master, hovertext='Adicionar uma tarefa',
text='+', fg='green3', command=self.open_task_window, width=1)
self.sub_button = MyButton(self.master, hovertext='Remover a tarefa selecionada', text='-', fg='red',
command=lambda: self.delete_task(self.tasks_widget.curselection()), width=1)

self.done_button = MyButton(self.master, hovertext='Finalizar tarefa e registar a menção.', text='Concluir',
command=lambda: EndTaskWindow(tk.Toplevel(), self.tasks_widget.curselection()))

self.view_button = MyButton(self.master, hovertext='Visualizar informações da tarefa', text='Visualizar',
command=lambda: ViewTaskWindow(tk.Toplevel(), self.tasks_widget.curselection()))

self.tasks_widget.bind('<Delete>', lambda x: self.delete_task(self.tasks_widget.curselection()))

self.hover_box = tk.Label(self.master, text=hover_std, bg='white', anchor='w')

self.combo_title = MyLabel(self.master, text='Exibir informações da matéria:', font='Tahoma 9 bold')
self.combo_subjects = ttk.Combobox(self.master, values=my_subjects, width=30)
self.combo_confirm = MyButton(self.master, text='Abrir',
hovertext='Exibir janela de informações da matéria selecionada',
command=lambda: SubjectWindow(tk.Toplevel(), self.combo_subjects.get()))
self.combo_confirm['font'] = 'Tahoma 9'

# Place Widgets
self.title.place(x=10, y=5)

self.tasks_title.place(x=10, y=30)
self.tasks_widget.place(x=10, y=58)

self.add_button.place(x=10, y=463)
self.sub_button.place(x=28, y=463)
self.done_button.place(x=46, y=463)
self.view_button.place(x=100, y=463)

self.combo_title.place(x=630, y=180)
self.combo_subjects.place(x=630, y=200)
self.combo_confirm.place(x=835, y=198)

self.hover_box.pack(side='bottom', fill='x')

def open_task_window(self):
"""Hey"""
window2 = tk.Toplevel()
self.add_button['state'] = 'disable'
self.sub_button['state'] = 'disable'
self.done_button['state'] = 'disable'
self.view_button['state'] = 'disable'
self.combo_confirm['state'] = 'disable'
self.taskwindow = AddTaskWindow(window2)

def delete_task(self, index):
delete_box = 'no'
if index != ():
delete_box = messagebox.askquestion('Deletar Tarefa', 'Deletar tarefa selecionada?')
if delete_box == 'yes':
self.tasks_widget.delete(index)
open_tasks.pop(index[0])
with open(file_open_tasks, 'wb') as outfile:
pickle.dump(open_tasks, outfile, pickle.HIGHEST_PROTOCOL)


class AddTaskWindow:
"""Launch the window for create a task in MainWindow.tasks_widget(tk.Listbox)

self.register_button -> self.create_task -> Task -> Create task object.
"""
def __init__(self, master):
self.master = master
app.done_button['state'] = 'disable'
master.title('Criar Tarefa')
master.geometry('600x400+500+200')
master.iconbitmap(icon_windows)
master.configure(bg=bg_std)
master.attributes('-topmost', True)
master.protocol('WM_DELETE_WINDOW', self.close_window)
master.focus_force()
self.radio_var = tk.StringVar()

# Setup Widgets
self.title_radio = MyLabel(self.master, text='Tipo de atividade:', font='Tahoma 8 bold')
self.radio1 = tk.Radiobutton(self.master, text='Prova', variable=self.radio_var, value='Prova', bg=bg_std,
activebackground=bg_std)
self.radio2 = tk.Radiobutton(self.master, text='Trabalho', variable=self.radio_var, value='Trabalho', bg=bg_std,
activebackground=bg_std)
self.radio3 = tk.Radiobutton(self.master, text='Outro(Sem menção)', variable=self.radio_var,
value='Outro(Sem menção)', bg=bg_std, activebackground=bg_std)

self.title_entry = MyLabel(self.master, text='Título da atividade:', font='Tahoma 8 bold')
self.entry = tk.Entry(self.master, width=60, relief='groove')

self.title_combo_subjects = MyLabel(self.master, text='Matéria da atividade:', font='Tahoma 8 bold')
self.combo_subjects = ttk.Combobox(self.master, values=my_subjects, width=60)

self.title_date = MyLabel(self.master, text='Data da atividade:', font='Tahoma 8 bold')
self.combo_day = ttk.Combobox(self.master, values=days, width=3)
self.combo_day.current(days.index(datetime.now().day))

self.combo_mouth = ttk.Combobox(self.master, values=mouths, width=10)
self.combo_mouth.current(datetime.now().month-1)

self.combo_year = ttk.Combobox(self.master, values=years, width=5)
self.combo_year.current(years.index(datetime.now().year))

self.register_button = MyButton(self.master, text='Criar tarefa', command=self.create_task)

self.description_box_title = MyLabel(self.master, text='Descrição da Tarefa:', font='Tahoma 10 bold')
self.description_box = ScrolledText(self.master, font='Consolas 9', width=60, height=10)

# Place Widgets
self.title_radio.place(x=10, y=10)
self.radio1.place(x=150, y=10)
self.radio2.place(x=210, y=10)
self.radio3.place(x=285, y=10)

self.title_entry.place(x=10, y=35)
self.entry.place(x=150, y=35)

self.title_combo_subjects.place(x=10, y=60)
self.combo_subjects.place(x=150, y=60)

self.title_date.place(x=10, y=85)
self.combo_day.place(x=150, y=85)
self.combo_mouth.place(x=190, y=85)
self.combo_year.place(x=271, y=85)

self.register_button.place(x=360, y=122)

self.description_box_title.place(x=10, y=125)
self.description_box.place(x=10, y=150)

def create_task(self):
"""Create the task object and update the 'MainWindow.tasks_widget(tk.Listbox)'."""
new_task = Task(subject=self.combo_subjects.get(),
title=self.entry.get(),
day=self.combo_day.get(),
month=self.combo_mouth.get(),
year=self.combo_year.get(),
category=self.radio_var.get(),
description=self.description_box.get('1.0', 'end'))

app.tasks_widget.delete(0, 'end')

open_tasks.insert(0, new_task)
open_tasks.sort(key=lambda task: task.full_date)
for task in open_tasks:
app.tasks_widget.insert('end', task)
with open(file_open_tasks, 'wb') as outfile:
pickle.dump(open_tasks, outfile, pickle.HIGHEST_PROTOCOL)
self.close_window()

def close_window(self):
app.add_button['state'] = 'active'
app.sub_button['state'] = 'active'
app.done_button['state'] = 'active'
app.view_button['state'] = 'active'
app.combo_confirm['state'] = 'active'
self.master.destroy()


class EndTaskWindow:
"""Lauch the window for end a task.

Invoked from MainWindow.done_button -> returns the current selection on the MainWindow.tasks_widget
-> task_index -> EndTaskWindow.__init__.
"""
def __init__(self, master, task_index):
self.master = master
if task_index != ():
self.task_index = task_index
self.task = open_tasks[task_index[0]]

master.title('Finalizar Tarefa')
master.minsize(width=250, height=190)
master.maxsize(width=250, height=190)
master.geometry('+500+200')
master.iconbitmap(icon_windows)
master.configure(bg=bg_std)
master.attributes('-topmost', True)
master.focus()
master.protocol('WM_DELETE_WINDOW', self.close_window)

# Setup Widgets
self.title_info = MyLabel(self.master, text='Dados da Atividade', font='Tahoma 14 bold')
self.info_label_header = MyLabel(self.master, text='Tipo:nTítulo:nMatéria:nData:', justify='left',
font='Tamoha 10 bold')
self.info_label = MyLabel(self.master, justify='left', font='Tahoma 10 italic',
text='{}n{}n{}n{}'.format(self.task.category, self.task.title, self.task.subject,
self.task.full_date))
self.title_combo_grades = MyLabel(self.master, text='Insira a menção final:', font='Tahoma 11 bold')
self.combo_grades = ttk.Combobox(self.master, values=grades, width=3)
self.finish_button = MyButton(self.master, text='Finalizar', command=lambda: self.end_task(
self.combo_grades.get()), anchor='center')

# Place Widgets
self.title_info.place(x=10, y=10)

self.info_label_header.place(x=10, y=40)
self.info_label.place(x=75, y=40)

self.title_combo_grades.place(x=10, y=125)
self.combo_grades.place(x=180, y=127)
self.finish_button.place(x=95, y=155)

def end_task(self, grade):
"""Set the task as done.

self.finish_button -> returns the current selection in self.combo_grades(tk.Combobox)

Define task.is_done as True and grade.
Remove this object from the list: open_task, append to list: ended_tasks
"""
self.task.is_done = True
self.task.grade = grade
self.close_window()
print(self.task.grade)
print(self.task.is_done)
ended_tasks.append(self.task)
open_tasks.remove(self.task)

app.tasks_widget.delete(0, 'end')

for task in open_tasks:
app.tasks_widget.insert('end', task)

with open(file_open_tasks, 'wb') as outfile:
pickle.dump(open_tasks, outfile, pickle.HIGHEST_PROTOCOL)

def close_window(self):
self.master.destroy()


class ViewTaskWindow:
def __init__(self, master, task_index):
self.master = master
if task_index != ():
self.task_index = task_index
self.task = open_tasks[task_index[0]]
master.title('Finalizar Tarefa')
master.minsize(width=500, height=450)
master.maxsize(width=500, height=450)
master.geometry('+500+75')
master.iconbitmap(icon_windows)
master.configure(bg=bg_std)
master.attributes('-topmost', True)
master.focus()
master.protocol('WM_DELETE_WINDOW', self.close_window)

print('text: ' + self.task.description)
if self.task.description == 'n':
self.description = 'Nada a exibir'
else:
self.description = self.task.description

# Setup Widgets
self.title_info = MyLabel(self.master, text='Dados da Atividade', font='Tahoma 14 bold')
self.info_label_header = MyLabel(self.master, text='Tipo:nTítulo:nMatéria:nData:', justify='left',
font='Tamoha 10 bold')
self.date_text = str(self.task.full_date).split(' ')
self.info_label = MyLabel(self.master, justify='left', font='Tahoma 10 italic',
text='{}n{}n{}n{}'.format(self.task.category, self.task.title,
self.task.subject,
self.date_text[0]))

self.description_title = MyLabel(self.master, text='Descrição da Tarefa:', font='Tahoma 11 bold')
self.description_label = MyLabel(self.master, text=self.description, font='Consolas 9', justify='left')

self.description_text = ScrolledText(self.master, width=60, height=20, font='Consolas 9')
self.description_text.insert('1.0', self.description)
self.description_text['state'] = 'disable'

# Place Widgets
self.title_info.place(x=10, y=10)

self.info_label_header.place(x=10, y=40)
self.info_label.place(x=75, y=40)

self.description_title.place(x=10, y=120)
self.description_text.place(x=10, y=150)
# self.description_label.place(x=10, y=150)

def close_window(self):
self.master.destroy()


class SubjectWindow:
"""Launch the window with all completed tasks of specified subject

Invoke by MainApplication.combo_confirm(tk.Button) -> returns the selection on MainApplication.combo_subjects
-> subject -> SubjectWindow.__init__.
"""
def __init__(self, master, subject):
if subject in my_subjects:
self.master = master
self.subject = subject
self.text_tasks_label = ''
app.combo_confirm['state'] = 'disabled'
master.title(subject)
master.geometry('800x400')
master.iconbitmap(icon_windows)
master.configure(bg=bg_std)
master.protocol('WM_DELETE_WINDOW', self.close_window)
else:
master.destroy()

# Setup Widgets
self.title = MyLabel(self.master, text=self.subject, font='Tahoma 15 bold')
self.label1 = MyLabel(self.master, text='Bases Tecnológicas', font='Tahoma 12 bold')
self.label2 = MyLabel(self.master, text='Atividades e Menções', font='Tahoma 12 bold')

for task in ended_tasks:
if task.subject == self.subject:
print(task)
print(task.str_task_complete())
self.text_tasks_label += task.str_task_complete() + 'n'

self.tasks_label = MyLabel(self.master, font='Tahoma 9', text='nothing here', justify='left')
self.tasks_label.configure(text=self.text_tasks_label)
# self.subject_tasks = tk.Listbox(self.master, width=130, relief='solid', highlightthickness=0)

# Place Widgets
self.title.place(x=10, y=10)
self.label2.place(x=10, y=55)
self.tasks_label.place(x=10, y=80)
# self.subject_tasks.place(x=10, y=80)

def close_window(self):
self.tasks_label.configure(text='')
dump_pickle(file_ended_tasks, ended_tasks)
self.master.destroy()
app.combo_confirm['state'] = 'active'


username = getpass.getuser()
file_open_tasks = r'C:Users{}AppDataLocaltasks_open.pkl'.format(username)
file_ended_tasks = r'C:Users{}AppDataLocaltasks_ended.pkl'.format(username)


if __name__ == '__main__':
open_tasks: list = load_pickle(file_open_tasks)
ended_tasks: list = load_pickle(file_ended_tasks)
root = tk.Tk()
app = MainWindow(root)
root.mainloop()









share|improve this question







New contributor




Wilson Cazarré is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.







$endgroup$

















    0












    $begingroup$


    First of all, I'm Brazillian so forgive me for my bad English, I will try my best.



    This is my first fully functional Tkinter Application. Just a simple task manager for my school year.
    Basically, I create a task in the left panel and when I set up this as complete, this task will appear in the current subject window (This window is very simple, I'm still working on it).



    I just want to know a few bunches of things:
    -How is my organization style and what can I improve in my way of code?
    How I said before, I'm Brazillian, that's why the interface is in Portuguese. But almost everything that I'm doing in my life I'm using English because I want to improve my writing skills.



    I thank the attention :)



    """Componentes Curriculares V0.1. This program is meant to be a task manager to your School Year.
    It is composed by various functions such as:
    -List of all your tasks and tests, and a complete school report based on these tasks.
    You can also add your topics for each subject that you are having along the year.
    The main language of the interface is Portuguese and their source code was written in English
    Python 3.6 is the current version.
    """

    import tkinter as tk
    from tkinter import ttk, messagebox
    from tkinter.scrolledtext import ScrolledText
    from datetime import datetime
    import pickle
    import getpass

    # Standard variables used for multiple widgets.
    fontlab_std = 'Tahoma 12 bold'
    fontbut_std = 'Tahoma 9'
    bg_std = 'cornsilk2'
    hover_std = 'Criado por Wilson Cazarré - 3° Mecatrônica. Alpha 0.1'
    icon_windows = 'book.ico'

    my_subjects = ['LPL',
    'Matemática',
    'Biologia',
    'Geografia',
    'História',
    'Química',
    'Física',
    'Filosofia',
    'Sociologia',
    'Educação Física',
    'Inglês',
    'Tecnologia de Manufatura 3',
    'Linguagem de Programação Aplicada a Mecatrônica',
    'Automação e Instrumentação Industrial 3',
    'Microcontroladores',
    'Tecnologia de Qualidade e processos',
    'Robótica e Manufatura Flexível',
    'Eletrônica Industrial e de Potência',
    'Planejamento e Desenvolvimento do Trabalho de Conclusão de Curso']
    grades = ['MB',
    'B',
    'R',
    'I']

    days = list(range(1, 32))
    mouths = ['Janeiro',
    'Fevereiro',
    'Março',
    'Abril',
    'Maio',
    'Junho',
    'Julho',
    'Agosto',
    'Setembro',
    'Outubro',
    'Novembro',
    'Dezembro']
    years = list(range(2019, 2030))
    weekdays = ['Segunda',
    'Terça-feira',
    'Quarta-feira',
    'Quinta-feira',
    'Sexta-feira',
    'Sábado',
    'Domingo']

    # ---------------------------------


    def load_pickle(file) -> list:
    try:
    with open(file, 'rb') as infile:
    tasks_objects = pickle.load(infile)
    tasks_objects.sort(key=lambda task: task.full_date)
    return tasks_objects
    except FileNotFoundError:
    return
    except PermissionError:
    messagebox.showerror('Acesso Negado', 'Erro ao ler o arquivo. Iniciar como administrador')


    def dump_pickle(file, obj):
    with open(file, 'wb') as outfile:
    pickle.dump(obj, outfile, pickle.HIGHEST_PROTOCOL)

    # --------------------------------- Custom Widgets with default options


    class MyButton(tk.Button):
    """Create a custom button widget, with default options."""
    def __init__(self, master=None, hovertext=None, **kw):
    tk.Button.__init__(self, master=master, **kw)
    self.configure(font=fontbut_std, relief='groove') # Default options
    if hovertext is not None:
    self.bind('<Enter>', lambda x: self.on_hover(hovertext))
    self.bind('<Leave>', lambda x: self.on_hover(hover_std))

    @staticmethod
    def on_hover(text):
    app.hover_box.configure(text=text)


    class MyLabel(tk.Label):
    """Create a custom button widget, with default options."""
    def __init__(self, master=None, cnf=None, **kw):
    tk.Label.__init__(self, master=master, cnf=cnf, **kw)
    self.configure(bg=bg_std)


    # --------------------------------- All windows, and the Task Class


    class Task:
    """Objects listed in the 'MainWindow.tasks_widget'.

    Tasks are saved in the following lists:
    list: open_tasks: tasks not completed.
    list: ended_tasks: tasks completed.
    """
    def __init__(self, subject, title, day, month, year, category, description=None, is_done=False, grade=None):
    self.subject = subject
    self.title = title
    self.day = day
    self.month = month
    self.year = year
    self.description = description
    self.is_done = is_done
    self.grade = grade
    self.category = category
    self.full_date = datetime(int(self.year), mouths.index(self.month) + 1, int(self.day))
    self.weekday = self.full_date.weekday()

    def __str__(self):
    return '{} - {}: "{}" para o dia {}/{}/{} ({})'.format(self.subject, self.category, self.title,
    self.day, self.month, self.year,
    weekdays[self.weekday])

    def str_task_complete(self):
    return '{}: "{}" Menção: {} - {}/{}/{}'.format(self.category, self.title, self.grade, self.day, self.month,
    self.year)


    class MainWindow:
    """Create the first window of the program.

    self.add_button - invoke AddTaskWindow -> create a task object.
    self.done_button - invoke EndTaskWindow -> set the task object as done.
    """
    def __init__(self, master):
    self.master = master
    # Master window configs
    master.title('Componentes Curriculares')
    master.minsize(width=900, height=520)
    master.maxsize(width=900, height=520)
    master.geometry('+360+100')
    master.iconbitmap(icon_windows)
    master.configure(bg=bg_std)

    # Setup Widgets
    self.title = MyLabel(self.master, text='Componentes Curriculares', font='Tahoma 15 bold', bg=bg_std,
    fg='DeepSkyBlue2', anchor='e', width=67)
    self.tasks_title = MyLabel(self.master, text='Provas, tarefas e eventos', font='Tahoma 12 bold')

    self.tasks_widget = tk.Listbox(self.master, width=100, height=25, relief='solid', highlightthickness=0)

    for task in open_tasks:
    self.tasks_widget.insert('end', task)

    self.tasks_widget.bind('<Enter>', lambda x: MyButton.on_hover('Duplo clique para concluir a tarefa.'))
    self.tasks_widget.bind('<Leave>', lambda x: MyButton.on_hover(hover_std))

    self.tasks_widget.bind('<Double-Button-1>',
    lambda x: EndTaskWindow(tk.Toplevel(), self.tasks_widget.curselection()))

    self.add_button = MyButton(self.master, hovertext='Adicionar uma tarefa',
    text='+', fg='green3', command=self.open_task_window, width=1)
    self.sub_button = MyButton(self.master, hovertext='Remover a tarefa selecionada', text='-', fg='red',
    command=lambda: self.delete_task(self.tasks_widget.curselection()), width=1)

    self.done_button = MyButton(self.master, hovertext='Finalizar tarefa e registar a menção.', text='Concluir',
    command=lambda: EndTaskWindow(tk.Toplevel(), self.tasks_widget.curselection()))

    self.view_button = MyButton(self.master, hovertext='Visualizar informações da tarefa', text='Visualizar',
    command=lambda: ViewTaskWindow(tk.Toplevel(), self.tasks_widget.curselection()))

    self.tasks_widget.bind('<Delete>', lambda x: self.delete_task(self.tasks_widget.curselection()))

    self.hover_box = tk.Label(self.master, text=hover_std, bg='white', anchor='w')

    self.combo_title = MyLabel(self.master, text='Exibir informações da matéria:', font='Tahoma 9 bold')
    self.combo_subjects = ttk.Combobox(self.master, values=my_subjects, width=30)
    self.combo_confirm = MyButton(self.master, text='Abrir',
    hovertext='Exibir janela de informações da matéria selecionada',
    command=lambda: SubjectWindow(tk.Toplevel(), self.combo_subjects.get()))
    self.combo_confirm['font'] = 'Tahoma 9'

    # Place Widgets
    self.title.place(x=10, y=5)

    self.tasks_title.place(x=10, y=30)
    self.tasks_widget.place(x=10, y=58)

    self.add_button.place(x=10, y=463)
    self.sub_button.place(x=28, y=463)
    self.done_button.place(x=46, y=463)
    self.view_button.place(x=100, y=463)

    self.combo_title.place(x=630, y=180)
    self.combo_subjects.place(x=630, y=200)
    self.combo_confirm.place(x=835, y=198)

    self.hover_box.pack(side='bottom', fill='x')

    def open_task_window(self):
    """Hey"""
    window2 = tk.Toplevel()
    self.add_button['state'] = 'disable'
    self.sub_button['state'] = 'disable'
    self.done_button['state'] = 'disable'
    self.view_button['state'] = 'disable'
    self.combo_confirm['state'] = 'disable'
    self.taskwindow = AddTaskWindow(window2)

    def delete_task(self, index):
    delete_box = 'no'
    if index != ():
    delete_box = messagebox.askquestion('Deletar Tarefa', 'Deletar tarefa selecionada?')
    if delete_box == 'yes':
    self.tasks_widget.delete(index)
    open_tasks.pop(index[0])
    with open(file_open_tasks, 'wb') as outfile:
    pickle.dump(open_tasks, outfile, pickle.HIGHEST_PROTOCOL)


    class AddTaskWindow:
    """Launch the window for create a task in MainWindow.tasks_widget(tk.Listbox)

    self.register_button -> self.create_task -> Task -> Create task object.
    """
    def __init__(self, master):
    self.master = master
    app.done_button['state'] = 'disable'
    master.title('Criar Tarefa')
    master.geometry('600x400+500+200')
    master.iconbitmap(icon_windows)
    master.configure(bg=bg_std)
    master.attributes('-topmost', True)
    master.protocol('WM_DELETE_WINDOW', self.close_window)
    master.focus_force()
    self.radio_var = tk.StringVar()

    # Setup Widgets
    self.title_radio = MyLabel(self.master, text='Tipo de atividade:', font='Tahoma 8 bold')
    self.radio1 = tk.Radiobutton(self.master, text='Prova', variable=self.radio_var, value='Prova', bg=bg_std,
    activebackground=bg_std)
    self.radio2 = tk.Radiobutton(self.master, text='Trabalho', variable=self.radio_var, value='Trabalho', bg=bg_std,
    activebackground=bg_std)
    self.radio3 = tk.Radiobutton(self.master, text='Outro(Sem menção)', variable=self.radio_var,
    value='Outro(Sem menção)', bg=bg_std, activebackground=bg_std)

    self.title_entry = MyLabel(self.master, text='Título da atividade:', font='Tahoma 8 bold')
    self.entry = tk.Entry(self.master, width=60, relief='groove')

    self.title_combo_subjects = MyLabel(self.master, text='Matéria da atividade:', font='Tahoma 8 bold')
    self.combo_subjects = ttk.Combobox(self.master, values=my_subjects, width=60)

    self.title_date = MyLabel(self.master, text='Data da atividade:', font='Tahoma 8 bold')
    self.combo_day = ttk.Combobox(self.master, values=days, width=3)
    self.combo_day.current(days.index(datetime.now().day))

    self.combo_mouth = ttk.Combobox(self.master, values=mouths, width=10)
    self.combo_mouth.current(datetime.now().month-1)

    self.combo_year = ttk.Combobox(self.master, values=years, width=5)
    self.combo_year.current(years.index(datetime.now().year))

    self.register_button = MyButton(self.master, text='Criar tarefa', command=self.create_task)

    self.description_box_title = MyLabel(self.master, text='Descrição da Tarefa:', font='Tahoma 10 bold')
    self.description_box = ScrolledText(self.master, font='Consolas 9', width=60, height=10)

    # Place Widgets
    self.title_radio.place(x=10, y=10)
    self.radio1.place(x=150, y=10)
    self.radio2.place(x=210, y=10)
    self.radio3.place(x=285, y=10)

    self.title_entry.place(x=10, y=35)
    self.entry.place(x=150, y=35)

    self.title_combo_subjects.place(x=10, y=60)
    self.combo_subjects.place(x=150, y=60)

    self.title_date.place(x=10, y=85)
    self.combo_day.place(x=150, y=85)
    self.combo_mouth.place(x=190, y=85)
    self.combo_year.place(x=271, y=85)

    self.register_button.place(x=360, y=122)

    self.description_box_title.place(x=10, y=125)
    self.description_box.place(x=10, y=150)

    def create_task(self):
    """Create the task object and update the 'MainWindow.tasks_widget(tk.Listbox)'."""
    new_task = Task(subject=self.combo_subjects.get(),
    title=self.entry.get(),
    day=self.combo_day.get(),
    month=self.combo_mouth.get(),
    year=self.combo_year.get(),
    category=self.radio_var.get(),
    description=self.description_box.get('1.0', 'end'))

    app.tasks_widget.delete(0, 'end')

    open_tasks.insert(0, new_task)
    open_tasks.sort(key=lambda task: task.full_date)
    for task in open_tasks:
    app.tasks_widget.insert('end', task)
    with open(file_open_tasks, 'wb') as outfile:
    pickle.dump(open_tasks, outfile, pickle.HIGHEST_PROTOCOL)
    self.close_window()

    def close_window(self):
    app.add_button['state'] = 'active'
    app.sub_button['state'] = 'active'
    app.done_button['state'] = 'active'
    app.view_button['state'] = 'active'
    app.combo_confirm['state'] = 'active'
    self.master.destroy()


    class EndTaskWindow:
    """Lauch the window for end a task.

    Invoked from MainWindow.done_button -> returns the current selection on the MainWindow.tasks_widget
    -> task_index -> EndTaskWindow.__init__.
    """
    def __init__(self, master, task_index):
    self.master = master
    if task_index != ():
    self.task_index = task_index
    self.task = open_tasks[task_index[0]]

    master.title('Finalizar Tarefa')
    master.minsize(width=250, height=190)
    master.maxsize(width=250, height=190)
    master.geometry('+500+200')
    master.iconbitmap(icon_windows)
    master.configure(bg=bg_std)
    master.attributes('-topmost', True)
    master.focus()
    master.protocol('WM_DELETE_WINDOW', self.close_window)

    # Setup Widgets
    self.title_info = MyLabel(self.master, text='Dados da Atividade', font='Tahoma 14 bold')
    self.info_label_header = MyLabel(self.master, text='Tipo:nTítulo:nMatéria:nData:', justify='left',
    font='Tamoha 10 bold')
    self.info_label = MyLabel(self.master, justify='left', font='Tahoma 10 italic',
    text='{}n{}n{}n{}'.format(self.task.category, self.task.title, self.task.subject,
    self.task.full_date))
    self.title_combo_grades = MyLabel(self.master, text='Insira a menção final:', font='Tahoma 11 bold')
    self.combo_grades = ttk.Combobox(self.master, values=grades, width=3)
    self.finish_button = MyButton(self.master, text='Finalizar', command=lambda: self.end_task(
    self.combo_grades.get()), anchor='center')

    # Place Widgets
    self.title_info.place(x=10, y=10)

    self.info_label_header.place(x=10, y=40)
    self.info_label.place(x=75, y=40)

    self.title_combo_grades.place(x=10, y=125)
    self.combo_grades.place(x=180, y=127)
    self.finish_button.place(x=95, y=155)

    def end_task(self, grade):
    """Set the task as done.

    self.finish_button -> returns the current selection in self.combo_grades(tk.Combobox)

    Define task.is_done as True and grade.
    Remove this object from the list: open_task, append to list: ended_tasks
    """
    self.task.is_done = True
    self.task.grade = grade
    self.close_window()
    print(self.task.grade)
    print(self.task.is_done)
    ended_tasks.append(self.task)
    open_tasks.remove(self.task)

    app.tasks_widget.delete(0, 'end')

    for task in open_tasks:
    app.tasks_widget.insert('end', task)

    with open(file_open_tasks, 'wb') as outfile:
    pickle.dump(open_tasks, outfile, pickle.HIGHEST_PROTOCOL)

    def close_window(self):
    self.master.destroy()


    class ViewTaskWindow:
    def __init__(self, master, task_index):
    self.master = master
    if task_index != ():
    self.task_index = task_index
    self.task = open_tasks[task_index[0]]
    master.title('Finalizar Tarefa')
    master.minsize(width=500, height=450)
    master.maxsize(width=500, height=450)
    master.geometry('+500+75')
    master.iconbitmap(icon_windows)
    master.configure(bg=bg_std)
    master.attributes('-topmost', True)
    master.focus()
    master.protocol('WM_DELETE_WINDOW', self.close_window)

    print('text: ' + self.task.description)
    if self.task.description == 'n':
    self.description = 'Nada a exibir'
    else:
    self.description = self.task.description

    # Setup Widgets
    self.title_info = MyLabel(self.master, text='Dados da Atividade', font='Tahoma 14 bold')
    self.info_label_header = MyLabel(self.master, text='Tipo:nTítulo:nMatéria:nData:', justify='left',
    font='Tamoha 10 bold')
    self.date_text = str(self.task.full_date).split(' ')
    self.info_label = MyLabel(self.master, justify='left', font='Tahoma 10 italic',
    text='{}n{}n{}n{}'.format(self.task.category, self.task.title,
    self.task.subject,
    self.date_text[0]))

    self.description_title = MyLabel(self.master, text='Descrição da Tarefa:', font='Tahoma 11 bold')
    self.description_label = MyLabel(self.master, text=self.description, font='Consolas 9', justify='left')

    self.description_text = ScrolledText(self.master, width=60, height=20, font='Consolas 9')
    self.description_text.insert('1.0', self.description)
    self.description_text['state'] = 'disable'

    # Place Widgets
    self.title_info.place(x=10, y=10)

    self.info_label_header.place(x=10, y=40)
    self.info_label.place(x=75, y=40)

    self.description_title.place(x=10, y=120)
    self.description_text.place(x=10, y=150)
    # self.description_label.place(x=10, y=150)

    def close_window(self):
    self.master.destroy()


    class SubjectWindow:
    """Launch the window with all completed tasks of specified subject

    Invoke by MainApplication.combo_confirm(tk.Button) -> returns the selection on MainApplication.combo_subjects
    -> subject -> SubjectWindow.__init__.
    """
    def __init__(self, master, subject):
    if subject in my_subjects:
    self.master = master
    self.subject = subject
    self.text_tasks_label = ''
    app.combo_confirm['state'] = 'disabled'
    master.title(subject)
    master.geometry('800x400')
    master.iconbitmap(icon_windows)
    master.configure(bg=bg_std)
    master.protocol('WM_DELETE_WINDOW', self.close_window)
    else:
    master.destroy()

    # Setup Widgets
    self.title = MyLabel(self.master, text=self.subject, font='Tahoma 15 bold')
    self.label1 = MyLabel(self.master, text='Bases Tecnológicas', font='Tahoma 12 bold')
    self.label2 = MyLabel(self.master, text='Atividades e Menções', font='Tahoma 12 bold')

    for task in ended_tasks:
    if task.subject == self.subject:
    print(task)
    print(task.str_task_complete())
    self.text_tasks_label += task.str_task_complete() + 'n'

    self.tasks_label = MyLabel(self.master, font='Tahoma 9', text='nothing here', justify='left')
    self.tasks_label.configure(text=self.text_tasks_label)
    # self.subject_tasks = tk.Listbox(self.master, width=130, relief='solid', highlightthickness=0)

    # Place Widgets
    self.title.place(x=10, y=10)
    self.label2.place(x=10, y=55)
    self.tasks_label.place(x=10, y=80)
    # self.subject_tasks.place(x=10, y=80)

    def close_window(self):
    self.tasks_label.configure(text='')
    dump_pickle(file_ended_tasks, ended_tasks)
    self.master.destroy()
    app.combo_confirm['state'] = 'active'


    username = getpass.getuser()
    file_open_tasks = r'C:Users{}AppDataLocaltasks_open.pkl'.format(username)
    file_ended_tasks = r'C:Users{}AppDataLocaltasks_ended.pkl'.format(username)


    if __name__ == '__main__':
    open_tasks: list = load_pickle(file_open_tasks)
    ended_tasks: list = load_pickle(file_ended_tasks)
    root = tk.Tk()
    app = MainWindow(root)
    root.mainloop()









    share|improve this question







    New contributor




    Wilson Cazarré is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
    Check out our Code of Conduct.







    $endgroup$















      0












      0








      0





      $begingroup$


      First of all, I'm Brazillian so forgive me for my bad English, I will try my best.



      This is my first fully functional Tkinter Application. Just a simple task manager for my school year.
      Basically, I create a task in the left panel and when I set up this as complete, this task will appear in the current subject window (This window is very simple, I'm still working on it).



      I just want to know a few bunches of things:
      -How is my organization style and what can I improve in my way of code?
      How I said before, I'm Brazillian, that's why the interface is in Portuguese. But almost everything that I'm doing in my life I'm using English because I want to improve my writing skills.



      I thank the attention :)



      """Componentes Curriculares V0.1. This program is meant to be a task manager to your School Year.
      It is composed by various functions such as:
      -List of all your tasks and tests, and a complete school report based on these tasks.
      You can also add your topics for each subject that you are having along the year.
      The main language of the interface is Portuguese and their source code was written in English
      Python 3.6 is the current version.
      """

      import tkinter as tk
      from tkinter import ttk, messagebox
      from tkinter.scrolledtext import ScrolledText
      from datetime import datetime
      import pickle
      import getpass

      # Standard variables used for multiple widgets.
      fontlab_std = 'Tahoma 12 bold'
      fontbut_std = 'Tahoma 9'
      bg_std = 'cornsilk2'
      hover_std = 'Criado por Wilson Cazarré - 3° Mecatrônica. Alpha 0.1'
      icon_windows = 'book.ico'

      my_subjects = ['LPL',
      'Matemática',
      'Biologia',
      'Geografia',
      'História',
      'Química',
      'Física',
      'Filosofia',
      'Sociologia',
      'Educação Física',
      'Inglês',
      'Tecnologia de Manufatura 3',
      'Linguagem de Programação Aplicada a Mecatrônica',
      'Automação e Instrumentação Industrial 3',
      'Microcontroladores',
      'Tecnologia de Qualidade e processos',
      'Robótica e Manufatura Flexível',
      'Eletrônica Industrial e de Potência',
      'Planejamento e Desenvolvimento do Trabalho de Conclusão de Curso']
      grades = ['MB',
      'B',
      'R',
      'I']

      days = list(range(1, 32))
      mouths = ['Janeiro',
      'Fevereiro',
      'Março',
      'Abril',
      'Maio',
      'Junho',
      'Julho',
      'Agosto',
      'Setembro',
      'Outubro',
      'Novembro',
      'Dezembro']
      years = list(range(2019, 2030))
      weekdays = ['Segunda',
      'Terça-feira',
      'Quarta-feira',
      'Quinta-feira',
      'Sexta-feira',
      'Sábado',
      'Domingo']

      # ---------------------------------


      def load_pickle(file) -> list:
      try:
      with open(file, 'rb') as infile:
      tasks_objects = pickle.load(infile)
      tasks_objects.sort(key=lambda task: task.full_date)
      return tasks_objects
      except FileNotFoundError:
      return
      except PermissionError:
      messagebox.showerror('Acesso Negado', 'Erro ao ler o arquivo. Iniciar como administrador')


      def dump_pickle(file, obj):
      with open(file, 'wb') as outfile:
      pickle.dump(obj, outfile, pickle.HIGHEST_PROTOCOL)

      # --------------------------------- Custom Widgets with default options


      class MyButton(tk.Button):
      """Create a custom button widget, with default options."""
      def __init__(self, master=None, hovertext=None, **kw):
      tk.Button.__init__(self, master=master, **kw)
      self.configure(font=fontbut_std, relief='groove') # Default options
      if hovertext is not None:
      self.bind('<Enter>', lambda x: self.on_hover(hovertext))
      self.bind('<Leave>', lambda x: self.on_hover(hover_std))

      @staticmethod
      def on_hover(text):
      app.hover_box.configure(text=text)


      class MyLabel(tk.Label):
      """Create a custom button widget, with default options."""
      def __init__(self, master=None, cnf=None, **kw):
      tk.Label.__init__(self, master=master, cnf=cnf, **kw)
      self.configure(bg=bg_std)


      # --------------------------------- All windows, and the Task Class


      class Task:
      """Objects listed in the 'MainWindow.tasks_widget'.

      Tasks are saved in the following lists:
      list: open_tasks: tasks not completed.
      list: ended_tasks: tasks completed.
      """
      def __init__(self, subject, title, day, month, year, category, description=None, is_done=False, grade=None):
      self.subject = subject
      self.title = title
      self.day = day
      self.month = month
      self.year = year
      self.description = description
      self.is_done = is_done
      self.grade = grade
      self.category = category
      self.full_date = datetime(int(self.year), mouths.index(self.month) + 1, int(self.day))
      self.weekday = self.full_date.weekday()

      def __str__(self):
      return '{} - {}: "{}" para o dia {}/{}/{} ({})'.format(self.subject, self.category, self.title,
      self.day, self.month, self.year,
      weekdays[self.weekday])

      def str_task_complete(self):
      return '{}: "{}" Menção: {} - {}/{}/{}'.format(self.category, self.title, self.grade, self.day, self.month,
      self.year)


      class MainWindow:
      """Create the first window of the program.

      self.add_button - invoke AddTaskWindow -> create a task object.
      self.done_button - invoke EndTaskWindow -> set the task object as done.
      """
      def __init__(self, master):
      self.master = master
      # Master window configs
      master.title('Componentes Curriculares')
      master.minsize(width=900, height=520)
      master.maxsize(width=900, height=520)
      master.geometry('+360+100')
      master.iconbitmap(icon_windows)
      master.configure(bg=bg_std)

      # Setup Widgets
      self.title = MyLabel(self.master, text='Componentes Curriculares', font='Tahoma 15 bold', bg=bg_std,
      fg='DeepSkyBlue2', anchor='e', width=67)
      self.tasks_title = MyLabel(self.master, text='Provas, tarefas e eventos', font='Tahoma 12 bold')

      self.tasks_widget = tk.Listbox(self.master, width=100, height=25, relief='solid', highlightthickness=0)

      for task in open_tasks:
      self.tasks_widget.insert('end', task)

      self.tasks_widget.bind('<Enter>', lambda x: MyButton.on_hover('Duplo clique para concluir a tarefa.'))
      self.tasks_widget.bind('<Leave>', lambda x: MyButton.on_hover(hover_std))

      self.tasks_widget.bind('<Double-Button-1>',
      lambda x: EndTaskWindow(tk.Toplevel(), self.tasks_widget.curselection()))

      self.add_button = MyButton(self.master, hovertext='Adicionar uma tarefa',
      text='+', fg='green3', command=self.open_task_window, width=1)
      self.sub_button = MyButton(self.master, hovertext='Remover a tarefa selecionada', text='-', fg='red',
      command=lambda: self.delete_task(self.tasks_widget.curselection()), width=1)

      self.done_button = MyButton(self.master, hovertext='Finalizar tarefa e registar a menção.', text='Concluir',
      command=lambda: EndTaskWindow(tk.Toplevel(), self.tasks_widget.curselection()))

      self.view_button = MyButton(self.master, hovertext='Visualizar informações da tarefa', text='Visualizar',
      command=lambda: ViewTaskWindow(tk.Toplevel(), self.tasks_widget.curselection()))

      self.tasks_widget.bind('<Delete>', lambda x: self.delete_task(self.tasks_widget.curselection()))

      self.hover_box = tk.Label(self.master, text=hover_std, bg='white', anchor='w')

      self.combo_title = MyLabel(self.master, text='Exibir informações da matéria:', font='Tahoma 9 bold')
      self.combo_subjects = ttk.Combobox(self.master, values=my_subjects, width=30)
      self.combo_confirm = MyButton(self.master, text='Abrir',
      hovertext='Exibir janela de informações da matéria selecionada',
      command=lambda: SubjectWindow(tk.Toplevel(), self.combo_subjects.get()))
      self.combo_confirm['font'] = 'Tahoma 9'

      # Place Widgets
      self.title.place(x=10, y=5)

      self.tasks_title.place(x=10, y=30)
      self.tasks_widget.place(x=10, y=58)

      self.add_button.place(x=10, y=463)
      self.sub_button.place(x=28, y=463)
      self.done_button.place(x=46, y=463)
      self.view_button.place(x=100, y=463)

      self.combo_title.place(x=630, y=180)
      self.combo_subjects.place(x=630, y=200)
      self.combo_confirm.place(x=835, y=198)

      self.hover_box.pack(side='bottom', fill='x')

      def open_task_window(self):
      """Hey"""
      window2 = tk.Toplevel()
      self.add_button['state'] = 'disable'
      self.sub_button['state'] = 'disable'
      self.done_button['state'] = 'disable'
      self.view_button['state'] = 'disable'
      self.combo_confirm['state'] = 'disable'
      self.taskwindow = AddTaskWindow(window2)

      def delete_task(self, index):
      delete_box = 'no'
      if index != ():
      delete_box = messagebox.askquestion('Deletar Tarefa', 'Deletar tarefa selecionada?')
      if delete_box == 'yes':
      self.tasks_widget.delete(index)
      open_tasks.pop(index[0])
      with open(file_open_tasks, 'wb') as outfile:
      pickle.dump(open_tasks, outfile, pickle.HIGHEST_PROTOCOL)


      class AddTaskWindow:
      """Launch the window for create a task in MainWindow.tasks_widget(tk.Listbox)

      self.register_button -> self.create_task -> Task -> Create task object.
      """
      def __init__(self, master):
      self.master = master
      app.done_button['state'] = 'disable'
      master.title('Criar Tarefa')
      master.geometry('600x400+500+200')
      master.iconbitmap(icon_windows)
      master.configure(bg=bg_std)
      master.attributes('-topmost', True)
      master.protocol('WM_DELETE_WINDOW', self.close_window)
      master.focus_force()
      self.radio_var = tk.StringVar()

      # Setup Widgets
      self.title_radio = MyLabel(self.master, text='Tipo de atividade:', font='Tahoma 8 bold')
      self.radio1 = tk.Radiobutton(self.master, text='Prova', variable=self.radio_var, value='Prova', bg=bg_std,
      activebackground=bg_std)
      self.radio2 = tk.Radiobutton(self.master, text='Trabalho', variable=self.radio_var, value='Trabalho', bg=bg_std,
      activebackground=bg_std)
      self.radio3 = tk.Radiobutton(self.master, text='Outro(Sem menção)', variable=self.radio_var,
      value='Outro(Sem menção)', bg=bg_std, activebackground=bg_std)

      self.title_entry = MyLabel(self.master, text='Título da atividade:', font='Tahoma 8 bold')
      self.entry = tk.Entry(self.master, width=60, relief='groove')

      self.title_combo_subjects = MyLabel(self.master, text='Matéria da atividade:', font='Tahoma 8 bold')
      self.combo_subjects = ttk.Combobox(self.master, values=my_subjects, width=60)

      self.title_date = MyLabel(self.master, text='Data da atividade:', font='Tahoma 8 bold')
      self.combo_day = ttk.Combobox(self.master, values=days, width=3)
      self.combo_day.current(days.index(datetime.now().day))

      self.combo_mouth = ttk.Combobox(self.master, values=mouths, width=10)
      self.combo_mouth.current(datetime.now().month-1)

      self.combo_year = ttk.Combobox(self.master, values=years, width=5)
      self.combo_year.current(years.index(datetime.now().year))

      self.register_button = MyButton(self.master, text='Criar tarefa', command=self.create_task)

      self.description_box_title = MyLabel(self.master, text='Descrição da Tarefa:', font='Tahoma 10 bold')
      self.description_box = ScrolledText(self.master, font='Consolas 9', width=60, height=10)

      # Place Widgets
      self.title_radio.place(x=10, y=10)
      self.radio1.place(x=150, y=10)
      self.radio2.place(x=210, y=10)
      self.radio3.place(x=285, y=10)

      self.title_entry.place(x=10, y=35)
      self.entry.place(x=150, y=35)

      self.title_combo_subjects.place(x=10, y=60)
      self.combo_subjects.place(x=150, y=60)

      self.title_date.place(x=10, y=85)
      self.combo_day.place(x=150, y=85)
      self.combo_mouth.place(x=190, y=85)
      self.combo_year.place(x=271, y=85)

      self.register_button.place(x=360, y=122)

      self.description_box_title.place(x=10, y=125)
      self.description_box.place(x=10, y=150)

      def create_task(self):
      """Create the task object and update the 'MainWindow.tasks_widget(tk.Listbox)'."""
      new_task = Task(subject=self.combo_subjects.get(),
      title=self.entry.get(),
      day=self.combo_day.get(),
      month=self.combo_mouth.get(),
      year=self.combo_year.get(),
      category=self.radio_var.get(),
      description=self.description_box.get('1.0', 'end'))

      app.tasks_widget.delete(0, 'end')

      open_tasks.insert(0, new_task)
      open_tasks.sort(key=lambda task: task.full_date)
      for task in open_tasks:
      app.tasks_widget.insert('end', task)
      with open(file_open_tasks, 'wb') as outfile:
      pickle.dump(open_tasks, outfile, pickle.HIGHEST_PROTOCOL)
      self.close_window()

      def close_window(self):
      app.add_button['state'] = 'active'
      app.sub_button['state'] = 'active'
      app.done_button['state'] = 'active'
      app.view_button['state'] = 'active'
      app.combo_confirm['state'] = 'active'
      self.master.destroy()


      class EndTaskWindow:
      """Lauch the window for end a task.

      Invoked from MainWindow.done_button -> returns the current selection on the MainWindow.tasks_widget
      -> task_index -> EndTaskWindow.__init__.
      """
      def __init__(self, master, task_index):
      self.master = master
      if task_index != ():
      self.task_index = task_index
      self.task = open_tasks[task_index[0]]

      master.title('Finalizar Tarefa')
      master.minsize(width=250, height=190)
      master.maxsize(width=250, height=190)
      master.geometry('+500+200')
      master.iconbitmap(icon_windows)
      master.configure(bg=bg_std)
      master.attributes('-topmost', True)
      master.focus()
      master.protocol('WM_DELETE_WINDOW', self.close_window)

      # Setup Widgets
      self.title_info = MyLabel(self.master, text='Dados da Atividade', font='Tahoma 14 bold')
      self.info_label_header = MyLabel(self.master, text='Tipo:nTítulo:nMatéria:nData:', justify='left',
      font='Tamoha 10 bold')
      self.info_label = MyLabel(self.master, justify='left', font='Tahoma 10 italic',
      text='{}n{}n{}n{}'.format(self.task.category, self.task.title, self.task.subject,
      self.task.full_date))
      self.title_combo_grades = MyLabel(self.master, text='Insira a menção final:', font='Tahoma 11 bold')
      self.combo_grades = ttk.Combobox(self.master, values=grades, width=3)
      self.finish_button = MyButton(self.master, text='Finalizar', command=lambda: self.end_task(
      self.combo_grades.get()), anchor='center')

      # Place Widgets
      self.title_info.place(x=10, y=10)

      self.info_label_header.place(x=10, y=40)
      self.info_label.place(x=75, y=40)

      self.title_combo_grades.place(x=10, y=125)
      self.combo_grades.place(x=180, y=127)
      self.finish_button.place(x=95, y=155)

      def end_task(self, grade):
      """Set the task as done.

      self.finish_button -> returns the current selection in self.combo_grades(tk.Combobox)

      Define task.is_done as True and grade.
      Remove this object from the list: open_task, append to list: ended_tasks
      """
      self.task.is_done = True
      self.task.grade = grade
      self.close_window()
      print(self.task.grade)
      print(self.task.is_done)
      ended_tasks.append(self.task)
      open_tasks.remove(self.task)

      app.tasks_widget.delete(0, 'end')

      for task in open_tasks:
      app.tasks_widget.insert('end', task)

      with open(file_open_tasks, 'wb') as outfile:
      pickle.dump(open_tasks, outfile, pickle.HIGHEST_PROTOCOL)

      def close_window(self):
      self.master.destroy()


      class ViewTaskWindow:
      def __init__(self, master, task_index):
      self.master = master
      if task_index != ():
      self.task_index = task_index
      self.task = open_tasks[task_index[0]]
      master.title('Finalizar Tarefa')
      master.minsize(width=500, height=450)
      master.maxsize(width=500, height=450)
      master.geometry('+500+75')
      master.iconbitmap(icon_windows)
      master.configure(bg=bg_std)
      master.attributes('-topmost', True)
      master.focus()
      master.protocol('WM_DELETE_WINDOW', self.close_window)

      print('text: ' + self.task.description)
      if self.task.description == 'n':
      self.description = 'Nada a exibir'
      else:
      self.description = self.task.description

      # Setup Widgets
      self.title_info = MyLabel(self.master, text='Dados da Atividade', font='Tahoma 14 bold')
      self.info_label_header = MyLabel(self.master, text='Tipo:nTítulo:nMatéria:nData:', justify='left',
      font='Tamoha 10 bold')
      self.date_text = str(self.task.full_date).split(' ')
      self.info_label = MyLabel(self.master, justify='left', font='Tahoma 10 italic',
      text='{}n{}n{}n{}'.format(self.task.category, self.task.title,
      self.task.subject,
      self.date_text[0]))

      self.description_title = MyLabel(self.master, text='Descrição da Tarefa:', font='Tahoma 11 bold')
      self.description_label = MyLabel(self.master, text=self.description, font='Consolas 9', justify='left')

      self.description_text = ScrolledText(self.master, width=60, height=20, font='Consolas 9')
      self.description_text.insert('1.0', self.description)
      self.description_text['state'] = 'disable'

      # Place Widgets
      self.title_info.place(x=10, y=10)

      self.info_label_header.place(x=10, y=40)
      self.info_label.place(x=75, y=40)

      self.description_title.place(x=10, y=120)
      self.description_text.place(x=10, y=150)
      # self.description_label.place(x=10, y=150)

      def close_window(self):
      self.master.destroy()


      class SubjectWindow:
      """Launch the window with all completed tasks of specified subject

      Invoke by MainApplication.combo_confirm(tk.Button) -> returns the selection on MainApplication.combo_subjects
      -> subject -> SubjectWindow.__init__.
      """
      def __init__(self, master, subject):
      if subject in my_subjects:
      self.master = master
      self.subject = subject
      self.text_tasks_label = ''
      app.combo_confirm['state'] = 'disabled'
      master.title(subject)
      master.geometry('800x400')
      master.iconbitmap(icon_windows)
      master.configure(bg=bg_std)
      master.protocol('WM_DELETE_WINDOW', self.close_window)
      else:
      master.destroy()

      # Setup Widgets
      self.title = MyLabel(self.master, text=self.subject, font='Tahoma 15 bold')
      self.label1 = MyLabel(self.master, text='Bases Tecnológicas', font='Tahoma 12 bold')
      self.label2 = MyLabel(self.master, text='Atividades e Menções', font='Tahoma 12 bold')

      for task in ended_tasks:
      if task.subject == self.subject:
      print(task)
      print(task.str_task_complete())
      self.text_tasks_label += task.str_task_complete() + 'n'

      self.tasks_label = MyLabel(self.master, font='Tahoma 9', text='nothing here', justify='left')
      self.tasks_label.configure(text=self.text_tasks_label)
      # self.subject_tasks = tk.Listbox(self.master, width=130, relief='solid', highlightthickness=0)

      # Place Widgets
      self.title.place(x=10, y=10)
      self.label2.place(x=10, y=55)
      self.tasks_label.place(x=10, y=80)
      # self.subject_tasks.place(x=10, y=80)

      def close_window(self):
      self.tasks_label.configure(text='')
      dump_pickle(file_ended_tasks, ended_tasks)
      self.master.destroy()
      app.combo_confirm['state'] = 'active'


      username = getpass.getuser()
      file_open_tasks = r'C:Users{}AppDataLocaltasks_open.pkl'.format(username)
      file_ended_tasks = r'C:Users{}AppDataLocaltasks_ended.pkl'.format(username)


      if __name__ == '__main__':
      open_tasks: list = load_pickle(file_open_tasks)
      ended_tasks: list = load_pickle(file_ended_tasks)
      root = tk.Tk()
      app = MainWindow(root)
      root.mainloop()









      share|improve this question







      New contributor




      Wilson Cazarré is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.







      $endgroup$




      First of all, I'm Brazillian so forgive me for my bad English, I will try my best.



      This is my first fully functional Tkinter Application. Just a simple task manager for my school year.
      Basically, I create a task in the left panel and when I set up this as complete, this task will appear in the current subject window (This window is very simple, I'm still working on it).



      I just want to know a few bunches of things:
      -How is my organization style and what can I improve in my way of code?
      How I said before, I'm Brazillian, that's why the interface is in Portuguese. But almost everything that I'm doing in my life I'm using English because I want to improve my writing skills.



      I thank the attention :)



      """Componentes Curriculares V0.1. This program is meant to be a task manager to your School Year.
      It is composed by various functions such as:
      -List of all your tasks and tests, and a complete school report based on these tasks.
      You can also add your topics for each subject that you are having along the year.
      The main language of the interface is Portuguese and their source code was written in English
      Python 3.6 is the current version.
      """

      import tkinter as tk
      from tkinter import ttk, messagebox
      from tkinter.scrolledtext import ScrolledText
      from datetime import datetime
      import pickle
      import getpass

      # Standard variables used for multiple widgets.
      fontlab_std = 'Tahoma 12 bold'
      fontbut_std = 'Tahoma 9'
      bg_std = 'cornsilk2'
      hover_std = 'Criado por Wilson Cazarré - 3° Mecatrônica. Alpha 0.1'
      icon_windows = 'book.ico'

      my_subjects = ['LPL',
      'Matemática',
      'Biologia',
      'Geografia',
      'História',
      'Química',
      'Física',
      'Filosofia',
      'Sociologia',
      'Educação Física',
      'Inglês',
      'Tecnologia de Manufatura 3',
      'Linguagem de Programação Aplicada a Mecatrônica',
      'Automação e Instrumentação Industrial 3',
      'Microcontroladores',
      'Tecnologia de Qualidade e processos',
      'Robótica e Manufatura Flexível',
      'Eletrônica Industrial e de Potência',
      'Planejamento e Desenvolvimento do Trabalho de Conclusão de Curso']
      grades = ['MB',
      'B',
      'R',
      'I']

      days = list(range(1, 32))
      mouths = ['Janeiro',
      'Fevereiro',
      'Março',
      'Abril',
      'Maio',
      'Junho',
      'Julho',
      'Agosto',
      'Setembro',
      'Outubro',
      'Novembro',
      'Dezembro']
      years = list(range(2019, 2030))
      weekdays = ['Segunda',
      'Terça-feira',
      'Quarta-feira',
      'Quinta-feira',
      'Sexta-feira',
      'Sábado',
      'Domingo']

      # ---------------------------------


      def load_pickle(file) -> list:
      try:
      with open(file, 'rb') as infile:
      tasks_objects = pickle.load(infile)
      tasks_objects.sort(key=lambda task: task.full_date)
      return tasks_objects
      except FileNotFoundError:
      return
      except PermissionError:
      messagebox.showerror('Acesso Negado', 'Erro ao ler o arquivo. Iniciar como administrador')


      def dump_pickle(file, obj):
      with open(file, 'wb') as outfile:
      pickle.dump(obj, outfile, pickle.HIGHEST_PROTOCOL)

      # --------------------------------- Custom Widgets with default options


      class MyButton(tk.Button):
      """Create a custom button widget, with default options."""
      def __init__(self, master=None, hovertext=None, **kw):
      tk.Button.__init__(self, master=master, **kw)
      self.configure(font=fontbut_std, relief='groove') # Default options
      if hovertext is not None:
      self.bind('<Enter>', lambda x: self.on_hover(hovertext))
      self.bind('<Leave>', lambda x: self.on_hover(hover_std))

      @staticmethod
      def on_hover(text):
      app.hover_box.configure(text=text)


      class MyLabel(tk.Label):
      """Create a custom button widget, with default options."""
      def __init__(self, master=None, cnf=None, **kw):
      tk.Label.__init__(self, master=master, cnf=cnf, **kw)
      self.configure(bg=bg_std)


      # --------------------------------- All windows, and the Task Class


      class Task:
      """Objects listed in the 'MainWindow.tasks_widget'.

      Tasks are saved in the following lists:
      list: open_tasks: tasks not completed.
      list: ended_tasks: tasks completed.
      """
      def __init__(self, subject, title, day, month, year, category, description=None, is_done=False, grade=None):
      self.subject = subject
      self.title = title
      self.day = day
      self.month = month
      self.year = year
      self.description = description
      self.is_done = is_done
      self.grade = grade
      self.category = category
      self.full_date = datetime(int(self.year), mouths.index(self.month) + 1, int(self.day))
      self.weekday = self.full_date.weekday()

      def __str__(self):
      return '{} - {}: "{}" para o dia {}/{}/{} ({})'.format(self.subject, self.category, self.title,
      self.day, self.month, self.year,
      weekdays[self.weekday])

      def str_task_complete(self):
      return '{}: "{}" Menção: {} - {}/{}/{}'.format(self.category, self.title, self.grade, self.day, self.month,
      self.year)


      class MainWindow:
      """Create the first window of the program.

      self.add_button - invoke AddTaskWindow -> create a task object.
      self.done_button - invoke EndTaskWindow -> set the task object as done.
      """
      def __init__(self, master):
      self.master = master
      # Master window configs
      master.title('Componentes Curriculares')
      master.minsize(width=900, height=520)
      master.maxsize(width=900, height=520)
      master.geometry('+360+100')
      master.iconbitmap(icon_windows)
      master.configure(bg=bg_std)

      # Setup Widgets
      self.title = MyLabel(self.master, text='Componentes Curriculares', font='Tahoma 15 bold', bg=bg_std,
      fg='DeepSkyBlue2', anchor='e', width=67)
      self.tasks_title = MyLabel(self.master, text='Provas, tarefas e eventos', font='Tahoma 12 bold')

      self.tasks_widget = tk.Listbox(self.master, width=100, height=25, relief='solid', highlightthickness=0)

      for task in open_tasks:
      self.tasks_widget.insert('end', task)

      self.tasks_widget.bind('<Enter>', lambda x: MyButton.on_hover('Duplo clique para concluir a tarefa.'))
      self.tasks_widget.bind('<Leave>', lambda x: MyButton.on_hover(hover_std))

      self.tasks_widget.bind('<Double-Button-1>',
      lambda x: EndTaskWindow(tk.Toplevel(), self.tasks_widget.curselection()))

      self.add_button = MyButton(self.master, hovertext='Adicionar uma tarefa',
      text='+', fg='green3', command=self.open_task_window, width=1)
      self.sub_button = MyButton(self.master, hovertext='Remover a tarefa selecionada', text='-', fg='red',
      command=lambda: self.delete_task(self.tasks_widget.curselection()), width=1)

      self.done_button = MyButton(self.master, hovertext='Finalizar tarefa e registar a menção.', text='Concluir',
      command=lambda: EndTaskWindow(tk.Toplevel(), self.tasks_widget.curselection()))

      self.view_button = MyButton(self.master, hovertext='Visualizar informações da tarefa', text='Visualizar',
      command=lambda: ViewTaskWindow(tk.Toplevel(), self.tasks_widget.curselection()))

      self.tasks_widget.bind('<Delete>', lambda x: self.delete_task(self.tasks_widget.curselection()))

      self.hover_box = tk.Label(self.master, text=hover_std, bg='white', anchor='w')

      self.combo_title = MyLabel(self.master, text='Exibir informações da matéria:', font='Tahoma 9 bold')
      self.combo_subjects = ttk.Combobox(self.master, values=my_subjects, width=30)
      self.combo_confirm = MyButton(self.master, text='Abrir',
      hovertext='Exibir janela de informações da matéria selecionada',
      command=lambda: SubjectWindow(tk.Toplevel(), self.combo_subjects.get()))
      self.combo_confirm['font'] = 'Tahoma 9'

      # Place Widgets
      self.title.place(x=10, y=5)

      self.tasks_title.place(x=10, y=30)
      self.tasks_widget.place(x=10, y=58)

      self.add_button.place(x=10, y=463)
      self.sub_button.place(x=28, y=463)
      self.done_button.place(x=46, y=463)
      self.view_button.place(x=100, y=463)

      self.combo_title.place(x=630, y=180)
      self.combo_subjects.place(x=630, y=200)
      self.combo_confirm.place(x=835, y=198)

      self.hover_box.pack(side='bottom', fill='x')

      def open_task_window(self):
      """Hey"""
      window2 = tk.Toplevel()
      self.add_button['state'] = 'disable'
      self.sub_button['state'] = 'disable'
      self.done_button['state'] = 'disable'
      self.view_button['state'] = 'disable'
      self.combo_confirm['state'] = 'disable'
      self.taskwindow = AddTaskWindow(window2)

      def delete_task(self, index):
      delete_box = 'no'
      if index != ():
      delete_box = messagebox.askquestion('Deletar Tarefa', 'Deletar tarefa selecionada?')
      if delete_box == 'yes':
      self.tasks_widget.delete(index)
      open_tasks.pop(index[0])
      with open(file_open_tasks, 'wb') as outfile:
      pickle.dump(open_tasks, outfile, pickle.HIGHEST_PROTOCOL)


      class AddTaskWindow:
      """Launch the window for create a task in MainWindow.tasks_widget(tk.Listbox)

      self.register_button -> self.create_task -> Task -> Create task object.
      """
      def __init__(self, master):
      self.master = master
      app.done_button['state'] = 'disable'
      master.title('Criar Tarefa')
      master.geometry('600x400+500+200')
      master.iconbitmap(icon_windows)
      master.configure(bg=bg_std)
      master.attributes('-topmost', True)
      master.protocol('WM_DELETE_WINDOW', self.close_window)
      master.focus_force()
      self.radio_var = tk.StringVar()

      # Setup Widgets
      self.title_radio = MyLabel(self.master, text='Tipo de atividade:', font='Tahoma 8 bold')
      self.radio1 = tk.Radiobutton(self.master, text='Prova', variable=self.radio_var, value='Prova', bg=bg_std,
      activebackground=bg_std)
      self.radio2 = tk.Radiobutton(self.master, text='Trabalho', variable=self.radio_var, value='Trabalho', bg=bg_std,
      activebackground=bg_std)
      self.radio3 = tk.Radiobutton(self.master, text='Outro(Sem menção)', variable=self.radio_var,
      value='Outro(Sem menção)', bg=bg_std, activebackground=bg_std)

      self.title_entry = MyLabel(self.master, text='Título da atividade:', font='Tahoma 8 bold')
      self.entry = tk.Entry(self.master, width=60, relief='groove')

      self.title_combo_subjects = MyLabel(self.master, text='Matéria da atividade:', font='Tahoma 8 bold')
      self.combo_subjects = ttk.Combobox(self.master, values=my_subjects, width=60)

      self.title_date = MyLabel(self.master, text='Data da atividade:', font='Tahoma 8 bold')
      self.combo_day = ttk.Combobox(self.master, values=days, width=3)
      self.combo_day.current(days.index(datetime.now().day))

      self.combo_mouth = ttk.Combobox(self.master, values=mouths, width=10)
      self.combo_mouth.current(datetime.now().month-1)

      self.combo_year = ttk.Combobox(self.master, values=years, width=5)
      self.combo_year.current(years.index(datetime.now().year))

      self.register_button = MyButton(self.master, text='Criar tarefa', command=self.create_task)

      self.description_box_title = MyLabel(self.master, text='Descrição da Tarefa:', font='Tahoma 10 bold')
      self.description_box = ScrolledText(self.master, font='Consolas 9', width=60, height=10)

      # Place Widgets
      self.title_radio.place(x=10, y=10)
      self.radio1.place(x=150, y=10)
      self.radio2.place(x=210, y=10)
      self.radio3.place(x=285, y=10)

      self.title_entry.place(x=10, y=35)
      self.entry.place(x=150, y=35)

      self.title_combo_subjects.place(x=10, y=60)
      self.combo_subjects.place(x=150, y=60)

      self.title_date.place(x=10, y=85)
      self.combo_day.place(x=150, y=85)
      self.combo_mouth.place(x=190, y=85)
      self.combo_year.place(x=271, y=85)

      self.register_button.place(x=360, y=122)

      self.description_box_title.place(x=10, y=125)
      self.description_box.place(x=10, y=150)

      def create_task(self):
      """Create the task object and update the 'MainWindow.tasks_widget(tk.Listbox)'."""
      new_task = Task(subject=self.combo_subjects.get(),
      title=self.entry.get(),
      day=self.combo_day.get(),
      month=self.combo_mouth.get(),
      year=self.combo_year.get(),
      category=self.radio_var.get(),
      description=self.description_box.get('1.0', 'end'))

      app.tasks_widget.delete(0, 'end')

      open_tasks.insert(0, new_task)
      open_tasks.sort(key=lambda task: task.full_date)
      for task in open_tasks:
      app.tasks_widget.insert('end', task)
      with open(file_open_tasks, 'wb') as outfile:
      pickle.dump(open_tasks, outfile, pickle.HIGHEST_PROTOCOL)
      self.close_window()

      def close_window(self):
      app.add_button['state'] = 'active'
      app.sub_button['state'] = 'active'
      app.done_button['state'] = 'active'
      app.view_button['state'] = 'active'
      app.combo_confirm['state'] = 'active'
      self.master.destroy()


      class EndTaskWindow:
      """Lauch the window for end a task.

      Invoked from MainWindow.done_button -> returns the current selection on the MainWindow.tasks_widget
      -> task_index -> EndTaskWindow.__init__.
      """
      def __init__(self, master, task_index):
      self.master = master
      if task_index != ():
      self.task_index = task_index
      self.task = open_tasks[task_index[0]]

      master.title('Finalizar Tarefa')
      master.minsize(width=250, height=190)
      master.maxsize(width=250, height=190)
      master.geometry('+500+200')
      master.iconbitmap(icon_windows)
      master.configure(bg=bg_std)
      master.attributes('-topmost', True)
      master.focus()
      master.protocol('WM_DELETE_WINDOW', self.close_window)

      # Setup Widgets
      self.title_info = MyLabel(self.master, text='Dados da Atividade', font='Tahoma 14 bold')
      self.info_label_header = MyLabel(self.master, text='Tipo:nTítulo:nMatéria:nData:', justify='left',
      font='Tamoha 10 bold')
      self.info_label = MyLabel(self.master, justify='left', font='Tahoma 10 italic',
      text='{}n{}n{}n{}'.format(self.task.category, self.task.title, self.task.subject,
      self.task.full_date))
      self.title_combo_grades = MyLabel(self.master, text='Insira a menção final:', font='Tahoma 11 bold')
      self.combo_grades = ttk.Combobox(self.master, values=grades, width=3)
      self.finish_button = MyButton(self.master, text='Finalizar', command=lambda: self.end_task(
      self.combo_grades.get()), anchor='center')

      # Place Widgets
      self.title_info.place(x=10, y=10)

      self.info_label_header.place(x=10, y=40)
      self.info_label.place(x=75, y=40)

      self.title_combo_grades.place(x=10, y=125)
      self.combo_grades.place(x=180, y=127)
      self.finish_button.place(x=95, y=155)

      def end_task(self, grade):
      """Set the task as done.

      self.finish_button -> returns the current selection in self.combo_grades(tk.Combobox)

      Define task.is_done as True and grade.
      Remove this object from the list: open_task, append to list: ended_tasks
      """
      self.task.is_done = True
      self.task.grade = grade
      self.close_window()
      print(self.task.grade)
      print(self.task.is_done)
      ended_tasks.append(self.task)
      open_tasks.remove(self.task)

      app.tasks_widget.delete(0, 'end')

      for task in open_tasks:
      app.tasks_widget.insert('end', task)

      with open(file_open_tasks, 'wb') as outfile:
      pickle.dump(open_tasks, outfile, pickle.HIGHEST_PROTOCOL)

      def close_window(self):
      self.master.destroy()


      class ViewTaskWindow:
      def __init__(self, master, task_index):
      self.master = master
      if task_index != ():
      self.task_index = task_index
      self.task = open_tasks[task_index[0]]
      master.title('Finalizar Tarefa')
      master.minsize(width=500, height=450)
      master.maxsize(width=500, height=450)
      master.geometry('+500+75')
      master.iconbitmap(icon_windows)
      master.configure(bg=bg_std)
      master.attributes('-topmost', True)
      master.focus()
      master.protocol('WM_DELETE_WINDOW', self.close_window)

      print('text: ' + self.task.description)
      if self.task.description == 'n':
      self.description = 'Nada a exibir'
      else:
      self.description = self.task.description

      # Setup Widgets
      self.title_info = MyLabel(self.master, text='Dados da Atividade', font='Tahoma 14 bold')
      self.info_label_header = MyLabel(self.master, text='Tipo:nTítulo:nMatéria:nData:', justify='left',
      font='Tamoha 10 bold')
      self.date_text = str(self.task.full_date).split(' ')
      self.info_label = MyLabel(self.master, justify='left', font='Tahoma 10 italic',
      text='{}n{}n{}n{}'.format(self.task.category, self.task.title,
      self.task.subject,
      self.date_text[0]))

      self.description_title = MyLabel(self.master, text='Descrição da Tarefa:', font='Tahoma 11 bold')
      self.description_label = MyLabel(self.master, text=self.description, font='Consolas 9', justify='left')

      self.description_text = ScrolledText(self.master, width=60, height=20, font='Consolas 9')
      self.description_text.insert('1.0', self.description)
      self.description_text['state'] = 'disable'

      # Place Widgets
      self.title_info.place(x=10, y=10)

      self.info_label_header.place(x=10, y=40)
      self.info_label.place(x=75, y=40)

      self.description_title.place(x=10, y=120)
      self.description_text.place(x=10, y=150)
      # self.description_label.place(x=10, y=150)

      def close_window(self):
      self.master.destroy()


      class SubjectWindow:
      """Launch the window with all completed tasks of specified subject

      Invoke by MainApplication.combo_confirm(tk.Button) -> returns the selection on MainApplication.combo_subjects
      -> subject -> SubjectWindow.__init__.
      """
      def __init__(self, master, subject):
      if subject in my_subjects:
      self.master = master
      self.subject = subject
      self.text_tasks_label = ''
      app.combo_confirm['state'] = 'disabled'
      master.title(subject)
      master.geometry('800x400')
      master.iconbitmap(icon_windows)
      master.configure(bg=bg_std)
      master.protocol('WM_DELETE_WINDOW', self.close_window)
      else:
      master.destroy()

      # Setup Widgets
      self.title = MyLabel(self.master, text=self.subject, font='Tahoma 15 bold')
      self.label1 = MyLabel(self.master, text='Bases Tecnológicas', font='Tahoma 12 bold')
      self.label2 = MyLabel(self.master, text='Atividades e Menções', font='Tahoma 12 bold')

      for task in ended_tasks:
      if task.subject == self.subject:
      print(task)
      print(task.str_task_complete())
      self.text_tasks_label += task.str_task_complete() + 'n'

      self.tasks_label = MyLabel(self.master, font='Tahoma 9', text='nothing here', justify='left')
      self.tasks_label.configure(text=self.text_tasks_label)
      # self.subject_tasks = tk.Listbox(self.master, width=130, relief='solid', highlightthickness=0)

      # Place Widgets
      self.title.place(x=10, y=10)
      self.label2.place(x=10, y=55)
      self.tasks_label.place(x=10, y=80)
      # self.subject_tasks.place(x=10, y=80)

      def close_window(self):
      self.tasks_label.configure(text='')
      dump_pickle(file_ended_tasks, ended_tasks)
      self.master.destroy()
      app.combo_confirm['state'] = 'active'


      username = getpass.getuser()
      file_open_tasks = r'C:Users{}AppDataLocaltasks_open.pkl'.format(username)
      file_ended_tasks = r'C:Users{}AppDataLocaltasks_ended.pkl'.format(username)


      if __name__ == '__main__':
      open_tasks: list = load_pickle(file_open_tasks)
      ended_tasks: list = load_pickle(file_ended_tasks)
      root = tk.Tk()
      app = MainWindow(root)
      root.mainloop()






      python object-oriented python-3.x tkinter






      share|improve this question







      New contributor




      Wilson Cazarré is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.











      share|improve this question







      New contributor




      Wilson Cazarré is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.









      share|improve this question




      share|improve this question






      New contributor




      Wilson Cazarré is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.









      asked 13 mins ago









      Wilson CazarréWilson Cazarré

      1




      1




      New contributor




      Wilson Cazarré is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.





      New contributor





      Wilson Cazarré is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.






      Wilson Cazarré is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.






















          0






          active

          oldest

          votes











          Your Answer





          StackExchange.ifUsing("editor", function () {
          return StackExchange.using("mathjaxEditing", function () {
          StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
          StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
          });
          });
          }, "mathjax-editing");

          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "196"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: false,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: null,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });






          Wilson Cazarré is a new contributor. Be nice, and check out our Code of Conduct.










          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f213928%2ftkinter-application-task-manager-for-my-school-year%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          0






          active

          oldest

          votes








          0






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes








          Wilson Cazarré is a new contributor. Be nice, and check out our Code of Conduct.










          draft saved

          draft discarded


















          Wilson Cazarré is a new contributor. Be nice, and check out our Code of Conduct.













          Wilson Cazarré is a new contributor. Be nice, and check out our Code of Conduct.












          Wilson Cazarré is a new contributor. Be nice, and check out our Code of Conduct.
















          Thanks for contributing an answer to Code Review Stack Exchange!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          Use MathJax to format equations. MathJax reference.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f213928%2ftkinter-application-task-manager-for-my-school-year%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          Terni

          A new problem with tex4ht and tikz

          Sun Ra