Visualizza post

Questa sezione ti permette di visualizzare tutti i post inviati da questo utente. N.B: puoi vedere solo i post relativi alle aree dove hai l'accesso.


Post - nuzzopippo

Pagine: [1] 2 3 4
1
Benvenuto e regolamento / Re:Salve
« il: Giugno 12, 2019, 07:26 »
Ciao @Transea, ben venuto

Piacciono i Litfiba anche a Te?

... magari impareremo assieme ;)

2
Benvenuto e regolamento / Re:Presentazione
« il: Giugno 12, 2019, 07:24 »
Ciao @ cavasayan, ben venuto :)

3
Ciao,

Interessato da alcuni aspetti del discorso ho fatto un po' di ricerche, tra le tante ho trovato questa pagina su html.it che mi sembra interessante (non ho ancora effettuato nessun test in merito), la segnalo

[Edit] Fatto un test preliminare in un virtualenv per python 2.7, su sistema ubuntu 18.04, installando da pip camelot-py e opencv-python, una tabella dati contenuta in un pdf creato con libreoffice viene letta ed esportata correttamente in formato csv, per excell credo occorrerebbero le librerie pandas, mi da errore e penso sia quello in motivo

4
In primo luogo, il codice che hai postato non dovrebbe neanche essere accettato in una sessione di shell

Python 3.6.7 (default, Oct 22 2018, 11:32:17)
[GCC 8.2.0] on linux
Type "help", "copyright", "credits" or "license()" for more information.
>>> class Prova:

def funzione(self):
print('Qualcosa')
funzione()


Traceback (most recent call last):
  File "<pyshell#21>", line 1, in <module>
    class Prova:
  File "<pyshell#21>", line 5, in Prova
    funzione()
TypeError: funzione() missing 1 required positional argument: 'self'


Ciò perché la chiamata di "funzione()" non ha riferimenti all'interno dell'oggetto (classe) in cui risiede ... ma non è questo l'errore che Tu indichi, supposto di porre una strutturazione di classe accettabile, il Tuo errore lo si riceve provando ad applicare direttamente la classe, bisogna prima istanziarla e poi richiamare il metodo di classe "funzione()", vedi sotto

>>> class Prova:
def funzione(self):
print('Qualcosa')


>>> Prova.funzione()
Traceback (most recent call last):
  File "<pyshell#6>", line 1, in <module>
    Prova.funzione()
TypeError: funzione() missing 1 required positional argument: 'self'
>>> my_ogg = Prova()
>>> my_ogg.funzione()
Qualcosa
>>>

Probabilmente sei ai primi approcci, suggerirei di partire da qui e seguenti, farsi i concetti generali sulle classi e riprovare, ti sarà utile :)

[Edit] dimenticavo, non necessariamente la classe istanziata deve essere assegnata, va bene anche un utilizzo del genere :

>>> Prova().funzione()
Qualcosa
>>>

che istanzia la classe Prova e richiama il metodo "funzione()" in unica soluzione

5
Base / Re:Libri per imparare Python
« il: Maggio 05, 2019, 13:04 »
Ciao :)

Iniziando a mia volta, questo libro l'ho trovato buono, tant'è che ho intenzione di rileggerlo.

Ti suggerirei di dare una guardata nella sezione "Documentazione" ed anche nelle altre sezioni, vi sono post in merito e materiale indicato per vari aspetti.

6
I miei saluti a Voi.

Cercando di realizzare un "controllo" personalizzato (assemblando vari widget) ho provato, tra l'altro, una "composizione" che prevede l'utilizzo di una scrollbar non associata alla view di un secondo widget.
L'utilizzo della scrollbar è relazionato al solo scorrimento di un indice di lista dati.

La prova, tutto sommato, ha avuto successo, almeno in linea di massima, in questo modo :
dichiarazione nello __init_della classe :
        self.pivot_scroll = tk.Scrollbar(self,
                                         orient=tk.VERTICAL,
                                         jump=1,
                                         command=self._scrollEvent)

l'opzione "jump=1" è data per limitare gli eventi al solo rilascio del tasto del mouse

definizione del "set" per la scrollbar al caricamento dei dati :
    def set_data(self, dati):
        self.dati = dati
        self.pivot = 0
        for riga in self.rows:
            riga.clear()
        # configurazione scrollbarr
        self.pivot_scroll.set(0, len(self.dati) - self.righe)
        # fine per scroll
        self._refresh_rows()

ove viene impostato, per la scrollbar, un "intervallo" pari alla consistenza dei dati decurtata degli elementi visualizzati, tale impostazione è necessaria, in assenza si hanno "out of range" ad ogni evento proveniente dalla scrollbar

gestito valutando i dati passati dalla scrollbar al gestore (handler, se volete) associato
    def _scrollEvent(self, *L):
        """Gestisce lo scroll della vertical barr associata."""
        if not self.dati: return
        for elem in L: print(elem, end=' - ')
        print()
        op, valore = L[0], L[1]
        if op == 'scroll':
            modo = L[2]
            if modo == 'pages':
                val = int(valore) * self.righe
            else:
                val = int(valore)
            if (self.pivot + val) < 0:
                self.pivot = 0
            elif (self.pivot + val) > (len(self.dati) - self.righe):
                self.pivot = len(self.dati) - self.righe
            else:
                self.pivot += val
        elif op == 'moveto':
            self.pivot += int(len(self.dati) * float(valore)) - 1
            if self.pivot < 0:
                self.pivot = 0
            elif self.pivot > len(self.dati) - self.righe:
                self.pivot = len(self.dati) - self.righe
        self._refresh_rows()


Come detto, le impostazioni sopra per funzionare funzionano ma in modo insoddisfacente : lo slider della scrollbar assume la dimensione dell'intera area disponibile, cosa non sorprendente, e (questo è strano) si "ridimensiona" in caso di trascinamento a partire dai bordi estremi dello stesso, tale ridimensionamento permate e da quel momento è possibile "agganciare" e trascinare lo slider, la "precisione" lascia a desiderare ed il posizionamento effettivo dello slider è insussistente.
Se occorressero maggiori dettagli od una visualizzazione grafica della circostanza potete vedere qui, sono semplici appunti di apprendimento.

Non so se è possibile farlo ma vorrei realizzare un controllo adeguato della rappresentazione dei dati visualizzati in rapporto all'insieme degli stessi, il tutto completamente avulso da view di elementi grafici.
Ho molto cercato e letto ma ho trovato pochissimo, se non nulla, di specifico in merito ad una definizione  delle specifiche dello slider o, magari, ci sono incappato e non ho compreso, data la mia ignoranza dell'inglese.

Qualcuno di Voi avrebbe indicazioni e/o suggerimenti in merito?

Grazie dell'attenzione  :caffè:

7
Base / Re:Storage parametri applicazione : un consiglio
« il: Aprile 23, 2019, 18:21 »
Grazie delle info @RicPol

Leggersi il s.o., quindi, poi regolarsi.

...Poi per fare questo sarebbe buona educazione fornire anche un installer/uninstaller che pulisce correttamente i vari pezzetti lasciati in giro...
Se però si trattta del solito programmino distribuito alla selvaggia, allora è di gran lunga preferibile usare una sub-directory "interna" ...
beh, la parte evidenziata rientra tra le "intenzioni" in divenire, anche se argomento che temo metterà a dura prova le mie denutrite meningi, allo stato men che selvagge.
La sub interna alla directory applicativa l'avevo considerata ma in genere non la uso per abitudine, più che altro perché le piccole applicazioni che faccio a mio uso e consumo le porto in giro su chiavetta e le faccio girare su diversi computer, tutti linux ma con caratteristiche differenti, alla lunga ho una preferenza per lo storage sulla macchina in uso ... anche se come motivo non è per nulla buono :)

Grazie, ciao

8
Base / Re:Storage parametri applicazione : un consiglio
« il: Aprile 22, 2019, 07:40 »
Vi ringrazio delle risposte.

Per lo meno, ho conferma che detto metodo è applicabile nei s.o. più diffusi, anche se "nascondere" lascia il tempo che trova.

Interessante la proposta di standard segnalata da @bebo, sarebbe ora che si adottassero schemi di comportamento unificati, per limitare la confusione nelle home-dir ... già ci pensa l'utente a crearla :)
da una veloce verifica nel mio Ubuntu 18.04, sembrerebbe parzialmente adottata solo da unity per sue specifiche esigenze, da verificare circa i permessi in scrittura

NzP:~$ echo "$XDG_DATA_HOME"

NzP:~$ echo "$XDG_CONFIG_HOME"

NzP:~$ echo "$XDG_CONFIG_DIRS"
/etc/xdg/xdg-unity:/etc/xdg
NzP:~$ echo "$XDG_CACHE_HOME"

NzP:~$ echo "$XDG_RUNTIME_DIR"
/run/user/1000
NzP:~$ ls "$XDG_RUNTIME_DIR"
bus     dconf  gnupg  gvfs-burn  pulse    unity
dbus-1  gdm    gvfs   keyring    systemd  update-notifier.pid
NzP:~$

Comunque, faccenda da tener d'occhio

9
Base / Storage parametri applicazione : un consiglio
« il: Aprile 20, 2019, 12:43 »
Buon giorno a Voi ... e buona Pasqua, data la prossimità :)

Desidererei un consiglio :
nei sistemi unix-like è ampiamente usato memorizzare parametri opzionali di una applicazione scelti da un utente in una direttrice nascosta nella home dell'utente, cosa semplice da realizzare con python

import os
...
def load_app_configurations():
    '''Acquisisce, se esistono, le scelte applicative salvate.'''
    home = os.path.expanduser('~')
    app_dir = os.path.join(home, '.app_name')
    if not os.path.exists(app_dir):
        os.mkdir(app_dir)

mi apprestavo ad utilizzare una tale metodologia ma mi son fermato un attimo, so che "funzionerebbe" anche in windows, almeno per alcune versioni, ma mi chiedo se esiste una qualche convenzione/linea guida in merito, almeno per l'ambito python ...  sapreste darmi suggerimenti in merito?

10
Tkinter / Re:layout "grid", classi e persistenza oggetti
« il: Aprile 16, 2019, 06:23 »
Risolto, il problema era nella notazione "unica" utilizzata per definire il widget e la sua posizione nella griglia : non da errore ma non restituisce l'oggetto creato. Bisogna, quindi, tener separate le definizioni ed i posizionamenti.

Mi hanno "fregato" la mancanza di eccezioni e "vecchie" esperienze.

Per improbabili interessati :

Notazione accettata ma inutilizzabile :

        self.lbl_dida = tk.Label(self,
                                text='...',
                                justify='left',
                                ).grid(row=0, column=1, sticky='nsew')


Notazione funzionale :

        self.lbl_dida = tk.Label(self,
                                text='...',
                                justify='left',
                                )
...
        self.lbl_dida.grid(row=0, column=1, sticky='nsew')


Mi si perdoni se Vi ho fatto perdere tempo a leggere.

11
Tkinter / [Risolto] layout "grid", classi e persistenza oggetti
« il: Aprile 15, 2019, 09:19 »
I miei saluti a Voi :)

Intrigato da una idea reperita altrove, mi sono avventurato a costruire una specie di "controllo" composito con tkinter che provvede ad esporre righe di immagini miniaturizzate e didascalie. Nel costruirlo mi sono anche scritto una serie di test per verificare la "resa" di quanto fatto in vali punti di sviluppo.

Ho implementato una versione utilizzante il metodo "pack()" costituita da due classi, una definente una singola "riga" dati (immagine/didascalia) mentre la seconda visualizza un insieme di tali righe e fornisce i metodi per la navigazione tra i dati. Tale versione è funzionante.

Insoddisfatto da alcune questioni di resa grafica degli automatismi di pack() ho provato a definire una variante dell'oggetto utilizzante il metodo "grid()" ed incappando già alla definizione della singola riga in una serie di problematiche che, dopo un po' di ricerche e prove, credo si individuino in una mancata persistenza degli oggetti invocati dal codice per una qualche peculiarità del metodo grid() che non mi riesce di individuare, probabilmente per la mia ignoranza dell'inglese (enorme palla al mio piede)

Appresso, esemplifico il codice, funzionante, del costruttore di una riga, versione utilizzante pack(), e della sua invocazione, con inseriti del print di debug.

costruttore :

class FRMTumbnail(tk.Frame):
    '''Pannello per singola miniatura (tumbnail) con descrizione.'''
    def __init__(self, master, mater, imgdim=60):
        self.mater = mater
        self.f_img = ''
        super().__init__(master)
        self.dim_tmb = imgdim
        self._curr_img = None
        self.indice = None
        self.default_bc = self.cget('bg')
        self.configure(relief='sunken', border=2, padx=2, pady=2)
        self.cnv_tmb = tk.Canvas(self,
                                 width=self.dim_tmb,
                                 height=self.dim_tmb,
                                 bg='#ffffc0',
                                 relief='raised',
                                 border=2
                              )
        self.cnv_tmb.pack(side='left')
        print('self.cnv_tmb è : ', self.cnv_tmb)
        print(self.cnv_tmb)
        self.cnv_tmb.bind('<Button-1>', self._scelto)
        f = tk.Frame(self, height=self.dim_tmb+4)
        f.pack(side='left', expand=True, fill='x')
        #f.pack_propagate(0)
        self.lbl_dida = tk.Label(f,
                                text='..'*10,
                                justify='left',
                                )
        self.lbl_dida.pack(expand=True, fill='both')
        print('self.lbl_dida è : ', self.lbl_dida)
        self.lbl_dida.bind('<Button-1>', self._scelto)


invocazione:

class GUI_01(tk.Tk):
    ''' Finestra principale test 01 : singola riga. '''

    def __init__(self, fnome='', dim=60):
        super().__init__()
        self.f_nome = fnome
        self.title('Test 01')
        sfondo = tk.Frame()
        sfondo.pack(fill='both')
        self.f = fd.FRMTumbnail(sfondo, None, dim)
        self.f.pack(fill='x')
        print('self.f è : ', self.f)
        f2 = tk.Frame(sfondo, relief='sunken', padx=2, pady=2)
        f2.pack(fill='x')
        btn = tk.Button(f2, text='Mostra immagine', command=self.mostra)
        btn.pack()
        self.minsize(300, self.winfo_reqheight())
        # self.update()
        centraFinestra(self)
   
    def mostra(self):
        self.f.set_fileimg(self.f_nome)
        self.f.set_dida("un po' di testo a caso")


Ed ora analoghi costruttore ed invocazione con grid(), si noti il commento dei "bind()", con ciò la riga viene visualizzata correttamente ma è inutilizzabile.

Costruttore:

class GriFRMTmb(tk.Frame):
    '''Pannello per singola miniatura (tumbnail) con descrizione.'''
    def __init__(self, master, mater, imgdim=60):
        self.mater = mater
        self.f_img = ''
        super().__init__(master)
        self.dim_tmb = imgdim
        self._curr_img = None
        self.indice = None
        self.default_bc = self.cget('bg')
        self.configure(relief='sunken', border=2, padx=2, pady=2)
        self.cnv_tmb = tk.Canvas(self,
                                 width=self.dim_tmb,
                                 height=self.dim_tmb,
                                 bg='#ffffc0',
                                 relief='raised',
                                 border=2
                                 ).grid(row=0, column=0, sticky='w')
        print('self.cnv_tmb è : ', self.cnv_tmb)
        #self.cnv_tmb.bind('<Button-1>', self._scelto)
        self.lbl_dida = tk.Label(self,
                                text='...',
                                justify='left',
                                ).grid(row=0, column=1, sticky='nsew')
        #self.lbl_dida.bind('<Button-1>', self._scelto)
        print('self.lbl_dida è : ', self.lbl_dida)
        self.columnconfigure(1, weight=1)


invocazione:

class GUI_01_G(tk.Tk):
    ''' Finestra principale test 01 - variante layout grid : singola riga. '''

    def __init__(self, fnome='', dim=60):
        super().__init__()
        self.f_nome = fnome
        self.title('Test 01-Grid')
        sfondo = tk.Frame().grid(sticky='nsew')
        self.f = fd.GriFRMTmb(sfondo, None, dim).grid(row=0,
                                                        padx=2,
                                                        pady=2,
                                                        sticky='ew'
                                                        )
        print('self.f è : ', self.f)
        btn = tk.Button(sfondo,
                        text='Mostra immagine',
                        command=self.mostra).grid(row=1,
                                                  padx=2,
                                                  pady=2,
                                                  sticky='nsew'
                                                  )
        self.columnconfigure(0, minsize=300, weight=1)
        self.update()
        centraFinestra(self)
   
    def mostra(self):
        self.f.set_fileimg(self.f_nome)
        self.f.set_dida("un po' di testo a caso")

(mi si perdoni l'incompleta aderenza alla Pep8)

e qui segue l'output del test effettuato per le due versioni :

NzP:~$ python3 test.py 1 risorse/01.jpg 60
self.cnv_tmb è :  .!frame.!frmtumbnail.!canvas
.!frame.!frmtumbnail.!canvas
self.lbl_dida è :  .!frame.!frmtumbnail.!frame.!label
self.f è :  .!frame.!frmtumbnail
NzP:~$ python3 test.py 5 risorse/01.jpg 60
self.cnv_tmb è :  None
self.lbl_dida è :  None
self.f è :  None
NzP:~$


Mi sembra evidente che con l'utilizzo di pack() le variabili di istanza nelle classi vengono correttamente create mentre utilizzando grid() invece no
 ... malgrado abbia cercato nella docs ed in rete mi son fermato qui, non mi riesce di capirne il perché e come rimediare, qualcuno di Voi conosce il problema e può darmi indicazioni in merito?

Scusate la lunghezza del post, non mi riuscirebbe di essere chiaro, altrimenti.

12
Base / Re:ottenere indirizzocompleto da zipcode
« il: Marzo 28, 2019, 20:11 »
Se con zipcode intendi il "CAP" italiano, non vai tanto liscio neanche limitando ai soli codici nazionali, essendo non univoci e, in diversi casi, anche multipli.

Esempio scaricando la lista dei comuni dal sito comuni-italiani.it, trovi si univocamente il tuo codice

>>> with open('listacomuni.csv', 'r', encoding='ISO-8859-2') as f:
lista = f.read().splitlines()
>>> for riga in lista:
elem = riga.split(';')
if elem[5] == '28822':
print(elem[1])

Cannobio
>>>


Però ci trovi più comuni già testando i primi in elenco:

>>> for riga in lista:
elem = riga.split(';')
if elem[5] == '26834':
print(elem[1])

Abbadia Cerreto
Corte Palasio

Ho verificato cap corrispondenti a più di una decina di comuni, e molti capoluoghi e città metropolitane hanno range di CAP assegnati ... problema di difficile soluzione il tuo, temo, non essendoci univocità di sorta.

Se hai dati ulteriori disponibili, vi sarebbero gli elenchi istat, più articolati.

13
Tkinter / Re:problema con menu tkinter
« il: Marzo 23, 2019, 10:37 »
sono un novizio di python ....
...
ma non funziona, inoltre come faccio se devo anche avere un return dalla funzione ?

Ciao @bot, mi perdonerai se rispondo più per fare esercizio che per dare una risposta esaustiva, la programmazione di interfacce grafiche è complessa e mi ci sono ancora avventurato poco.

Complessa è anche la risposta in merito all'argomento che poni, dipendendo in notevole misura dal design progettuale della applicazione, mio parere (gli esperti correggano) è che di per se le funzioni di callback dovrebbero limitarsi a gestire gli eventi, delegando al corpo delle funzioni di ottenere ciò che occorre ed eseguire le azioni opportune.
È opportuno, posto il "problema" progettare il proprio codice e le proprie classi in modo idoneo ad ottenere il risultato voluto tenendo presente che in sede di inizializzazione (ed anche dopo, spesso) non è che conoscano i valori dei parametri che Tu vorresti passare ... Ti ho preparato un esempio in tal senso partendo da codice recentemente postato in questo post, l'idea è semplicemente di ottenere che al comando di menu "Cerca Libro" una funzione si occupi di interrogare uno specifico oggetto per ottenere i dati inseriti nei controlli e li stampi.
Se copi il codice e lo modifichi come sotto indicato:
RIGA 71
        menu_libri.add_command(label='Cerca libro', command=self._cerca_libro)


CLASSE FinestraPrincipale - aggiugere metodo

    def _cerca_libro(self):
        if isinstance(self.sfondo, FrmLibro):
            valori = self.sfondo.dai_valori()
            print(valori)
        else:
            print('Nessun pannello libri presente')


CLASSE FrmLibro - aggiungere metodo

    def dai_valori(self):
        valori = {'autore': self.autore.get(),
                  'titolo': self.titolo.get()
                  }
        return valori

vedrai che lo farà SE starai utilizzando un pannello di classe "FrmLibro".
Sotto un output senza e con utilizzo di tale pannello (Frame, per meglio dire)
>>> %Run con_classi.py
Nessun pannello libri presente
{'autore': 'Nicola Aloia - Fausto Rabitti', 'titolo': 'SQL Sintassi e utilizzo'}


Andiamo ora ad una parte specifica del Tuo post, ossia : come inserire un parametro "variabile" nella definizione del command di un menu?

Risposta non semplice al mio (basso) livello di conoscenza (gli esperti potranno, bontà loro, integrare) , la prima domanda da porsi è : come fa l'istanza di menu a conoscere il parametro da utilizzare, , come si ottiene tale parametro?
Alla sua definizione, la funzione di callback potrà al più conoscere le variabili di classe ed istanza della classe in cui viene definita, potrà leggerli direttamente e/o  ottenerli se tali variabili sono "oggetti" grafici (widgets) riportando il discorso all'esempio prima esposto.

Comunque, diciamo che voglia "per forza" passare un "parametro" ad una funzione di callback invocata alla selezione di una voce di menu, non potrai farlo direttamente, provaci, una definizione con parametro alla definizione di un command di menu viene eseguito alla sola inizializzazione (mi si corregga se sbaglio), ma puoi ricorrere ad uno "sporco trucco" e definire una funzione lambda da richiamare al "command=...", a patto che tale "parametro" sia un oggetto conoscibile (una entry, una istanza StringVar, etc...), ciò riporta sempre alla considerazione iniziale ma voglio proporti n esempio funzionante in tal senso, è una variante all'esempio precedente (compattato ai soli "libri") che legge e richiama una funzione esterna alla classe di ricerca, in una lista di tuple, una stringa inserita nel titolo.
Il codice :

# -*- coding: utf-8 -*-

import tkinter as tk
import tkinter.messagebox as tm

libri = [('SQL Sintassi ed utilizzo', 'Nicola Aloia - Fausto Rabitti'),
         ('Core Java 2 volume 1 - Fondamenti', 'Cay S. Horstmann - Gary Cornell'),
         ('Core Java 2 volume 2 - Tecniche avanzate', 'Cay S. Horstmann - Gary Cornell'),
         ('La svastica sul sole', 'Philip K. Dick'),
         ('Universo Orbitsville', 'Bob Shaw'),
         ('scienza e coscienza', 'A.C. Bhaktivedanta Swami Pabhupada')
         ]


# *** CLASSI DELLE FINESTRE ***

class LoginFrame(tk.Toplevel):
   
    def __init__(self, master=None):
        self.master = master
        super().__init__(self.master)
        self.label_nome_utente = tk.Label(self, text="Nome Utente")
        self.label_password = tk.Label(self, text="Password")
        self.entry_nome_utente = tk.Entry(self)
        self.entry_password = tk.Entry(self, show="*")
        self.label_nome_utente.grid(row=0, sticky=tk.E)
        self.label_password.grid(row=1, sticky=tk.E)
        self.entry_nome_utente.grid(row=0, column=1)
        self.entry_password.grid(row=1, column=1)
        self.logbtn = tk.Button(self, text="Login", command=self._login_btn_clicked)
        self.logbtn.grid(columnspan=2)
        self.update()
        centra_finestra(self)
       
    def _login_btn_clicked(self):
        nome_utente = self.entry_nome_utente.get()
        password = self.entry_password.get()

        if nome_utente == "marco" and password == "password":
            self.destroy()
            self.master.mostra()
        else:
            self.master.chiudi()


class FinestraPrincipale(tk.Tk):
   
    def __init__(self):
        super().__init__()
        # configurazione
        self.title('pyLibri 0.1')
        self.geometry('960x640')
       
        f = tk.Frame(self)
        f.pack(expand=True, fill='both')
        subf1 = tk.Frame(f, padx=5, pady=5)
        subf1.pack(expand=True, fill='x', padx=5, pady=5)
        lbl1 = tk.Label(subf1, text='Titolo :', width=7, justify='left')
        lbl1.pack(side='left', anchor='n')
        self.titolo = tk.Entry(subf1, width=15)
        self.titolo.pack(side='left', expand=True, fill='x', anchor='n')
        subf2 = tk.Frame(f, padx=5, pady=5)
        subf2.pack(expand=True, fill='x', padx=5, pady=5)
        lbl2 = tk.Label(subf2, text='Autore :', width=7, justify='left')
        lbl2.pack(side='left', anchor='n', padx=5, pady=5)
        self.autore = tk.Entry(subf2, width=15)
        self.autore.pack(side='left', expand=True, fill='x', anchor='n', padx=5, pady=5)
       
        barra_menu = tk.Menu(self)
        self.config(menu=barra_menu)
        menu_libri = tk.Menu(barra_menu)
        barra_menu.add_cascade(label='Libri', menu=menu_libri)
        menu_libri.add_command(label='Nuovo libro')
        x = lambda: self._cerca_libro(self.titolo.get())
        menu_libri.add_command(label='Cerca libro', command=x)
        menu_libri.add_command(label='Cancella libro')
        menu_uscita = tk.Menu(barra_menu)
        barra_menu.add_cascade(label='Uscita', menu=menu_uscita)
        menu_uscita.add_command(label='Esci', command=self.destroy)
        self.sfondo = tk.Frame(self, padx=0, pady=0)
        self.sfondo.pack(expand=True, fill='both', padx=0, pady=0)
        self.nascondi()
        LoginFrame(self)
       
    def nascondi(self):
        ''' Nasconde la finestra.'''
        self.withdraw()

    def mostra(self):
        ''' Mostra la finestra '''
        self.deiconify()
        centra_finestra(self)
   
    def chiudi(self):
        ''' Chiude la finestra.'''
        tm.showerror("Errore", "Nome utente o password errata")
        self.destroy()
   
    def _cerca_libro(self, titolo):
        if titolo:
            print('Cerco libri con', titolo, 'nel titolo')
            risult = cerca_titolo(titolo)
            if risult:
                for libro in risult:
                    print(libro)
            else:
                print('Nessun elemento trovato')
        else:
            print('Nessun titolo inserito')
       

# *** FUNZIONI GLOBALI ****

def centra_finestra(gui):
    ''' Centra una finestra, passata come parametro, sullo schermo '''
    l = gui.winfo_screenwidth()
    a = gui.winfo_screenheight()
    wx = gui.winfo_width()
    wy = gui.winfo_height()
    gui.geometry('{}x{}+{}+{}'.format(wx, wy, (l-wx)//2, (a-wy)//2))


def cerca_titolo(titolo):
    ''' Simula una ricerca in una lista di titoli'''
    risult = []
    for libro in libri:
        if libro[0].lower().find(titolo.lower()) != -1:
            risult.append(libro)
    return risult


# *** START APPLICAZIONE ***

if __name__ == '__main__':
    app = FinestraPrincipale()
    app.mainloop()


Personalmente, non conosco o immagino metodi per ottenere un valore di ritorno alla selezione di una voce di menu.
La selezione di una voce di menu è e rimane, un evento, suo compito è scatenare azioni non restituire "risultati", sono le azioni avviate a dover produrre risultati.

Spero che ciò che credo (si correggano i miei eventuali abbagli) di aver capito ed ho cercato di esporre Ti sia utile.

14
Tkinter / Re:Tkinter e menu
« il: Marzo 13, 2019, 19:59 »

Ciao @ElTriestin, benvenuto.

È un paio di giorni  che guardo questo post, aspettando gli utenti esperti, per imparare dalla Loro risposta, dato che non si vedono oso proporre io una risposta, pur avendo fatto un solo tentativo di programmare GUI in python e presto convintomi che ho molto da imparare "prima" di ritentare.

Veniamo alla Tua domanda :
Ciao a tutti
...Suppongo di dover creare una funzione che "disegni" campi di testo e label con poi il salvataggio dei valori in una tabella MySQL (il programma già funziona in shell, anche se non mi soddisfa perchè la visualizzazione degli elenchi in shell non è pratica)

Sarà solo una mia opinabile opinione ma non credo proprio sia conveniente l'utilizzo di "funzioni" nella programmazione di interfacce grafiche, ritengo molto più indicato l'utilizzo di classi.
Vedo nel Tuo codice una tendenza alla creazione "dinamica" delle interfacce ... si può fare ma, secondo me, ci si complica la vita, in primo luogo, poi credo anche Ti renda impossibile ciò che vuoi fare : che fine fanno i widget che vorresti sostituire (faccenda implicita nella struttura) e come li trovi per gestirli?
Faccenda complessa questa, costringerebbe a tener traccia di una enormità di controlli (per testi, anagrafiche, prentazioni, etc.) e gestirli, molto meglio pensare a finestre specializzate per i vari aspetti operativi e magari una principale per la visualizzazione dei dati imho.

In ogni caso, trovo "improprio" distruggere Tk e ricrearlo, non sarebbe meglio dedicarlo alla finestra principale e nasconderlo per mostrarlo dopo il login?, quest'ultimo potrebbe essere fatto tramite una finestra Toplevel, p.e.

 ... comunque ho dedicato un'oretta a tirar fuori un esempio funzionante sulla base del Tuo codice eseguire la visualizzazione per un "Nuovo libro" (solo per titolo ed autore) facendo la relativa selezione da menu, preparato un "oggetto" per detta visualizzazione ed una funzione di classe preposta (        _carica_libro) la variante alle istruzioni da Te poste è semplicemente
        menu_libri.add_command(label='Nuovo libro', command=self._carica_libro)

il richiamo della funzione alla definizione del command

C'è un però, bisogna eliminare prima ciò che viene sostituito, guardati la classe "FinestraPrincipale" e l'uso della variabile di istanza "self.sfondo", credo che applicata alle altre "visualizzazioni" dovrebbe funzionare ... anche se personalmente eviterei di utilizzare una tale metodica.

Sotto il codice da me fatto (con le considerazioni di sopra), spero possa esserti utile

# -*- coding: utf-8 -*-

import tkinter as tk
import tkinter.messagebox as tm

# *** CLASSI DEI PANNELLI ***

class FrmLibro(tk.Frame):
    ''' Pannello dei libri.'''
   
    def __init__(self, master, *a, **k):
        super().__init__(master, *a, **k)
        self.master = master
        subf1 = tk.Frame(self, padx=5, pady=5)
        subf1.pack(expand=True, fill='x', padx=5, pady=5)
        lbl1 = tk.Label(subf1, text='Titolo :', width=7, justify='left')
        lbl1.pack(side='left', anchor='n')
        self.titolo = tk.Entry(subf1, width=15)
        self.titolo.pack(side='left', expand=True, fill='x', anchor='n')
        subf2 = tk.Frame(self, padx=5, pady=5)
        subf2.pack(expand=True, fill='x', padx=5, pady=5)
        lbl2 = tk.Label(subf2, text='Autore :', width=7, justify='left')
        lbl2.pack(side='left', anchor='n', padx=5, pady=5)
        self.autore = tk.Entry(subf2, width=15)
        self.autore.pack(side='left', expand=True, fill='x', anchor='n', padx=5, pady=5)
       

# *** CLASSI DELLE FINESTRE ***

class LoginFrame(tk.Toplevel):
   
    def __init__(self, master=None):
        self.master = master
        super().__init__(self.master)
        self.label_nome_utente = tk.Label(self, text="Nome Utente")
        self.label_password = tk.Label(self, text="Password")
        self.entry_nome_utente = tk.Entry(self)
        self.entry_password = tk.Entry(self, show="*")
        self.label_nome_utente.grid(row=0, sticky=tk.E)
        self.label_password.grid(row=1, sticky=tk.E)
        self.entry_nome_utente.grid(row=0, column=1)
        self.entry_password.grid(row=1, column=1)
        self.logbtn = tk.Button(self, text="Login", command=self._login_btn_clicked)
        self.logbtn.grid(columnspan=2)
        self.update()
        centra_finestra(self)
       
    def _login_btn_clicked(self):
        nome_utente = self.entry_nome_utente.get()
        password = self.entry_password.get()

        if nome_utente == "marco" and password == "password":
            self.destroy()
            self.master.mostra()
        else:
            self.master.chiudi()


class FinestraPrincipale(tk.Tk):
   
    def __init__(self):
        super().__init__()
        # configurazione
        self.title('pyLibri 0.1')
        self.geometry('960x640')
        barra_menu = tk.Menu(self)
        self.config(menu=barra_menu)
        menu_libri = tk.Menu(barra_menu)
        barra_menu.add_cascade(label='Libri', menu=menu_libri)
        menu_libri.add_command(label='Nuovo libro', command=self._carica_libro)
        menu_libri.add_command(label='Cerca libro')
        menu_libri.add_command(label='Cancella libro')
        menu_soci = tk.Menu(barra_menu)
        barra_menu.add_cascade(label='Soci', menu=menu_soci)
        menu_soci.add_command(label='Nuovo socio')
        menu_soci.add_command(label='Cerca socio')
        menu_soci.add_command(label='Cancella socio')
        menu_prenotazioni = tk.Menu(barra_menu)
        barra_menu.add_cascade(label='Prenotazioni', menu=menu_prenotazioni)
        menu_prenotazioni.add_command(label='Nuova prenotazione')
        menu_prenotazioni.add_command(label='Cerca prenotazione')
        menu_prenotazioni.add_command(label='Cancella prenotazione')
        menu_uscita = tk.Menu(barra_menu)
        barra_menu.add_cascade(label='Uscita', menu=menu_uscita)
        menu_uscita.add_command(label='Esci', command=self.destroy)
        self.sfondo = tk.Frame(self, padx=0, pady=0)
        self.sfondo.pack(expand=True, fill='both', padx=0, pady=0)
        self.nascondi()
        LoginFrame(self)
       
    def nascondi(self):
        ''' Nasconde la finestra.'''
        self.withdraw()

    def mostra(self):
        ''' Mostra la finestra '''
        self.deiconify()
        centra_finestra(self)
   
    def chiudi(self):
        ''' Chiude la finestra.'''
        tm.showerror("Errore", "Nome utente o password errata")
        self.destroy()
   
    def _carica_libro(self):
        self.sfondo.destroy()
        self.sfondo = FrmLibro(self, padx=0, pady=0)
        self.sfondo.pack(expand=True, fill='both', padx=0, pady=0)
       
       

# *** FUNZIONI GLOBALI ****

def centra_finestra(gui):
    ''' Centra una finestra, passata come parametro, sullo schermo '''
    l = gui.winfo_screenwidth()
    a = gui.winfo_screenheight()
    wx = gui.winfo_width()
    wy = gui.winfo_height()
    gui.geometry('{}x{}+{}+{}'.format(wx, wy, (l-wx)//2, (a-wy)//2))

# *** START APPLICAZIONE ***

if __name__ == '__main__':
    app = FinestraPrincipale()
    app.mainloop()


15
Base / Re:Compilare campi cedola da stampare
« il: Marzo 01, 2019, 12:14 »
Esiste un software con il quale posso misurare esattamente le coordinate di un file immagine su cui poi scrivo?

Intendi un programma qualsiasi per ottenere le coordinate iniziali in cui inerire del testo in una immagine?

Per tale scopo potrebbe essere utile GIMP, un programma di foto-ritocco, scorrendo col mouse su di una immagine nella finestra sono presenti le coordinate correnti del cursore, che possono essere espresse in varie modalità, tra cui pixel (unità base per le immagini) e punti (unità base per i fonts).

In merito alla "precisione", cosa intendi?

Pagine: [1] 2 3 4