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 path
The 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