Qt5 para comunicação serial – Aplicação

Introdução

No post anterior Comunicação Serial com Arduino e Qt5 Widgets Application – Parte 2, finalizamos a nossa aplicação com Qt5 para comunicação serial com qualquer dispositivo embarcado, que para facilitar o post utilizamos um Arduino UNO.

Agora, avançando um pouco mais, vamos ver como criar ações, usando Qt5 para comunicação serial, para serem enviadas e/ou recebidas via serial e ocorrer eventos como acender/apagar um led, obter informações do microcontrolador e diversas possibilidades que você possa imaginar.

Novamente usarei um Arduino UNO para facilitar a prototipação e focar na aplicação alto nível, mas para o framework estamos usando Qt5 para comunicação serial. Então poderá aplicar o que faremos aqui em um 8051 montado na protoboard como em um ARM Cortex-M, desde que utilize comunicação serial.

Configuração do Host

Neste artigo utilizarei a distribuição Linux Mint 17 Qiana 64 bits, mas não há problemas em realizar o procedimento em um Ubuntu ou outra distribuição suportada pelo Qt5. A seguir são listados os seus pré-requisitos: 

  • Qt5 Instalado com o Qt Creator;

  • IDE Arduino >=1.6.2;

  • Arduino UNO;

  • Plugin Qt Serial.

Criando o projeto

Devemos criar o nosso projeto. Para isso abra o Qt5 e em seguida vá em FileNew File or Project…, na janela a seguir selecione Application e Qt Widgets Application e Choose…. No nome do projeto digite AppGuiArduino, na opção de Kit Selection deixe o padrão selecionado e clique em Next. Na próxima janela Class Information selecione QWidget em Base class e Next, na janela seguinte sobre opções de versionamento pode clicar em Finish.

Ficou confuso? Veja o artigo anterior Comunicação Serial com Arduino e Qt5 Widgets Application – Parte 2 que mostrei como fazer essa parte passo a passo com imagens.

É muito importante ver o artigo anterior porque neste projeto iremos novamente criar a classe comserial e anexar o mesmo código que já utilizamos, pois assim focamos em desenvolver nossa aplicação e a parte de tratar a comunicação serial utilizamos a que já foi feita anteriormente.

Desenhando a tela

Agora a parte divertida do artigo, onde o trabalho é achar os componentes em Widgets e montar a tela usando o Qt Design. No final do artigo anterior eu comentei como seria a aplicação deste post, houve algumas mudanças para trazer mais informações e ser mais didática. Segue na Figura 1 como ficará nossa aplicação com o posicionamento dos Widgets.

Qt5 para comunicacao serial: Posicionamento dos widgets
Figura 1 – Tela inicial apos posicionar os widgets

Agora vem uma etapa que pode agregar muito a aplicação e que muitos desenvolvedores não dão tanta importância. Muitas vezes a preocupação é o background ou o core da aplicação, segurança, estabilidade e outros fatores que ficam no nível mais abaixo, mas o cliente muitas vezes preza por uma aparência agradável ou um melhor layout, de fácil utilização.

E é onde focaremos agora, na “perfumaria” de nossa aplicação, adicionando ícones, colocando atalhos e informações para ajudar o operador.

Os ícones utilizados nesta aplicação foram todos obtidos no site IconsPedia, muitos possuem licenças free mas olhe as informações dos pacotes caso a ideia seja comercializar a aplicação.

No diretório do projeto criei um diretório chamado icons onde estão todos os ícones utilizados, e agora veremos como utilizar estes em nossa aplicação.

Vamos criar uma estrutura em nossa aplicação para anexar estes ícones, para isso deve-se clicar com o botão direito em cima do nome do projeto e clicar em Add New…, em seguida selecionar Qt e logo a frente Qt Resource File, como na Figura 2.

Qt5 para comunicacao serial: CriandoResourceFileQt5
Figura 2 – Criando um Resource File para os icones

Prosseguindo agora no diretório Resources que surgir em nosso projeto, expanda-o, clique com o botão direito em cima de icons.qrc, selecione Add Existing Files… e selecione todos os ícones no diretório icons em nosso projeto. E o projeto ficará como a Figura 3.

Qt5 para comunicacao serial: ResurceFileIconsComplete
Figura 3 – Adicionando os ícones em nossa aplicação

Voltando a tela da aplicação, vamos selecionar o botão Sair e ir até o Property Editor do lado direito do QtCreator. Procure por QAbstractButton e clique na caixa de seleção na opção icon como na Figura 4.

Qt5 para comunicacao serial: QAbstrationButtonSelectionResouce
Figura 4 – Selecionando o ícone em QAbstractButton

Selecione Choose Resource…, na janela que abrir deve-se selecionar icon no lado esquerdo e no lado direito o ícone que deseja usar no botão, como podemos ver na Figura 5.

Qt5 para comunicacao serial: ChooseIconButtonQt5
Figura 5 – Selecionando o ícones para o widget PushButton

Voltando ao QAbstractButton expanda a opção iconSize e mude de 16 x 16 para 32 x 32, na sequência vamos criar um atalho para o botão Sair. Para isso clique em shortcut e pressione a tecla que será o atalho, no caso da aplicação eu pressionei F4 e veja como ficarão as propriedades do nosso botão na Figura 6.

Qt5 para comunicacao serial: QAbstrationButtonShortcut
Figura 6 – Configurando atalho e o tamanho do ícone do widget

Uma opção legal a ser utilizada é adicionar uma mensagem ao posicionar o mouse sobre o botão, por exemplo se o operador parar o cursor em cima de Sair. E se você desejar que apareça a mensagem ‘Sair da aplicação’, procure a propriedade toolTip e insira o texto, como na Figura 7.

Qt5 para comunicacao serial: QAbstrationButtonToolTip
Figura 7 – Adicionando uma descrição ao widget

Pronto, customizamos o widget PushButton do botão Sair, agora pode aplicar o mesmo procedimento nos demais botões, e por fim nossa aplicação ficará como a Figura 8.

Qt5 para comunicacao serial: Qt5ArduinoPosicionamentoIconesTelaFinal
Figura 8 – Design da tela final da nossa aplicação

Código Qt5 para comunicação serial

Chegando nesta etapa sua tela deverá estar pronta, já deverá ter criado a classe comserial com comserial.h e comserial.cpp idêntico ao artigo anterior, e agora iremos apenas criar as ações dos botões para tratar o que será enviado e recebido pela serial.

Recordando que para dar ação a um botão a maneira mais simples sem ter que lidar com Sinais e Slots neste momento é clicar com o botão direito do mouse no botão e selecionar Go to Slot… e em seguida selecionar clicked() e OK.

Segue o código utilizado em widget.h:

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include "comserial.h"

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();

private slots:
    void on_btnAppClose_clicked();
    void WriteData(const QByteArray data);
    QString ReadData();

    void on_btnSetLed_clicked();

    void on_btnDevOpen_clicked();

    void on_btnDevClose_clicked();

    void on_btnGetVersion_clicked();

    void on_btnGetinfoHW_clicked();

    void on_btnHelp_clicked();

    void on_btnAbout_clicked();

    void on_btnBWTerminal_clicked();

    void on_editSendCmd_returnPressed();

private:
    Ui::Widget *ui;

    bool PaletaLogBW;

    QSerialPort *devserial;
    comserial *procSerial;

    void CarregarInfoDispSerial(void);

};

#endif // WIDGET_H

E agora o widget.cpp:

#include "widget.h"
#include "ui_widget.h"
#include <QMessageBox>


Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);

    /* Criando objeto da classe QSerialPort*/
    devserial = new QSerialPort(this);

    /* Criando objeto da classe comserial para manipular leitura/escrita */
    procSerial = new comserial(devserial);

    /* Carrega os dispositivos seriais disponiveis */
    QStringList DispSeriais = procSerial->CarregarDispositivos();

    /* Inseri os Dispositivos no ComboBox */
    ui->cbDevList->addItems(DispSeriais);

    /* Habilita PushButton "Conectar" se encontrou dispositivo seiral.
     * Caso contrario, um erro é reportado no Log
     */
    if(DispSeriais.length() > 0) {
        ui->btnDevOpen->setEnabled(true);
        ui->teLog->append("### Porta serial pronta para ser utilizada.");
    }
    else { ui->teLog->append("### Nenhuma porta serial foi detectada!"); }


    connect(devserial, SIGNAL(readyRead()), this, SLOT(ReadData()));
}

Widget::~Widget()
{
    delete ui;
}

void Widget::on_btnAppClose_clicked()
{
    exit(0);
}

void Widget::WriteData(const QByteArray data)
{
    procSerial->Write(data);
}

QString Widget::ReadData()
{
    QString data = procSerial->Read();
    qDebug() << "RX UART: " << data << endl;
    return data;
}

void Widget::on_btnSetLed_clicked()
{

        QString StatusLed;

        /* PixMap com os icones de Led ON e Led OFF */
        QPixmap LedON(":icons/Light-bulb-on-32.png");
        QPixmap LedOFF(":icons/Light-bulb-off-32.png");

        /* Escrevendo 11 no dispositivo da serial Arduino */
        WriteData("11\n");

        /* Pegando o retorno do comando e armazenando em uma QString */
        StatusLed = ReadData();

        /*
         * Verifico se o que voltou foi ON ou OFF
         * Baseado no retorno:
         *  ON  -> Mudo o icone do botão e escrevo Ligar [F10]
         *  OFF -> Mudo o icone do botão e escrevo Desligar [F10]
         */
        if (strcmp(StatusLed.toUtf8(),"ON")) {
            ui->btnSetLed->setIcon(LedOFF);
            ui->btnSetLed->setText("Ligar [F10]");
            ui->btnSetLed->setShortcut(Qt::Key_F10);
        }
        else {
            ui->btnSetLed->setIcon(LedON);
            ui->btnSetLed->setText("Desligar [F10]");
            ui->btnSetLed->setShortcut(Qt::Key_F10);
        }
}

void Widget::on_btnDevOpen_clicked()
{
    bool statusOpenSerial;

    statusOpenSerial = procSerial->Conectar(ui->cbDevList->currentText(),
                                             ui->cbDevBaudRate->currentText().toInt()

                                            );
    /*
     * Se conectou com sucesso no disposito serial
     *  Desabilito o botão Conectar e Sair
     *  Habilito Desconectar, Versao, Hardware e Ligar [F10]
     */
    if (statusOpenSerial) {
        ui->btnDevClose->setEnabled(true);
        ui->btnDevOpen->setEnabled(false);

        ui->btnGetinfoHW->setEnabled(true);
        ui->btnSetLed->setEnabled(true);
        ui->btnGetVersion->setEnabled(true);

        ui->btnAppClose->setEnabled(false);

        ui->teLog->append("### Porta serial aberta com sucesso!");
    }
    else {
        ui->teLog->append("Falha ao abrir conexão serial.");
    }
}

void Widget::on_btnDevClose_clicked()
{
    bool statusCloseSerial;


    statusCloseSerial = procSerial->Desconectar();

    /*
     * Descontando a porta serial com sucesso
     *  Desabilito os botões Versao, Desconectar, Hardware, Ligar [F10]
     *  Habilito Sair e Conectar
     */
    if (statusCloseSerial) {
        ui->btnDevClose->setEnabled(false);
        ui->btnDevOpen->setEnabled(true);
        ui->btnAppClose->setEnabled(true);

        ui->btnGetinfoHW->setEnabled(false);
        ui->btnGetVersion->setEnabled(false);
        ui->btnSetLed->setEnabled(false);

        ui->teLog->append("### Porta serial fechada com sucesso!");
    }
    else {
        ui->teLog->append("### Falha ao fechar conexão serial.");
    }
}

void Widget::on_btnGetVersion_clicked()
{
    QString GetVersionHw;

    /* Envia o comando 13 para o Arduino */
    WriteData("13\n");

    /* A resposta é armazenada na variavel GetVersionHW */
    GetVersionHw = ReadData();

    /* É removida qualquer tabulação */
    GetVersionHw = GetVersionHw.simplified();

    /* E a saida é anexada a tela de Log de nossa aplicação */
    ui->teLog->append(GetVersionHw);
}

void Widget::on_btnGetinfoHW_clicked()
{
    QString GetInfoHw;
    QStringList InfoHW;

    /* Enviando comando para obter informações do Device */
    WriteData("12\n");

    /* Recebendo as informações */
    GetInfoHw = ReadData();

    /* Confirmando se recebeu os dados */
    if( GetInfoHw.size() > 0 ) {
        GetInfoHw = GetInfoHw.simplified();

        /* Ex: 4.3.2|UNO
         * O que chegou pela serial foi adicionado na variavel GetInfoHW
         * então acima removemos qualquer tabulação e abaixo um split
         * baseado no caractere |, então sera quebrado em 2 posicoes
         * 0 - 4.3.2
         * 1 - UNO
         */
        InfoHW = GetInfoHw.split("|");

        /* Inserindo nos devidos Edits */
        ui->editDevCompiler->setText(InfoHW[0]);
        ui->editDevModel->setText(InfoHW[1]);

    }
    else {
        ui->teLog->append("### Erro ao obter informações do Dispositivo, tente novamente.");
    }

}

void Widget::on_btnHelp_clicked()
{
    /*
     * Usando MessageBox para configurada uma simples mensagem
     * para exibir ao operador ao cliente em Ajuda
     * Neste exemplo usamos o tipo Information para estilo de MessageBox
     */
    QMessageBox msgHelp;
    msgHelp.setWindowTitle("Ajuda");
    msgHelp.setInformativeText("Em desenvolvimento...");
    msgHelp.setIcon(QMessageBox::Information);
    msgHelp.exec();
}

void Widget::on_btnAbout_clicked()
{
    /*
     * Usando MessageBox para configurar uma simples mensagem
     * para exibir ao operador ao clicar em Sobre
     * O legal aqui é o uso de sintaxe HTML para isso!
     */
    QMessageBox msgAbout;
    msgAbout.setWindowTitle("Sobre");
    msgAbout.setTextFormat(Qt::RichText);
    msgAbout.setText(""
                     "<center><strong>Desenvolvido por</strong><br>Cleiton Bueno<br><br>"
                     "Mais em: <a href='https://embarcados.com.br'>Embarcados</a></center><br><br>"
                     "Contato: <a href='mailto:cleitonrbueno@gmail.com'>cleitonrbueno@gmail.com</a>"
                     "");
    msgAbout.exec();
}

void Widget::on_btnBWTerminal_clicked()
{
    QPalette paleta;
    /*
     * Verifica se PaletaBW é True ou False
     * Se True: Fundo Preto, Fonte Branco
     * Se False: Fundo Branco, Fonte Preto
     */

    if(PaletaLogBW) {
        paleta.setColor(QPalette::Base,Qt::black);
        paleta.setColor(QPalette::Text,Qt::white);
        ui->teLog->setPalette(paleta);
        PaletaLogBW=false;
    }
    else {
        paleta.setColor(QPalette::Base,Qt::white);
        paleta.setColor(QPalette::Text,Qt::black);
        ui->teLog->setPalette(paleta);
        PaletaLogBW=true;
    }
}

void Widget::on_editSendCmd_returnPressed()
{
    QByteArray CmdSendUart;

    //ui->teLog->append("> "+ui->editSendCmd->text());
    /* Envia para stdout (Debug) o comando a ser escrito na Serial */
    qDebug() << "TX UART:" << CmdSendUart << endl;

    /*
     * Armazena a string digitada em Comandos em CmdSendUart
     * e remove qualquer tabulação
     */
    CmdSendUart = ui->editSendCmd->text().toLatin1().simplified();

    /*
     *  Escreve na serial o que foi digitado em Comandos
     */
    WriteData(CmdSendUart+"\n");

    /* Limpar o edit do Comandos */
    ui->editSendCmd->clear();

    /*
     *  A resposta é enviada para a tela de Log da aplicação
     */
    ui->teLog->append("Resposta: "+ReadData());
}

Se copiar e colar o código acima irá funcionar, porém você deverá utilizar os nomes corretos para os PushButtons, QLineEdit e demais Widgets. Caso prefira, faça o download de todo o projeto no final do artigo, ou crie seus widgets com os nomes que achar melhor e apenas use os códigos acima.

Os botões Sobre, Sair, Ajuda e Cor Terminal é um bônus do que você pode usar criando estas ações. O foco agora é atacar o Conectar, Desconectar, Versão, Hardware e Ligar|Desligar.

A lógica é até simples, pois para ler e escrever na serial só usamos ReadData() e WriteData(), o resto é logica e estrutura do Qt5.

Código Arduino

Segue abaixo o código utilizado para o firmware do Arduino UNO, não comentarei muito aqui sobre o mesmo pois inseri bastante comentários nos principais pontos. Mas um resumo é que estou usando o Led que posso interagir com o pino 13, e enviando pela serial o comando ‘11‘ (Acender/Apagar Led), ‘12‘ (obter informações do microcontrolador) e ‘13‘ (a versão configurada no meu firmware).

Usaremos uma simples Máquina de Estado. Para mais informações sobre Máquina de Estado, confira o excelente artigo Máquina de Estado, do Pedro Betoleti.

/*
 * Defines
 */
#define LED_ONBOARD 13
#define FW_VERSION "1.0"

/*
 * Globais
 */
unsigned char FLAG_CONTROL_RX_UART_DATA = 0; 
const unsigned int SIZE_BUF_RX = 10;

/* 
 * Estruturas
 */
typedef enum States{
  NONE='10',    //10
  CALL_LED,     //11
  CALL_INFO,    //12
  CALL_VERSION  //13
};

/*
 * Prototipos das funcoes
 */
void ProcToggleLed(int);
void ProcInfo();
void ProcVersion();
void ProcStatesUARTRx(char *buffRx);
void CheckUARTRx(char *bufRx);


/*
 * Funcoes
 */
void ProcInfo()
{ 
  
  /* Retorna o versao do GCC utilizado para compilar */
  Serial.write(__VERSION__);
  Serial.write('|');

  
  /* Retorna o Modelo do Arduino */
  #if defined(__AVR_ATmega168__)
    Serial.write("DIECIMILA");
  #endif 
  #if defined(__AVR_ATmega328P__)
    Serial.write("UNO");
  #endif
  #if defined(__AVR_ATmega2560__) || defined(__AVR_ATmega1280__)
    Serial.write("MEGA");
  #endif
  #if defined(__AVR_ATmega32U4__)
    Serial.write("LEONARDO");
  #endif
  #if defined(__SAM3X8E__)
    Serial.write("DUE");
  #endif

  Serial.flush();
}


void ProcVersion()
{
  /* Retorna a versao atual deste Firmware */
  Serial.write(FW_VERSION);  
  Serial.flush();
}


void ProcToggleLed(int)
{
  /* Pegando o status atual do Led (Pino 13) */
  volatile int led_status = digitalRead(LED_ONBOARD);
  
  /* Enviando o outro estado para o Pino */
  digitalWrite(LED_ONBOARD, !led_status);
  
  /* Enviando na serial se o Led esta aceso ou apagado */
  if(!led_status) { Serial.write("ON"); }
  else { Serial.write("OFF"); }
  
  Serial.flush();
}


void ProcStatesUARTRx(char *buffRx)
{
  /* Flag para sinalizar quando tem dados no Buffer RX */
  if(FLAG_CONTROL_RX_UART_DATA) {
   
    /* Ira continuar apenas se o primeiro caractere
        for 1 sendo do range do nosso States
    */
    if (buffRx[0] != '1') return;
    
    /* 
       Neste caso me interessa apenas o segundo 
       caractere do Buffer, ele seria o ID para 
       meus States
    */
    switch(buffRx[1]) {
      case NONE:
        break;
      case CALL_LED:
        ProcToggleLed(LED_ONBOARD);
        break;
      case CALL_INFO:
        ProcInfo();
        break;
      case CALL_VERSION:
        ProcVersion();
        break;
      default:
        break;
    }
    FLAG_CONTROL_RX_UART_DATA=0;
  }  
}


void CheckUARTRx(char *buffRx)
{
  static unsigned int pos_buf_rx = 0;
  /* Caso tenha algo na serial, ira tratar e/ou guardar no buffer */
  if( Serial.available()>0 ) {
    const byte RxDataUart = Serial.read();
    
    switch (RxDataUart) {
      case '\n':
        /* Inseri terminador no final do buffer */
        buffRx[pos_buf_rx] = 0;
      
        /* Sinaliza que o Buffer esta pronto */
        FLAG_CONTROL_RX_UART_DATA=1;
      
        /* Reseta o valor de indice para o Buffer de Recepção */
        pos_buf_rx = 0;  
        break;
      case '\r':
        /* Ignora Carriage Return ou pode colocar junto ao /n */
        break;
      default:
        /* Inseri no buffer se ainda nao encher */
        if (pos_buf_rx < (SIZE_BUF_RX - 1))
          buffRx[pos_buf_rx++] = RxDataUart;
        break;
      }
      
      Serial.flush();
  }
}


/* Inicializando e configurando os perifericos usados */
void setup() {
  
  /* Inicialização Serial 115200 bps */
  Serial.begin(115200,SERIAL_8N1);
  
  /* Inicialização do Led OUTPUT */
  pinMode(LED_ONBOARD, OUTPUT);
}


/* Loop Principal Infinito */
void loop() {
  
  /* Buffer para recepção dos dados vindos da Serial */
  static char RxBuffer[SIZE_BUF_RX];
  
  /*
    Rotina para verificar se tem algo para receber na serial
    e como parametro envia o buffer para RX
   */
  CheckUARTRx(RxBuffer);
  
  /*
    Rotina para processar o que chegou pela serial
   */
  ProcStatesUARTRx(RxBuffer);

}

Executando a aplicação no Linux

Resumidamente, a função da nossa aplicação é, se tiver porta serial no computador, listar em Portas e libera o botão Conectar. Caso contrario, não libera o botão e exibe uma mensagem que não encontrou portas seriais.

Conectando a porta serial, os botões são liberados e podemos executar as três ações Versão, Hardware e Ligar/Desligar, o legal que ligar e desligar o led é com o mesmo botão e o ícone do mesmo irá mudar conforme o status do led.

Em Comandos o que for digitado e a seguir pressionado ENTER é enviado ao dispositivo serial. No nosso caso podemos testar com 11, 12 e 13.

Vamos testar a aplicação e ver os resultados nas Figuras 9 e 10.

Qt5 para comunicacao serial: Qt5AplicaçãoFinalComunicandoArduino
Figura 9 – Testando a aplicação Qt5 com Arduino
Qt5 para comunicacao serial: Qt5AplicaçãoFinalCOmunicandoArduinoeComandos
Figura 10 – Aplicação Qt5 com Arduino e enviando comandos

Todo o código-fonte utilizado na aplicação e o firmware do Arduino podem ser baixados no link abaixo. Contém todo o projeto para compilar e executar, fazer as suas modificações e adaptações para uso.

[wpdm_asset id=’17’]

Saiba mais

– Comunicação serial com Arduino utilizando Qt5 Console Application

– Comunicação serial com Arduino e Qt5 Widgets Application – Parte 1

– Comunicação serial com Arduino e Qt5 Widgets Application – Parte 2

Referências

– Máquina de estado

– https://www.iconspedia.com/

– https://doc.qt.io/qt-5/qserialport.html

– https://doc.qt.io/qt-5/qlineedit.html

– https://doc.qt.io/qt-5/qpixmap.html

– https://doc.qt.io/qt-5/resources.html

– https://doc.qt.io/qt-5/qabstractbutton.html

Licença Creative Commons Esta obra está licenciada com uma Licença Creative Commons Atribuição-CompartilhaIgual 4.0 Internacional.
Comentários:
Notificações
Notificar
8 Comentários
recentes
antigos mais votados
Inline Feedbacks
View all comments
Pedro Filho
Pedro Filho
20/08/2015 19:13

Excelente Tutorial, muito bacana mesmo trabalhar com o Qt, eu que nunca tinha visto antes, começei a tentar algumas coisas aqui depois do primeiro tutorial, vi que tudo é muito simples mesmo.

Espero que esse não seja o último da série 🙂

Cleiton Bueno
Cleiton Bueno
Reply to  Pedro Filho
21/08/2015 08:54

Olá Pedro, fico feliz que tenha gostado desta série.
Tenho uma noticia boa e uma ruim, a ruim é que acabou esta serie de comunicação serial e a boa é que outros artigos com outros temas viram usando Qt5 😉

Abraço!

Caio Pereira
Caio Pereira
14/08/2015 10:35

Belo Artigo Cleiton, Antes de alguém pensar em fazer em Java, dê uma olhada neste artigo que ficou muito bom! Aliás, em java, o trabalho será muito maior!

Cleiton Bueno
Cleiton Bueno
Reply to  Caio Pereira
14/08/2015 11:09

Olá Caio!
Fico feliz que tenha gostado, realmente Qt esta ganhando muita força em termos de desenvolver aplicações gráficas multiplataforma.
E o elenco da ferramenta é forte, mais artigos com Qt estão por vir.

Abraço

( André Tenório )
( André Tenório )
13/08/2015 14:49

Sem comentários, muto bom mesmo! Aguardamos mais! 🙂

Cleiton Bueno
Cleiton Bueno
Reply to  ( André Tenório )
13/08/2015 21:06

Bacana que gostou André, e realmente vem mais por ae 🙂

Abraão Allysson Dos Santos
Abraão Allysson Dos Santos
13/08/2015 12:16

Excelente tutorial!

Cleiton Bueno
Cleiton Bueno
Reply to  Abraão Allysson Dos Santos
13/08/2015 12:55

Olá Abraão!

Legal que gostou do post, e muita coisa legal esta por vir utilizando Qt.

Abraço.

Home » Software » Sistemas Operacionais » Qt5 para comunicação serial – Aplicação

EM DESTAQUE

WEBINARS

VEJA TAMBÉM

JUNTE-SE HOJE À COMUNIDADE EMBARCADOS

Talvez você goste: