PDA

View Full Version : QFtp in a separate instances



baray98
9th April 2008, 18:18
I tried using Ftp in my Qdialog widget to do a multiple download, and it work fine , now since i have two server that i can ping on at the same time so i tried having two instances of my dialog then download at the same time , what i noticed that the other instance of my dialog will wait for the the the other to be done downloading and then start its download ....I wanted them to be parrallel not serial download between instances of my dialog.

Any hints guys of what should i set in QFtp?

baray98

wysota
9th April 2008, 19:36
It's not a problem with QFtp, but with the fact that you have two modal dialogs and they are blocking each other. Either use non-modal dialogs (QWidget::show instead of QDialog::exec) or use a single dialog. You can also try making ftp objects independent of the dialogs, but that's more work.

baray98
10th April 2008, 01:31
my dialog are non-modal, i thought that was the problem, but it did not help. I noticed that that when my first dialog is in the middle of file download then once I make my other dialog to do a download , my first dialog will continue downloading until its done on that file then the waiting will happen .....( waits for the second dialog to be done with its download ) then my first dialog will resume....

baray98

baray98
10th April 2008, 01:49
when you said "blocking each other" meaning i can get away with using QWidget instead of QDialog as my inherited class?

I Poped these dialog like below:



void DeviceWidget::Ftp(void)
{
if (!m_FtpDialog)
{
m_FtpDialog = new FtpDialog(0);
m_FtpDialog->setWindowTitle(tr("FTP Download for %1").arg(getStringName(m_config.deviceId)));
}

m_FtpDialog->show();
m_FtpDialog->raise();
m_FtpDialog->activateWindow();
}

baray98
10th April 2008, 01:52
I tried inheriting QWidget but it has different it frozen my first dialog (which was in the middle of downloading a file ) and when my other dialog downloaded the file it somehow triggered my first dialog to think that he is done with his file....

so.. it did not work .. somehow the QFtp objects (instances) are tied together...

still seeking for answer to my questions,

baray98

wysota
10th April 2008, 10:25
Can we see some code related to ftp downloading?

baray98
10th April 2008, 18:24
my signal and slots connection


ftp = new QFtp(this);
connect(ftp, SIGNAL(commandFinished(int, bool)),
this, SLOT(ftpCommandFinished(int, bool)));
connect(ftp, SIGNAL(listInfo(const QUrlInfo &)),
this, SLOT(addToList(const QUrlInfo &)));
connect(ftp, SIGNAL(dataTransferProgress(qint64, qint64)),
this, SLOT(updateDataTransferProgress(qint64, qint64)));






void FtpDialog::downloadFile()
{
m_dir = QFileDialog::getExistingDirectory(this, tr("Save To Directory"),
m_dir,
QFileDialog::ShowDirsOnly
| QFileDialog::DontResolveSymlinks);
if (m_dir.isEmpty())
{
return;
}
selectedFiles = fileList->selectedItems(); // fileList is a QTreeWidget
disconnect(downloadButton, SIGNAL(clicked()), this, SLOT(downloadFile()));
connect(downloadButton, SIGNAL(canceled()), this, SLOT(cancelDownload()));
for (int i = 0; i < selectedFiles.count(); i++)
{
QTreeWidgetItem* item = selectedFiles.at(i);
QIcon icon = item->icon(NameColumn);
icon.addFile(":/ftpSelected.png");
item->setIcon(NameColumn,icon);
}

for (int i = 0 ; i < selectedFiles.count(); i++)
{
currentFileItem = selectedFiles.at(i);
fileList->setCurrentItem(currentFileItem);
QString fileName = currentFileItem->text(NameColumn);
done = false;
if (QFile::exists(m_dir+"/"+fileName))
{
QMessageBox::critical(this, tr("FTP"),
tr("There already exists a file called \"%1\" in "
"the target directory. For safety reason,"
"Delete the existing file manually in \"%2\" !")
.arg(fileName)
.arg(m_dir));
continue;
}

file = new QFile(m_dir+"/"+fileName);
if (!file->open(QIODevice::WriteOnly))
{
QMessageBox::information(this, tr("FTP"),
tr("Unable to save the file %1: %2.")
.arg(fileName).arg(file->errorString()));
delete file;
continue;
}
startTime = QTime::currentTime();
ftp->get(currentFileItem->text(NameColumn), file); // getting file starts here
statusLabel->setText(tr("Downloading %1...to Directory %2").arg(fileName)
.arg(m_dir));
downloadButton->setText("Cancel Download");
while(ftp->hasPendingCommands() || ftp->currentCommand()!=QFtp::None)
{
qApp->processEvents();
}
}
selectedFiles.clear();
downloadButton->setText("Download");
disconnect(downloadButton, SIGNAL(canceled()), this, SLOT(cancelDownload()));
connect(downloadButton, SIGNAL(clicked()), this, SLOT(downloadFile()));
}

void FtpDialog::ftpCommandFinished(int, bool error)
{
setCursor(Qt::ArrowCursor);

if (ftp->currentCommand() == QFtp::ConnectToHost)
{
if (error)
{
QMessageBox::information(this, tr("FTP"),
tr("Unable to connect to the FTP server "
"at %1. Please check that the host "
"name is correct.")
.arg(ftpServerLineEdit->text()));
connectOrDisconnect();
return;
}

statusLabel->setText(tr("Logged onto %1.")
.arg(ftpServerLineEdit->text()));
fileList->setFocus();
downloadButton->setDefault(true);
connectButton->setEnabled(true);
return;
}
if (ftp->currentCommand() == QFtp::Close)
{
statusLabel->setText(tr("Disconnected from %1.")
.arg(ftpServerLineEdit->text()));
return;
}


if (ftp->currentCommand() == QFtp::Login)
ftp->list();

if (ftp->currentCommand() == QFtp::Get)
{
if (error)
{
statusLabel->setText(tr("Canceled download of %1.")
.arg(file->fileName()));
file->close();
file->remove();

selectedFiles.clear();
done = true;
}
else
{
statusLabel->setText(tr("Downloaded %1 ")
.arg(file->fileName()));
file->close();
done = true;
previousTime = QTime(0,0,0,0);
previousReadBytes = 0;
currentFileItem->setText(DownloadStatusColumn,QString("%1")
.arg(100));
currentFileItem->setIcon(NameColumn,QPixmap(":/ftpDownloaded.png"));
}
delete file;
enableDownloadButton();
}
else if (ftp->currentCommand() == QFtp::List)
{
if (isDirectory.isEmpty())
{
fileList->addTopLevelItem(new QTreeWidgetItem(QStringList() << tr("<empty>")));
fileList->setEnabled(false);
}
}
}

wysota
10th April 2008, 20:47
Why are you using processEvents()? Why not rely on QFtp's signals?

baray98
11th April 2008, 03:03
like what for example... it thought there was nothing wrong in that but can you elaborate on the logic of not using processEvents().

baray98

wysota
11th April 2008, 06:54
You are practically spinning a local event loop effectively stopping the flow and probably preventing your other window from executing its code. You should really use an event controlled approach.

You should connect to its signals, queue requests and return from the function. When QFtp is done doing its job, it will call your slot so can do everything you want to do.