JSON常来做数据传输的格式,本文采用UDP通信来传递JSON格式的数据

  • UDP Server端采用Qt Widgets技术
  • UDP Client端采用Qt Quick技术
效果如图所示:

在这里插入图片描述
在这里插入图片描述


  • Server端代码
  1. mainwidget.h
#ifndef MAINWIDGET_H
#define MAINWIDGET_H

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

QT_BEGIN_NAMESPACE
namespace Ui { class MainWidget; }
QT_END_NAMESPACE

class MainWidget : public QWidget
{
    Q_OBJECT

public:
    MainWidget(QWidget *parent = nullptr);
    ~MainWidget();
    static void appendLogToEdit(QtMsgType type, const QMessageLogContext &context, const QString &msg);

private slots:
    void on_sendBtn_clicked();

signals:

private:
    void initUI();
    void initConnect();

private:
    UdpSendUnit* m_udpSend;

private:
    Ui::MainWidget *ui;
    static MainWidget *mainWidget;
};
#endif // MAINWIDGET_H
  1. mainwidget.cpp
#include "mainwidget.h"
#include "ui_mainwidget.h"
#include <QDebug>
#include <QDateTime>
#include <QMutex>
#include <QFile>

MainWidget *MainWidget::mainWidget = nullptr;

MainWidget::MainWidget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::MainWidget)
{
    ui->setupUi(this);
    MainWidget::mainWidget = this;
    qInstallMessageHandler(appendLogToEdit);
    this->setWindowTitle("XX数据采集中心");
    this->setFixedSize(500, 400);
    initUI();
    m_udpSend = new UdpSendUnit(ui->IP_Liedt->text(), ui->Port_Liedt->text().toInt(), this);

    initConnect();
}

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

void MainWidget::appendLogToEdit(QtMsgType type, const QMessageLogContext &context, const QString &msg)
{
    Q_UNUSED(context);
    static QMutex mutex;
    mutex.lock();

    QString fileName = QDateTime::currentDateTime().toString("yyyyMMdd-hh") + ".log";

    QString time;
    time.append(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss") + " ");

    if(MainWidget::mainWidget != nullptr)
    {
        MainWidget::mainWidget->ui->textBrowser->append(time + msg);
    }
    mutex.unlock();
}

void MainWidget::on_sendBtn_clicked()
{
    m_udpSend->start();
}

void MainWidget::initUI()
{
    ui->IP_Lbl->setText("RemoteHost:");
    ui->Port_Lbl->setText("Port:");
    ui->name_Lbl->setText("Name:");
    ui->beepValue_Lbl->setText("BeepValue:");
    ui->sendBtn->setText("发送");

    ui->IP_Liedt->setText("127.0.0.1");
    ui->Port_Liedt->setText("18000");
    ui->name_Liedt->setText("high");
    ui->beepValue_Liedt->setText("1");


    ui->textBrowser->setStyleSheet("QTextBrowser{ color: \"red\"; font: bold 16px \"微软雅黑\" }");
    ui->textBrowser->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
    ui->textBrowser->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
}

void MainWidget::initConnect()
{
    connect(ui->name_Liedt, &QLineEdit::textChanged, m_udpSend, &UdpSendUnit::nameValue_slot);
    connect(ui->beepValue_Liedt, &QLineEdit::textChanged, m_udpSend, &UdpSendUnit::beepValue_slot);
}
  1. udpsendunit.h
#ifndef UDPSENDUNIT_H
#define UDPSENDUNIT_H

#include <QObject>
#include <QThread>
#include <QUdpSocket>

#include <QJsonObject>
#include <QJsonDocument>

class UdpSendUnit : public QThread
{
    Q_OBJECT
public:
    explicit UdpSendUnit(QString ip, int port, QObject *parent = nullptr);

protected:
    void run() override;

signals:

public slots:
    void nameValue_slot(QString nameStr);
    void beepValue_slot(QString beepStr);

private:
    QUdpSocket* m_socket;
    QJsonObject m_json;

    QString m_ip;
    int m_port;

    QString m_name;
    int m_beep;

    bool m_flag;
};

#endif // UDPSENDUNIT_H
  1. udpsendunit.cpp
#include "udpsendunit.h"
#include <QDebug>
#include <QTextCursor>

UdpSendUnit::UdpSendUnit(QString ip, int port, QObject *parent) : QThread(parent)
{
    m_ip = ip;
    m_port = port;
    m_flag = false;
    m_socket = new QUdpSocket(this);
    m_socket->bind(QHostAddress::AnyIPv4, 9988);

    m_name = "H";
    m_beep = 1;
}

void UdpSendUnit::run()
{
    long long flag = 0;
    while(true){
        flag++;
        m_json.insert("name", m_name);

        if(m_flag)
        {
            m_json.insert("beep", m_beep);
            m_flag = false;
            flag = m_beep;
        }
        else{
            m_json.insert("beep", flag);
        }

        QJsonDocument _jsonDoc(m_json);
        QByteArray _byteArray = _jsonDoc.toJson(QJsonDocument::Indented);

        //QString strTmp = QString(_jsonDoc.toJson(QJsonDocument::Indented));
        QString strTmp = QString(_jsonDoc.toJson(QJsonDocument::Compact));
        qDebug() << strTmp;

        m_socket->writeDatagram(_byteArray, QHostAddress(m_ip), m_port);

        QThread::sleep(1);
    }
}

void UdpSendUnit::nameValue_slot(QString nameStr)
{
    m_name = nameStr;
}

void UdpSendUnit::beepValue_slot(QString beepStr)
{
    m_beep = beepStr.toInt();
    m_flag = true;
    m_json.insert("beep", m_beep);
}
  1. main.cpp
#include "mainwidget.h"

#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWidget w;
    w.show();
    return a.exec();
}

  • Client端代码
  1. udprecvunit.h
#ifndef UDPRECVUNIT_H
#define UDPRECVUNIT_H

#include <QObject>
#include <QThread>
#include <QUdpSocket>

class UdpRecvUnit : public QThread
{
    Q_OBJECT
public:
    explicit UdpRecvUnit(QObject *parent = nullptr);
    Q_PROPERTY(QString nameStr READ getAlias WRITE setAlias NOTIFY aliasChanged)
    Q_PROPERTY(int beepInt READ getBeep WRITE setBeep NOTIFY beepChanged)
    Q_PROPERTY(QString jsonValue READ getJsonValue WRITE setJsonValue NOTIFY jsonValueChanged)

    QString getAlias() const;
    int getBeep() const;
    QString getJsonValue() const;

public slots:
    void setAlias(QString nameStr);
    void setBeep(int beepInt);
    void setJsonValue(QString jsonValue);

protected:
    void run() override;

private:
    void analyseData(QByteArray data);

signals:
    void aliasChanged(QString nameStr);
    void beepChanged(int beepInt);

    void jsonValueChanged(QString jsonValue);

private:
    QUdpSocket* m_socket;
    QString m_nameStr;
    int m_beepInt;
    QString m_jsonValue;
};

#endif // UDPRECVUNIT_H
  1. udprecvunit.cpp
#include "udprecvunit.h"
#include <QJsonObject>
#include <QJsonDocument>
#include <QDebug>

UdpRecvUnit::UdpRecvUnit(QObject *parent) : QThread(parent)
{
    m_socket = new QUdpSocket(this);
    m_socket->bind(QHostAddress::AnyIPv4, 18000);

    m_nameStr = "Test";
    m_beepInt = 1;
}

void UdpRecvUnit::run()
{
    while(true){
        if(m_socket->hasPendingDatagrams())
        {
            QByteArray datagram;
            datagram.resize(m_socket->pendingDatagramSize());
            m_socket->readDatagram(datagram.data(), datagram.size());

            analyseData(datagram);
        }

        QThread::msleep(1500);
    }
}

void UdpRecvUnit::analyseData(QByteArray data)
{
    QJsonParseError jsonError;
    QJsonDocument parseDoc = QJsonDocument::fromJson(data, &jsonError);
    if(jsonError.error == QJsonParseError::NoError)
    {
        if(parseDoc.isObject()){
            QJsonObject obj = parseDoc.object();
            //qDebug() << obj.value("name").toString();
            //qDebug() << obj.value("beep").toInt();

            m_nameStr = obj.value("name").toString();
            m_beepInt = obj.value("beep").toInt();
            m_jsonValue = QString(parseDoc.toJson(QJsonDocument::Indented));
        }
    }
}

QString UdpRecvUnit::getAlias() const
{
    return m_nameStr;
}

int UdpRecvUnit::getBeep() const
{
    return m_beepInt;
}

void UdpRecvUnit::setAlias(QString nameStr)
{
    if (m_nameStr == nameStr)
        return;

    m_nameStr = nameStr;
    emit aliasChanged(m_nameStr);
}

void UdpRecvUnit::setBeep(int beepInt)
{
    if (m_beepInt == beepInt)
        return;

    m_beepInt = beepInt;
    emit beepChanged(m_beepInt);
}

QString UdpRecvUnit::getJsonValue() const
{
    return m_jsonValue;
}

void UdpRecvUnit::setJsonValue(QString jsonValue)
{
    if (m_jsonValue == jsonValue)
        return;

    m_jsonValue = jsonValue;
    emit jsonValueChanged(m_jsonValue);
}
  1. main.cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include "udprecvunit.h"
#include "uidata.h"
#include <QtQml>

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

    QGuiApplication app(argc, argv);

    QQmlApplicationEngine engine;

    UdpRecvUnit* m_udpRecv = new UdpRecvUnit();
    m_udpRecv->start();

    UIData* m_uiData = new UIData();

    engine.rootContext()->setContextProperty("UIData", m_uiData);
    engine.rootContext()->setContextProperty("UDPRecv", m_udpRecv);

    const QUrl url(QStringLiteral("qrc:/main.qml"));
    QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
                     &app, [url](QObject *obj, const QUrl &objUrl) {
        if (!obj && url == objUrl)
            QCoreApplication::exit(-1);
    }, Qt::QueuedConnection);
    engine.load(url);

    return app.exec();
}
  1. uidata.h
#ifndef UIDATA_H
#define UIDATA_H

#include <QObject>

class UIData : public QObject
{
    Q_OBJECT
public:
    explicit UIData(QObject *parent = nullptr);
    Q_PROPERTY(QString nameStr READ getAlias WRITE setAlias NOTIFY aliasChanged)
    Q_PROPERTY(int beepInt READ getBeep WRITE setBeep NOTIFY beepChanged)

    QString getAlias() const;
    int getBeep() const;

public slots:
    void setAlias(QString nameStr);
    void setBeep(int beepInt);

signals:
    void aliasChanged(QString nameStr);
    void beepChanged(int beepInt);

private:
    QString m_nameStr;
    int m_beepInt;
};

#endif // UIDATA_H
  1. uidata.h
#include "uidata.h"

UIData::UIData(QObject *parent) : QObject(parent)
{

}

QString UIData::getAlias() const
{
    return m_nameStr;
}

int UIData::getBeep() const
{
    return m_beepInt;
}

void UIData::setAlias(QString nameStr)
{
    if (m_nameStr == nameStr)
        return;

    m_nameStr = nameStr;
    emit aliasChanged(m_nameStr);
}

void UIData::setBeep(int beepInt)
{
    if (m_beepInt == beepInt)
        return;

    m_beepInt = beepInt;
    emit beepChanged(m_beepInt);
}
  1. main.qml
import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.12
import QtQuick.Controls 1.4 as Controls14
import QtQuick.Dialogs 1.2
import Qt.labs.calendar 1.0
import QtQuick.Layouts 1.12

Window {
    id: root;
    visible: true
    width: 640
    height: 480
    title: qsTr("XX监视系统")

    property alias dlgContent : textContainer.text
    property alias jsonContent : txtContent.text

    ColumnLayout{
        id: clmnLy;
        anchors.fill: parent;
        spacing: 20;

        RowLayout{
            //anchors.top: parent.top;
            Layout.fillWidth: true;
            Layout.maximumWidth: 80;

            spacing: 20;
            TextEdit {
                id: txt;
                //x: (parent.width - txt.width) / 2;
                //y: (parent.height - txt.height) / 2;
                //anchors.left: btn.right;
                //y: 20;

                width: 240;
                text: "highlander";
                font.family: "Helvetica";
                font.pointSize: 18;
                color: "blue";
                focus: true;
            }

            Button{
                id: btn;
                //x: (parent.width - btn.width) / 2;
                //y: 20;
                text: qsTr("弹窗");

                onClicked: {
                    console.log("MessageBox Test");
                    modelessDlg.open();
                }
            }
        }

        Rectangle{
            height: 2;
            color: "yellow";
            width: root.width;
        }

        Rectangle{
            id: rec;
            width: root.width;
            height: root.height;
            Layout.fillWidth: true;

            /*
            TextEdit{
                id: txtContent;
                anchors.fill: parent;
                font.pointSize: 20;
                wrapMode: TextEdit.Wrap;
                readOnly: true;

                MouseArea {
                    anchors.fill: parent;
                    drag.target: txtContent;
                    drag.axis: Drag.YAxis;

                    drag.minimumY: -(parent.height-480);
                    drag.maximumY: 0
                }
            }
            */

            ScrollView{
                anchors.fill: parent;

                TextArea{
                    id: txtContent;
                    // anchors.fill: parent;
                    font.pointSize: 18;
                    wrapMode: TextEdit.Wrap;
                    readOnly: true;
                    color: "green";
                }
            }
        }
    }

    Dialog{
        id: modelessDlg;
        visible: false;
        modality: "NonModal";
        standardButtons: Dialog.Ok;
        title: "报警";

        Text {
            id: textContainer
            anchors.fill: parent
            horizontalAlignment: Qt.AlignLeft
            verticalAlignment: Qt.AlignTop
            color: "red";
            font.pointSize: 18;
        }

        onAccepted: {
            console.log("OK clicked.");
            UDPRecv.beepInt = UDPRecv.beepInt + 1;
        }
        onRejected: {
            UDPRecv.beepInt = 200;
        }

        // 自定义内容
        //contentItem: Rectangle{
        //    color: "red";
        //    implicitWidth: 300;
        //    implicitHeight: 200;
        //    Text {
        //        anchors.centerIn: parent;
        //        text: qsTr("text");
        //    }
        //}

        /*
        添加日历控件
        Controls14.Calendar {
            id: calendar
            onDoubleClicked: dateDialog.click(StandardButton.Save)
        }
        */
    }

    //定时器
    Timer {
        interval: 1000;
        running: true;
        repeat: true
        onTriggered: {
            txt.text = UDPRecv.nameStr;

            if(UDPRecv.beepInt % 5 == 0)
            {
                //modelessDlg.open();
                modelessDlg.visible = true;
                console.log("报警提示显示");
            }
            else if(UDPRecv.beepInt % 9 == 0)
            {
                //modelessDlg.close();
                modelessDlg.visible = false;
                console.log("报警提示隐藏");
            }

            dlgContent = UDPRecv.beepInt;
            //console.log(UDPRecv.beepInt);

            jsonContent += UDPRecv.jsonValue;
        }
    }

}

  • 工程文件添加配置
QT += network

DESTDIR = bin
CONFIG -= debug_and_release
MOC_DIR = tmp/moc
RCC_DIR = tmp/rcc
UI_DIR = tmp/ui
OBJECTS_DIR = tmp/obj
Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐