# -*- 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("", self.img_firma_paint) self.cv_firma.bind("", 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("", 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