The article directories

  • 0 background
  • 1 Sending Data
    • 1.1 Js methods for sending and receiving data calls:
    • 1.2 QML (for calling JS methods)
    • 1.3 Invoking methods
    • 1.4 Handling JSON Returned Values
  • 2 Sending Data
    • 2.1 Sending single Data
    • 2.2 Send structure
  • 3. Easy to make mistakes when packing

0 background

Because logging in the account and sending some data need to use HTTP request to send and receive JSON data, so I consulted relevant information and combined with my own practice, sorted out the following blog post.

1 Sending Data

1.1 Js methods for sending and receiving data calls:

// GET
function get(url, success, failure)
{
    var xhr = new XMLHttpRequest;
    xhr.open("GET", url);
    xhr.onreadystatechange = function() {
        handleResponse(xhr, success, failure);
    }
    xhr.send();
}
// POST
function post(success, failure, url, arg,)
{

    var xhr = new XMLHttpRequest;
    xhr.open("POST", url);
    xhr.setRequestHeader("Content-Length", arg.length);
    xhr.setRequestHeader("Content-Type"."application/x-www-form-urlencoded;"); / / post necessary
    xhr.onreadystatechange = function() {
        handleResponse(xhr, success, failure);
    }
    xhr.send(arg);
}

// Process the return value
function handleResponse(xhr, success, failure){
// console.log(xhr);
// console.log(success);
// console.log(failure);
    if (xhr.readyState == XMLHttpRequest.DONE) {
        if (xhr.status ==  200) {if(success ! =null&& success ! =undefined)
            {
                var result = xhr.responseText;
                try{
                    success(result, JSON.parse(result));
                }catch(e){ success(result, {}); }}}else{
            if(failure ! =null&& failure ! =undefined) failure(xhr.responseText, xhr.status); }}}Copy the code

1.2 QML (for calling JS methods)

import QtQuick 2.0
import QtQuick.Window 2.2
import "ajax.js" as Ajax

Item {

    //loginAccount
    // Login interface
    function  loginAccount(ajax, deviceid, lastloginversion, password, username, loginfield, type) {
    // Prints parameters
       console.log("Login send parameters :", ajax, deviceid, lastloginversion, password, username, loginfield,  type) // Prints parameter data
        Ajax.post(
             function (data){              // The successful callback function
                 console.log("Return value of successful login :", data);
					// Slot function called after success: public property
                    $Login.activeResult(data);
                    console.log('Enter login interface');

            },function (data){              // Failed callback function
                // Slot function called after failure
                  $Login.failHttpResult(data);
                console.log(data)
            },
            "The request url: such as http://88.888.88.88/api/app/login?"."ajax=" + ajax
                  + "&deviceid=" + deviceid
                  + "&lastloginversion="+ lastloginversion
                  + "&password=" + password
                  + "&username=" + username
                  + "&loginfield=" + loginfield
                  + "&type=" + type,

                  Login.invokeFunc
                  );
            }
            
    // Send a JSON structure
    function  sendDiscernData2(dataStruct, user_id) {
        //imageData,
       console.log("Data sent to the game end :", dataStruct, user_id) // Prints parameter data

        Ajax.post(
            function (data){              // The successful callback function
               // Successfully called slot function
                $ShowImage.activeResult2(data);
                console.log("Identify interface 2 success:", data);

            },function() {// Failed callback function
            // Failed to call the slot function
				$ShowImage.failResult2(data);                
                console.log("Interface 2 error:", data);
            },
              "Requested url"."data="+dataStruct
                  +"&user_id="+user_id, ShowImage.invokeFunc ); }}Copy the code

The above two files are introduced into the project as resource files [general QML and calling JS are placed in the same directory] :

1.3 Invoking methods

Header file. H

#include <QQmlApplicationEngine>
#include <QQmlContext>
#include<QQmlComponent>
#include<QJsonObject>
#include<QJsonArray>
#include<QJsonValue>
#include<QJsonParseError>


// Adjust the login interface
private:
    QQmlApplicationEngine engine;
    QObject *engineObject;      // Point to a running QML object
public slots:
       /** * @brief Activation result returns (may succeed, may fail) * @param returns JSON array * @return Returns whether the login succeeded */
       void activeResult(const QVariant &);
       /** * @brief failHttpResult Activation failed */
       void failHttpResult(const QVariant &);
Copy the code

.cpp file:

Add the following code to the constructor:

    // Set QML global access properties
    //engine.load("D:/Qfile/testAjax/file/main.qml");
    engine.rootContext() - >setContextProperty("Login".this);

    // Point the Widget variable in QML to the current class. This allows the QML and Widget classes to be connected
    // Create QML and get running QML objects
    The QStringLiteral macro constructs the constant string STR directly into a QString at compile time
    //QQmlComponent component(&engine, QUrl("qrc:/main.qml"));
   //QQmlComponent component(&engine, "D:/Qfile/testAjax/file/main.qml");

    QQmlComponent component(&engine);
     component.loadUrl(QUrl(QStringLiteral("qrc:/http/main.qml")));

    engineObject = component.create(a);// Pass the reference to QML for binding
   engine.rootContext() - >setContextProperty("$Login".this);
Copy the code

1.4 Handling JSON Returned Values

The value returned after the call:

 {
 "success":true."jwt":"gfsdgfgs"."message": {"gender":0."nation":""."birth_date":""."bio":""."msn":""."real_name":""."type":1."devicetype":0."password":"123455"."jihuo_status":0."server_ip":"47.108.50.146"."email":""."onlineflag":0."qq":""."salt":""."mobile":""."avatar":""."priority":0."deviceid":"1"."weixin":""."wifi_name":0."user_id":1."nick_name":""."wifi_password":0."node_id":0."username":"A1234500"},
 "devices": [{"top":28."mj_count":108."user_id":1."bottom":28."serial_number":"12345601"."version_number":1."direction":0}, {"top":26."mj_count":108."user_id":1."bottom":26."serial_number":"12345602"."version_number":1."direction":1}, {"top":28."mj_count":108."user_id":1."bottom":28."serial_number":"12345603"."version_number":1."direction":2}, {"top":26."mj_count":108."user_id":1."bottom":26."serial_number":"12345604"."version_number":1."direction":3}}]Copy the code

Debugging information Printed pictures:



Analytical method:

// Get the returned value
void Login::activeResult(const QVariant &var)
{

    QVector<QPair<QString, int>>serialNumberInformation;
    QMap<QString, int> serialNumber2Direction;
    QMap<int, QString> direction2SerialNumber;
    QByteArray userAccount;
    QString wifiAccount;
    QString wifiPassword;

    int userId = 0;

     QString serial_number;
     QJsonParseError jsonError;
     QJsonDocument doucment = QJsonDocument::fromJson(var.toByteArray(), &jsonError);
     qDebug() < <"Parse document";

     if(! doucment.isNull() && (jsonError.error == QJsonParseError::NoError)) {
         qDebug() < <"No parsing error occurred";
         if (doucment.isObject()) {
           qDebug() < <"JSON document as object";

             QJsonObject object = doucment.object(a);// Convert to object
             /* * Parse a single data */
             // Check whether the login succeeds
             if (object.contains("success")) {  // Contains the specified key
                 QJsonValue value = object.value("success");  // Get the value of the specified key
                 if(value == true){
                     loginStatus = true;
                     qDebug() < <"Login successful";
                 }else{
                     loginStatus = false;
                     qDebug() < <"Login failed"; }}/* * Parse multiple structures */
             if (object.contains("devices")) {
                 QJsonValue value = object.take("devices");
                 if(value.isArray()){
                     QJsonArray arr = value.toArray(a);qDebug() << arr.size(a);for(int i = 0; i < arr.size(a); i++) { QJsonValue value = arr.at(i);

                         QPair<QString, int> tempInfo;
                         tempInfo.first = value["serial_number"].toString(a); tempInfo.second = value["direction"].toInt(a); serialNumberInformation.push_back(tempInfo);

                         serialNumber2Direction[tempInfo.first] = tempInfo.second;
                         direction2SerialNumber[tempInfo.second] = tempInfo.first;

                         if(userId == 0){
                             userId = value["user_id"].toInt(a); }//qDebug()<<i<<":"<<value["serial_number"].toString();}}}// Get the serial number
             /* * Parse a single */
             // Get the account
             if(object.contains("message")){
                 QJsonValue value = object.take("message");
                 QString tempUsername = value["username"].toString(a);qDebug() < <"tempUsername:"<<tempUsername;

                 for (int i = 0; i < tempUsername.size(a); i +=2) {
                     userAccount += HexStringToByteArray(tempUsername.mid(i,2));
                 }
                // qDebug()<<"userAccount:"<<userAccount.toHex().toUpper();
                 wifiAccount = value["wifi_name"].toString(a);qDebug() < <"wifiAccount:"<<wifiAccount;
                 wifiPassword = value["wifi_password"].toString(a);qDebug() < <"wifiPassword:"<<wifiPassword; }}// JSON document as object
     }// No parsing error occurred

}
Copy the code

2 Sending Data

2.1 Sending single Data

    m_username = ui->accountComboBox->currentText() ;
    m_password = ui->passwordLineEdit->text(a);// Send data formally

        QVariant ajax = true;
        QVariant deviceid = 1.0;
        QVariant lastloginversion = 1.0;
        QVariant devicetype = 0;
        QVariant password = static_cast<QVariant>(m_password);
        QVariant username = static_cast<QVariant>(m_username);
        QVariant loginfield = "username";
        QVariant type =  "username";


// Call the method to send data
// Send in the same order as QML is passed in
        QMetaObject::invokeMethod(engineObject, "loginAccount".Q_ARG(QVariant, ajax),
                                  Q_ARG(QVariant, deviceid),
                                  Q_ARG(QVariant, lastloginversion),
                                  Q_ARG(QVariant, password),
                                  Q_ARG(QVariant, username),
                                  Q_ARG(QVariant, loginfield),
                                  Q_ARG(QVariant, type));
Copy the code

2.2 Send structure

Ideas:

  • 1 Use QVariantList to store QVariantMap data
  • 2 Convert QVariantList to QJsonArray, then to QJsonDocument, then to QString
  • 3 Remove the Spaces and newlines after the turn
  • 4 Call the method to send data
void ShowImage::sendAllDiscernCardResult(a)
{

    // Get time; The 2020-08-27 18:56:06
    QDateTime curDateTime = QDateTime::currentDateTime(a); QVariantList varList; QVariantMap tempMap;for (int i = 1; i <= eastCardSum; i++) { tempMap["add_time"] = curDateTime.toString("yyyy-MM-dd hh:mm:ss");
        tempMap["chupai_direction"] = "1";
        tempMap["direction"] = 0;
        tempMap["id"] = 0;
        tempMap["mahjong_number"] = i;//((i % 2 == 0) ? (i - 1): (i + 1))
        tempMap["napai_direction"] = 1;
        tempMap["result"] =  recognitionCardData[0] [0][i];
        tempMap["serial_number"] = usrId;
        tempMap["yuce_direction"] = 1;
        tempMap["zhuo_id"] = 1;

        varList<<tempMap;
    }

    for (int i = 1; i <= southCardSum; i++) { tempMap["add_time"] = curDateTime.toString("yyyy-MM-dd hh:mm:ss");
        tempMap["chupai_direction"] = "1";
        tempMap["direction"] = 1;
        tempMap["id"] = 0;
        tempMap["mahjong_number"] = i;
        tempMap["napai_direction"] = 1;
        tempMap["result"] =  recognitionCardData[0] [1][i];
        tempMap["serial_number"] = usrId;
        tempMap["yuce_direction"] = 1;
        tempMap["zhuo_id"] = 1;

        varList<<tempMap;
    }

    for (int i = 1; i <= westCardSum; i++) { tempMap["add_time"] = curDateTime.toString("yyyy-MM-dd hh:mm:ss");
        tempMap["chupai_direction"] = "1";
        tempMap["direction"] = 2;
        tempMap["id"] = 0;
        tempMap["mahjong_number"] = i;
        tempMap["napai_direction"] = 1;
        tempMap["result"] =  recognitionCardData[0] [2][i];
        tempMap["serial_number"] = usrId;
        tempMap["yuce_direction"] = 1;
        tempMap["zhuo_id"] = 1;

        varList<<tempMap;
    }

    for (int i = 1; i <= northCardSum; i++) { tempMap["add_time"] = curDateTime.toString("yyyy-MM-dd hh:mm:ss");
        tempMap["chupai_direction"] = "1";
        tempMap["direction"] = 3;
        tempMap["id"] = 0;
        tempMap["mahjong_number"] = i;
        tempMap["napai_direction"] = 1;
        tempMap["result"] =  recognitionCardData[0] [3][i];
        tempMap["serial_number"] = usrId;
        tempMap["yuce_direction"] = 1;
        tempMap["zhuo_id"] = 1;

        varList<<tempMap;
    }


   QJsonArray dataArray = QJsonArray::fromVariantList(varList);
 // qDebug()<<"dataArray:"<<dataArray;
   QJsonDocument dataDoc;
   dataDoc.setArray(dataArray);
   //
   QString dataString = static_cast<QString>(dataDoc.toJson());
   / / to a newline
   dataString.remove(QChar('\n'), Qt::CaseInsensitive);
   / / to space
   dataString.remove(QChar('\ 040'), Qt::CaseInsensitive);
   QVariant dataStruct = static_cast<QVariant>(dataString);

   usrId = 1;

   QVariant user_id = static_cast<QVariant>(usrId);
   
   // Send data
   QMetaObject::invokeMethod(engineObject, "sendDiscernData2".Q_ARG(QVariant, dataStruct),
                             Q_ARG(QVariant, user_id));

}
Copy the code

3. Easy to make mistakes when packing

General QT program package, many people like to useWindeployqt program pathThe QML environment is not properly packaged and is prone to errors such as:



To solve the problem, run the following command:

Windeployqt. exe --qmldir./ QML program pathCopy the code