Autore Topic: Come si esce correttamente da un programma grafico?  (Letto 2182 volte)

Offline Gianluigi

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 4.243
  • Tonno verde
    • Mostra profilo
Re:Come si esce correttamente da un programma grafico?
« Risposta #15 il: 22 Novembre 2021, 12:50:40 »
Ora che, malgrado sia febbricitante, Benoit Minisini ha corretto uno dei bug che affliggono la trayicon il progetto allegato su Ubuntu 20.04 con Gambas ultimo Master funziona

Grazie Gianluigi, mi sai dire che versione contiene la fix per la trayicon?

Ciao
Cris

Ultima master, ma il mio esempio funziona anche con la stabile.
Solo se hai dei sotto menu potresti avere dei problemi con versioni più datate della master, ma solo con desktop gtk

 :ciao:
nuoto in attesa del bacio di una principessa che mi trasformi in un gambero azzurro

Offline Cris_70

  • Gamberetto
  • *
  • Post: 12
    • Mostra profilo
Re:Come si esce correttamente da un programma grafico?
« Risposta #16 il: 23 Novembre 2021, 10:14:28 »
Purtroppo anche con l'ultima master non funziona. E poi il mio problema non è legato alla TrayIcon, infatti il comando Quit dal menù della TrayIcon funziona.
Facciamo che appena ho tempo provo a produrre un programmino che illustri il comportamento anomalo.

Ciao
Cris

Offline Gianluigi

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 4.243
  • Tonno verde
    • Mostra profilo
Re:Come si esce correttamente da un programma grafico?
« Risposta #17 il: 23 Novembre 2021, 12:22:43 »
Purtroppo anche con l'ultima master non funziona. E poi il mio problema non è legato alla TrayIcon, infatti il comando Quit dal menù della TrayIcon funziona.
Facciamo che appena ho tempo provo a produrre un programmino che illustri il comportamento anomalo.

Ciao
Cris

Scusa ma non ho capito, mi stai dicendo che il progetto di esempio che ho allegato a te non funziona?
Perché a me funziona correttamente, quando esco dal programma cliccando sul Pulsante Quit della FMain si chiude anche la trayicon oltre alle finestre aperte.
nuoto in attesa del bacio di una principessa che mi trasformi in un gambero azzurro

Offline Cris_70

  • Gamberetto
  • *
  • Post: 12
    • Mostra profilo
Re:Come si esce correttamente da un programma grafico?
« Risposta #18 il: 04 Dicembre 2021, 14:59:49 »
Ciao Gianluigi

Scusa ma non ho capito, mi stai dicendo che il progetto di esempio che ho allegato a te non funziona?
Perché a me funziona correttamente, quando esco dal programma cliccando sul Pulsante Quit della FMain si chiude anche la trayicon oltre alle finestre aperte.

No scusa non sono stato chiaro.
Intendevo solo dire che il mio problema non è risolto. Ma il mio problema è diverso, lo capirete meglio non appena riesco a trovare il tempo per produrre un piccolo programma demo.

Scusate la lungaggine, ma il fatto è che il programma in questione lo posso testare solo in ambiente di lavoro e generalmente durante le ore di lavoro non ho molto tempo libero per dedicarmi a produrre il programma che dimostri il problema.

Ciao
Cris

Offline Cris_70

  • Gamberetto
  • *
  • Post: 12
    • Mostra profilo
Re:Come si esce correttamente da un programma grafico?
« Risposta #19 il: 04 Dicembre 2021, 17:43:10 »
Ok, mi sono preso un momento per mettere giù il programmino.
In realtà ho riutilizzato un altro esempio che avevo mandato a Benoit, che illustra un bug con i sottomenù nella tray.

Ho aggiunto la funzione DoSomething() che, quando si seleziona la voce "entry4" nel TrayMenu, tenta di chiudere il programma con me.Close.

Alcune precisazioni:
- dovete usare il menu TrayMenu nella finestra principale, se invece lo fate usando il menù contestuale della tray icon non funzionerà, per via del bug segnalato precedentemente (a meno che stiate usando una versione recente del branch 3.17)
- il codice così com'è sembra non avere senso, ma ovviamente si tratta solo di un esempio per triggerare il "bug"

Come potrete vedere, quando si sceglie la voce "entry4" il programma si chiude, ma non subito dopo la me.Close, ma solo dopo aver eseguito tutto il codice che può eseguire... in pratica dopo aver esaurito tutto lo stack delle chiamate.

Ora immaginatevi un programma che ha uno stack di chiamate profondo magari 4 o 5 livelli, al 5° livello trova un errore non recuperabile e chiede all'utente se vuole ritentare o meno. L'utente risponde "no" e quindi il programma deve terminare. Ma invece di terminare dopo la me.Close, questo va avanti ad eseguire (o cercare di eseguire) tutto il codice che c'è dopo la Button1_Click() finché ha esaurito tutto lo stack.
L'unico modo per fermarlo lì dove deve essere fermato è inserire una Quit. O almeno io non ho trovato altro modo.

Dove sbaglio?

Ciao
Cristiano
« Ultima modifica: 04 Dicembre 2021, 17:57:58 da Cris_70 »

Offline vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.719
  • Ne mors quidem nos iunget
    • Mostra profilo
Re:Come si esce correttamente da un programma grafico?
« Risposta #20 il: 05 Dicembre 2021, 00:43:15 »
quando si sceglie la voce "entry4" il programma si chiude
Un primo reale problema che riscontro è la sollevazione di un "Warning", e più precisamente il seguente:
gbx3 [5476]: warning: circular references detected:
gbx3:     2 DBusConnection

Per eliminare questo avviso, ho dovuto eliminare la sub-routine:
Codice: [Seleziona]
Public Sub Form_Close()
  TrayIcon1.Delete
End
e far distruggere l'Oggetto "TrayIcon1" con la modalità - che tempo fa Gianluigi ci ha insegnato a fare per qualsiasi Oggetto si tratti - assegnandogli il valore "Null".
In questo caso più precisamente:
Codice: [Seleziona]
Public Function DoSomething(i As Integer) As Boolean

  If i = 4 Then
      TrayIcon1 = Null    <=======
    Me.close
    Return True
  Endif
  Return False

End


L'unico modo per fermarlo lì dove deve essere fermato è inserire una Quit. O almeno io non ho trovato altro modo.
Se io pongo l'istruzione "Quit" dopo quella "Me.Close", ottengo almeno due Warning:

gbx3 [8155]: warning: circular references detected:
gbx3:     1 DBusStatusIconMenu
gbx3:     1 DBusStatusIcon
gbx3:     2 DBusConnection
gbx3:     4 DBusObject
gbx3 [8155]: warning: 5 allocation(s) non freed.


Se pongo la sola istruzione "Quit" (quindi senza "Me.Close"), ottengo i medesimi due Warning.

Per ottenere un'uscita "pulita", dopo aver attivato il Componente "gb.signal", devo impostare la sub-routine come segue:
Codice: [Seleziona]
Public Function DoSomething(i As Integer) As Boolean
 
  If i = 4 Then
    Signal.Send(Application.Handle, Signal.SIGKILL)
    Return True
  Endif

  Return False

End
Tale soluzione impedirà al programma di proseguire oltre tale riga del "Signal.Send()".

Al riguardo e più in generale si veda il paragrafo presente in questa pagina della nostra wiki:
   https://www.gambas-it.org/wiki/index.php?title=Chiudere_programmi_esterni#mediante_le_risorse_della_Classe_.22Signal.22_di_Gambas
« Ultima modifica: 05 Dicembre 2021, 01:13:36 da vuott »
« Chiunque, non ricorrendo lo stato di necessità, nel proprio progetto Gambas fa uso delle istruzioni Shell o Exec, è punito con la sanzione pecuniaria da euro 20,00 a euro 60,00. »

Offline Cris_70

  • Gamberetto
  • *
  • Post: 12
    • Mostra profilo
Re:Come si esce correttamente da un programma grafico?
« Risposta #21 il: 05 Dicembre 2021, 15:34:56 »
Ciao vuott!

Un primo reale problema che riscontro è la sollevazione di un "Warning", e più precisamente il seguente:
gbx3 [5476]: warning: circular references detected:
gbx3:     2 DBusConnection


Si, questo è esattamente il motivo per cui si vuole evitare di usare la "Quit" nei programmi grafici.
O almeno credo, nel senso che, per quanto uno cerchi di deallocare tutto quello che ha allocato, ci sono sempre questi warning all'uscita con Quit. Io non sono mai riuscito ad evitarli, perlomeno.

Per eliminare questo avviso, ho dovuto eliminare la sub-routine:
Codice: [Seleziona]
Public Sub Form_Close()
  TrayIcon1.Delete
End
e far distruggere l'Oggetto "TrayIcon1" con la modalità - che tempo fa Gianluigi ci ha insegnato a fare per qualsiasi Oggetto si tratti - assegnandogli il valore "Null".
In questo caso più precisamente:
Codice: [Seleziona]
Public Function DoSomething(i As Integer) As Boolean

  If i = 4 Then
      TrayIcon1 = Null    <=======
    Me.close
    Return True
  Endif
  Return False

End

Mmm, si ok così funzionerà anche ma non è ottimale. Non funziona allo stesso modo se invece l'istruzione
TrayIcon1 = Null
la metti nella Form_Close()? (Non ho provato, più tardi lo faccio)

Rimane poi il problema degli altri warning.

Per ottenere un'uscita "pulita", dopo aver attivato il Componente "gb.signal", devo impostare la sub-routine come segue:
Codice: [Seleziona]
Public Function DoSomething(i As Integer) As Boolean
 
  If i = 4 Then
    Signal.Send(Application.Handle, Signal.SIGKILL)
    Return True
  Endif

  Return False

End
Tale soluzione impedirà al programma di proseguire oltre tale riga del "Signal.Send()".

Si ok, ma così stai dicendo al sistema operativo di killare il tuo stesso programma. Eviterà anche i warning, ma non lo chiamerei un'scita "pulita".

In ogni caso, il punto che qui volevo sollevare è che l'indicazione di usare la chiusura della form principale come metodo di uscita non funziona. O almeno non funziona sempre.
Credo che questa sia una mancanza piuttosto grave, a cui si dovrebbe trovare un rimedio più "architetturale" (==> Benoit?).

E poi: perché quando faccio click sul pulsante di chiusura il programma esce senza warning, mentre quando esco con Quit dopo aver chiuso la form principale ho dei warning? Alla fine, il codice di deallocazione che viene eseguito è lo stesso.

Ciao
Cris

Offline vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.719
  • Ne mors quidem nos iunget
    • Mostra profilo
Re:Come si esce correttamente da un programma grafico?
« Risposta #22 il: 30 Dicembre 2021, 20:14:22 »
Non funziona allo stesso modo se invece l'istruzione
TrayIcon1 = Null
la metti nella Form_Close()?
Dunque funziona ugualmente se quell'istruzione la metti nella routine del Metodo nascosto "_free()":
Codice: [Seleziona]
Public Sub _free()

    TrayIcon1 = Null

End
Puoi usare anche quest'altra istruzione:
Codice: [Seleziona]
Free(Object.Address(TrayIcon1))
« Chiunque, non ricorrendo lo stato di necessità, nel proprio progetto Gambas fa uso delle istruzioni Shell o Exec, è punito con la sanzione pecuniaria da euro 20,00 a euro 60,00. »

Offline spheris5

  • Gamberetto
  • *
  • Post: 19
    • Mostra profilo
Re:Come si esce correttamente da un programma grafico?
« Risposta #23 il: 06 Febbraio 2022, 21:28:45 »
Uso spesso il comando QUIT perché il mio programma non si chiude correttamente con me.close.
Una funzione mal programmata, un errore nel codice e la mia applicazione non si chiude. Il comando QUIT è magico.
quindi continuo ad usarlo.

Offline vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.719
  • Ne mors quidem nos iunget
    • Mostra profilo
Re:Come si esce correttamente da un programma grafico?
« Risposta #24 il: 06 Febbraio 2022, 22:17:55 »
Certo, però, come dice l'avvertenza nella wiki ufficiale di Gambas:
   https://gambaswiki.org/wiki/lang/quit?l=it
l'uso dell'istruzione "Quit" in ambiente grafico, non è una soluzione molto ortodossa.
« Chiunque, non ricorrendo lo stato di necessità, nel proprio progetto Gambas fa uso delle istruzioni Shell o Exec, è punito con la sanzione pecuniaria da euro 20,00 a euro 60,00. »