C++ ftp avec Qt.

Nathan -  
Char Snipeur Messages postés 9813 Date d'inscription   Statut Contributeur Dernière intervention   -
Bonjour,

J'aimerais savoir comment je pourrais m'y prendre afin de recupéré l'arborescense d'un ftp afin de la mettre dans une vue QTreeView avec comme modele un QStandardItem.
J'aimerais bien un petit code explicatif ou une explication dessus car je ne suis pas parvenue a le faire...
J'ai vu le signal : listInfo ( const QUrlInfo & i ) emi a la suite d'un QFtp::list ( const QString & dir = QString() ), mais c'est un QUrlInfo et j'avoue que je n'ai pas bien l'habitude d'utilisé cette objet.

Merci d'avance,
Cordialement Nathan;
A voir également:

23 réponses

Char Snipeur Messages postés 9813 Date d'inscription   Statut Contributeur Dernière intervention   1 299
 
tu y retourne forcément, ce que je te demandait c'est de vérifier.
Il faut bien voir que ftp->currentCommand() est différent de id !!
Le problème c'est que tu es dans la fonction qui est appelé lorsqu'une commande se termine, rien ne dit qu'une autre n'est pas en court, donc tu peux avoir une différence entre les deux.
Je pense que tu prends le programme par le mauvais bout.
Mais j'avoue que cette histoire d'id de commande n'est pas facile à gérer pour exécuter un programme séquentiellement.
Bref, à ta place je réfléchirait à une meilleur manière de structurer ton programme.
1
Char Snipeur Messages postés 9813 Date d'inscription   Statut Contributeur Dernière intervention   1 299
 
Il faut le faire à la main, je pense, à chaque entré du répertoire, tu captes le signal, et tu lances récursivement une recherche dans l'entrée trouvé. Ensuite, il faut réussir à tout bien organisé en hiérarchie.
Il reste aussi à discriminer les répertoires des fichiers.
0
Nathan
 
Justement c'est sa que j'ai essayé et que je ne parviens pas a faire... :/
J'arrive pas trop a manipulé le QUrlInfo.
0
greg
 
Ca se fait tout seul sous Windows avec la Winapi...
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Char Snipeur Messages postés 9813 Date d'inscription   Statut Contributeur Dernière intervention   1 299
 
Je n'ai pas vu qu'ils renvoyaient une QUrlInfo dans la doc.
Déjà, arrive tu à avoir la liste du répertoire courant ?
0
Nathan
 
Non justement je n'arrive pas.
Voici mon code (version reduite) :

fileList = new QTreeWidget;  //Je fais mon QTreeWidget
fileList->setEnabled(false);
fileList->setRootIsDecorated(false);
fileList->setHeaderLabels(QStringList() << tr("Name") << tr("Size") << tr("Owner") << tr("Group") << tr("Time"));
fileList->header()->setStretchLastSection(false);

QWidget *widget = new QWidget;
QGridLayout layout_1 = new QGridLayout;
layout_1->addWidget(fileList, 3, 0);      //Je place mon QTreeWidget dans ma fenêtre via un layout
widget->setLayout(layout_1);

connect(ftp, SIGNAL(commandFinished(int, bool)), this, SLOT(commandefini(int, bool)));
connect(ftp, SIGNAL(listInfo(QUrlInfo)), this, SLOT(arbo(QUrlInfo)));  //connexion des signaux avec les slots...

void fenetre::commandefini(int i, bool i2)
    {

        if (ftp->currentCommand() == QFtp::ConnectToHost)
        {
            if (i2)
            {
                ftp->close();
            }
        }

        if (ftp->currentCommand() == QFtp::Login)
        {
            ftp->list(); //Une fois la commande longin() terminé je lance list()
        }
}

void fenetre::arbo(QUrlInfo arbo1)
{
     QTreeWidgetItem *item = new QTreeWidgetItem;
     item->setText(0, arbo1.name());
     item->setText(1, QString::number(arbo1.size()));
     item->setText(2, arbo1.owner());
     item->setText(3, arbo1.group());
     item->setText(4, arbo1.lastModified().toString("MMM dd yyyy"));

     isDirectory[arbo1.name()] = arbo1.isDir();  //J'ai un QHash<QString, bool> isDirectory;
 dans mon .h
     fileList->addTopLevelItem(item);
     if (!fileList->currentItem())
     {
         fileList->setCurrentItem(fileList->topLevelItem(0));
         fileList->setEnabled(true);
     }

}


J'ai essayer de rajouté un : QMessageBox::information(this, "Information", "test");
au slot arbo pour voir si celui si été émi et je n'ai meme pas vu de petite boite dialogue s'ouvrir :(
J'en deduit donc que le slot arbo et fautive je n'arrive pas a sevoir pouquoi :/
0
Char Snipeur Messages postés 9813 Date d'inscription   Statut Contributeur Dernière intervention   1 299
 
Normalement, Qt marque un message d'erreur lorsque qu'une connexion est mal réalisée.
est tu sur que ftp->list() est bien appelé ?
De plus, je pense que tu utilises mal le commandFinished.
void fenetre::commandefini(int i, bool i2)
    {
        qDebug()<<"dans le slot."<<ftp->currentCommand()<<i<<i2;
        if (ftp->currentCommand() == QFtp::ConnectToHost)
        {
            if (i2)
            {
                ftp->close();
            }
        }

        if (ftp->currentCommand() == QFtp::Login)
        {
            ftp->list(); //Une fois la commande longin() terminé je lance list()
        }
}

Je pense qu'il faut utiliser "i", lorsque tu lance une commande, elle se voi attribué un id, et selon l'id tu peux savoir laquelle est finie, ce qui n'est pas forcément celle en cour. ça dépendra de comment ça se déroule.
0
Nathan
 
J'ai rajuté la ligne : qDebug()<<ftp->currentCommand()<<i<<i2;
Sa marche toujours pas... d'ailleurs t'est sur qu'il faut la rajouté ?
Sur cette exemple : http://doc.trolltech.com/4.5/network-ftp-ftpwindow-cpp.html ils le font pas...
0
Char Snipeur Messages postés 9813 Date d'inscription   Statut Contributeur Dernière intervention   1 299
 
cette ligne est une ligne de debug, c'est à dire que ça doit écrire le texte fourni sur une sorti console.
Est-ce que le programme écrit quelque chose ? si tu préfère met une boite d'information.
0
Nathan
 
Oui sa m'a renvoyé ceci :
commandefini : 3 1 false
commandefini : 4 2 false

J'ai donc modofié mon slot :
 void fenetre::commandefini(int i, bool i2)
    {

        if (ftp->currentCommand() == 3)
        {
            if (i2)
            {
                ftp->close();
            }
        }

        if (ftp->currentCommand() == 4)
        {
            ftp->list();
            QMessageBox::information(this, "Information", "test"); 
        }
    }


La boite de dialogue c'est ouverte donc mon slot arbo ne fonctionne pas :/
De plus j'ai mi ta ligne debug :

void fenetre::arbo(const QUrlInfo &arbo1)
{
    qDebug()<<"arbo : "<< arbo1.name();

     QTreeWidgetItem *item = new QTreeWidgetItem;
     item->setText(0, arbo1.name());
     item->setText(1, QString::number(arbo1.size()));
     item->setText(2, arbo1.owner());
     item->setText(3, arbo1.group());
     item->setText(4, arbo1.lastModified().toString("MMM dd yyyy"));

     isDirectory[arbo1.name()] = arbo1.isDir();
     fileList->addTopLevelItem(item);
     if (!fileList->currentItem())
     {
         fileList->setCurrentItem(fileList->topLevelItem(0));
         fileList->setEnabled(true);
     }

}


Et la rien pas de message par contre... 8-)
Logiquement je devrait voir s'affiché un QString de ma constante QUrlInfo...
0
Char Snipeur Messages postés 9813 Date d'inscription   Statut Contributeur Dernière intervention   1 299
 
Ce n'est pas que le slot ne fonctionne pas, mais peutêtre que le signal n'est pas émit.
récupére l'id :
int idList=ftp->list();
qDebug()<<idList<<ftp->state();
tu peux aussi récupérer le signal commandStarted(int) afin de faire une sorti de la commande qui est lancé.
Il est possible que le site ftp mette du temps à répondre.
Retournes tu dans commandefini après list() ?
0
Nathan
 
    void fenetre::commandefini(int i, bool i2)
    {

        if (ftp->currentCommand() == 3)
        {
            if (i2)
            {
                ftp->close();
            }
        }

        if (ftp->currentCommand() == 4)
        {
            int id = ftp->list();
            qDebug()<< id << ftp->state();
        }
    }


Il y a un truc bizard la avec ce code sa m'affiche :
Starting C:/jéjé/jeje/projet/Net Developpe/release/Net Developpe.exe...
3 4

J'ai un 3 sa devrait pas valoir 4 logiquement ? :s

Si non effectivement mon site ftp est lent mais au bout d'un certain temps sa devrait venir...

Et non pour le moment j'utilise commandefini juste pour login() et connectToHost
0
Nathan
 
Je débute avec QFtp donc oui j'ai un peu de mal, mais je pense avoir compri.
Dans mon slot pour me connecté j'ai ceci :
ftp->connectToHost(ftptext->text(), portnum->value());
ftp->login(utilisateurtext->text(), mdptext->text());

J'ai donc enchainé deux méthode de QFtp a la suite.
Je suppose donc que connectToHost n'est pas terminé lors de l'appel a login mais sa fonctionne c'est pourquoi je l'ai laissé.
Maintenant ce que je n'arrive toujours pas a comprendre c'est pourquoi lorsque je fais : int id = ftp->list();
la valeur de id est 3 alors que ftp->list(); est censé renvoyé sa valeur 6 et non 3 (valeur de connectToHost)
Si je fais ceci :
    void fenetre::commandefini(int i, bool i2)  //debut de mon slot
    {

        if (ftp->currentCommand() == 3)  //Si currentCommand() est terminé
        {
            if (i2)  //Si il c'est produit une erreur
            {
                ftp->close();
            }

        if (ftp->currentCommand() == 4)  //Une fois que currentCommand() est terminé je verifie si list() est terminé aussi
        {
            int id = ftp->list();
            qDebug()<< id << ftp->state();
        }

        }

    }
0
Nathan
 
Désolé pour le double poste, je viens de me rendre conte que je me suis trompé pour le code plus haut.
Etant donné que visiblement le ftp->connectToHost() ce fini apres ftp->login() la solution reviendrais a mettre ftp->list() une fois que ftp->connectToHost() est terminé non ?
Si non il faudrait attendre que le ftp->connectToHost() soit terminé pour lancé ftp->login() et apres une fois que ftp->login() est terminé lancé ftp->list().
0
Char Snipeur Messages postés 9813 Date d'inscription   Statut Contributeur Dernière intervention   1 299
 
ba oui, je pense que c'est le principe.
J'ai l'impression que tu as mal compris le principe de signal.
0
Nathan
 
Sa fait toujours pareil... :s
Starting C:/jéjé/jeje/projet/Net Developpe/release/Net Developpe.exe...
3 3
Pourtant j'ai bien mi cette fois :
    void fenetre::commandefini(int i, bool i2)
    {

        if (ftp->currentCommand() == 3)
        {
            if (i2)
            {
                ftp->close();
            }
            else
            {
            int id = ftp->list();
            qDebug()<< id << ftp->state();
            }
        }

        if (ftp->currentCommand() == 4)
        {
        }
    }

Tu saurais m'expliqué pourquoi id vaut 3 stp
Normalement ftp->list() renvoit la valeur de lui meme dans le int soit 6, hor il me renvoi la valeur de ftp->connectToHost()
0
Char Snipeur Messages postés 9813 Date d'inscription   Statut Contributeur Dernière intervention   1 299
 
Je ne sais pas, je n'ai pas ton programme entier en tête.
Faire :
void fenetre::commandefini(int i, bool i2)
    {
        if(i2) ftp->close();// dès qu'il y a une erreur il faut fermer le ftp !
        if (i == 3)
        {
            int id = ftp->list();
            qDebug()<<" lancement du list"<< id << ftp->state();
        }

        if (i == 4)
        {
             qDebug()<<"l'id recu vaut 4";
        }
        if(i!=3 && i!=4)qDebug()<<"fin d'une autre commande";
    }
me semble plus juste. Tu persistes avec currentCommand(), qui est beaucoup trop incertain. Tu viens de recevoir le signal comme quoi une commande est terminé, et tu lui demande laquelle est en court ! Et vu que tu relance des commande dans ta fonction, il n'est pas impossible que currentCommand change de valeur au court de la fonction.
0
Nathan
 
Quand je mes ton code j'obtiens ceci :

fin d'une autre commande 1
fin d'une autre commande 2

Avec id qui vaut 1 et 2.
Ces id correspondent aux methodes QFtp::SetTransferMode et QFtp::SetProxy. Pourtant je ne les utilisent nul part dans mon code.
A la suite de sa j'ai essayé le code :

void fenetre::commandefini(int i, bool i2)
{

        if (i2)
        {
                ftp->close();
        }

        if (i == 2)
        {
            int id = ftp->list();
            qDebug()<< id << ftp->state();
        }

        if (i == 1)
        {
            qDebug()<<4;
        }

        if(i!=3 && i!=4)qDebug()<<"fin d'une autre commande"<<i;
}


Et sa m'a renvoyé :

Starting C:/jéjé/jeje/projet/Net Developpe/release/Net Developpe.exe...
4
fin d'une autre commande 1
3 4
fin d'une autre commande 2

Je comprend pas pourquoi sa me renvoi 1 et 2 alors que j'utilise pas ces fonctions... :s
0
Char Snipeur Messages postés 9813 Date d'inscription   Statut Contributeur Dernière intervention   1 299
 
Merde, j'avais pas compris ça comme ça...
vérifie la valeur de QFtp::List
0
Nathan
 
Dans mon code QFtp::List vaut toujours 3, alors qu'il devrait valoir 6
3 c'est la valeur de QFtp::ConnectToHost :/
0