Get Image FileList from FTP server
-
wrote on 28 Jul 2015, 08:51 last edited by A Former User
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 ?
-
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 }
-
@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 }
wrote on 29 Jul 2015, 03:08 last edited by mkdh@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?
-
@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 ?
-
@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 ?
-
@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 ?
wrote on 30 Jul 2015, 02:08 last edited by mkdhThe 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; }
-
@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 ?
-
@mkdh Which method ?
-
wrote on 30 Jul 2015, 09:22 last edited by p3c0
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
-
@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
-
@mkdh You're Welcome :) Also please surround your code with ``` (3 backticks) while posting it here. It looks more nicer. I have now added those in your previous post. Happy Coding ...
2/13