国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

QT基于TCP協(xié)議實現(xiàn)數(shù)據(jù)傳輸以及波形繪制——安卓APP及Windows程序雙版本

這篇具有很好參考價值的文章主要介紹了QT基于TCP協(xié)議實現(xiàn)數(shù)據(jù)傳輸以及波形繪制——安卓APP及Windows程序雙版本。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

文章代碼有非常非常之詳細的解析?。。≈T位可放心食用

這個玩意我做了兩個,一個是安卓app,一個是Windows程序。代碼并非全部都是由我從無到有實現(xiàn),只是實現(xiàn)了我想要的功能。多虧了巨人的肩膀,開源萬歲?。?!

我把程序放到GitHub上,需要的可自取。

安卓app:? ?maihelo/Android-WIFI (github.com)

windows程序:maihelo/Windows_tcp (github.com)?

(上面暫且為空,過兩天把代碼整理好就發(fā)上來)

下面我分別對安卓app版本和Windows程序版本進行簡要技術(shù)整理

安卓app:

首先需要對安卓環(huán)境進行配置,這個不同的QT版本對應(yīng)不同的SDK,NDK那些玩意,在這里不做詳細解析。

配置環(huán)境完成以后就可以使用工程了,燒入手機以后呈現(xiàn)出來的效果是這樣的。

QT基于TCP協(xié)議實現(xiàn)數(shù)據(jù)傳輸以及波形繪制——安卓APP及Windows程序雙版本,QT,qt,開發(fā)語言

?整個工程的框架是:

1、ui頁面繪制

ui頁面有兩個

QT基于TCP協(xié)議實現(xiàn)數(shù)據(jù)傳輸以及波形繪制——安卓APP及Windows程序雙版本,QT,qt,開發(fā)語言

還有一個就是上面的效果圖

主要是一些PushButton、Lable、CharView控件

2、控件槽函數(shù)的設(shè)計

2.1、第二張圖的“全國大學(xué)生電子設(shè)計大賽上位機”的PushButton

void Widget2::on_MenuBt1_clicked()
{
    if(Widget::flag == 0)//通過判斷靜態(tài)成員變量flag來判斷是否創(chuàng)建了Widget
    {
        Widget *first = new Widget;//創(chuàng)建一個新的 Widget
        first->setGeometry(this->geometry());返回當(dāng)前 Widget2 對象的位置和大小信息,用于Widget的呈現(xiàn)
        first->show();//將新創(chuàng)建的 Widget 對象顯示在屏幕上
    }
    this->close();//關(guān)閉Widget2
}

這段代碼的功能就是按下按鈕以后,創(chuàng)建一個Widget并關(guān)閉Widget2,實現(xiàn)簡單的跳轉(zhuǎn)功能。

2.2、按下開啟服務(wù)器按鈕之后的槽函數(shù)

void Widget::on_pushButton_Open_clicked()
{
    if(net_flag == 0)//檢查是否連接網(wǎng)絡(luò)
    {
        if(ui->lineEdit_IP->currentText() != "")//如果IP地址欄不為空
        {
            QString str = ui->lineEdit_IP->currentText();//收集當(dāng)前IP地址欄的IP地址
            if(isIpAddr(str))//判斷IP地址是否有效
            {
                address.setAddress(str);//設(shè)置收集的IP地址為當(dāng)前IP地址
                if(ui->lineEdit_Port->text() != "")//判斷端口欄是否為空
                {
                    port = ui->lineEdit_Port->text().toUInt();//設(shè)置當(dāng)前端口欄的數(shù)字為端口號,并且轉(zhuǎn)為uint16_t格式
                    net_flag = 1;//網(wǎng)絡(luò)連接標(biāo)志
                    tcpServer->listen(address,port);//傳入IP地址和端口號開始監(jiān)聽
                    connect(tcpServer,SIGNAL(newConnection()),this,SLOT(TCPnewconnect_slot()));//當(dāng)連接成功后,將 newConnection 信號連接到 this(即 Widget 對象)的 TCPnewconnect_slot() 槽函數(shù)
                    ui->label_show->setText("正在連接...");//ui頁面上的label_show發(fā)送字符串"正在連接..."
                }
                else//與上面對應(yīng),如果端口欄為空
                {
                    QMessageBox::warning(NULL, QStringLiteral("警告"), QStringLiteral("端口號不能為空"),QMessageBox::Ok | QMessageBox::Ok);
                }
            }
            else//與上面對應(yīng),如果IP地址無效
            {
                QMessageBox::warning(NULL, QStringLiteral("警告"), QStringLiteral("IP不合法"),QMessageBox::Ok | QMessageBox::Ok);//彈窗警告
            }
        }
        else//與上面對應(yīng),如果為IP地址欄為空
        {
            QMessageBox::warning(NULL, QStringLiteral("警告"), QStringLiteral("IP不能為空"),QMessageBox::Ok | QMessageBox::Ok);//彈窗警告
        }
    }
}

這個槽函數(shù)的作用是:根據(jù)IP地址欄和端口號欄的輸入信息,判斷是否有效以后,根據(jù)提供的IP地址和端口號開啟監(jiān)聽,并通過connect函數(shù)開啟一個TCP server,如果連接客戶端成功則轉(zhuǎn)到另外一個槽函數(shù)TCPnewconnect_slot(),并且輸出“連接成功”的信息。

TCPnewconnect_slot():
void Widget::TCPnewconnect_slot()
{
    tcpSocket = tcpServer->nextPendingConnection();//獲取新的客戶端連接,并將返回的 QTcpSocket 對象賦值給 tcpSocket 成員變量
    connect(tcpSocket,SIGNAL(readyRead()),this,SLOT(TCPreadyread_slot()));//當(dāng)有TcpSocket的readyRead()信號,也就是客戶端有數(shù)據(jù)發(fā)送上來的時候,連接當(dāng)前Wiget的槽函數(shù)TCPreadyread_slot()
    ui->label_show->setText("網(wǎng)絡(luò)已連接");//標(biāo)簽顯示
}

這個槽函數(shù)收到客戶端發(fā)送的數(shù)據(jù)以后,再跳轉(zhuǎn)到TCPreadyread_slot()槽函數(shù),這個槽函數(shù)是數(shù)據(jù)處理這塊的,我到第四大點的時候再詳細講。

2.3、按下關(guān)閉服務(wù)器按鈕以后的槽函數(shù)

void Widget::on_pushButton_Close_clicked()
{
    if(net_flag == 1)//判斷網(wǎng)絡(luò)是否連接,如果是,往下
    {
        tcpSocket->close();//關(guān)閉tcpSocket,斷開與當(dāng)前客戶端的連接
        tcpServer->close();//關(guān)閉tcpServer,停止監(jiān)聽新的客戶端連接
        disconnect(tcpServer,SIGNAL(newConnection()),this,SLOT(TCPnewconnect_slot()));//將tcpServer的newConnection()信號與槽函數(shù)TCPnewconnect_slot()斷開連接
        disconnect(tcpSocket,SIGNAL(readyRead()),this,SLOT(TCPreadyread_slot()));//將tcpSocket的readyRead()信號與槽函數(shù)TCPreadyread_slot()斷開連接
        net_flag = 0;//將flag置為0,表示網(wǎng)絡(luò)斷開
    }
     ui->label_show->setText("連接已關(guān)閉");//輸出標(biāo)簽信息
}

這個槽函數(shù)是斷開對客戶端的監(jiān)聽和連接,斷開各種信號與相應(yīng)槽函數(shù)的連接,關(guān)閉服務(wù)器。

3.4、按下掃描按鍵以后的槽函數(shù)

void Widget::on_Scan_clicked()
{
    ui->lineEdit_IP->clear();//IP地址欄全部清空
    QList<QString> strIpAddress;
    QList<QHostAddress> ipAddressesList = QNetworkInterface::allAddresses();//獲取主機所有IP地址并存放在ipAddressesList這個列表里
    // 獲取第一個本主機的IPv4地址
    int nListSize = ipAddressesList.size();
    for (int i = 0; i < nListSize; ++i)
    {
           if (ipAddressesList.at(i) != QHostAddress::LocalHost &&ipAddressesList.at(i).toIPv4Address())//排除主機IP地址,并且保證IP地址是IPV4格式
           {
               strIpAddress.append(ipAddressesList.at(i).toString());//將滿足條件的IP地址放入strIpAddress里面
              // break;
           }
     }
     // 如果沒有找到,則以本地IP地址為IP
     if (strIpAddress.isEmpty())strIpAddress.append(QHostAddress(QHostAddress::LocalHost).toString());
     ui->lineEdit_IP->addItems(strIpAddress);//把IP地址顯示到IP地址欄

}

這個槽函數(shù)是用于查找設(shè)備當(dāng)中的IP地址,并且將它顯示到IP地址欄。

3、繪圖板塊的設(shè)計

    //設(shè)置坐標(biāo)軸
    chart2->addSeries(line2);// 添加數(shù)據(jù)線 line2 到圖表 chart2 中
    chart2->setTheme(QChart::ChartThemeQt);//設(shè)置圖表 chart2 的主題為 Qt 默認(rèn)的主題


    line2->setName("時域波形");//數(shù)據(jù)線名稱

    line2->setColor(Qt::red);//數(shù)據(jù)線的顏色

//創(chuàng)建兩個 QValueAxis 對象 axisX2 和 axisY2,用于設(shè)置 X 軸和 Y 軸的顯示樣式和屬性
    QValueAxis *axisX2 = new QValueAxis;
    QValueAxis *axisY2 = new QValueAxis;



    axisX2->setLabelFormat("%.0f");//顯示格式為 "%.0f",即只顯示整數(shù)部分
    axisX2->setLabelsAngle(45);//標(biāo)簽角度為 45 度(x軸或者y軸的刻度標(biāo)簽)
    axisX2->setLabelsColor(Qt::blue);//標(biāo)簽顏色
    axisY2->setLabelFormat("%.0f");
    axisY2->setLabelsAngle(45);
    axisY2->setLabelsColor(Qt::blue);


    axisX2->setRange(0,200);//x軸的范圍
    axisY2->setRange(0,255);//y軸的范圍
    axisX2->setGridLineVisible(true);//設(shè)置網(wǎng)格線是否可見
    axisX2->setGridLineColor(Qt::black);//網(wǎng)格線的顏色
    axisX2->setMinorTickCount(1);//精度設(shè)置為1
    axisX2->setMinorGridLineColor(Qt::black);//設(shè)置小網(wǎng)格為黑色
    axisX2->setMinorGridLineVisible(true);//設(shè)置小網(wǎng)格可見
    axisX2->setLabelsVisible(false); //設(shè)置刻度是否顯示
    axisY2->setGridLineVisible(true);
    axisY2->setGridLineColor(Qt::black);
    axisY2->setMinorTickCount(1);
    axisY2->setMinorGridLineColor(Qt::black);
    axisY2->setMinorGridLineVisible(true);
    axisY2->setLabelsVisible(false); //設(shè)置刻度是否顯示


    //將 X 軸和 Y 軸添加到圖表 chart2 中
    chart2->addAxis(axisX2,Qt::AlignBottom);
    chart2->addAxis(axisY2,Qt::AlignLeft);
    chart2->layout()->setContentsMargins(0, 0, 0, 0);//設(shè)置外邊界全部為0
    chart2->setMargins(QMargins(0, 0, 0, 0));//設(shè)置內(nèi)邊界全部為0
    chart2->setBackgroundRoundness(0);//設(shè)置背景區(qū)域無圓角



    line2->attachAxis(axisX2);//將數(shù)據(jù)線 line2 附加到 X 軸 axisX2
    line2->attachAxis(axisY2);//將數(shù)據(jù)線 line2 附加到 Y 軸 axisY2


    ui->widget_2->setChart(chart2);//顯示圖表 chart2

4、數(shù)據(jù)處理板塊設(shè)計

根據(jù)第二大點所遺留下來的問題,TCPnewconnect_slot()槽函數(shù)收到客戶端發(fā)送的數(shù)據(jù)以后,再跳轉(zhuǎn)到TCPreadyread_slot()槽函數(shù)。數(shù)據(jù)處理就在TCPreadyread_slot()里面進行。


extern uint8_t  cmd_buffer[A_CMD_MAX_SIZE];
static uint16_t  size = 0;
void Widget::TCPreadyread_slot()
{

    uint16_t  size = 0;

    //定義兩個數(shù)組
    QByteArray temp1;
    QByteArray temp2;
    int iterationCount = 0; // 用于計數(shù)循環(huán)迭代次數(shù)

    do {
        temp2 = temp1;//先將temp1中的數(shù)傳遞給temp2
        temp1 = tcpSocket->readAll();//temp1讀客戶端發(fā)送的數(shù)據(jù)
        iterationCount++;//次數(shù)加一

        qDebug() << "Iteration:" << iterationCount;打印次數(shù)
        qDebug() << "Data read in this iteration:" << temp2;//打印temp2里面的值

    } while (!temp1.isEmpty());//當(dāng)temp1里面沒有數(shù)據(jù)時,退出循環(huán)

        qDebug() << "temp2 len is:" << temp2.length();//打印數(shù)據(jù)的長度


        // 將QByteArray轉(zhuǎn)換為QString
        QString dataStr = QString::fromUtf8(temp2);//把數(shù)組里面的數(shù)據(jù)轉(zhuǎn)化為字符串

        // 使用split函數(shù)按逗號拆分字符串,得到QStringList
        QStringList strList = dataStr.split(',');

        // 創(chuàng)建一個整型數(shù)組,用于存儲拆分后的數(shù)字
        QList<int> dataArray;

        // 遍歷QStringList,將每個字符串轉(zhuǎn)換為整數(shù)并存儲到dataArray中
        //注意這里和C語言的用法不太一樣,它的初始化部分和執(zhí)行條件以及迭代部分會自動檢測更新
        for (const QString& str : strList) {
            bool ok;//布爾變量??,用于存儲ture和false兩個值
            int number = str.toInt(&ok);//如果成功,則布爾變量返回ture,并且把值存放在number中,否則布爾變量為false
            if (ok) {//如果布爾變量為ture
                dataArray.append(number);//將number里面的值放入dataArray數(shù)組里面
            }
        }

        // 輸出拆分后的整數(shù)數(shù)組
        for (int number : dataArray) {//輸出dataArray里面的數(shù)
            qDebug() << number;
        }


        qDebug() << "dataArray len is:" << dataArray.length();//長度


    for(int i = 0;i<dataArray.length();i++)
    {
        A_queue_push(dataArray[i]);                            //添加指令里面的數(shù)據(jù)
        size = A_queue_find_cmd(cmd_buffer,A_CMD_MAX_SIZE);    //從緩沖區(qū)中獲取一條指令 ,這里會有個返回值size,如果size=0,代表沒有一條完整的指令,自然葉無法進入指令處理函數(shù)里面去(一條完整的指令包括幀頭和幀尾以及數(shù)據(jù)體)                                               
       


        if(size>0)                                              //接收到指令
        {
            qDebug() << "Contents of cmd_buffer:";
            for (uint16_t i = 0; i < size; i++) {
                qDebug() << static_cast<int>(cmd_buffer[i]);
            }
            qDebug() << "size:" << size;


            A_ProcessMessage(cmd_buffer, size,ui);                             //指令處理
        }
    }


}

經(jīng)過上面的分析我們知道,數(shù)據(jù)處理主要是對指令的處理。而指令處理主要包括以下三個函數(shù)

A_queue_push(dataArray[i]);
A_queue_find_cmd(cmd_buffer,A_CMD_MAX_SIZE); 
A_ProcessMessage(cmd_buffer, size,ui); 

下面逐個來分析:

A_queue_push(dataArray[i]);

#define A_CMD_HEAD 0XEE                                                  //幀頭
#define A_CMD_TAIL 0xFFFCFFFF                                           //幀尾(這里需要注意以下,不是一個數(shù)喔,不然數(shù)據(jù)溢出沒法判斷是不是幀尾咯)

typedef struct A_QUEUE
{
    uint16_t _head;                                                       //隊列頭
    uint16_t _tail;                                                       //隊列尾
    uint8_t _data[A_QUEUE_MAX_SIZE];                                       //隊列數(shù)據(jù)緩存區(qū)
} A_QUEUE;

static A_QUEUE A_que = {0,0,0};                                            //指令隊列
static uint32_t A_cmd_state = 0;                                           //隊列幀尾檢測狀態(tài)
static uint16_t A_cmd_pos = 0;                                              //當(dāng)前指令指針位置

/*!
*  \brief  清空指令數(shù)據(jù)
*/
void A_queue_reset()
{
    A_que._head = A_que._tail = 0;
    A_cmd_pos = A_cmd_state = 0;
}
/*!
* \brief  添加指令數(shù)據(jù)
* \detial 串口接收的數(shù)據(jù),通過此函數(shù)放入指令隊列
*  \param  _data 指令數(shù)據(jù)
*/
void A_queue_push(uint32_t _data)
{
    uint16_t pos = (A_que._head+1)%A_QUEUE_MAX_SIZE; //每來一個數(shù)據(jù)隊列頭就會+1
    if(pos!=A_que._tail)                                                //非滿狀態(tài)
    {
        A_que._data[A_que._head] = _data;        //數(shù)據(jù)依次進入依次存放在隊列里面
        A_que._head = pos;                       //隊列頭每來一個數(shù)據(jù)+1的基礎(chǔ)

        // 添加調(diào)試信息
       qDebug() << "A_queue_push: Data added to queue:" << static_cast<int>(_data);
       qDebug() << "A_queue_push: Queue head:" << A_que._head << "Queue tail:" << A_que._tail;
    }

}

A_queue_push(dataArray[i]);的作用是在dataArray數(shù)組遍歷的條件下,將數(shù)組里面的數(shù)據(jù)依次放入隊列中。

A_queue_find_cmd(cmd_buffer,A_CMD_MAX_SIZE);

//從隊列中取一個數(shù)據(jù)
static void queue_pop(uint8_t* _data)
{
    if(A_que._tail!=A_que._head)                                          //非空狀態(tài)
    {
        
        *_data = A_que._data[A_que._tail];
        A_que._tail = (A_que._tail+1)%A_QUEUE_MAX_SIZE;
    }
}

//獲取隊列中有效數(shù)據(jù)個數(shù)
uint16_t A_queue_size()
{
    return ((A_que._head+A_QUEUE_MAX_SIZE-A_que._tail)%A_QUEUE_MAX_SIZE);
}
/*!
*  \brief  從指令隊列中取出一條完整的指令
*  \param  cmd 指令接收緩存區(qū)
*  \param  buf_len 指令接收緩存區(qū)大小
*  \return  指令長度,0表示隊列中無完整指令
*/
uint16_t A_queue_find_cmd(uint8_t *buffer,uint16_t buf_len)//qdata uint8_t   qsize uint16_t
{
    uint16_t cmd_size = 0;
    uint8_t _data = 0;

    while(A_queue_size()>0)//當(dāng)隊列的長度(有效數(shù)字個數(shù))大于0時往下
    {

        //取一個數(shù)據(jù)
        queue_pop(&_data);

        if(A_cmd_pos==0&&_data!=A_CMD_HEAD)                               //指令第一個字節(jié)必須是幀頭,否則跳過
        {
            qDebug() << "Skipping data:" << static_cast<int>(_data);
            continue;
        }

        // 輸出當(dāng)前取出的數(shù)據(jù)和指令指針位置
        qDebug() << "A_queue_find_cmd: Current data: " << _data << " A_cmd_pos: " << A_cmd_pos;

        if(A_cmd_pos<buf_len)                                           //防止緩沖區(qū)溢出,這里傳入的形參是A_CMD_MAX_SIZE(一條指令最大的大?。?,也就是2048
        buffer[A_cmd_pos++] = _data;//每進入一次while循環(huán),數(shù)據(jù)會依次更新到buffer里面

        A_cmd_state = ((A_cmd_state<<8)|_data);   //拼接最后4個字節(jié),組成一個32位整數(shù),如果不是最后四個字節(jié),那自然無法進入下面的if語句

        qDebug() <<" A_cmd_state: " << A_cmd_state;

        //最后4個字節(jié)與幀尾匹配,得到完整幀
        if(A_cmd_state==A_CMD_TAIL)
        {

            cmd_size = A_cmd_pos;                                       //指令字節(jié)長度
            A_cmd_state = 0;                                            //重新檢測幀尾巴
            A_cmd_pos = 0;                                              //復(fù)位指令指針

#if(CRC16_ENABLE)
            //去掉指令頭尾EE,尾FFFCFFFF共計5個字節(jié),只計算數(shù)據(jù)部分CRC
            if(!CheckCRC16(buffer+1,cmd_size-5))                      //CRC校驗
                return 0;

            cmd_size -= 2;                                            //去掉CRC16(2字節(jié))
#endif
            qDebug() << "Found complete command! Command size:" << cmd_size;
            return cmd_size;                        //返回指令的大小
        }
    }
    return 0;                                                         //沒有形成完整的一幀
}

這個函數(shù)是尋找一條完整的指令,如果尋找成功則返回指令的字節(jié)大小。解析里面有說一條完整的指令需要幀頭和幀尾,如果不滿足則無法獲取cmd_size的值,也就無法進入數(shù)據(jù)處理函數(shù)A_ProcessMessage(cmd_buffer, size,ui);所以發(fā)送指令的時候一定要按照標(biāo)準(zhǔn)的格式來發(fā)送。我的數(shù)據(jù)格式如下:

		int touAndCmd[] = {0XEE,0x03,0,1};//幀頭以及以下id號,這篇代碼下面就講
		int dataBuffer[] = {10,20,30,40,50,60,70,80,90,100,110,100,90,80,70,60,50,40,30,20,10};
		int zhenwei[] = {0xFF,0xFC,0xFF,0xFF};//真尾,別傻傻的0xFFFCFFFF了(手動狗頭)
		
		
		int len = sizeof(touAndCmd)/sizeof(touAndCmd[0]);
		int len1 = sizeof(dataBuffer)/sizeof(dataBuffer[0]);
		int len2 = sizeof(zhenwei)/sizeof(zhenwei[0]);
		

        //下面自己看了,就是發(fā)送一串?dāng)?shù)據(jù),然后以逗號隔開就完了
		for(int i = 0;i<len;i++){
		
 				printf("%d,",touAndCmd[i]);
		}
		
		for(int k = 0;k<5;k++){
				for(int i = 0;i<len1;i++){
	
						printf("%d,",dataBuffer[i]);
				}
		}
		
		for(int m = 0;m<len2;m++){
			if(m == (len2-1)){
				printf("%d",zhenwei[m]);
			}else{
				printf("%d,",zhenwei[m]);
				}
		}
	

好了,最后一步:

A_ProcessMessage(cmd_buffer, size,ui);怎么處理我們發(fā)送上來的數(shù)據(jù)?

#include "qglobal.h"
#include "cmd_queue.h"
#include "process_fun.h"
#include "widget.h"
uint8_t  cmd_buffer[A_CMD_MAX_SIZE];
void A_ProcessMessage(/*A_PCTRL_MSG */uint8_t msg[2048], uint16_t size,Ui::Widget *dis)
{

/*這是cmd_type的宏定義,其實用不上這么多
enum A_CtrlType
{
    A_kCtrlUnknown=0x00,
    A_kCtrlButton=0x01,                             //按鈕
    A_kCtrlText = 0x02,                            //文本
    A_kCtrlGraph = 0x03,                           //曲線圖控件
    A_kCtrlTable = 0x04,                           //表格控件
    A_kCtrlMenu = 0x05,                            //菜單控件
    A_kCtrlSelector = 0x06,                        //選擇控件
};
*/

      uint8_t cmd_type = msg[1];            //命令類型
      uint8_t screen_id = msg[2];          //畫面ID
      uint8_t control_id = msg[3];        //控件ID
//調(diào)試信息打印
    qDebug() << "cmd_type:"<<msg[1];

    qDebug() << "screen_id:"<<screen_id;

    qDebug() << "control_id:"<<control_id;


    switch(cmd_type)
    {
    case A_kCtrlButton:                                                   //按鈕控件
        A_NotifyButton(screen_id,control_id);
        break;
    case A_kCtrlText:                                                     //文本控件
//        A_NotifyText(screen_id,control_id,msg->param,dis);
          A_NotifyText(screen_id,control_id,&msg[4],dis);
        break;
    case A_kCtrlGraph:
//        A_NotifyGraph(screen_id,control_id,len,&msg->param[2]);                   //畫圖控件
        A_NotifyGraph(screen_id, control_id, size - 8, &msg[4]); // 注意減去幀頭、幀尾和控件ID的長度
    default:
        break;
    }
}




void A_NotifyText(uint16_t screen_id, uint16_t control_id, uint8_t *str,Ui::Widget *dis)
{
    if(screen_id == 0)//判斷輸入的第二個數(shù)是否為0,如果是,就可以為那些基波啥啥啥的賦值了
    {
      if(control_id == 3)
      {
            Widget::updatedata3(str,1,dis);
      }
      else if(control_id == 4)
      {
            Widget::updatedata3(str,2,dis);
      }
      else if(control_id == 5)
      {
            Widget::updatedata3(str,3,dis);
      }
      else if(control_id == 6)
      {
            Widget::updatedata3(str,4,dis);
      }
      else if(control_id == 7)
      {
            Widget::updatedata3(str,5,dis);
      }
      else if(control_id == 8)
      {
            Widget::updatedata3(str,6,dis);
      }
    }
}
void A_NotifyButton(uint16_t screen_id, uint16_t control_id)
{
  if(screen_id == 0)
  {
    if(control_id == 10)
    {

    }
    else if(control_id == 3)
    {

    }
  }
}

void A_NotifyGraph(uint16_t screen_id, uint16_t control_id, uint16_t length,uint8_t *str)
{
    int i = 0;
    float temp = 0;
    if(screen_id == 0)
    {
//      if(control_id == 0)//這里因為我只用了一個畫布,所以這里就不要啦
//      {
//          qDebug()<<length<<endl;
//          qDebug()<<str;
//          while(i<length)
//          {
//              temp = str[i++];
//              Widget::updatedata(temp);
//          }
//      }
//      else
          if(control_id == 1)
      {
          while(i<length)
          {
              temp = str[i++];
              Widget::updatedata2(temp);//Widget中不斷進行updatedata2這個函數(shù)
          }
      }
    }
}

好的,到這里所有代碼基本分析完畢了,由上面我們知道updatedata2是畫布的updatedata3是各個空白框的。下面最后來看一下這兩個函數(shù):

void Widget::updatedata2(float input)
{
    static int i2=0;//先整個作用在這個函數(shù)里邊的靜態(tài)變量
    static QVector<QPointF> data0=line2->pointsVector();//QVector<QPointF> 類型的容器,用于存儲圖表的數(shù)據(jù)點

//控制數(shù)值在0-255之間
    if(input<0)input = 0;
    if(input>255)input = 255;
    if(i2<1024)
    {
        data0.append(QPointF(i2,input));//在 data0 中添加一個新的數(shù)據(jù)點,x 坐標(biāo)為 i2,y 坐標(biāo)為 input
        i2++;
        line2->replace(data0);//將更新后的數(shù)據(jù)點更新到 line2 圖表中
    }
    else//如果數(shù)據(jù)量超過1024
    {
        QVector<QPointF> data2;//再來一個容器
        for(int j = 0;j<1023;j++)
        {
            data2.append(QPointF(j,data0.at(j+1).y()));//將 data0 中的數(shù)據(jù)點從索引 1 開始拷貝到 data2,相當(dāng)于刪除data0中的數(shù)據(jù)
        }
        data2.append(QPointF(1023,input));//data2添加新的數(shù)據(jù)點,x 坐標(biāo)為 1023,y 坐標(biāo)為 input
        data0 = data2;//更新data0中的數(shù)據(jù)
        line2->replace(data0);///將更新后的數(shù)據(jù)點更新到 line2 圖表中
    }

}

updatedata3:

void Widget::updatedata3(uint8_t* input,int index,Ui::Widget *dis)
{
    QByteArray qstr;//定義一個數(shù)組
    int i = 0;
    for(i;i<sizeof(input);i++)//遍歷input里面的數(shù)據(jù)
    {
        qstr.append(input[i]);//qstr存放input里面的數(shù)據(jù)
    }
    QString str = QString(qstr);//將 QByteArray 類型的 qstr 轉(zhuǎn)換為 QString 類型的 str
    qDebug()<<str;
    switch(index)//index不同寫入不同的空白框
    {
        case 1:
        {
            dis->lineEdit->setText(str);
            break;
        }
        case 2:
        {
            dis->lineEdit_2->setText(str);
            break;
        }
        case 3:
        {
            dis->lineEdit_3->setText(str);
            break;
        }
        case 4:
        {
            dis->lineEdit_4->setText(str);
            break;
        }
        case 5:
        {
            dis->lineEdit_5->setText(str);
            break;
        }
        case 6:
        {
           dis->lineEdit_6->setText(str+"%");
            break;
        }
    }
}

Windows程序和這個大同小異,就不具體介紹了,看懂上面這些Windows程序肯定莫得問題。文章來源地址http://www.zghlxwxcb.cn/news/detail-611322.html

到了這里,關(guān)于QT基于TCP協(xié)議實現(xiàn)數(shù)據(jù)傳輸以及波形繪制——安卓APP及Windows程序雙版本的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • Wireshark數(shù)據(jù)抓包分析之傳輸層協(xié)議(TCP協(xié)議)

    Wireshark數(shù)據(jù)抓包分析之傳輸層協(xié)議(TCP協(xié)議)

    ? ? ? ? 通過使用wireshark對TCP協(xié)議的數(shù)據(jù)包的抓取分析TCP協(xié)議的具體內(nèi)容 ? ? ? ? 1.需要了解TCP協(xié)議的三次握手過程 ? ? ? ? 2.需要了解TCP協(xié)議的四次揮手的過程 part1:3次握手和4次揮手的數(shù)據(jù)包的獲取 1.通過使用TCP測試工具在機器一中創(chuàng)建服務(wù)器,并且進行相應(yīng)的配置,然

    2024年02月11日
    瀏覽(48)
  • 【TCP 協(xié)議】報文格式,數(shù)據(jù)可靠傳輸?shù)臋C制(一)

    【TCP 協(xié)議】報文格式,數(shù)據(jù)可靠傳輸?shù)臋C制(一)

    哈嘍,大家好~我是你們的老朋友: 保護小周??? 本期為大家?guī)淼氖蔷W(wǎng)絡(luò)編程的 TCP 傳輸控制協(xié)議的概念 ,首先會講解 TCP 協(xié)議的報文格式 ,在學(xué)習(xí)報文格式之后,會學(xué)習(xí)兩種 TCP 保證數(shù)據(jù)可靠傳輸?shù)臋C制, 確認(rèn)應(yīng)答,超時重傳, 這也是TCP 中較為核心的機制,以及接收緩

    2024年02月01日
    瀏覽(92)
  • UDP(用戶數(shù)據(jù)報協(xié)議)和TCP(傳輸控制協(xié)議)是互聯(lián)網(wǎng)協(xié)議(IP)中兩種主要的傳輸層協(xié)議

    UDP(用戶數(shù)據(jù)報協(xié)議)和TCP(傳輸控制協(xié)議)是互聯(lián)網(wǎng)協(xié)議(IP)中兩種主要的傳輸層協(xié)議

    您的描述是正確的。UDP(用戶數(shù)據(jù)報協(xié)議)和TCP(傳輸控制協(xié)議)是互聯(lián)網(wǎng)協(xié)議(IP)中兩種主要的傳輸層協(xié)議。他們之間有幾個重要的區(qū)別,其中之一就是建立連接的方式。 連接方式: ? TCP:在進行數(shù)據(jù)傳輸之前,需要通過三次握手(3-way handshake)建立連接。這可以確保

    2024年02月02日
    瀏覽(105)
  • Qt的TCP傳輸數(shù)據(jù),出現(xiàn)中文亂碼的解決方案

    Qt的TCP傳輸數(shù)據(jù)中文亂碼的問題,可能是由于編碼不一致導(dǎo)致的。可以嘗試以下方法解決: 在發(fā)送數(shù)據(jù)之前,將中文字符串進行編碼轉(zhuǎn)換。例如,將QString類型的中文字符串轉(zhuǎn)換成UTF-8編碼的字節(jié)數(shù)組,可以使用QString的toUtf8()函數(shù),示例代碼如下: QString str = \\\"中文字符串\\\"; QB

    2024年02月09日
    瀏覽(52)
  • TCP/IP網(wǎng)絡(luò)編程(二) 套接字協(xié)議及其數(shù)據(jù)傳輸特性

    關(guān)于協(xié)議 如果相隔比較遠的兩人進行通話,必須先決定通話方式,如果一方選擇電話,另一方也必須選擇電話,否則接受不到消息。 總之,協(xié)議就是為了完成數(shù)據(jù)交換而定好的約定。 創(chuàng)建套接字 協(xié)議族 通過socket函數(shù)的第一個參數(shù)傳遞套接字中使用的協(xié)議分類信息,此協(xié)議

    2024年02月10日
    瀏覽(92)
  • 如何用JAVA實現(xiàn)一款高可用的TCP數(shù)據(jù)傳輸服務(wù)器——【基于netty4.x】

    如何用JAVA實現(xiàn)一款高可用的TCP數(shù)據(jù)傳輸服務(wù)器——【基于netty4.x】

    震驚!這可能是我與底層最接近的一次編程體驗 首先netty是一款高性能、封裝性良好且靈活、基于NIO(真·非阻塞IO)的開源框架??梢杂脕硎謱憌eb服務(wù)器、TCP服務(wù)器等,支持的協(xié)議豐富,如:常用的HTTP/HTTPS/WEBSOCKET,并且提供的大量的方法,十分靈活,可以根據(jù)自己的需求量身

    2024年01月19日
    瀏覽(30)
  • Socket TCP/IP協(xié)議數(shù)據(jù)傳輸過程中的粘包和分包問題

    Socket TCP/IP協(xié)議數(shù)據(jù)傳輸過程中的粘包和分包問題

    一:通過圖解法來描述一下分包和粘包,這樣客戶更清晰直觀的了解: 下面對上面的圖進行解釋: 1.正常情況:如果Socket Client 發(fā)送的數(shù)據(jù)包,在Socket Server端也是一個一個完整接收的,那個就不會出現(xiàn)粘包和分包情況,數(shù)據(jù)正常讀取。 2.粘包情況:Socket Client發(fā)送的數(shù)據(jù)包,

    2024年02月12日
    瀏覽(22)
  • 通信模型四層(TCP/IP)、五層、七層(OSI)的作用、協(xié)議及數(shù)據(jù)傳輸單位

    通信模型四層(TCP/IP)、五層、七層(OSI)的作用、協(xié)議及數(shù)據(jù)傳輸單位

    四層模型 五層模型 七層模型 每層作用 物理層:傳輸比特流 數(shù)據(jù)鏈路層:控制網(wǎng)絡(luò)層和物理層之間的通信 網(wǎng)絡(luò)層:IP尋址和路由選擇 傳輸層:建立、維護、管理端到端連接 會話層:建立、維護、管理會話連接 表示層:數(shù)據(jù)格式化,加密、解密、 應(yīng)用層:為應(yīng)用程序提供網(wǎng)

    2024年02月03日
    瀏覽(28)
  • 詳解TCP/IP協(xié)議第三篇:通信數(shù)據(jù)在OSI通信模型的上下傳輸

    詳解TCP/IP協(xié)議第三篇:通信數(shù)據(jù)在OSI通信模型的上下傳輸

    ???? 學(xué)習(xí)交流群: ??1:這是孫哥suns給大家的福利! ??2:我們免費分享Netty、Dubbo、k8s、Mybatis、Spring...應(yīng)用和源碼級別的視頻資料 ????3:QQ群:583783824 ? ???? ?工作微信:BigTreeJava 拉你進微信群,免費領(lǐng)??! ????4:本文章內(nèi)容出自上述:Spring應(yīng)用課程!????

    2024年02月09日
    瀏覽(22)
  • 【計算機網(wǎng)絡(luò)】網(wǎng)絡(luò)協(xié)議五層模型下的各層數(shù)據(jù)傳輸?shù)慕Y(jié)構(gòu)(以TCP包為例)

    【計算機網(wǎng)絡(luò)】網(wǎng)絡(luò)協(xié)議五層模型下的各層數(shù)據(jù)傳輸?shù)慕Y(jié)構(gòu)(以TCP包為例)

    1.應(yīng)用層 ???? 應(yīng)用層的數(shù)據(jù)就是我們寫的代碼的內(nèi)容。比如我要傳一個字符串 “hello wolrd” 到目的主機,那么 報文M 就表示的是 hello world 的二進制(0 1)形式。 ???? 應(yīng)用層就是我們主機的應(yīng)用程序的那一層。比如你用 visual studio運行了你寫好的代碼程序,正在運行的代

    2024年02月03日
    瀏覽(33)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包