Pergunta

Existe alguma maneira de integrar Boost.Asio com Qt4 (preferencial) ou loop principal do GTK? GTK fornece poll (2) como API então tecnicamente é deve ser possível. Qt fornece sua própria camada de rede, no entanto eu prefiro usar código existente escrito para Boost.Asio. Eu quero integrá-los sem usando um thread adicional.

Existe alguma referência como fazer isso para Qt4 (preferencial) ou GTKmm?

Graças.

Editar

Eu quero clearify várias coisas para tornar a resposta mais fácil. Ambos Qt e GTKmm fornecer "Seleccionar como" funcionalidade:

Assim, a pergunta é, como integrar existentes "seletores / pollers" como reator io_service Boost.Asio. Hoje, Boost.Asio pode usar escolha, kqueue, epoll, / dev / enquete e iocp como serviço de reator / proactor. Eu quero integrá-lo à principal loop de quadro GUI.

Todas as sugestões e soluções (melhor) são bem vindas.

Foi útil?

Solução

É questão bastante antigo, mas para aqueles que estão lendo isso agora eu gostaria de compartilhar minha código que é uma implementação de QAbstractEventDispatcher para boost :: asio.

Tudo que você precisa é adicionar a seguinte linha antes de criar QApplication (geralmente está em main ()).

QApplication::setEventDispatcher(new QAsioEventDispatcher(my_io_service));

Ele fará com que io_service está sendo executado em conjunto com a aplicação qt em um segmento sem latência adicional e queda de desempenho (como em solução com a chamada io_service :: poll () "de tempos em tempos").

Infelizmente, a minha solução é para POSIX sistemas apenas, uma vez que usar asio :: POSIX :: stream_descriptor. suporte do Windows podem precisar abordagem completamente diferente ou muito semelhantes -. Eu realmente não sei

Outras dicas

simples: Construir um slot QT que chama a io_service::poll_one() pertencente ao gui. Ligação que o slot de sinal tick do QT.

Em Profundidade: Felizmente para você Boost.Asio é muito bem desenhado. Há muitas opções sobre como fornecer um segmento de execução para os internos assíncronos subjacentes. As pessoas já têm mencionar usando io_service::run(), uma chamada de bloqueio com muitas desvantagens.

Você só estão autorizados a widgets de acesso gui a partir de um único segmento. roscas externas geralmente precisam eventos pós à GUI, se eles querem fazer mutação qualquer widget. Isto é muito semelhante à forma como Asio funciona.

A abordagem ingênua é uma thread apenas dedicar (ou temporizador) para executar io_service::run() e ter o manipulador de conclusão Asio postar um sinal gui. Este irá trabalho.

Em vez disso você pode usar a garantia de que os manipuladores de conclusão só será chamado no segmento de execução do chamador io_service. Não tem o io_service::run() chamada fio de gui como é o bloqueio e poderia pendurar o gui. Em vez disso use io_service::poll() ou io_service::poll_one(). Isso fará com que qualquer pendente manipuladores de conclusão Asio a ser chamado a partir do fio de gui. Desde os manipuladores estão funcionando no segmento gui eles estão livres para modificar os widgets.

Agora você precisa certificar-se o io_service tem a chance de correr regularmente. Eu recomendo ter uma chamada de sinal gui repetindo poll_one() algumas vezes. Acredito QT tem um sinal de carrapato que faria o truque. Você poderia rolar naturalmente o seu sinal QT própria para mais controle.

Se entendi sua pergunta corretamente, você tem código escrito para Boost.Asio. Você gostaria de usar esse código dentro de um aplicativo GUI.

O que não está claro na sua pergunta é se você quer envolver as camadas de rede Qt / Gtk através asynio para o seu código de trabalho, se você está apenas à procura de uma solução para ter tanto um ciclo de eventos gui e asynio juntos.

Vou assumir o segundo caso.

Ambos Qt e Gtk têm métodos para integrar eventos estrangeiros em seu ciclo de eventos. Ver, por exemplo qtgtk onde o ciclo de eventos Qt está conectado a Gtk.

No caso específico da Qt, se você quiser gerar eventos para Qt, você pode usar a seguinte classe: QAbstractEventDispatcher .

Depois de uma rápida olhada impulso asio, eu acho que você precisa fazer o seguinte:

  • têm um QTimer recorrentes com duração zero que as chamadas io_service :: run () o tempo todo. Dessa forma, boost :: asio vai chamar seu manipulador de conclusão logo que a sua operação assíncrona for concluída.
  • no seu manipulador de conclusão, duas opções:
    • Se a sua operação conclusão é longa, separado do GUI, fazer o seu negócio e certifique-se de qApp.processEvents de chamada () regularmente para manter o GUI responsivo
    • se você quiser apenas para se comunicar de volta com o gui:
      1. QEvent tipo
      2. costume
      3. subscrever este evento
      4. publicar seu evento para o Qt ciclo de eventos usando QCoreApplication :: postEvent ( ) .

Genuinamente integrando os principais laços é possível. É apenas uma grande dor (e eu ainda tenho que realmente tentar).

Running io_service :: run () em um segmento separado é provavelmente o caminho a percorrer.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top