天天看點

Qt之序列槽案例

Qt之序列槽案例

    • 概述:
    • 代碼示例:
      • .pro
      • .h
      • .cpp
    • 運作效果圖:
    • over:
    • 文末一句話:

概述:

1. 今天跟大家分享下Qt的序列槽使用,本案例是之前配合公司項目調試自己編寫的小軟體

2. Qt使用視窗的一些函數這裡就不該大家一一介紹,函數作用直接會在代碼的注釋說明

3. 大家忽略我的注釋格式,當時項目測試着急,是以簡單注釋了下

4. 如果大家想知道序列槽的通信方式以及連線方式可以參考我前面的文章

5. 本案例資料模式是ACELL格式,本案例帶有收發資料記錄存儲功能

6. 本案例序列槽的一寫基本配置寫死了,大家可以根據界面判斷進行設定相關資料

代碼示例:

.pro

#-------------------------------------------------
#
# Project created by QtCreator 2019-08-01T12:20:47
#
#-------------------------------------------------
#	這裡要把序列槽庫添加上 serialport
QT       += core gui serialport

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = Seri
TEMPLATE = app


SOURCES += main.cpp\
        Seri.cpp

HEADERS  += Seri.h

FORMS    += Seri.ui

DISTFILES +=

RESOURCES += \
    image.qrc

           

.h

#ifndef SERI_H
#define SERI_H

#include <QWidget>
#include <QWidget>
#include <QDebug>
#include <QFile>
#include <QFileDialog>
#include <QtSerialPort/qserialport.h>
#include <QtSerialPort/qserialportinfo.h>

namespace Ui {
class Seri;
}

class Seri : public QWidget
{
    Q_OBJECT

public:
    explicit Seri(QWidget *parent = 0);
    ~Seri();
private:
    inline void myDebugCall();                                      //自調用解析函數
    inline void mySend(const char* sendData,const QString text);    //自調用發送函數
    inline void myState();                                          //自調用對狀态燈重新整理

signals:
    SIGNAL_recv(QByteArray arry);	//接收資料通過信号将資料發送出去
private slots:
    void on_Open_clicked();         //打開序列槽
    void recv_Com();                //序列槽來消息響應槽
    void recvAnaly();               //接收立即處理信号槽--信号可以當槽使用--同樣也可以emit--哈哈--奇葩吧
    void on_Write_clicked();        //發送資料
    void on_btnA_save_clicked();    //儲存接收資料按鈕
    void on_btnB_save_clicked();    //儲存發送資料按鈕
    void on_btn_close_clicked();    //關閉序列槽按鈕
    void on_pushButton_clicked();   //清空顯示區
private:
    QSerialPort* m_serial;          //序列槽
    QByteArray str;                 //私有存儲接收資料成員變量
    bool click;                     //判斷打開序列槽按鈕是否被點選
private:
    Ui::Seri *ui;
};

#endif // SERI_H
           

.cpp

#include "Seri.h"
#include "ui_Seri.h"


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

    m_serial = new QSerialPort(this);                                           //建立序列槽 QSerialPort() 括号中可以設定參數 序列槽名... 待研究完善

    foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts())     //周遊擷取目前可使用序列槽設定到comboBoxSeri控件上
    {
        if(ui->comboBoxSeri->currentText() != info.description())
        {
            ui->comboBoxSeri->addItem(info.portName());							//将本機可以使用序列槽名加載到界面
        }
    }
    connect(m_serial,SIGNAL(readyRead()),SLOT(recv_Com()));                     //接到序列槽資料響應

    ui->label_State->setProperty("state","No");                                 //狀态燈初始為紅色 沒有打開
    
    this->click = false;

}

Seri::~Seri()
{
    delete ui;
}
/*
 * 自調用資料解析列印
 */
void Seri::myDebugCall()
{
    for (int i = 0;i < str.size();i++)
    {
        qDebug() << str.at(i);
    }
}

/*
 * 統一資料發送函數
 */
void Seri::mySend(const char *sendData, const QString text)
{
    m_serial->write(sendData);
    QString str = sendData + text;
    ui->sendtextEdit->append(str);
    ui->sendtextEdit->append("|---------------------------------------------------------|");
}
/*
 *重新整理狀态燈
 */
void Seri::myState()
{
    style()->unpolish(ui->label_State);
    style()->polish(ui->label_State);
    update();
}

/*
 * 打開序列槽按鈕
 */
void Seri::on_Open_clicked()
{
    m_serial->setPortName(ui->comboBoxSeri->currentText());
    if(m_serial->open(QIODevice::ReadWrite) == true) { ui->label_State->setProperty("state","Ok");  click = true;/*判斷打開序列槽是否打開成功*/ }
    else{ui->label_State->setProperty("state","No");}
    m_serial->setBaudRate(QSerialPort::Baud9600,QSerialPort::AllDirections);    //設定波特率和讀寫方向
    m_serial->setDataBits(QSerialPort::Data8);                                  //設定資料位8
    m_serial->setParity(QSerialPort::OddParity);                                //校驗位
    m_serial->setStopBits(QSerialPort::OneStop);                                //一位停止位
    m_serial->setFlowControl(QSerialPort::NoFlowControl);                       //無流控制--好像并沒有什麼用

    myState();                                                                  //重新整理狀态燈 此控制後期要加到序列槽是否打開成功邏輯中
}

/*
 * 接受資料槽 并在界面上顯示内容
 */
void Seri::recv_Com()
{
    QByteArray temp = m_serial->readAll();            //在緩沖區讀取資料--此處應該循環擷取資料 直到\n為止
    if(!temp.isEmpty())                               //如果讀到資料不為空
    {
        ui->recvBrowser->append(QString(temp));       //把接到的資料現在界面顯示後在進行邏輯處理
    }
    this->str = temp;                                 //把收到的資料利用成員函數進行存儲友善後面解析
    temp.clear();                                     //接到資料進行存儲後進行清空操作
    emit recvAnaly();                                 //發出信号 有新資料到來 響應recvAnaly()進行解析
}
/*
 * 發送資料按鈕
 */
void Seri::on_Write_clicked()
{
    m_serial->write(ui->sendtextEdit->toPlainText().toLatin1());
    ui->sendtextEdit->clear();                                                  //發送後直接清空顯示區

    QByteArray temp = m_serial->readAll();
    ui->sendtextEdit->setText(temp);

}

/*
 * 通過recv_Com(槽)接收到資料發出信号進行邏輯分發處理
 */
void Seri::recvAnaly()
{
    myDebugCall();
    //此處進行資料解析
}

/*
 * 儲存記錄的收發資料按鈕
 */
void Seri::on_btnA_save_clicked()
{
    QString textFile = QFileDialog::getSaveFileName(this,tr("Save txt"),"",tr("text (*.txt)"));
    QFile file(textFile);
    if(!file.open(QFile::WriteOnly | QFile::Text)) return;
    QTextStream out(&file);     //分行寫入檔案
    out << ui->recvBrowser->toPlainText();
}

/*
 * 關閉序列槽按鈕
 */
void Seri::on_btn_close_clicked()
{
    m_serial->close();
    m_time->stop();
    ui->label_State->setProperty("state","No");
    myState();
}

/*
 * 儲存資料發送按鈕
 */
void Seri::on_btnB_save_clicked()
{
    QString textFile = QFileDialog::getSaveFileName(this,tr("Save txt"),"",tr("text (*.txt)"));
    QFile file(textFile);
    if(!file.open(QFile::WriteOnly | QFile::Text)) return;
    QTextStream out(&file);   //分行寫入檔案
    out << ui->sendtextEdit->toPlainText();
}

/*
 * 清空顯示區按鈕
 */
void Seri::on_pushButton_clicked()
{
    ui->recvBrowser->clear();
    ui->sendtextEdit->clear();
}

           

運作效果圖:

Qt之序列槽案例

over:

歡迎大家關注作者在文末評論、點贊、轉發以及批評指正!

如果大家有更好的方法或有問題可以在文末評論一起讨論!

共同學習!

共同進步!

文末一句話:

一晃來北京4個年頭了,從機械到銷售再到一個程式猿,在這一路感謝家人的鼓勵和支援,也感謝這些年自己的堅持和一顆敢幻想的心,最後再補充一句:你自己要是想要幹什麼确定好,接下來就沿着這個目标堅持不懈的努力下去,幹就完了!

繼續閱讀