Simple FTP client



  • Hi I am curious, how hard is it to get a simple FTP client created in QT?
    This is what I am trying to do:

    1. In Menu Press a button should open a ftp window.
    2. FTP should connect to aremote server
    3. ftp should put a file to remote server.
    4. ftp disconnects when window closes.

    No need to get file or list files. Just simple put. I am loking at an example, but that seems too elaborate
    for my needs.



  • Actually what you want to achieve seems to be quite easy to do. Of course it depends on how much you know about Qt (mind the lower case t!) or how fast you're learning.

    The "QtNetwork":http://qt-project.org/doc/qt-4.8/qtnetwork.html module provides a quite decent built-in FTP protocol with the "QFtp":http://qt-project.org/doc/qt-4.8/qftp.html class - although they recommend using "QNetworkAccessManager":http://qt-project.org/doc/qt-4.8/qnetworkaccessmanager.html (however I like QFtp much more for that task).

    It seems you are new to Qt - so I would recommend you to get familiar with some basic concepts before getting deeper into this. As with every framework out there you need to understand the basics before you can build more complex solutions.



  • Hi Daniel, appreciate the feedback. Yes I am new to Qt and C++. I am trying to learn really quick, I have a deadline to meet. My fault for procrastinating.



  • In that case I would recommend you to familiarize with QFtp. It provides all features you'll commonly want to use as member functions. I think it's worth mentioning that QFtp works completely asynchronous which means you have to react on the "QFtp::commandFinished(...)":http://qt-project.org/doc/qt-4.8/qftp.html#commandFinished signal for most algorithms.

    I think that it is easier to understand than sending FTP requests with QNetworkAccessManager as that requires some more work and is not so familiar if you know FTP.



  • It may not be a problem for you but notice that QFtp will be deprecated with Qt5:
    http://labs.qt.nokia.com/2011/05/12/qt-modules-maturity-level-the-list/



  • I knew that (still don't get why somebody would decide that) but thought it would be okay to reference to QFtp since QTShahal seems to be in need of a solution without much work :) - and as QNetworkAccessManager (still?) does not provide real FTP support I think QFtp to be the solution of choice.



  • I am trying this code from http://doc.trolltech.com/4.3/network-ftp.html

    @// main.cpp
    #include <QCoreApplication>
    #include <QDebug>
    #include <QFtp>
    class Ftp : public QFtp
    {
    Q_OBJECT
    public:
    Ftp(QObject* parent = 0)
    {
    connect(this, SIGNAL(listInfo(QUrlInfo)), this, SLOT(doListInfo(QUrlInfo)));
    connect(this, SIGNAL(done(bool)), QCoreApplication::instance(), SLOT(quit()));
    }
    protected slots:
    void doListInfo(const QUrlInfo& info)
    {
    qDebug() << info.name();
    }
    };
    int main(int argc, char* argv[])
    {
    QCoreApplication app(argc, argv);
    Ftp ftp;
    ftp.connectToHost("ftp.trolltech.com");
    ftp.login();
    ftp.list();
    ftp.close();
    return app.exec();
    }
    #include "main.moc"@

    I am testing this so that I can modify it for my use, but I am getting the following error:

    :-1: error: No rule to make target debug/main.moc', needed bydebug/Ftp.o'. Stop.

    Any idea how to resolve this? Thanks in advance



  • sorry .. I got the above code from here:

    http://www.qtcentre.org/threads/8139-QFtp-sample-program


  • Moderators

    How and what of Qt did you install?
    Do you use an IDE (e.g. Qt creator)?



  • I am using Qt creator


  • Moderators

    I am not an expert on Qt creator, but I assume that the reason of your problem lies in the fact that you just added a new class definition to your main.cpp.

    You need to introduce an additional header file containing the class definition. The macro Q_OBJECT shall add an additional build step for "moc".



  • I dont think that's it or I am not doing the header correctly. Trying the following now:
    Header file:
    @#ifndef MAINWINDOW_H
    #define MAINWINDOW_H
    #include <QMainWindow>
    namespace Ui {
    class MainWindow;
    class ButtonClicked;
    class Ftp;
    class QFtp;
    }
    class MainWindow : public QMainWindow
    {
    Q_OBJECT

    public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
    private slots:
    void ButtonClicked();
    void Ftp();
    private:
    Ui::MainWindow *ui;
    };

    #endif // MAINWINDOW_H
    @

    FTP.cpp:
    @// Ftp.cpp
    #include <QCoreApplication>
    #include <QDebug>
    #include <QFtp>

    int main(int argc, char* argv[])
    {
    QCoreApplication app(argc, argv);
    QStringList args = QCoreApplication::arguments();

    Ftp putter;
    if (!putter.putFile &#40;QUrl(args[1]&#41;))
        return 1;
    
    QObject::connect(&putter, SIGNAL(done()), &app, SLOT(quit()));
        return app.exec();
    

    }

    class Ftp : public QObject
    {
    Q_OBJECT

    public:
    Ftp(QObject* parent = 0);
    bool putFile (const QUrl &url);

    signals:
    void done();
    private slots;
    void ftpDone(bool error);

    private:
    QFtp ftp;
    QFile file;
    };

    FtpPut::FtpPut(QObject *parent)
    : QObject(parent)
    {
    connect (&ftp, SIGNAL(done(bool)), this, SLOT(ftpDone(bool)));
    }

    ftp.connectToHost(url.host(), url.port(21));
    ftp.login();
    ftp.put(url.path(), &file);
    ftp.close();
    return true;
    }
    @

    I modified this from a book that I bought. Originally the code was for getting a file. I still see this error:

    :-1: error: No rule to make target debug/main.moc', needed bydebug/Ftp.o'. Stop.


  • Moderators

    Well your source code changed considerably from previous post. You NEED to straighten your code. Otherwise the tools are being confused as well.

    You need to separate to header (declarations) and source (implementations) files.

    For your last code it would look similar to the following code.

    NOTE: Just roughly separated to give an idea what is meant. Not compiled not tested. And I am sure it will not compile, because some headers need to be included.

    MainWindow.h:
    @#ifndef MAINWINDOW_H
    #define MAINWINDOW_H
    #include <QMainWindow>
    namespace Ui {
    class MainWindow;
    class ButtonClicked;
    class Ftp;
    class QFtp;
    }
    class MainWindow : public QMainWindow
    {
    Q_OBJECT

    public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
    private slots:
    void ButtonClicked();
    void Ftp();
    private:
    Ui::MainWindow *ui;
    };

    #endif // MAINWINDOW_H
    @

    FTP.h:
    @
    #ifndef FTP_H_INCLUDED
    #define FTP_H_INCLUDED

    #includes <<<<<<<<<are missing

    class Ftp : public QObject
    {
    Q_OBJECT

    public:
    Ftp(QObject* parent = 0);
    bool putFile (const QUrl &url);

    signals:
    void done();
    private slots;
    void ftpDone(bool error);

    private:
    QFtp ftp;
    QFile file;
    };
    #endif
    @

    FTP.cpp:
    @// Ftp.cpp
    #include <QCoreApplication>
    #include <QDebug>
    #include <QFtp>

    #include "FTP.h"

    FtpPut::FtpPut(QObject *parent)
    : QObject(parent)
    {
    connect (&ftp, SIGNAL(done(bool)), this, SLOT(ftpDone(bool)));
    }

    ftp.connectToHost(url.host(), url.port(21));
    ftp.login();
    ftp.put(url.path(), &file);
    ftp.close();
    return true;
    }
    @

    main.cpp:
    @
    #includes <<<<<<<<<<<<<<<<<<<<are missing here

    int main(int argc, char* argv[])
    {
    QCoreApplication app(argc, argv);
    QStringList args = QCoreApplication::arguments();

    Ftp putter;
    if (!putter.putFile &#40;QUrl(args[1]&#41;))
        return 1;
    
    QObject::connect(&putter, SIGNAL(done()), &app, SLOT(quit()));
        return app.exec&#40;&#41;;
    

    }
    @



  • Thanks, I will try that and see what happens.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.