Quais são alguns métodos de design padrão para adicionar GUI a um aplicativo de linha de comando? [fechadas]

8

Eu tenho um aplicativo Linux C incorporado que é executado com uma CLI simples. Agora, tenho a tarefa de criar uma GUI que realize a mesma funcionalidade que o programa de linha de comando. Eu não sou um designer de GUI bem-sucedido e a maioria se minha experiência estiver em codificação C profundamente incorporada.

Meu pensamento inicial é usar o qtcreator para criar a GUI, mas há várias questões em que estou pensando.

  • Avançando, quero manter o programa CL e o programa GUI e, de preferência, mesmo que eles sejam exatamente o mesmo executável que pode ser iniciado nos dois modos. A menos que isso seja uma má ideia?
  • Meu código está em C até agora, e qt é nativamente c ++
  • Eu gostaria de uma correlação direta, onde o botão pressionado na GUI chama as mesmas funções que eu chamo da CLI
  • Como melhor faço isso de forma limpa e eficiente? Existe alguma outra tecnologia ou biblioteca que simplifique isso? Não preciso usar o qt se houver algo melhor.
Brandon Yates
fonte
Depende dos requisitos de latência, se houver. Para GUIs simples, você pode usar linguagens de script (Yad / Zenity / GTKdialog / TclTk / ... et cetera et cetera) para criar um protótipo rápido da aparência. Normalmente, você precisa evitar a correspondência 1 para 1 entre a GUI e o código - a idéia é tornar a interface utilizável e intuitiva, não forçar o usuário a aprender os aspectos internos do seu aplicativo.
Deer Hunter
Este artigo objectmentor.com/resources/articles/TheHumbleDialogBox.pdf provavelmente o ajudará - explica "model view apresentador", que é a melhor abordagem que conheço para tornar a interface do usuário intercambiável.
Doc Brown

Respostas:

11

Eu poderia lhe dar algumas orientações básicas sobre como criar a GUI equivalente para um aplicativo CLI, no que diz respeito ao design. Como você realmente faria as chamadas está fora do escopo desta resposta.

  • opções como -p -v etc são caixas de seleção

insira a descrição da imagem aqui

  • opções mutuamente exclusivas são um grupo de botões de opção

insira a descrição da imagem aqui

  • parâmetros que são um nome de arquivo são uma caixa de texto com um botão "escolher" que mostra uma caixa de diálogo para escolher um arquivo quando pressionada

insira a descrição da imagem aqui

  • parâmetros de string em geral são caixas de texto
  • Os parâmetros numéricos podem ser caixas de texto, caixas de combinação ou caixas de rotação, dependendo dos valores conhecidos, sendo restritos em um intervalo ou em formato livre.

insira a descrição da imagem aqui

insira a descrição da imagem aqui

  • usos totalmente divergentes são separados em guias (por exemplo, adicionar a meta-opção "commit" ao git, altera todo o conjunto de opções e parâmetros esperados / permitidos)

insira a descrição da imagem aqui

  • Depois que os parâmetros são inseridos, um botão executa a ação

insira a descrição da imagem aqui

Nota: a validação de entrada deve ser proativa , ou seja, você deve impedir que o usuário execute a ação quando os parâmetros obrigatórios não foram inseridos, esmaecendo o botão executar e, geralmente, esmaecendo ou ativando elementos da GUI para transmitir o uso adequado. Nos aplicativos CLI, o usuário apenas executa o comando e recebe uma mensagem de erro, ou seja, a validação é reativa.

Tulains Córdova
fonte
1
Muito bom conselho. Não é uma resposta por si só, mas um ótimo "como" complementar o outro "o que fazer" respostas.
Bobson
6

Geralmente, isso pode ser resolvido escrevendo um front-end da GUI que cria uma linha de comando . Nesse ponto, você simplesmente chama a antiga função "main ()" da CLI com os argumentos na ordem apropriada.

O que você precisa fazer, depende da saída. Você pode se dar bem ao agrupar todos printf()em uma função variável de saída genérica, que na versão CLI passará o controle para printfenquanto na versão GUI enviar a saída para uma janela de log de rolagem ou algo assim.

Dessa forma, o aplicativo CLI é praticamente inalterado e o front-end da GUI, embora perca em eficiência, permanece pouco acoplado e pode ser mantido de forma independente (em alguns casos, uma maquete - ou mesmo uma alternativa real à GUI - pode ser independente aplicativo que gera o binário da CLI com os argumentos adequados; tipo do que você pode fazer com o AutoIt no Windows, por assim dizer).

Mas isso depende muito do que o aplicativo realmente faz . Essa abordagem ainda pode ser seguida em maior ou menor grau, mas pode se tornar desconfortável se, por exemplo, você desejar executar a rotina da CLI ciclicamente ou algo assim; ou se o programa espera operar com uma entrada de stdin.

LSerni
fonte
Idéia interessante, embora eu realmente não veja a vantagem de criar um argumento de linha de comando em vez de chamar o mesmo método dos dois lugares. Além disso, parece estranho invocar o principal várias vezes ao longo da vida do programa GUI.
jhewlett
1
Se você não fizer isso, corre o risco de a GUI fazer coisas que não são possíveis a partir de uma linha de comando.
Pieter B
1
@ jhewlett, este é reconhecidamente um atalho. main()em si deve ser pouco mais que um front-end de análise de argumentos para o corpo do programa "real". Mas, se esse fosse o caso, considero que adotar sua opção (que é a melhor) teria sido tão direta que não justificaria uma pergunta em primeiro lugar.
LSerni
3

a primeira coisa que você quer fazer é separar o back-end (atrás da CLI atual) do front-end (a CLI)

separe essencialmente a visão / controlador (CLI) do modelo para que todo o código de funcionalidade possa ser separado em seu próprio módulo independente (que você pode compilar em uma biblioteca estática, por exemplo)

então você pode usar a interface C pública desse módulo para codificar contra você na GUI do QT

para a correlação do pressionamento de botão, existe uma implementação extensa de slot de sinal no QT, e o criador do QT lidará com muitas das ligações para você (é tão simples quanto clicar com o botão direito do mouse-> ir para o slot ...-> clicar () - > tipo foo())

catraca arrepiante
fonte
1

Se o seu aplicativo CLI atual usar um formato de entrada e saída razoavelmente estruturado (particularmente a saída. Ele deve ser estruturado o suficiente para ser analisado por uma máquina), você sempre poderá criar um aplicativo GUI separado que se comunique com o aplicativo CLI por meio de pipes e / ou arquivos temporários.

Para integrar a GUI ao aplicativo atual, é necessário poder separar completamente o manuseio de E / S do restante do aplicativo, para que você possa construir a parte sem E / S como uma biblioteca e parafusar uma interface com o usuário ( GUI ou CLI) para isso. Se o aplicativo original nunca foi projetado para isso, pode ser uma tarefa difícil, porque é muito fácil dispersar as printfchamadas por todo o lugar.

O fato de Qt ser C ++ e seu aplicativo estar em C não deve ser um grande obstáculo para um aplicativo integrado, desde que a interface para a parte de back-end esteja escrita no subconjunto comum de C e C ++. Então você só tem a curva de aprendizado do C ++ para superar.

Bart van Ingen Schenau
fonte