在Qt与Http通信的时候,会根据不同的情况使用同步或者异步的方式进行数据请求。
同步,即发送Http请求之后,会一直等待服务器返回的数据,接收到数据之前,程序一直阻塞。
异步,即发送Http请求之后,程序可以继续往下执行,接收到服务器返回的数据时自动调用其对应的槽函数处理数据。
Tcp异步编程的核心就是Qt的信号槽机制
,通过关联对应的信号,等信号来了之后在做出相应的响应。显然,异步操作是可以主线程(GUI)中使用,因为它不会阻塞主线程,这也是与同步根本的区别。下面展示tcp异步编程的基本步骤,包含客户端和服务端。
头文件:
public slots:
void slotCoreTcpReceiveAll(const QString &ip, const QString &sCD, const QVariant &jsonData, int number, bool isError, const QVariantMap &map) override;
源文件(注意绑定槽函数中的操作):
ui->toolbar->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);//样式:文本在图标下面
//toolBar
QAction * ac = Q_NULLPTR;
{
ac = new QAction(QIcon(StyleObject::init()->getCurrentSkinDirPath()+"/images/upload"),tr("Upload"),this);
ui->toolbar->addAction(ac);
//绑定槽函数!!!!!!!!!!!!!!!!
connect(ac,&QAction::triggered,this,[=](bool checked){
uploadAudioFile();
});
ac = new QAction(QIcon(StyleObject::init()->getCurrentSkinDirPath()+"/images/refresh_normal"),tr("Refresh"),this);
ui->toolbar->addAction(ac);
connect(ac,&QAction::triggered,this,[=](bool checked){
UiClass::init()->showWaittingWidget(tr("refresh..."),this);
refreshAudioList();
});
ui->toolbar->addSeparator();
ac = new QAction(QIcon(StyleObject::init()->getCurrentSkinDirPath()+"/images/delete_hover"),tr("Delete"),this);
ui->toolbar->addAction(ac);
connect(ac,&QAction::triggered,this,[this](){
deleteAudioFile();
});
}
uploadAudioFile中发送请求
void AudioManagementView::uploadAudioFile()
{
QString filePath = QFileDialog::getOpenFileName(this,tr("Audio file"),PublicClass::init()->getSoundsPath(),"*.wav");
if(filePath.isEmpty()){
return;
}
QFileInfo fileInfo(filePath);
// SCDebug<<"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~filePath:"<<filePath;
QString sCompleteBaseName = fileInfo.completeBaseName();
if(PublicClass::init()->isChinese(sCompleteBaseName)){
slotMessage(QString(tr("Chinese filename is not supported")),SCToastr::E_Warning);
return;
}
if(sCompleteBaseName.toLocal8Bit().size()>20){
slotMessage(QString(tr("File name's length larger than 20 bytes are not supported")),SCToastr::E_Warning);
return;
}
QFile file(fileInfo.filePath());
if(!file.open(QIODevice::ReadOnly)){
slotMessage(QString(tr("Failed to open audio file:")).arg(file.errorString()),SCToastr::E_Warning);
return;
}
QByteArray b = file.readAll();
file.close();
QVariantMap jsonMap;
jsonMap.insert("type","uploadFile");
jsonMap.insert("filePath", AdvancedViewCommon::init()->_audioPath + "/" + fileInfo.fileName());
// SCDebug<<"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~jsonMap"<<jsonMap;
//发送请求
RobotManager::init()->sendData(RobotInterface::E_CoreTcp,jsonMap,b,"robot_core_operate_req","",E_AudioManagement);
UiClass::init()->releaseWaittingWidget(this);
refreshAudioList();
}
与请求对应的函数(接收了所有数据)
void AudioManagementView::slotCoreTcpReceiveAll(const QString &ip, const QString &sCD, const QVariant &jsonData , int number, bool isError,const QVariantMap &map)
{
Q_UNUSED(ip)
if(number != E_AudioManagement) return;
if(isError){
UiClass::init()->releaseWaittingWidget(this);
UiClass::init()->showToastr(QString(("%1")).arg(jsonData.toString()),SCToastr::E_Warning,this);
return;
}
auto type = map.value("jsonData").toMap().value("type").toString();
if(sCD == "robot_core_operate_req"){
if("uploadFile"==type){
refreshAudioList();
}else if("getFileList"==type){
QString jsonString = jsonData.toString();
QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonString.toUtf8());
QVariant revData = jsonDoc.toVariant();
getFileList_var=revData.toList();
refreshTable(revData.toList());
UiClass::init()->releaseWaittingWidget(this);
}else if("downloadFile"==type){
downloadFile_var = jsonData.toByteArray();
}
}else if(sCD == "robot_core_audiodriverlist_req"){
// QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonData.toByteArray());
// QJsonObject nobj = QJsonObject(jsonDoc.object());
// QVariantMap var = nobj.toVariantMap();
// SCDebug<<"~~~~~~~~~~~~~~~~~~~~~~~~~jsondata::"<<jsonData;
}
}