tesseramento/iscritti.py

503 lines
18 KiB
Python

# -*- coding: utf-8 -*-
# Per la generazione dei reports:
# - https://www.reportlab.com/
# - https://pythonhosted.org/PollyReports/tutorial.html
# - https://pbpython.com/pdf-reports.html
# Smart Card
# - https://pyscard.sourceforge.io/
# - https://www.mmxforge.net/index.php/sviluppo/python/item/9-lettura-dei-dati-della-tessera-sanitaria-con-python
import tkinter as tk
import tkinter.ttk as ttk
import tkinter.messagebox as tkMessagebox
from locale import (setlocale, LC_ALL)
from PIL import Image
from PIL import ImageDraw
from PIL import ImageTk
from db import Db
from datepicker import Datepicker
from const import MESSAGE_BOX_TITLE
from iscritto import Iscritto
FRM_PADX = 5
FRM_PADY = 3
FRA_PADX = 5
FRA_PADY = 3
LBL_PADX = 3
LBL_PADY = 3
TXT_PADX = 5
TXT_PADY = 3
IMG_PADX = 5
IMG_PADY = 3
BTN_PADX = 5
BTN_PADY = 3
setlocale(LC_ALL, '')
class Iscritti():
def __init__(self, parent):
self.parent = parent
self.larghezza_firma = 800
self.altezza_firma = 300
self.img_firma_color_fg = "black"
self.img_firma_color_bg = "white"
self.img_firma_penwidth = 5
self.iscritto = Iscritto(self.larghezza_firma,
self.altezza_firma,
self.img_firma_color_fg,
self.img_firma_color_bg)
self.create_widgets()
parent.update()
return
def create_widgets(self):
self.configure_master()
self.crea_master_widgets()
return
def configure_master(self):
# Crea la finestra a tutto schermo
# (non funziona su Mint 19.1)
# self.parent.wm_state('zoomed')
self.parent.focus_set()
self.parent.title("GOLEM - Iscritti")
self.parent.rowconfigure(0, weight=1)
self.parent.columnconfigure(0, weight=1)
self.parent.protocol("WM_DELETE_WINDOW", self.esci)
return
def crea_master_widgets(self):
self.fra_master = ttk.Frame(self.parent)
row_number = 0
s1 = ttk.Separator(self.fra_master, orient=tk.HORIZONTAL)
s1.grid(row=row_number, column=0, sticky=tk.W + tk.E)
row_number += 1
self.crea_frame_pulsanti(self.fra_master, row_number)
self.fra_master.rowconfigure(row_number, weight=0)
row_number += 1
s2 = ttk.Separator(self.fra_master, orient=tk.HORIZONTAL)
s2.grid(row=row_number, column=0, sticky=tk.W + tk.E)
row_number += 1
self.crea_frame_dati(self.fra_master, row_number)
self.fra_master.rowconfigure(row_number, weight=1)
row_number += 1
self.fra_master.columnconfigure(0, weight=1)
self.fra_master.grid(row=0,
column=0,
padx=FRA_PADX,
pady=FRA_PADX,
sticky=tk.N + tk.W + tk.S + tk.E)
return
def crea_frame_pulsanti(self, parent, row_number):
self.fra_pulsanti = ttk.Frame(parent)
self.fra_pulsanti.grid(row=row_number,
column=0,
padx=FRA_PADX,
pady=FRA_PADX,
sticky=tk.N + tk.W + tk.S + tk.E)
child_row = 0
self.crea_widgets_pulsanti(self.fra_pulsanti, child_row)
self.fra_pulsanti.rowconfigure(0, weight=1)
child_row += 1
return
def crea_widgets_pulsanti(self, parent, row_number):
child_column = 0
self.btn_nuovo = ttk.Button(parent, text="Nuovo", command=self.nuovo)
self.btn_nuovo.grid(row=row_number,
column=child_column,
padx=BTN_PADX,
pady=BTN_PADX,
sticky=tk.N + tk.W + tk.S + tk.E)
parent.columnconfigure(child_column, weight=1)
# Funzionalita' ricerca da implementare (datagrid in tkinter???)
# child_column += 1
# self.btn_cerca = ttk.Button(parent, text="Cerca", command=self.cerca)
# self.btn_cerca.grid(row=row_number,
# column=child_column,
# padx=BTN_PADX,
# pady=BTN_PADX,
# sticky=tk.N + tk.W + tk.S + tk.E)
# parent.columnconfigure(child_column, weight=1)
child_column += 1
self.btn_salva = ttk.Button(parent, text="Salva", command=self.salva)
self.btn_salva.grid(row=row_number,
column=child_column,
padx=BTN_PADX,
pady=BTN_PADX,
sticky=tk.N + tk.W + tk.S + tk.E)
parent.columnconfigure(child_column, weight=1)
child_column += 1
self.btn_esci = ttk.Button(parent, text="Esci", command=self.esci)
self.btn_esci.grid(row=row_number,
column=child_column,
padx=BTN_PADX,
pady=BTN_PADX,
sticky=tk.N + tk.W + tk.S + tk.E)
parent.columnconfigure(child_column, weight=1)
return
def crea_frame_dati(self, parent, row_number):
self.fra_dati = ttk.Frame(parent)
self.fra_dati.grid(row=row_number,
column=0,
padx=FRA_PADX,
pady=FRA_PADX,
sticky=tk.N + tk.W + tk.S + tk.E)
child_row = 0
self.crea_widgets_id(self.fra_dati, child_row)
self.fra_dati.rowconfigure(child_row, weight=1)
child_row += 1
self.crea_widgets_cognome(self.fra_dati, child_row)
self.fra_dati.rowconfigure(child_row, weight=1)
child_row += 1
self.crea_widgets_nome(self.fra_dati, child_row)
self.fra_dati.rowconfigure(child_row, weight=1)
child_row += 1
self.crea_widgets_data_nascita(self.fra_dati, child_row)
self.fra_dati.rowconfigure(child_row, weight=1)
child_row += 1
self.crea_widgets_comune_nascita(self.fra_dati, child_row)
self.fra_dati.rowconfigure(child_row, weight=1)
child_row += 1
self.crea_widgets_email(self.fra_dati, child_row)
self.fra_dati.rowconfigure(child_row, weight=1)
child_row += 1
self.crea_widgets_occupazione(self.fra_dati, child_row)
self.fra_dati.rowconfigure(child_row, weight=1)
child_row += 1
self.crea_widgets_fonte(self.fra_dati, child_row)
self.fra_dati.rowconfigure(child_row, weight=1)
child_row += 1
self.crea_widgets_data_firma(self.fra_dati, child_row)
self.fra_dati.rowconfigure(child_row, weight=1)
child_row += 1
self.crea_widgets_firma(self.fra_dati, child_row)
self.fra_dati.rowconfigure(child_row, weight=1)
child_row += 1
self.fra_dati.columnconfigure(0, weight=0)
self.fra_dati.columnconfigure(1, weight=1)
self.fra_dati.columnconfigure(2, weight=1)
return
def crea_widgets_id(self, parent, row_number):
self.lbl_id = ttk.Label(parent, text="Id", anchor=tk.W)
self.lbl_id.grid(row=row_number,
column=0,
padx=LBL_PADX,
pady=LBL_PADY,
sticky=tk.N + tk.S + tk.E + tk.W)
self.txt_id = ttk.Entry(parent,
textvariable=self.iscritto.id,
state="readonly")
self.txt_id.grid(row=row_number,
column=1,
columnspan=2,
padx=TXT_PADX,
pady=TXT_PADY,
sticky=tk.N + tk.S + tk.E + tk.W)
return
def crea_widgets_cognome(self, parent, row_number):
self.lbl_cognome = ttk.Label(parent, text="Cognome", anchor=tk.W)
self.lbl_cognome.grid(row=row_number,
column=0,
padx=LBL_PADX,
pady=LBL_PADY,
sticky=tk.N + tk.S + tk.E + tk.W)
self.txt_cognome = ttk.Entry(parent, textvariable=self.iscritto.cognome)
self.txt_cognome.grid(row=row_number,
column=1,
columnspan=2,
padx=TXT_PADX,
pady=TXT_PADY,
sticky=tk.N + tk.S + tk.E + tk.W)
return
def crea_widgets_nome(self, parent, row_number):
self.lbl_nome = ttk.Label(parent, text="Nome", anchor=tk.W)
self.lbl_nome.grid(row=row_number,
column=0,
padx=LBL_PADX,
pady=LBL_PADY,
sticky=tk.N + tk.S + tk.E + tk.W)
self.txt_nome = ttk.Entry(parent, textvariable=self.iscritto.nome)
self.txt_nome.grid(row=row_number,
column=1,
columnspan=2,
padx=TXT_PADX,
pady=TXT_PADY,
sticky=tk.N + tk.S + tk.E + tk.W)
return
def crea_widgets_data_nascita(self, parent, row_number):
self.lbl_data_nascita = ttk.Label(parent,
text="Data di nascita",
anchor=tk.W)
self.lbl_data_nascita.grid(row=row_number,
column=0,
padx=LBL_PADX,
pady=LBL_PADY,
sticky=tk.N + tk.S + tk.E + tk.W)
self.txt_data_nascita = Datepicker(parent,
dateformat="%x",
datevar=self.iscritto.data_nascita)
self.txt_data_nascita.grid(row=row_number,
column=1,
columnspan=2,
padx=TXT_PADX,
pady=TXT_PADY,
sticky=tk.N + tk.S + tk.E + tk.W)
return
def crea_widgets_comune_nascita(self, parent, row_number):
self.lbl_comune_nascita = ttk.Label(parent,
text="Comune di nascita",
anchor=tk.W)
self.lbl_comune_nascita.grid(row=row_number,
column=0,
padx=LBL_PADX,
pady=LBL_PADY,
sticky=tk.N + tk.S + tk.E + tk.W)
self.txt_comune_nascita = ttk.Entry(
parent, textvariable=self.iscritto.comune_nascita)
self.txt_comune_nascita.grid(row=row_number,
column=1,
columnspan=2,
padx=TXT_PADX,
pady=TXT_PADY,
sticky=tk.N + tk.S + tk.E + tk.W)
return
def crea_widgets_email(self, parent, row_number):
self.lbl_email = ttk.Label(parent, text="E-mail", anchor=tk.W)
self.lbl_email.grid(row=row_number,
column=0,
padx=LBL_PADX,
pady=LBL_PADY,
sticky=tk.N + tk.S + tk.E + tk.W)
self.txt_email = ttk.Entry(parent, textvariable=self.iscritto.email)
self.txt_email.grid(row=row_number,
column=1,
columnspan=2,
padx=TXT_PADX,
pady=TXT_PADY,
sticky=tk.N + tk.S + tk.E + tk.W)
return
def crea_widgets_occupazione(self, parent, row_number):
self.lbl_occupazione = ttk.Label(parent,
text="Occupazione",
anchor=tk.W)
self.lbl_occupazione.grid(row=row_number,
column=0,
padx=LBL_PADX,
pady=LBL_PADY,
sticky=tk.N + tk.S + tk.E + tk.W)
self.txt_occupazione = ttk.Entry(parent,
textvariable=self.iscritto.occupazione)
self.txt_occupazione.grid(row=row_number,
column=1,
columnspan=2,
padx=TXT_PADX,
pady=TXT_PADY,
sticky=tk.N + tk.S + tk.E + tk.W)
return
def crea_widgets_fonte(self, parent, row_number):
self.lbl_fonte = ttk.Label(parent, text="Fonte", anchor=tk.W)
self.lbl_fonte.grid(row=row_number,
column=0,
padx=LBL_PADX,
pady=LBL_PADY,
sticky=tk.N + tk.S + tk.E + tk.W)
self.txt_fonte = ttk.Entry(parent, textvariable=self.iscritto.fonte)
self.txt_fonte.grid(row=row_number,
column=1,
columnspan=2,
padx=TXT_PADX,
pady=TXT_PADY,
sticky=tk.N + tk.S + tk.E + tk.W)
return
def crea_widgets_data_firma(self, parent, row_number):
self.lbl_data_firma = ttk.Label(parent, text="Data firma", anchor=tk.W)
self.lbl_data_firma.grid(row=row_number,
column=0,
padx=LBL_PADX,
pady=LBL_PADY,
sticky=tk.N + tk.S + tk.E + tk.W)
self.txt_data_firma = Datepicker(parent,
dateformat="%x",
datevar=self.iscritto.data_firma)
self.txt_data_firma.grid(row=row_number,
column=1,
columnspan=2,
padx=TXT_PADX,
pady=TXT_PADY,
sticky=tk.N + tk.S + tk.E + tk.W)
return
def crea_widgets_firma(self, parent, row_number):
# https://www.youtube.com/watch?v=rhvJ_M218EQ
self.img_firma_old_x = None
self.img_firma_old_y = None
self.lbl_firma = ttk.Label(parent, text="Firma", anchor=tk.N + tk.W)
self.lbl_firma.grid(row=row_number,
column=0,
padx=LBL_PADX,
pady=LBL_PADY,
sticky=tk.N + tk.S + tk.E + tk.W)
larghezza = self.larghezza_firma
altezza = self.altezza_firma
self.cv_firma = tk.Canvas(
parent,
width=larghezza,
height=altezza,
border=1,
background=self.img_firma_color_bg,
relief=tk.SUNKEN)
self.cv_firma.bind("<B1-Motion>", self.img_firma_paint)
self.cv_firma.bind("<ButtonRelease-1>", self.img_firma_reset)
self.cv_firma.grid(row=row_number,
column=1,
padx=IMG_PADX,
pady=IMG_PADY,
sticky=tk.N + tk.W)
self.draw_frirma = ImageDraw.Draw(self.iscritto.img_firma)
self.fra_pulsanti_firma = ttk.Frame(parent)
self.fra_pulsanti_firma.columnconfigure(0, weight=1)
self.fra_pulsanti_firma.grid(row=row_number,
column=2,
padx=FRA_PADX,
pady=FRA_PADX,
sticky=tk.N + tk.W + tk.S + tk.E)
self.btn_firma_clear = ttk.Button(self.fra_pulsanti_firma,
text="Pulisci")
self.btn_firma_clear.bind("<Button-1>", self.img_firma_clear)
self.btn_firma_clear.grid(row=0,
column=0,
padx=BTN_PADX,
pady=BTN_PADX,
sticky=tk.N + tk.W + tk.S + tk.E)
return
def img_firma_paint(self, e):
if self.img_firma_old_x and self.img_firma_old_y:
self.cv_firma.create_line(self.img_firma_old_x,
self.img_firma_old_y,
e.x,
e.y,
width=self.img_firma_penwidth,
fill=self.img_firma_color_fg,
capstyle=tk.ROUND,
smooth=True)
xy = [self.img_firma_old_x, self.img_firma_old_y, e.x, e.y]
self.draw_frirma.line(xy,
width=self.img_firma_penwidth,
fill=self.img_firma_color_fg)
self.img_firma_old_x = e.x
self.img_firma_old_y = e.y
return
def img_firma_reset(self, e):
self.img_firma_old_x = None
self.img_firma_old_y = None
return
def img_firma_clear(self, e):
self.cv_firma.delete("all")
return
def nuovo(self):
self.iscritto.new()
# # Alla canvas non e' associata nessuna tkinger.Variable()
# # quindi lavoro direttamente sul widget
self.cv_firma.delete("all")
self.draw_frirma = ImageDraw.Draw(self.iscritto.img_firma)
return
def cerca(self):
tkMessagebox.showinfo(MESSAGE_BOX_TITLE, "valido, salvo!")
pass
def salva(self):
if self.iscritto.is_valid():
salva = tkMessagebox.askyesno(MESSAGE_BOX_TITLE,
"Convermi salvataggio?")
if salva:
db = Db()
db.insert_new(self.iscritto)
self.nuovo()
else:
tkMessagebox.showinfo(MESSAGE_BOX_TITLE,
"non valido e quindi non posso salvare!")
self.parent.update()
def esci(self):
if tkMessagebox.askyesno(MESSAGE_BOX_TITLE, "Esco?"):
self.parent.update()
self.parent.destroy()
return