Alguma alternativa prática ao modelo de sinais + slots para programação GUI?

9

Atualmente, a maioria dos kits de ferramentas da GUI usa o modelo Sinais + Slots. Foi Qt e GTK +, se não estou errado, quem foi o pioneiro.

Você sabe, os widgets ou objetos gráficos (às vezes até os que não são exibidos) enviam sinais para o manipulador de loop principal. O manipulador de loop principal chama os eventos , retornos de chamada ou slots atribuídos a esse widget / objeto gráfico. Geralmente, existem virtualmanipuladores de eventos padrão (e na maioria dos casos ) já fornecidos pelo kit de ferramentas para lidar com todos os sinais predefinidos; portanto, diferentemente dos projetos anteriores, em que o desenvolvedor teve que escrever todo o loop principal e o manipulador para cada mensagem. (pense em WINAPI), o desenvolvedor precisa se preocupar apenas com os sinais de que precisa para implementar novas funcionalidades.

Agora, esse design está sendo usado na maioria dos kits de ferramentas modernos, até onde eu sei. Existem Qt, GTK +, FLTK etc. Há Java Swing. O C # ainda possui um recurso de idioma (eventos e delegados) e o Windows Forms foi desenvolvido nesse design. De fato, na última década, esse design para programação de GUI se tornou uma espécie de padrão não-escrito. Uma vez que aumenta a produtividade e fornece maior abstração.

No entanto, minha pergunta é:

Existe algum projeto alternativo, paralelo ou prático para a programação GUI moderna?

ou seja, o design de Sinais + Slots, o único prático na cidade? É possível fazer a programação da GUI com outro design? Existem kits de ferramentas da GUI modernos (de preferência bem-sucedidos e populares) criados em um design alternativo?

ApprenticeHacker
fonte
O paradigma da fila de mensagens que você encontra na API do Windows não é como eventos e delegados. Os delegados são chamados de forma síncrona e imediatamente, como std::function, não um sinal assíncrono. Além disso, o WinAPI não fornecem DefWindowProcque processa mensagens do Windows como uma implementação padrão. Então, eu vou postar que sua pergunta é baseada em lógica falha.
DeadMG
2
QT e GTK + estão longe de ser os primeiros frameworks de GUI que estavam usando uma abordagem orientada a eventos. O conceito remonta ao Smalltalk-80 ( en.wikipedia.org/wiki/Smalltalk ).
Doc Brown
Pergunta interessante, estou curioso para saber se esse modelo muda muito com as interfaces multi-touch.
Ben DeMott
Eu seria generoso e presumiria que ele conhece o SendMessage, que é síncrono, não apenas o PostMessage. No entanto, ele ainda está errado no sentido de que você nunca precisou escrever o loop inteiro de manipulação de mensagens para cada mensagem.
Gbjbaanb
O JavaFx fornece um mecanismo semelhante por meio de suas APIs de ligação.
Eng.Fouad

Respostas:

5

Esse é um dos meus assuntos favoritos e, por cerca de uma década (anos 70 a 86), pensei que ter uma GUI composta por objetos que respondessem a eventos era a maneira certa de fazê-lo.

Então eu tropecei em outra maneira de fazê-lo descrito aqui e com um projeto sourceforge aqui .

Em poucas palavras, o problema com os objetos é que eles persistem e, se você escrever um código para criá-los, também precisará escrever um código para modificá-los gradualmente, se forem necessárias alterações, e de alguma forma receber mensagens para eles. Não seria bom se você pudesse pintar o que queria e repintá-lo se quiser algo diferente e não precisar se preocupar com a persistência de objetos anteriores? Também não seria bom se você nunca tivesse que escrever um código para o tratamento de mensagens, porque tudo é feito sob o capô?

É isso que esse pacote faz. Para diálogos simples, ele salva uma ordem de magnitude no código. Para diálogos complexos que mudam dinamicamente, eles são possíveis.

PS: Eu fiz isso apenas para UIs de desktop e UIs de terminal remoto, não para UIs de navegadores da web. Tenho certeza de que é possível, mas não tive a chance de tentar.

Mike Dunlavey
fonte
+1, mas como é possível obter funcionalidades extras, como entrada definida pelo usuário?
ApprenticeHacker
@IntermediateHacker: Não sei ao certo o que você quer dizer com entrada definida pelo usuário. Você quer dizer ter um aplicativo de designer de formulários?
precisa saber é o seguinte
2

Bem, existem duas maneiras distintas de fazer isso:

  1. Faça com que cada widget exponha um mecanismo de inscrição granular (Sinal / Slot, Observador / Observável, Evento / Delegado) e faça com que o código do cliente seja assinado e tome as devidas providências.
  2. Construiu um widget em relação a uma abstração dos dados apresentados e solicitou que o código do cliente implementasse essa abstração.

Aqui está um exemplo para a segunda abordagem:

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

E agora você pode criar um código LabelButtoncontra LabledActione um cliente pode simplesmente implementá-lo ou usar alguma implementação padrão genérica, se disponível e adequada.

De certa forma, a segunda abordagem é menos flexível, mas mais rígida. Você de alguma forma não une a vista com o modelo por meios relativamente atômicos. Você projeta uma GUI adequada com base em seus requisitos e implementa os adaptadores entre essa GUI e sua lógica de domínio / aplicativo.

back2dos
fonte
Model / View / Controller é bom, mas é apenas uma extensão do padrão de observador, porque a parte do controlador é apenas um observador do widget e na parte do modelo o widget é observador do modelo, por isso é o mesmo mecanismo inverso .
Jan Hudec
1

Alguns sistemas do tipo controle usam uma abordagem de banco de dados - cada controle da GUI é vinculado a um arquivado no banco de dados, para que a GUI sempre reflita o estado do banco de dados. Ganchos de banco de dados são usados ​​para acionar funções quando um valor é alterado.

Martin Beckett
fonte
4
ainda não é esse slot de sinal apenas com uma camada extra de banco de dados?
Ratchet freak #
Em última análise debaixo dela é todas as interrupções ou retornos de chamada - eles são as operações assíncronas única de baixo nível
Martin Beckett