Results 1 to 17 of 17

Thread: qftp in qthread canot upload file

  1. #1
    Join Date
    Dec 2006
    Posts
    36
    Thanked 1 Time in 1 Post

    Default qftp in qthread canot upload file

    I used qftp in the qthread,but when i upload file ,I Cannot find the uploaded file and the signal code cannot be executed when debug.the following is code
    Qt Code:
    1. //////////////storethread.h/////////
    2. class storescpThread:public QThread
    3. {
    4. Q_OBJECT
    5. public:
    6. storescpThread(QTextEdit *txtEdit,QObject *parent = 0);
    7. ~storescpThread();
    8. private slots:
    9. void connectOrDisconnect();
    10. void ftpListInfo(const QUrlInfo &urlInfo);
    11. void ftpCommandFinished(int commandId, bool error);
    12. void updateDataTransferProgress(qint64 readBytes,qint64 totalBytes);
    13. private :
    14. QTextEdit * textEdit;
    15. QFtp *ftp;
    16. QFile *file;
    17. QStringList fileList;
    18. }
    19. /////////////////////////storethread.cxx//////////
    20. storescpThread::storescpThread(QTextEdit *txtEdit,QObject *parent): QThread(parent)
    21. {
    22. ftp=0;
    23. }
    24. void storescpThread::connectOrDisconnect()
    25. {
    26. if (ftp) {
    27. ftp->abort();
    28. ftp->deleteLater();
    29. ftp = 0;
    30. }
    31.  
    32. ftp = new QFtp(this);
    33.  
    34. //the SLOT function not be perfomed! why?
    35. [FONT="Arial Black"]connect(ftp, SIGNAL(commandFinished(int, bool)),
    36. this, SLOT(ftpCommandFinished(int, bool)));
    37. connect(ftp, SIGNAL(listInfo(const QUrlInfo &)),
    38. this, SLOT(ftpListInfo(const QUrlInfo &)));
    39. connect(ftp, SIGNAL(dataTransferProgress(qint64, qint64)),
    40. this, SLOT(updateDataTransferProgress(qint64, qint64)));[/FONT]
    41.  
    42. ftp->connectToHost("192.168.1.1");
    43. ftp->login("ftpuser","ftpuser");
    44. ftp->cd("/data"); //init dir
    45. fileList.clear();
    46. ftp->list();
    47. QFile file("c:\\testdata.jpg");
    48. if (!file.open(QIODevice::ReadOnly))
    49. return false;
    50. QFileInfo fi(filename);
    51. ftp->put(&file,"testtest.jpg"); //the file not be uploaded!!!!!
    52.  
    53.  
    54. }
    55. // the following SLOT not be perfomed!where is the emited message?
    56. void storescpThread::ftpCommandFinished(int, bool error)
    57. {
    58.  
    59. if (ftp->currentCommand() == QFtp::ConnectToHost) {
    60. if (error) {
    61. QMessageBox::information(0, tr("FTP"),
    62. tr("error"));
    63. return;
    64. }
    65. return;
    66. }
    67.  
    68. if (ftp->currentCommand() == QFtp::Get) {
    69.  
    70. }
    71. if (ftp->currentCommand() == QFtp::List) {
    72. QMessageBox::information(0, tr("FTP"),"LIST");
    73. }
    74. if (ftp->currentCommand() == QFtp::Put) {
    75.  
    76. }
    77. }
    78.  
    79. void storescpThread::updateDataTransferProgress(qint64 readBytes, qint64 totalBytes)
    80. {
    81. }
    82.  
    83. void storescpThread::ftpListInfo(const QUrlInfo &urlInfo)
    84. {
    85. fileList<<urlInfo.name() ;
    86. }
    To copy to clipboard, switch view to plain text mode 

  2. #2
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Thanks
    8
    Thanked 541 Times in 521 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: qftp in qthread canot upload file

    I can tell you why it doesn't work.

    QFtp uses QTimer to schedule commands. QTimer posts timer events in the thread that created it. But your QThread does not have an event handler (can be started only with exec() ).

    Funny thing is that sometimes, when an event is posted in a thread that does not have an event handler, it will break your main thread's event handler ( just happened to my yesterday). You should see a message in the console: "QObject: startTimer - timers cannot be started from another thread" and everything stops in the main thread..

    Solution - Post events from your thread in the QApplication thread (which has an event loop ), and create the FTP server, handle ftp commands ( clients, etc ... ), as responses to these events.

    If you decide to use this then you will need to implement your own custom events classes.

    Or, maybe someone else has a better solution that this.

    Regards.
    Marcel.

  3. #3
    Join Date
    Dec 2006
    Posts
    36
    Thanked 1 Time in 1 Post

    Default Re: qftp in qthread canot upload file

    thanks,can you tell me how post event to main thread?I never thought QFP is so poor!
    Last edited by cxl2253; 5th April 2007 at 07:41.

  4. #4
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Thanks
    8
    Thanked 541 Times in 521 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: qftp in qthread canot upload file

    With QApplication::postEvent.

    Take a look at the QApplication and QEvent descriptions in the Assistant.

    Are you sure you need a thread for the ftp server? Since it uses a timer to schedule commands, it will probably not block your interface... Never used it, though...

  5. #5
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: qftp in qthread canot upload file

    You have to start the event loop of the thread by reimplementing run() and calling exec() there. Without that signals/slots won't work in the thread.

  6. #6
    Join Date
    Dec 2006
    Posts
    36
    Thanked 1 Time in 1 Post

    Default Re: qftp in qthread canot upload file

    In fact I have reimplement the run() and call exec(),but it's still not success.I am very disppointed.Maybe anybody can give a demo ,how to call QFTP in Qthread??thanks.

  7. #7
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: qftp in qthread canot upload file

    Could you verify first that your slots actually get called?

  8. #8
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Thanks
    8
    Thanked 541 Times in 521 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: qftp in qthread canot upload file

    Calling exec() in run() won't block everything? I mean, exec() will exit when exit() is called.
    That is why I suggested the events solution. There is no need to implement an event handler in the thread.

    Regards

  9. #9
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    5,372
    Thanks
    28
    Thanked 976 Times in 912 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: qftp in qthread canot upload file

    Quote Originally Posted by cxl2253 View Post
    Qt Code:
    1. class storescpThread:public QThread
    2. {
    3. Q_OBJECT
    4. public:
    5. storescpThread(QTextEdit *txtEdit,QObject *parent = 0);
    6. ~storescpThread();
    7. private slots:
    8. void connectOrDisconnect();
    9. void ftpListInfo(const QUrlInfo &urlInfo);
    10. void ftpCommandFinished(int commandId, bool error);
    11. void updateDataTransferProgress(qint64 readBytes,qint64 totalBytes);
    12. private :
    13. QTextEdit * textEdit;
    14. QFtp *ftp;
    15. QFile *file;
    16. QStringList fileList;
    17. }
    To copy to clipboard, switch view to plain text mode 
    Where is storescpThread::run()? How did you manage to use storescpThread without it? Also QTextEdit shouldn't be there --- you can't use widgets in a non-GUI thread.

    Quote Originally Posted by cxl2253 View Post
    ftp = new QFtp(this);
    Don't make "this" a parent of ftp object, as it should live the new thread, whereas "this" lives in the GUI-thread.

    Quote Originally Posted by cxl2253 View Post
    connect(ftp, SIGNAL(commandFinished(int, bool)), this, SLOT(ftpCommandFinished(int, bool)));
    connect(ftp, SIGNAL(listInfo(const QUrlInfo &)), this, SLOT(ftpListInfo(const QUrlInfo &)));
    connect(ftp, SIGNAL(dataTransferProgress(qint64, qint64)), this, SLOT(updateDataTransferProgress(qint64, qint64)));
    Better add Qt::DirectConnection paremeter to each of these connect statements.

    How do you start that thread? Do you make any connections between storescpThread and other objects in other parts of your application?

    Quote Originally Posted by marcel View Post
    You should see a message in the console: "QObject: startTimer - timers cannot be started from another thread" and everything stops in the main thread..
    Most likely you create objects in a wrong place. All objects that should live in a new thread should be created within QTread::run().

    Quote Originally Posted by marcel View Post
    Calling exec() in run() won't block everything? I mean, exec() will exit when exit() is called.
    That is why I suggested the events solution. There is no need to implement an event handler in the thread.
    On the contrary, it will make QFtp and queued connections work.

  10. #10
    Join Date
    Dec 2006
    Posts
    36
    Thanked 1 Time in 1 Post

    Default Re: qftp in qthread canot upload file

    thanks for your reply, i rewrite my code,but it's stiil no message.
    Qt Code:
    1. /////////////////////////cstorescp.h//////////////
    2. static unsigned long classAddress;
    3. class storescpThread:public QThread
    4. {
    5. Q_OBJECT
    6. public:
    7. storescpThread(QTextEdit *txtEdit,QObject *parent = 0);
    8. ~storescpThread();
    9. void StartStoreScp();
    10. protected:
    11. void run();
    12. void connectOrDisconnect();
    13. static void emitMsg( unsigned long user_value,char * filename)
    14. {
    15. storescpThread* pthis = (storescpThread*)user_value;
    16. pthis->setText(filename);
    17.  
    18. }
    19. private slots:
    20. void connectOrDisconnect();
    21. bool upLoadFile(QString checkcode,QString filename);
    22.  
    23. void ftpListInfo(const QUrlInfo &urlInfo);
    24. void ftpCommandFinished(int commandId, bool error);
    25. void updateDataTransferProgress(qint64 readBytes,qint64 totalBytes);
    26.  
    27.  
    28. private :
    29. QTextEdit * textEdit;
    30. QFtp *ftp; //连接FTP
    31. QFile *file;
    32. QStringList fileList;
    33.  
    34. int startSCP();
    35. void setText(T_DIMSE_StoreProgressState state,char * name);
    36. OFCondition storeSCP();
    37. static void storeSCPCallback();
    38.  
    39. }
    40.  
    41.  
    42. /////////////////////////cstorescp.cpp//////////////
    43. storescpThread::storescpThread(QTextEdit *txtEdit,QObject *parent): QThread(parent)
    44. {
    45. textEdit=txtEdit;
    46. classAddress =(unsigned long)this ;
    47. ftp=0;
    48. }
    49.  
    50. int storescpThread::startSCP()
    51. {
    52. /////consuming operation ///////
    53. while (!bTerminated)
    54. {
    55. Sleep(1); // avoid freeze!
    56. if (!dicom_storescp_process())
    57. break;
    58. }
    59. }
    60.  
    61. void storescpThread::run()
    62. {
    63. startSCP();
    64. exec();
    65. }
    66.  
    67. void storescpThread::setText(T_DIMSE_StoreProgressState state,char * name)
    68. {
    69. textEdit->append(name);
    70. upLoadFile("030600030230","c:\\1.jp2");
    71. }
    72. void storescpThread::connectOrDisconnect()
    73. {
    74. if (ftp) {
    75. ftp->abort();
    76. ftp->deleteLater();
    77. ftp = 0;
    78. }
    79. ftp = new QFtp;
    80. connect(ftp, SIGNAL(commandFinished(int, bool)),
    81. this, SLOT(ftpCommandFinished(int, bool)),Qt::DirectConnection );
    82. connect(ftp, SIGNAL(listInfo(const QUrlInfo &)),
    83. this, SLOT(ftpListInfo(const QUrlInfo &)),Qt::DirectConnection );
    84. connect(ftp, SIGNAL(dataTransferProgress(qint64, qint64),Qt::DirectConnection ),
    85. this, SLOT(updateDataTransferProgress(qint64, qint64)),Qt::DirectConnection );
    86.  
    87. ftp->connectToHost("192.168.1.3");
    88. ftp->login("ftpuser","ftpuser");
    89. ftp->cd("/pisdata"); //init dir
    90. fileList.clear();
    91. ftp->list();
    92. }
    93. bool storescpThread::upLoadFile(QString checkcode,QString filename)
    94. {
    95. connectOrDisconnect();
    96. QString ftpPath="/pisdata/";
    97. ftp->cd(ftpPath);
    98. QFile file(filename);
    99. if (!file.open(QIODevice::ReadOnly))
    100. return false;
    101. QFileInfo fi(filename);
    102. ftp->put(&file,"111.jp2");
    103. return true;
    104. }
    105. void storescpThread::ftpCommandFinished(int, bool error)
    106. {
    107.  
    108. if (ftp->currentCommand() == QFtp::ConnectToHost) {
    109. return;
    110. }
    111. return;
    112. }
    113.  
    114. if (ftp->currentCommand() == QFtp::Get) {
    115. }
    116. if (ftp->currentCommand() == QFtp::List) {
    117. QMessageBox::information(0, tr("FTP"),"LIST");
    118. }
    119. if (ftp->currentCommand() == QFtp::Put) {
    120.  
    121. }
    122. }
    123.  
    124. void storescpThread::updateDataTransferProgress(qint64 readBytes,
    125. qint64 totalBytes)
    126. {
    127. //progressDialog->setMaximum(totalBytes);
    128. //progressDialog->setValue(readBytes);
    129. }
    130.  
    131.  
    132. void storescpThread::ftpListInfo(const QUrlInfo &urlInfo)
    133. {
    134. fileList<<urlInfo.name() ;
    135. }
    136.  
    137. void storescpThread::storeSCPCallback()
    138. {
    139. //now call the static function to ftp
    140. emitMsg(classAddress,progress->state,cbdata->imageFileName);
    141. }
    142. OFCondition storescpThread::storeSCP()
    143. {
    144. storeProvider(storeSCPCallback); ////////third party callback function
    145. }
    146.  
    147. void storescpThread::StartStoreScp()
    148. {
    149. if (!isRunning()) {
    150. start(NormalPriority);
    151. }
    152. }
    153. ////////////frmmain.cpp
    154. //textEdit constructed in SetUpUI
    155. frmMainWindow::frmMainWindow()
    156. {
    157. setupUi(this);
    158. mystorescpThread=new storescpThread(textEdit);
    159. mystorescpThread->StartStoreScp();
    160. }
    To copy to clipboard, switch view to plain text mode 
    Last edited by cxl2253; 6th April 2007 at 12:53.

  11. #11
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: qftp in qthread canot upload file

    This won't work. In StartSCP you enter an endless loop and exec() doesn't have a chance to execute. What does dicom_storescp_process() do?

  12. #12
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    5,372
    Thanks
    28
    Thanked 976 Times in 912 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: qftp in qthread canot upload file

    Quote Originally Posted by cxl2253 View Post
    QFile file("c:\\testdata.jpg");
    if (!file.open(QIODevice::ReadOnly)) return false;
    QFileInfo fi(filename);
    ftp->put(&file,"testtest.jpg"); //the file not be uploaded!!!!!
    You create file on the stack and then you pass a pointer to it to a non-blocking method --- this won't work, because QFtp::put() only stores that pointer and returns... and then file gets destroyed leaving ftp with a dangling pointer.

    Quote Originally Posted by cxl2253 View Post
    Qt Code:
    1. void storescpThread::setText(T_DIMSE_StoreProgressState state,char * name)
    2. {
    3. textEdit->append(name);
    4. upLoadFile("030600030230","c:\\1.jp2");
    5. }
    To copy to clipboard, switch view to plain text mode 
    You can't access widgets from a non-GUI thread directly. Better define a signal and connect it via queued connection to that text edit's append() slot.

  13. #13
    Join Date
    Dec 2006
    Posts
    36
    Thanked 1 Time in 1 Post

    Default Re: qftp in qthread canot upload file

    thanks for your help.But the emitMsg is called in static callback function.Maybe it's difficult to use SIGNAL/SLOTS. I have posted simililar problem,much people tell me that it is imposible to post signal in static function.
    Anymore ,you said dangling pointer, Do you mean I should decalre the QFile file variable as private member variable of storescpThread?

  14. #14
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    5,372
    Thanks
    28
    Thanked 976 Times in 912 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: qftp in qthread canot upload file

    Quote Originally Posted by cxl2253 View Post
    But the emitMsg is called in static callback function.
    setText() isn't a static method and you can emit signals from it. Touching widgets from a non-GUI thread will end with random crashes.

    Quote Originally Posted by cxl2253 View Post
    Do you mean I should decalre the QFile file variable as private member variable of storescpThread?
    You already have one, but you don't use it.

  15. #15
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    5,372
    Thanks
    28
    Thanked 976 Times in 912 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: qftp in qthread canot upload file

    Quote Originally Posted by cxl2253 View Post
    classAddress =(unsigned long)this ;
    Better use void * and reinterpret_cast, just in case you stumble upon an architeture where unsigned long has a different size than pointers.

  16. #16
    Join Date
    Dec 2006
    Posts
    36
    Thanked 1 Time in 1 Post

    Default Re: qftp in qthread canot upload file

    thanks,jacek. I will try it . if there are any questions,can you help me again?

  17. #17
    Join Date
    Dec 2006
    Posts
    36
    Thanked 1 Time in 1 Post

    Default Re: qftp in qthread canot upload file

    thanks ,jacek,I have emit the mssage and receive it now ,I must delete the moc file and re-moc it. Before i only re-moc it, thanks again.

Similar Threads

  1. File Binary Upload QHttp find the bug/s
    By patrik08 in forum Qt Programming
    Replies: 13
    Last Post: 10th June 2008, 07:51
  2. Sending Binary File with QFTP
    By nbkhwjm in forum Newbie
    Replies: 2
    Last Post: 7th March 2007, 18:10
  3. QHttp "PUT METHOD" QT Problem File Upload. RFC 2616
    By patrik08 in forum Qt Programming
    Replies: 7
    Last Post: 25th October 2006, 22:02

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.