Get Image FileList from FTP server
-
Hi,
I am trying to build a Menu for FTP FileList to my android and iOS mobile.
I am using widgets code.
Of course, somebody use QFtp, but I use QNetworkAccessManager .below code is to link my FileList.txt which contain all the file path:
QNetworkAccessManager *manager= new QNetworkAccessManager(this); QUrl url("ftp://XXXXXXXXXX/OOOOOOO/FileList.txt"); url.setUserName("QQ"); url.setPassword("123"); url.setPort(21); QNetworkRequest request(url); manager->get(request); connect(manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(replyFinished(QNetworkReply*)));
Then, I build my file list after get the fillets.txt
BindLV(){ ........ QStringList fileList=slFileName; for (int i=0; i<fileList.count(); i++) { item = new QStandardItem(); QString tmpFilePaht=fileList[i]; QStringList sltmpFileName(tmpFilePaht.split("/")); QIcon icon=GetListIcon(tmpFilePaht); item->setData(icon,ListviewDelegate::IconRole); item->setData(tmpFilePaht,ListviewDelegate::headerTextRole); }
}
below is my jpg icon in the cell:
QIcon diaCloudFileList::GetListIcon(QString strFilePath){ QIcon icon=QIcon(":/Icon/Resources/Icon/ZhsFile.png"); QNetworkAccessManager *manager= new QNetworkAccessManager(this); QUrl url("ftp://sXXXXX/QQQQQQQQQQ"+strFilePath+".jpg"); url.setUserName("AAAA"); url.setPassword("123"); url.setPort(21); QNetworkRequest request(url); manager->get(request); connect(manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(replyIcon(QNetworkReply*)));//**I want to get my icon here and return this icon** return icon; }
But it just slot the signal in the GetListIcon method.
I want to get icon in the GetListIcon method and return this icon,
then I can put this icon to my FileList...What should I do ?
-
@mkdh If you are receiving the data in
replyIcon
then you can just useQPixmap
orQImage
to construct the actual image from that data using loadFromData method.
Something like:void MyClass::replyIcon(QNetworkReply* reply) { QByteArray data = reply->readAll(); QPixmap pix; pix.loadFromData(data); //pix now contains the image }
-
@p3c0
Thanks for your reply.
But this is not the question I want to ask. ^____^
my question is:
I want to get icon in the GetListIcon method and return this icon,
then I can put this icon to my FileList...When I trace the process in Qt, its process flow look like:
--->start BindLV()
--->i=0--->GetListIcon(tmpFilePaht)---->set signal,slot and trigger this event //yet finished
--->i=1--->GetListIcon(tmpFilePaht)---->set signal,slot and trigger this event//yet finished
--->i=2--->GetListIcon(tmpFilePaht)---->set signal,slot and trigger this event//yet finished
........
--->end BindLV()
--->replyIcon(QNetworkReply*) for i=2 // finished here
--->replyIcon(QNetworkReply*) for i=0 // finished here
--->replyIcon(QNetworkReply*) for i=1 // finished here
...Now, I find a solution,
active slot replyFinished(QNetworkReply*) //get filelist
--->setlsIcon()//get iconList //set signal and slot for each file and trigger those event.
--->BindLV()
when filelist.count()==iconList.count() in the slot replyIcon(QNetworkReply *reply)
//I modify this method. I bind ListView with fileList and iconList.But I must waiting till all file has been download.......it is a long time.
Dose any one has other ideas? or suggestion?
-
@mkdh Do you mean that you want to wait till the complete image is downloaded ? Since
QNetworkAccessManager
is asynchronous you will need to implement your own event loop and quit it when finished. For eg. in your functionQIcon diaCloudFileList::GetListIcon(QString strFilePath){ QNetworkAccessManager *manager= new QNetworkAccessManager(this); ... QNetworkRequest request(url); QNetworkReply *reply = manager->get(request); QEventLoop loop; connect(reply, SIGNAL(finished()), &loop, SLOT(quit())); loop.exec(); //Then usual stuff QByteArray data = reply->readAll(); QPixmap pix; pix.loadFromData(data); return QIcon(pix); }
Did I get it right ?
-
The total time for loading all those images would be need waste some waiting time.
Is it possible to make my process more quickly? (multi thread or...)QIcon diaCloudFileList::GetListIcon(QString strFilePath){ icon=QIcon(":/Icon/Resources/Icon/ZhsFile.png"); QNetworkAccessManager *manager= new QNetworkAccessManager(this); QUrl url("ftp://xxx@xx.xx.xx.xx/xx"+strFilePath+".jpg"); url.setUserName("xx"); url.setPassword("xxx"); url.setPort(21); QNetworkRequest request(url); QNetworkReply* reply=manager->get(request); QEventLoop eventloop; connect(reply,SIGNAL(finished()),&eventloop,SLOT(quit())); eventloop.exec(); QByteArray data = reply->readAll(); QPixmap pix; pix.loadFromData(data); icon=QIcon(pix); return icon; }
-
void diaCloudFileList::replyFinished(QNetworkReply *reply){ QByteArray bytes=reply->readAll(); QString str=""; for(int i=0;i<bytes.size();i++){ str+=bytes.at(i); } //show each line QStringList input_rows(str.split(QRegExp("\n|\r\n|\r"))); slFileName=input_rows; reply->close(); BindLV_Asynchronous(); reply->close(); setlsIcon(); } void diaCloudFileList::BindLV_Asynchronous(){ init_styleditemdelegate_cell *listdelegate; model = new QStandardItemModel(this); ui->lvwFile->setModel(model); listdelegate = new init_styleditemdelegate_cell(); ui->lvwFile->setItemDelegate(listdelegate); QStandardItem *item ;//= new QStandardItem(); QDir dir=QDir::rootPath(); QString myPath; myPath=gData->strFileFolder; dir.cd(gData->strFileFolder); dir.setNameFilters(QStringList()<<"*.xxx"); qDebug() << "Scanning: " << dir.path(); QStringList fileList=slFileName; for (int i=0; i<fileList.count(); i++) { item = new QStandardItem(); QString tmpFilePaht=fileList[i]; QStringList sltmpFileName(tmpFilePaht.split("/")); // ui->lblWaiting->setText(strWait+QString::number(i+1)+"/"+QString::number(this->slFileName.count()));//"Please wait.. Process Loading..."" icon=QIcon(":/Icon/Resources/Icon/xxxFile.png"); item->setData(icon,init_styleditemdelegate_cell::IconRole); item->setData(tmpFilePaht,init_styleditemdelegate_cell::headerTextRole); item->setData(sltmpFileName[sltmpFileName.count()-1]+".zhs",init_styleditemdelegate_cell::subHeaderTextrole); item->setEditable(false); model->appendRow(item); } // if(model->rowCount()>0){ // ui->lvwFile->setCurrentIndex(model->indexFromItem(model->item(0,0))); // connect(btnOK, SIGNAL(onClicked()), this, SLOT(on_btnOK_clicked())); // } ShowIni(); // ui->lblWaiting->setVisible(false); } void diaCloudFileList::setlsIcon(){ icon=QIcon(":/Icon/Resources/Icon/xxxFile.png"); for (int i=0; i<slFileName.count(); i++) { QString tmpFilePaht=slFileName[i]; QNetworkAccessManager *manager= new QNetworkAccessManager(this); QUrl url("ftp://xxxx@xx.xx.xx.xx/xx"+tmpFilePaht+".jpg"); url.setUserName("xxx"); url.setPassword("xxx"); url.setPort(21); QNetworkRequest request(url); QNetworkReply* reply=manager->get(request); reply->setProperty("idx", i); connect(manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(replyIcon(QNetworkReply*))); } } void diaCloudFileList::replyIcon(QNetworkReply *reply){ ui->lblWaiting->setText("replyIcon"+QString::number(this->lsIcon.count())+"/"+QString::number(this->slFileName.count()));//"Please wait.. Process Loading..."" QByteArray bytes=reply->readAll(); QImage image=QImage::fromData(bytes); QPixmap sidebar_project_icon_Pixmap = sidebar_project_icon_Pixmap.fromImage(image); icon = sidebar_project_icon_Pixmap; this->lsIcon.push_back(icon); int i = reply->property("idx").toInt(); this->lsIdx.push_back(i); ui->lblWaiting->setText("Please wait.. Process Loading..."+QString::number(this->lsIcon.count())+"/"+QString::number(this->slFileName.count()));//"Please wait.. Process Loading..."" QModelIndex index = ui->lvwFile->model()->index(i,0); ui->lvwFile->model()->setData(index,icon,init_styleditemdelegate_cell::IconRole); if(this->lsIcon.count()==this->slFileName.count()){ ui->lblWaiting->setVisible(false); ui->lblWaiting->setText("Please wait.. Process Loading..."); if(model->rowCount()>0){ ui->lvwFile->setCurrentIndex(model->indexFromItem(model->item(0,0))); connect(btnOK, SIGNAL(onClicked()), this, SLOT(on_btnOK_clicked())); } } // if(this->lsIcon.count()==this->slFileName.count()){ // QList<QIcon> tmpList=this->lsIcon; // for(int k=0;k<this->lsIcon.count();k++){ // int curIdx=this->lsIdx[k]; // this->lsIcon[curIdx]=tmpList[k]; // } // BindLV(); // ui->lblWaiting->setVisible(false); // ui->lblWaiting->setText("Please wait.. Process Loading..."); // } }
-
@mkdh It's good that you switched back to async way :)
Hmm I find some places that can be improved:- In
replyIcon
you are converting data toQImage
and again back toQPixmap
. I see you have never usedimage
in that function. It would be better to convert it directly toQPixmap
. - In
setlsIcon
you have a for loop where you create those manyQNetworkAccessManager
objects but never delete it. That would cause a lots of memory leak. Sure you have passedthis
but those wont be deleted until parent gets deleted. Better to handle it in app's runtime. Same forinit_styleditemdelegate_cell
and others if any. - In
replyFinished
you are concatenatingbytes
tostr
and then again splitting it. Wont directly split be possible ?
- In