Topic: Passaggio valore ad una classe Dialog  (Letto 580 volte)

0 Utenti e 1 Visitatore stanno visualizzando questo topic.

Offline momo79

  • python erectus
  • ***
  • Post: 100
  • Punti reputazione: 0
    • Mostra profilo
Passaggio valore ad una classe Dialog
« il: Marzo 09, 2017, 21:11 »
Rieccomi di nuovo. Volevo sapere se per passare un valore da una finestra principale Frame a una Dialog il codice seguente può andar bene o meno:

import wx

class NewFinestra(wx.Dialog):
    def __init__(self, parola, *a, **k):
        wx.Dialog.__init__(self, *a, **k)
        lbl = wx.StaticText(self, -1, label=parola, pos = (10,10) )
class MyFrame(wx.Frame):
    def __init__(self, *a, **k):
        wx.Frame.__init__(self, *a, **k)
       
        p = wx.Panel(self, -1)
        b1 = wx.Button(p, -1, "Premi", pos = (10, 10))
        b1.Bind(wx.EVT_BUTTON, self.apri)

    def apri(self, evt):
        a='Ciao'
        newFinestra = NewFinestra(a, self, -1, title='Prova', size=(500,500))
        newFinestra.ShowModal()
       
       
   


app=wx.App()
frame=MyFrame(None)
frame.Show()
app.MainLoop()



Questa è solo una prova. Il programma che sto facendo ha in una finestra  una ListCtrl con i vari elenchi. Quando l'utente clicca su un valore(una riga)  vorrei far aprire un'altra finestra (wx.Dialog) riportando gli stessi valori.

Offline riko

  • python deus
  • *
  • moderatore
  • Post: 7.453
  • Punti reputazione: 12
    • Mostra profilo
    • RiK0 Tech Temple
Re:Passaggio valore ad una classe Dialog
« Risposta #1 il: Marzo 10, 2017, 00:31 »
Per che definizione di bene? Perche' se la domanda e' "funziona?", eseguilo e lo scoprirai.
Se la domanda e' "e' buon codice", no, non lo e'. Non ci si avvicina nemmeno. Ci sarebbe qualcosa da ridire quasi ad ogni riga.
Pero' non lo devo mantenere io. E la cosa che ti devi chiedere (al di la dello stile) e' se funziona.
Ci sono modi migliori? Questa e' probabilmente la domanda che sottointendi. A naso, direi che sarebbe piacevole. Sembra molto macchinoso; d'altra parte la maggior parte dei dialoghi modali delle applicazioni che uso sono piuttosto standard. Quindi non mi stupirei che sia necessaria un po' di macchinazione.

Tipo una cosa che mi insospettisce e' che tu stia facendo piazzamento assoluto alla visual basic vecchio stile. Che diventa parecchio doloroso da mantenere, per cui praticamente tutti i toolkit ti danno delle astrazioni per dire dove vuoi che sia il controllo, non esattamente in che pixel deve stare.

Offline momo79

  • python erectus
  • ***
  • Post: 100
  • Punti reputazione: 0
    • Mostra profilo
Re:Passaggio valore ad una classe Dialog
« Risposta #2 il: Marzo 10, 2017, 09:29 »
Quello che chiedevo io è se c'erano modi migliori. Il programma se eseguito funziona.

Offline RicPol

  • python sapiens sapiens
  • ******
  • Post: 2.869
  • Punti reputazione: 9
    • Mostra profilo
Re:Passaggio valore ad una classe Dialog
« Risposta #3 il: Marzo 10, 2017, 11:07 »
Allora, non sarei così pessimista come Riko, anche se è chiaro che quel codice non va tanto bene.
Lasciamo perdere le cose che non c'entrano con il problema in questione: il posizionamento assoluto: va benissimo per risparmiare due righe di codice quando si postano esempi su un forum (io lo faccio sempre), ma ovviamente in un progetto reale non va mai usato. I nomi stravaganti mezzi italiani e mezzi inglesi. ShowModal. Eccetera.

Restiamo sul tema. Passare dei valori da una finestra "madre" a una finestra "figlia", diciamo. Il problema qui è che l'esempio che fai è talmente tanto minimale da essere fuorviante. Se il caso reale fosse davvero SOLO quello del tuo esempio, allora ti dirò: probabilmente userei quasi (ho detto: quasi!) la stessa tecnica. Il problema è che la vita reale in genere è più complessa. Molto più complessa.

Iniziamo facendo finta che davvero dobbiamo occuparci SOLO del caso del tuo esempio.
In generale, la tua soluzione non va bene perché viola il principio di sostituzione di Liskov. Ora: ce l'ha ordinato il medico, di rispettare il principio di sostituzione? Se lo chiedi a Riko, sai già la risposta. Se lo chiedi a me, ti dico che se la violazione si mantiene molto localizzata, boh... fai un po' come ti pare. L'importante è che lo capisci.
D'altra parte, proprio nel tuo caso c'è un modo semplice per migliorare parecchio le cose: basta passare il valore non come argomento posizionale, ma come argomento opzionale:

class NewFinestra(wx.Dialog):
    def __init__(self, parent, id=wx.ID_ANY, title='',
                 pos=wx.DefaultPosition, size=wx.DefaultSize,
                 style=wx.DEFAULT_DIALOG_STYLE, name=wx.DialogNameStr,
                 parola=''):  # <- ta daaa! aggiungo 'parola' come keyword
        wx.Dialog.__init__(self, parent, id, title, pos, size, style, name)
        # etc.

# da istanziare con qualcosa del genere (per riprendere il tuo esempio):
newFinestra = NewFinestra(self, title='Prova', size=(500,500), parola='ciao')


O addirittura, se proprio non vuoi sprecarti a copiare tutta la signature di wx.Dialog:

class NewFinestra(wx.Dialog):
    def __init__(self, *a, **k):
        parola = k.pop('parola', '') # prima elimino 'parola' dalla signature
        wx.Dialog.__init__(self, *a, **k) # poi inizializzo la classe base
        # etc. etc.


(questo però è un tantino irresponsabile: se fai così, assicurati di aggiungere una docstring che spiega molto per benino tutto quanto).

Questo è il modo che userei io (e che in genere si può usare) se davvero dovessimo SOLO risolvere il problema del tuo esempio. Se te lo studi un po' e lo confronti con il tuo, capisci la differenza. Nota che qui wxPython non c'entra nulla: è tutta questione di sana (più o meno) programmazione OOP.


Detto questo, nella vita reale le cose sono ben più complesse. In generale il problema di "trasferire dati tra una finestra e un'altra" è un problema di "trasferire dati tra la gui e l'applicazione", e si risolve con un'architettura MCV più generale (e robusta, si spera).
Ora, wxPython offre alcune soluzioni per "trasferire dati" che tu puoi usare, o no: una sono i validatori (ne parlo nella mia guida), un'altra sono i DataViewModel (cercali nella demo). Ora, ripeto, puoi benissimo scegliere di non appoggiarti a queste funzionalità: il fatto è che wxPython tende a invadere anche le parti di "model" e di "controller" nella triade MCV, e questo può anche non piacere.
Ma quello che devi capire, per esempio, è che un validatore è un oggetto che si mette in mezzo tra le finestre della tua gui e il tuo model sottostante per fare da "controller" e spingere i dati avanti e indietro. Se non vuoi usare un validatore o un DataViewModel, dovresti comunque cominciare a pensare a un controller di qualche tipo.