[wxpython] procedurale o OOP?

Messaggioda mic_1 » 05/02/2020, 19:34

Ciao a tutti!!!

Ho trovato un intoppo al mio progetto che ora vi descrivo:

Ho creato una finestra con dei TAB. Ogni tab è suddiviso in due sezioni verticali:
- A -> visualizzazione immagine distribuzione
- B -> tasti per FitLine e FitPowerLaw

Alla pressione del tasto viene aperta la finestra della elaborazione su scatter.

Mi chiedevo...e chiedo soprattutto a voi perchè non lo so :-D E' possibile inserire l'immagine ottenuta da B ad A anche se essendo procedurale indietro non si torna? Come posso risolvere? Devo per forza modificare il codice portando da procedurale ad oggetti???? :?: :?:

Sono veramente preoccupata perchè non so quante modifiche debba fare....

C'è un modo semplice per risolvere questo inghippo????? GRAZIE! Sono preoccupata...
Ultima modifica di mic_1 il 06/02/2020, 12:17, modificato 1 volta in totale.
mic_1
Junior Member
Junior Member
 
Messaggio: 154 di 386
Iscritto il: 11/01/2011, 18:11

Re: [wxpython] procedurale o OOP?

Messaggioda mic_1 » 05/02/2020, 20:08

... da ignorante.... chiedo...

se facessi un controllo in A sull'evento bottone B e un refresh.. potrei risolvere ???

Ho provato ieri a cercare qualcosa su refresh() ma non saprei come usarlo...

Consigli??? Ne avrei proprio bisogno!!! Grazie!!!!
mic_1
Junior Member
Junior Member
 
Messaggio: 155 di 386
Iscritto il: 11/01/2011, 18:11

Re: [wxpython] procedurale o OOP?

Messaggioda Raptorista » 07/02/2020, 10:51

Ciao, senza vedere codice non è facile dare una risposta, soprattutto perché non ho mai usato wxpython, ma ci provo comunque. Tutto ciò che segue, quindi, è "assumendo che abbia interpretato correttamente il tuo messaggio".
mic_1 ha scritto:E' possibile inserire l'immagine ottenuta da B ad A anche se essendo procedurale indietro non si torna? Come posso risolvere? Devo per forza modificare il codice portando da procedurale ad oggetti???? :?: :?:

Teoricamente esiste un modo procedurale di fare la cosa, ma non è detto che sia pratico.
Forse basta che tu conservi, nel frame che contiene B, una copia dell'oggetto che in A visualizza l'immagine e, tramite la sua interfaccia, gli passi la nuova immagine da visualizzare.
Un matematico ha scritto:... come mia nonna che vuole da anni il sistema per vincere al lotto e crede che io, in quanto matematico, sia fallito perché non glielo trovo


Immagine
Avatar utente
Raptorista
Moderatore
Moderatore
 
Messaggio: 5392 di 9616
Iscritto il: 28/09/2008, 19:58

Re: [wxpython] procedurale o OOP?

Messaggioda mic_1 » 11/02/2020, 11:32

Vi riporto una parte di codice. L'image viene visualizzata, non in trasparenza, nella class B e non A.
Grazie

Codice:
class A(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent)
        sizer = wx.BoxSizer()
        sizer.Add(self, 1, wx.EXPAND)
        self.Parent.SetSizer(sizer)
        self.Distrib_CLCentr()   #funzione richiamata con image
        buf = io.BytesIO()
        plt.savefig(buf, format = 'png', dpi=100)
        buf.seek(0)
        plt.close()
        self.sizer = wx.BoxSizer(wx.HORIZONTAL)

        if wx.UpdateUIEvent.CanUpdate(self):
            self.UpdateWindowUI(wx.UPDATE_UI_FROMIDLE)
            print('print1')
            self.Image1 = wx.Image(buf2, wx.BITMAP_TYPE_ANY)
            self.Image2 = wx.StaticBitmap(self, wx.ID_ANY, wx.Bitmap(self.Image1))
            self.sizer.Add(self.Image2, 1, wx.ALIGN_CENTRE)
            self.sizer.Add(self.Image, 1, wx.ALIGN_CENTRE)
        else:
            self.Image = wx.Image(buf, wx.BITMAP_TYPE_ANY)
            self.Image = wx.StaticBitmap(self, wx.ID_ANY, wx.Bitmap(self.Image))
            self.sizer.Add(self.Image, 1, wx.ALIGN_CENTRE)
        self.SetSizer(self.sizer)

class B(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent)
        self.Button()   # uno dei pulsanti richiama all'evento la funzione OnFit che genera la seconda image che vorrei sovrapporre in trasparenza alla prima image. Ce ne sarà poi un'altra da sovrapporre allo stesso modo.

    def OnFit(self, event):
        global buf2, eid, Image1
        eid = event.GetId()
        ....... #codice di calcolo
        self.fig, self.ax = plt.subplots()
        self.fig.set_size_inches(15, 10)
        self.ax.scatter(xCL, yCL, alpha=0.6) 
        self.ax.plot(xdata , np.polyval(p1, xdata) ,'r-')
        self.ax.set(xlabel='Number of Neighbors', ylabel='Closeness Centrality')
        self.ax.yaxis.grid(linestyle='--')
        self.xticks = ([0, 1, 10, 100, roundup(max(xCL), n = 2)])
        self.yticks = list(frange(0.000, roundup2(float(max(yCL)))+0.025, 0.025))
        self.yticks_ = np.around(self.yticks, 4)
        self.ax.set_xticks(self.xticks)
        self.ax.set_yticks(self.yticks_)
        self.ax.set_xticklabels(self.xticks, fontsize=8) #per stabilire un intervallo uso np.arange()
        self.ax.set_yticklabels(self.yticks_, fontsize=8)
        buf2 = io.BytesIO()
        plt.savefig(buf2, format = 'png', dpi=100) #, bbox_inches='tight')
        buf2.seek(0)
        if wx.UpdateUIEvent.CanUpdate(self):
            self.UpdateWindowUI(wx.UPDATE_UI_FROMIDLE)
            plt.close()
            A(self) 
mic_1
Junior Member
Junior Member
 
Messaggio: 156 di 386
Iscritto il: 11/01/2011, 18:11

Re: [wxpython] procedurale o OOP?

Messaggioda mic_1 » 26/02/2020, 13:42

Purtroppo non sono riuscita a trovare la soluzione. Qualche consiglio??? Non per mettere fretta a nessuno ma avrei urgenza. grz
mic_1
Junior Member
Junior Member
 
Messaggio: 158 di 386
Iscritto il: 11/01/2011, 18:11

Re: [wxpython] procedurale o OOP?

Messaggioda Raptorista » 27/02/2020, 13:35

Purtroppo da quel codice non si capisce granché. Per caso il repository è su GitLab o simili? Magari potendo eseguire il codice si capisce meglio.
Un matematico ha scritto:... come mia nonna che vuole da anni il sistema per vincere al lotto e crede che io, in quanto matematico, sia fallito perché non glielo trovo


Immagine
Avatar utente
Raptorista
Moderatore
Moderatore
 
Messaggio: 5405 di 9616
Iscritto il: 28/09/2008, 19:58

Re: [wxpython] procedurale o OOP?

Messaggioda mic_1 » 16/03/2020, 13:48

No, solo wxpython.

Dal codice ho tolto solo parti di calcolo... niente che possa ostacolarne la comprensione.

Codice:
if wx.UpdateUIEvent.CanUpdate(self):
            self.UpdateWindowUI(wx.UPDATE_UI_FROMIDLE)


Mi permette di inserire l'image nel tab ma lo inserisce nel tab della classe 2-B e non nella tab della classe 1-A

Cosa sbaglio? come dev'essere usato? c'è un modo più semplice per ottenere il risultato?
Ho salvato l'image in trasparenza inserendo l'apposito parametro in plt.savefig() ma io non vedo nulla...

Inoltre avrei bisogno di distribuire l'asse x : l'ho suddivisa in 0, 10, 100, 700 ma vorrei che queste suddivisioni siano equidistanti tra loro. come fare?
Grazie!
mic_1
Junior Member
Junior Member
 
Messaggio: 159 di 386
Iscritto il: 11/01/2011, 18:11

Re: [wxpython] procedurale o OOP?

Messaggioda claudio86 » 05/05/2020, 09:31

Il post è abbastanza confuso.

Innanzitutto è difficile capire cosa succede se mostri solamente parti del programma. Non sappiamo come hai creato le finestre e come interagiscono tra loro. L'ideale sarebbe creare un programma minimo completo, cioè qualcosa che possiamo direttamente eseguire, e che mostri il problema (e nient'altro). Così chi legge può immediatamente provare ad eseguire il codice e modificarlo per trovare una soluzione. Se invece lasci a chi ti potrebbe aiutare il compito di scrivere il resto, è facile che lasci perdere e passi oltre.
(Non prenderlo come un attacco ovviamente, è un consiglio per aumentare le possibilità che qualcuno ti aiuti)

Detto questo, il mio consiglio è di provare a fare un passo indietro e provare una cosa più semplice. Invece che un'immagine, prova a scrivere un programma dove premendo un pulsante nel tab B, scriva del testo nel tab A. Una volta trovata una soluzione, dovrebbe essere semplice modificarla per funzionare con un'immagine.

Non conosco wxpython, ho solo usato molto brevemente wxwidgets in C++ ormai quasi una quindicina di anni fa, e in per interfacce grafiche in Python ho abbastanza familiarità con PyQt, ma generalmente questi framework funzionano con qualche tipo di sistema di eventi o messaggi:

- L'elemento A è in attesa di un messaggio (per esempio implementa una funzione OnClick).
- L'elemento B manda un messaggio.
- L'elemento A riceve il messaggio e lo processa nel modo opportuno.

Non so di preciso come funzioni in wxpython, ma dovresti trovare documentazione e tutorial sul suo sito, o altrove su internet.

P.S.
La domanda di Raptorista relativa a Gitlab era per capire se il progetto completo è disponibile online da qualche parte. Gitlab è una piattaforma dove puoi creare progetti pubblici o privati usando il sistema di versionamento git. Se non lo conosci, git (o alternative come mercurial e darcs) è un concetto decisamente fondamentale nello sviluppo di software.
"This theorem, as many others, is proven by writing zero in a creative way…"
claudio86
Senior Member
Senior Member
 
Messaggio: 547 di 1130
Iscritto il: 09/01/2011, 15:12

Re: [wxpython] procedurale o OOP?

Messaggioda mic_1 » 05/05/2020, 18:20

Ciao Claudio, grazie! (wxpython non è wxwidgets di python? )

Ho un Frame suddiviso in Tab (avevo suddiviso ogni tab (class) in 2 sezioni (2 sottoclass) richiamandole come classi ma ho risolto creando un'unica classe in questo modo:

Codice:
class Tab(wx.Panel):     
     def __init__(self, parent):
        wx.Panel.__init__(self, parent)
        self.parent = parent
        start = time.monotonic()   
        print('inizio Tab7  : {:>9.2f}'.format(start))
        self.hSplitter = wx.SplitterWindow(self)
        self.panelSX = wx.Panel(self.hSplitter)
        self.panelDX = wx.Panel(self.hSplitter)       
        self.hSplitter.SplitVertically(self.panelSX, self.panelDX)
        self.hSplitter.SetSashGravity(0.7)   
        self.hSplitter.SetBackgroundColour((0xff, 0xff, 0xff))                   

        vbox = wx.BoxSizer(wx.VERTICAL)                               
        sizer = wx.BoxSizer()
        sizer.Add(self, 1, wx.EXPAND)
        self.Parent.SetSizer(sizer)
        self.Distrib_CLCentr()
        buf = io.BytesIO()
        plt.savefig(buf, format = 'png', dpi=100) #, bbox_inches='tight')
        buf.seek(0)
        plt.close()
        self.sizer = wx.BoxSizer(wx.HORIZONTAL)
        self.Image = wx.Image(buf, wx.BITMAP_TYPE_ANY)
        self.Image = wx.StaticBitmap(self.panelSX, wx.ID_ANY, wx.Bitmap(self.Image))
        self.sizer.Add(self.Image, 0, wx.ALIGN_CENTRE)
        self.Centre()
        self.hSplitter.SetSizer(vbox)         

        self.Button()

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.hSplitter, 1, wx.EXPAND)
        self.SetSizer(sizer)       
        end = time.monotonic()
        print('fine  Tab7    : {:>9.2f}'.format(end))
        print('intervallo: {:>9.2f}'.format(end - start))

    def Distrib_CLCentr(self):
         calcolo e creazione image1

    def Button(self):
        # 3 bottoni di cui 1 lancia la FIT

    def FIT(self, event):
        calcolo e creazione image2
        buf2 = io.BytesIO()
        plt.savefig(buf2, format = 'png', dpi=100, transparent=True)
        buf2.seek(0)
        #IN QUESTO PUNTO L'IMAGE2 VIENE INSERITA NEL PANNELLO DI SX.
        if event:
            self.Image = wx.Image(buf2, wx.BITMAP_TYPE_ANY)
            self.Image = wx.StaticBitmap(self.panelSX, wx.ID_ANY, wx.Bitmap(self.Image))
            self.sizer.Add(self.Image, 0, wx.ALIGN_CENTRE)
        else:
            pass


VORREI ORA RENDERE IL BOTTONE CHE RICHIAMA LA FUNZIONE FIT COME ENABLE/DISABLE
mic_1
Junior Member
Junior Member
 
Messaggio: 165 di 386
Iscritto il: 11/01/2011, 18:11

Re: [wxpython] procedurale o OOP?

Messaggioda claudio86 » 06/05/2020, 07:52

mic_1 ha scritto:wxpython non è wxwidgets di python?

Sì, ma i linguaggi sono abbastanza diversi quindi ci possono essere differenze sostanziali anche nelle librerie. Inoltre sono davvero passati quasi quindici anni, non mi ricordo granché.

mic_1 ha scritto:VORREI ORA RENDERE IL BOTTONE CHE RICHIAMA LA FUNZIONE FIT COME ENABLE/DISABLE

Dovrebbe bastare chiamare Enable() e Disable() sul pulsante.

Immagino però che quello che tu voglia davvero è disabilitare il pulsante durante l'operazione di fitting, che può richiedere tempo. In teoria basterebbe appunto chiamare Disable() all'inizio ed Enable() alla fine, ma potrebbe essere (molto) più complicato. Nell'esecuzione di quella funzione, il controllo non ritorna mai al al framework che gestisce l'interfaccia grafica, quindi tutte le finestre potrebbero sembrare bloccate. La soluzione di solito è di eseguire tale funzione in un thread separato, e quando termina aggiornare l'interfaccia usando qualche tipo di sincronizzazione o evento. Non so come si possa fare in wxwidgets, né soprattutto in wxpython, considerato che Python non offre un vero multithreading.
"This theorem, as many others, is proven by writing zero in a creative way…"
claudio86
Senior Member
Senior Member
 
Messaggio: 549 di 1130
Iscritto il: 09/01/2011, 15:12

Prossimo

Torna a Informatica

Chi c’è in linea

Visitano il forum: Nessuno e 1 ospite