Qualche alternativa pratica al modello Signals + Slots per la programmazione della GUI?


9

La maggior parte dei toolkit GUI oggigiorno utilizza il modello Signals + Slots. Sono stati Qt e GTK +, se non sbaglio, a fare da pionieri.

Sai, i widget o gli oggetti grafici (a volte anche quelli che non sono visualizzati) inviano segnali al gestore del ciclo principale. Il gestore del ciclo principale chiama quindi gli eventi , i callback o gli slot assegnati per quel widget / oggetto grafico. Di solito ci sono virtualgestori di eventi predefiniti (e nella maggior parte dei casi ) già forniti dal toolkit per gestire tutti i segnali predefiniti, quindi, a differenza dei progetti precedenti in cui lo sviluppatore doveva scrivere l'intero ciclo principale e il gestore per ogni messaggio stesso (pensa WINAPI), lo sviluppatore deve solo preoccuparsi dei segnali su cui ha bisogno per implementare nuove funzionalità.

Ora, per quanto ne so, questo design viene utilizzato nella maggior parte dei toolkit moderni. Ci sono Qt, GTK +, FLTK ecc. C'è Java Swing. C # ha persino una funzione linguistica (eventi e delegati) e Windows Forms è stato sviluppato su questo progetto. In effetti, nell'ultimo decennio, questo progetto per la programmazione della GUI è diventato una specie di standard non scritto. Dal momento che aumenta la produttività e fornisce una maggiore astrazione.

Tuttavia, la mia domanda è:

Esiste un design alternativo, parallelo o pratico per la moderna programmazione della GUI?

vale a dire il design Signals + Slots è l'unico pratico in città? È possibile eseguire la programmazione della GUI con qualsiasi altro design? Sono disponibili toolkit moderni (preferibilmente di successo e popolari) basati su un design alternativo?


Il paradigma della coda messaggi che trovi nell'API di Windows non è come eventi e delegati. I delegati vengono chiamati in modo sincrono e immediatamente, come std::function, non un segnale asincrono. Inoltre, il WinAPI non prevede DefWindowProcche elabora i messaggi di Windows come implementazione di default. Quindi suppongo che la tua domanda sia basata su una logica imperfetta.
DeadMG

2
QT e GTK + sono lungi dall'essere i primi framework GUI che utilizzavano un approccio event driven. Il concetto risale a Smalltalk-80 ( en.wikipedia.org/wiki/Smalltalk ).
Doc Brown

Domanda interessante, sono curioso di sapere se questo modello cambia molto con le interfacce multi-touch.
Ben DeMott

Sarei generoso e presumo che conosca SendMessage che è sincrono, non solo PostMessage. Tuttavia, ha ancora torto in quanto non hai mai dovuto scrivere l'intero ciclo di gestione dei messaggi per ogni messaggio.
gbjbaanb,

JavaFx fornisce un meccanismo simile attraverso le sue API Bindings.
Ing

Risposte:



5

Questo è il mio argomento preferito e per circa un decennio (dagli anni '70 al '86) ho pensato che avere una GUI composta da oggetti che rispondessero agli eventi fosse il modo giusto per farlo.

Poi mi sono imbattuto in un altro modo per farlo descritto qui e con un progetto sourceforge qui .

In poche parole, il problema con gli oggetti è che persistono e, se si scrive codice per crearli, è necessario anche scrivere codice per modificarli in modo incrementale se sono necessarie modifiche e in qualche modo ottenere messaggi da e verso di essi. Non sarebbe bello se tu potessi semplicemente dipingere ciò che volevi e poi ridipingerlo se vuoi qualcosa di diverso e non devi preoccuparti della persistenza degli oggetti precedenti? Non sarebbe bello anche se non dovessi mai scrivere codice per la gestione dei messaggi, perché è tutto fatto sotto il cofano?

Questo è quello che fa quel pacchetto. Per dialoghi semplici, salva un ordine di grandezza nel codice. Per dialoghi complessi che cambiano dinamicamente, li rende possibili.

PS L'ho fatto solo per le interfacce utente desktop e le interfacce terminale remoto, non per le interfacce browser web. Sono sicuro che è possibile, ma non ho avuto la possibilità di provarlo.


+1, ma come è possibile ottenere funzionalità extra, come input definiti dall'utente?
ApprenticeHacker

@IntermediateHacker: non sono sicuro di cosa intendi per input definito dall'utente. Intendi avere un'app di progettazione moduli?
Mike Dunlavey,

2

Bene, ci sono due modi distinti per farlo:

  1. Fai in modo che ogni widget esponga un meccanismo di sottoscrizione granulare (segnale / slot, osservatore / osservabile, evento / delegato) e abboni il codice client e agisca di conseguenza.
  2. Costruito un widget contro un'astrazione dei dati che presenta e il codice client implementa tale astrazione.

Ecco un esempio per il secondo approccio:

interface Action {
     void execute();
     Bool isEnabled();
     Null<String> description();//used for tooltip
}
interface LabledAction extends Action {
     String getName();
}

E ora puoi creare un LabelButtoncontro un LabledActioncodice client e puoi semplicemente implementarlo o utilizzare un'implementazione predefinita generica, se disponibile e adatta.

In un certo senso il secondo approccio è meno flessibile, ma più rigido. In qualche modo non si collega semplicemente la vista con il modello con mezzi relativamente atomici. Si progetta una GUI adatta in base alle proprie esigenze e quindi si implementano gli adattatori tra quella GUI e la logica del dominio / dell'applicazione.


Model / View / Controller è buono, ma è solo un'estensione del modello di osservatore, perché la parte del controller è solo un osservatore del widget e nella parte del modello il widget è l'osservatore del modello, quindi è lo stesso meccanismo al contrario .
Jan Hudec,

1

Alcuni sistemi di tipo di controllo utilizzano un approccio al database: ogni controllo GUI è collegato a un file archiviato nel database in modo che la GUI rifletta sempre lo stato del database. Gli hook DB vengono utilizzati per attivare le funzioni quando un valore cambia.


4
non è ancora questo slot di segnale solo con un livello DB aggiuntivo?
maniaco del cricchetto

Alla fine, al di sotto, ci sono tutti gli interrupt o i callback - sono le uniche operazioni asincrone di basso livello
Martin Beckett,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.