Page 1 of 2 12 LastLast
Results 1 to 20 of 30

Thread: QThread exec proplem to stop...

  1. #1
    Join Date
    May 2006
    Posts
    788
    Thanks
    49
    Thanked 48 Times in 46 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default QThread exec proplem to stop...

    this is my 2° QThread wo i write ...
    the class to get remote dir list work on apache2 now to get recursive dir and file list i like a QThread to speed up all... how i can tell QThread to paint data to a model...

    if i make a
    connect(this, SIGNAL(finished()), this, SLOT(PaintData()));
    not work ... but data exist...

    all class are on main attachment...


    Qt Code:
    1. class DavListDir : public QThread
    2. {
    3. Q_OBJECT
    4.  
    5. public:
    6. void run();
    7. void SetUrl( QUrl u );
    8. signals:
    9. void statusMessage(QString);
    10. void TimeEnd();
    11. private:
    12. QUrl urltogrep;
    13. HTTP_propfind *jobb;
    14. public slots:
    15. void PaintData();
    16. };
    17. void DavListDir::SetUrl( QUrl u )
    18. {
    19. urltogrep = QUrl(u);
    20. connect(this, SIGNAL(finished()), this, SLOT(PaintData()));
    21. }
    22.  
    23. void DavListDir::PaintData()
    24. {
    25. /* prepare to paint remote dir list on tree model */
    26. std::cout << "end cycle " << std::endl;
    27. std::cout << qPrintable(jobb->GetDAVData()) << std::endl;
    28. }
    29.  
    30. void DavListDir::run()
    31. {
    32. jobb = new HTTP_propfind(urltogrep);
    33. jobb->Start();
    34. exec();
    35. }
    To copy to clipboard, switch view to plain text mode 
    Attached Files Attached Files

  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: QThread exec proplem to stop...

    As I told you some time ago, you cannot update widgets from any other thread than the GUI thread.

    There are a few solutions to this, but all involve passing the model data to the GUI thread.
    In your case this is fairly simple. Since the data is complete (OK) when finished(), then connect the finished() signal somewhere in your GUI thread.

    Then, when it is emitted, in the slot from the GUI thread just get thread->job->GetDAVData() before you delete the thread.

    I hope you understand what I mean.

    Another solution is to register the type of jobb as a Qt metatype and pass it through a signal to the GUI thread.

    But the first solution is simpler and will work for you.

    Regards

  3. #3
    Join Date
    May 2006
    Posts
    788
    Thanks
    49
    Thanked 48 Times in 46 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: QThread exec proplem to stop...

    Yes but on cast can i not access the objekt QThread ?

    DavListDir *incomming = qobject_cast<DavListDir *>(sender());

    QThread not emit finished ?? why?

    QThread is hard eat..

    and so poor examples .. on the new code search... google.

    http://www.google.com/codesearch?hl=...lang%3Ac%2B%2B




    Qt Code:
    1. /* ############################# QThread start method ###*/
    2.  
    3. class DavListDir : public QThread
    4. {
    5. Q_OBJECT
    6.  
    7. public:
    8. void run();
    9. QString GetxmlData();
    10. void SetUrl( QUrl u );
    11. signals:
    12. void statusMessage(QString);
    13. void TimeEnd();
    14. private:
    15. QUrl urltogrep;
    16. HTTP_propfind *jobb;
    17. public slots:
    18. };
    19. void DavListDir::SetUrl( QUrl u )
    20. {
    21. urltogrep = QUrl(u);
    22. }
    23. QString DavListDir::GetxmlData()
    24. {
    25. return jobb->GetDAVData();
    26. }
    27.  
    28. void DavListDir::run()
    29. {
    30. jobb = new HTTP_propfind(urltogrep);
    31. jobb->Start();
    32. exec();
    33. }
    34.  
    35.  
    36. /* ############################# compose dir tree #*/
    37.  
    38.  
    39. class Tree_Dir_LS : public QObject
    40. {
    41. Q_OBJECT
    42. //
    43. public: Tree_Dir_LS( QObject* = 0 )
    44. {
    45. passage = 0;
    46. std::cout << "construct class " << std::endl;
    47. ls_a(QUrl("http://user:pass@192.168.1.33/webdav/"));
    48. ls_a(QUrl("http://user:pass@192.168.1.33/webdav/www/"));
    49. ls_a(QUrl("http://user:pass@192.168.1.33/webdav/www/notexist/"));
    50.  
    51. }
    52.  
    53. public:
    54. void ls_a( QUrl dir )
    55. {
    56. DavListDir *cann = new DavListDir();
    57. cann->SetUrl(dir);
    58. cann->start(QThread::HighPriority);
    59. connect(cann, SIGNAL(finished()), this, SLOT(PaintData()));
    60. }
    61.  
    62. protected:
    63. int passage;
    64. private:
    65. signals:
    66. public slots:
    67. void PaintData()
    68. {
    69. passage++;
    70. DavListDir *incomming = qobject_cast<DavListDir *>(sender()); /* any sender dir level having any info from dir... path e file */
    71. std::cout << "----------------append dir tree nr. " << passage << " --------------" << std::endl;
    72. std::cout << qPrintable(incomming->GetxmlData()) << std::endl;
    73. incomming->quit();
    74. }
    75.  
    76. };
    To copy to clipboard, switch view to plain text mode 

  4. #4
    Join Date
    May 2006
    Posts
    788
    Thanks
    49
    Thanked 48 Times in 46 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: QThread exec proplem to stop...

    Is this mistake if i say QObject can not get QThread finisch signal; only Gui like QWidget, QDialog, QMainWindow can du that?

    This QThread must build recursive remote dir and get info to pass on QObject... like a dirmodel.

  5. #5
    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: QThread exec proplem to stop...

    No, they should get the finished signal.
    The only thing you must worry about is the thread finish condition.
    I mean, when does the thread stop? Are the recursion conditions correct?
    If you can get these straight, then the thread will exit OK and you will get the finished signal, therefore be able to extract the data.

    Please correct me if I'm wrong.

    Regards

  6. #6
    Join Date
    May 2006
    Posts
    788
    Thanks
    49
    Thanked 48 Times in 46 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: QThread exec proplem to stop...

    Quote Originally Posted by marcel View Post
    No, they should get the finished signal.
    The only thing you must worry about is the thread finish condition.
    I mean, when does the thread stop? Are the recursion conditions correct?
    If you can get these straight, then the thread will exit OK and you will get the finished signal, therefore be able to extract the data.

    Please correct me if I'm wrong.
    Regards
    yes this is correct ... on the QObject i call the QThread wo self exec() this call
    HTTP_propfind( QUrl urigo ) <- this emit only a return QString xml ls info from dir or empty..
    on error...

    on subclass QHttp i have only two signal..

    connect(this, SIGNAL(requestFinished(int, bool)), this, SLOT(EndTakeData(int, bool)));
    connect(this, SIGNAL(done(bool)), this, SLOT(abort()));

    can this break QThread?

    can this break finished() signal ... i show on main.moc and i found the signal from QThread -> QObject.....

    Qt Code:
    1. void ls_a( QUrl dir )
    2. {
    3. DavListDir *cann = new DavListDir(); /* QThread */
    4. cann->SetUrl(dir);
    5. cann->start(QThread::HighPriority);
    6. connect(cann, SIGNAL(finished()), this, SLOT(Read_LS_all()));
    7. }
    8.  
    9. void Read_LS_all()
    10. {
    11. DavListDir *incomming = qobject_cast<DavListDir *>(sender());
    12. QString xmlls = incomming->GetxmlData();
    13. append xmlls to tree..
    14. ..........
    To copy to clipboard, switch view to plain text mode 

    or must i start the QThread on QObject
    class....
    cann->start(QThread::HighPriority); ++
    cann->wait() ++

    like $QTDIR/examples/threads/waitconditions ?

    note at end on main.cpp i have

    #include "main.moc"

    can this break signal.. ? i think no if i leave QThread the ls dir QHttp runn corecet..

  7. #7
    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: QThread exec proplem to stop...

    Creating the QHttp object does not break anything because you start the thread's event loop with exec. QHttp will emit timer events from time to time, so it needs an event loop.

    How were you starting the thread until now?
    The correct way is calling start ( you can do that from the thread's creator/parent ).
    Once you call start, the run() method is executed. After it leaves run() the finished signal will be emitted.
    So if you don't get the finished signal it means that something goes wrong in run().

    About wait conditions: why do you use them? Do you have any shared data that the GUI thread and the worker thread have to read/write?
    From what I have seen you don't need wait conditions. Not even a mutex, because, from what you said, the complete data( the directory structure ) is available only when the thread finishes.

    You don't need any casts, or anything. Just in the thread's creator, when you receive the finished signal, get the data and update the model.

    Could you post the code section where you create the thread and the whole current version of the thread code?
    And please do not post any additional code, because it tends to be misleading .

    Regards

  8. #8
    Join Date
    May 2006
    Posts
    788
    Thanks
    49
    Thanked 48 Times in 46 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: QThread exec proplem to stop...

    Quote Originally Posted by marcel View Post
    Creating the QHttp object does not break anything because you start the thread's event loop with exec. QHttp will emit timer events from time to time, so it needs an event loop.

    How were you starting the thread until now?
    The correct way is calling start ( you can do that from the thread's creator/parent ).
    Once you call start, the run() method is executed. After it leaves run() the finished signal will be emitted.
    So if you don't get the finished signal it means that something goes wrong in run().
    Could you post the code section where you create the thread and the whole current version of the thread code?
    And please do not post any additional code, because it tends to be misleading .

    Regards
    on this case the mistake is that all run on main.cpp if QObject send and take finisch

    all code is on one main.cpp attachment...

    pro file ...

    Qt Code:
    1. TEMPLATE = app
    2. TARGET =
    3. DEPENDPATH += .
    4. INCLUDEPATH += .
    5. QT += xml
    6. QT += network
    7. CONFIG += console
    8. CONFIG += qt warn_off release
    9. LANGUAGE = C++
    10. TARGET = xx
    11. DESTDIR = ./
    12. SOURCES += main.cpp
    To copy to clipboard, switch view to plain text mode 
    Attached Files Attached Files

  9. #9
    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: QThread exec proplem to stop...

    OK, just took a look on your code.
    jobb->Start will exit immediately.

    What I have missed to tell you is that when using QThread::exec, to stop the thread you either must destroy the main widget or call QThread::exit() or QThread::quit().

    You must do one of the last two.
    You must call them when QHttp has finished. This means that you will have to add a signal in HTTP_propfind that will be connected to a slot in the thread ( endThread for example ).

    You must emit the signal from HTTP_propfind when QHttp has finished all request ( meaning when you are sure everything is done ).
    In the endThread slot you just call exit(0) or quit().
    This sequence results in the finished signal getting emitted.

    However - I noticed you use the thread only for the QHttp requests. QHttp alone is not designed(thought) to be used in a separate thread.
    It is asynchronous and state driven - meaning it will not block the parent thread wile working.
    On the other hand, there is nothing wrong in using QHttp like you did - just some extra code.
    Anyway, it is your decision.

    Regards

  10. #10
    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: QThread exec proplem to stop...

    Quote Originally Posted by marcel View Post
    The correct way is calling start ( you can do that from the thread's creator/parent ).
    Once you call start, the run() method is executed. After it leaves run() the finished signal will be emitted.
    Actually, it's a little different if you want to use signals within the thread. See my next comment.
    So if you don't get the finished signal it means that something goes wrong in run().
    One has to call exec() within run() to start the event loop for the thread so that signals can be emitted. Without it QHttp or any other class that uses events (signals included) won't function properly. Please note that this doesn't concern the finished() signal as it is emitted from the parent (where QThread object was created) thread.

  11. #11
    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: QThread exec proplem to stop...

    Yes, exactly what I said.
    But Patrik's problem is that he cannot stop the thread .
    Everything works well ( he starts the event loop and all ), but the thread doesn't ever finish because he wasn't calling exit or quit anywhere.

    One has to call exec() within run() to start the event loop for the thread so that signals can be emitted.
    Not so sure about that. Signals can be emitted from within the thread to other threads - this works because the are nothing but some events. It is similar to calling QApplication: postEvent( someThread, someEvent ).

    Without it QHttp or any other class that uses events (signals included) won't function properly
    Yes, any event that targets this thread( without an event loop ) is a potential danger to the entire application ( therefore to other threads ).
    It happened to me - I was trying to create a pixmap( load it from disk ) in some thread that didn't have an event loop. But QPixmapCache( used internally by QPixmap ) sends timer events to the creator thread.
    This resulted in the GUI thread's event loop getting compromised ( most of the times stopped processing it's own events ).
    I am not sure if you remember it, but it was about the same time when I had problems with that crash in QProgressDialog.
    Anyway, to make a long story short ( too late, I guess ), signals can be emitted from threads without event handlers but the other way around is not safe at all - actually it won't work( since we're talking about queued connection ).

    Please note that this doesn't concern the finished() signal as it is emitted from the parent (where QThread object was created) thread.
    Good to know that.

    Regards

  12. The following user says thank you to marcel for this useful post:

    patrik08 (20th May 2007)

  13. #12
    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: QThread exec proplem to stop...

    Quote Originally Posted by marcel View Post
    Not so sure about that. Signals can be emitted from within the thread to other threads - this works because the are nothing but some events. It is similar to calling QApplication: postEvent( someThread, someEvent ).
    I'm talking about using signals within a thread, but this generally applies to using slots across threads as well.

    Yes, any event that targets this thread( without an event loop ) is a potential danger to the entire application ( therefore to other threads ).
    If a thread doesn't have an event loop, all its objects' events won't ever be processed.

  14. The following user says thank you to wysota for this useful post:

    patrik08 (20th May 2007)

  15. #13
    Join Date
    May 2006
    Posts
    788
    Thanks
    49
    Thanked 48 Times in 46 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: QThread exec proplem to stop...

    Hurra now is run .... and i can take 10 or more remote dir ls -al on 800
    millisecond. (lan)

    the next QHttp i build direct inside QThread to suppress many class...


    Qt Code:
    1. /*
    2.  on subclass QHttp i suppress close on this way ..
    3.  i observer that QThread wait for close ...
    4. ( opinion or mistake? whitout this close nothing run.. )
    5. */
    6. void close()
    7. {
    8. deleteLater();
    9. }
    10.  
    11.  
    12.  
    13. class DavListDir : public QThread
    14. {
    15. Q_OBJECT
    16. public:
    17. void run();
    18. QString GetxmlData();
    19. void SetUrl( QUrl u );
    20. signals:
    21. void statusMessage(QString);
    22. void TimeEnd();
    23. private:
    24. QUrl urltogrep;
    25. QString ned;
    26. HTTP_propfind *jobb;
    27. public slots:
    28. void quit();
    29.  
    30. };
    31. void DavListDir::quit()
    32. {
    33. ned = jobb->GetDAVData();
    34. emit finished();
    35. std::cout << "----- quit call..." << std::endl;
    36. exit(0);
    37. }
    38. void DavListDir::SetUrl( QUrl u )
    39. {
    40. urltogrep = QUrl(u);
    41. jobb = new HTTP_propfind(urltogrep); /* QHttp first setup header .... */
    42. connect(jobb, SIGNAL(done(bool)), this, SLOT(quit()));
    43. }
    44.  
    45. QString DavListDir::GetxmlData()
    46. {
    47. return ned;
    48. }
    49.  
    50. void DavListDir::run()
    51. {
    52. if (!urltogrep.isValid()) {
    53. quit();
    54. return;
    55. }
    56. jobb->start();
    57. exec(); /* QHttp start request */
    58. forever{
    59. if (isFinished()) {
    60. ned = jobb->GetDAVData();
    61. emit finished();
    62. }
    63. };
    64. }
    To copy to clipboard, switch view to plain text mode 

  16. #14
    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: QThread exec proplem to stop...

    Hmmm.... This code is.... well... how should I say that.... hmm... incorrect
    This way the thread will never terminate... What's the point of spinning in the forever loop?

  17. #15
    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: QThread exec proplem to stop...

    You shouldn't emit finished() from the thread.
    Wysota said that the parent must emit this signal - seem logical.

    Anyway, the code in run() that comes after exec() gets called only when you call quit() or exit().
    I suppose it is correct, but you shouldn't emit finished() here. Just let the thread exit from run() by itself, and it's parent will emit finished() when appropriate.

    Regards.

  18. #16
    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: QThread exec proplem to stop...

    Quote Originally Posted by wysota View Post
    Hmmm.... This code is.... well... how should I say that.... hmm... incorrect
    This way the thread will never terminate... What's the point of spinning in the forever loop?
    It will finish, but only if he calls quit() outside the thread ...This is one crazy thread.

    Oh, BTW QThread::quit() is not virtual, neither is exit. So I'm not sure how correct it is to reimplement it. Anyway, if qt uses your class, it will call the base class version.

    On the other hand, if you use it on an instance of your class, it will get called ok.
    Why not rename it to something else, and call exit or quit in that function, as you do now.

  19. #17
    Join Date
    May 2006
    Posts
    788
    Thanks
    49
    Thanked 48 Times in 46 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: QThread exec proplem to stop...

    Quote Originally Posted by wysota View Post
    Hmmm.... This code is.... well... how should I say that.... hmm... incorrect
    This way the thread will never terminate... What's the point of spinning in the forever loop?
    not enter on forefer ... i delete...

  20. #18
    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: QThread exec proplem to stop...

    Well, OK then.
    But remember, even if the code works right now, it is not conceptually correct.
    So, when you have the time, you should do a small redesign of your thread subclass.

    Regards

  21. #19
    Join Date
    May 2006
    Posts
    788
    Thanks
    49
    Thanked 48 Times in 46 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: QThread exec proplem to stop...

    Quote Originally Posted by marcel View Post
    It will finish, but only if he calls quit() outside the thread ...This is On the other hand, if you use it on an instance of your class, it will get called ok.
    Why not rename it to something else, and call exit or quit in that function, as you do now.
    is running ....

    Qt Code:
    1. class DavListDir : public QThread
    2. {
    3. Q_OBJECT
    4. public:
    5. void run();
    6. void SetUrl( QUrl u );
    7. signals:
    8. void DataXml(QString);
    9. /*void TimeEnd();*/
    10. private:
    11. QUrl urltogrep;
    12. QString ned;
    13. HTTP_propfind *jobb;
    14. public slots:
    15. void grepdata();
    16.  
    17. };
    18. void DavListDir::grepdata()
    19. {
    20. ned = jobb->GetDAVData();
    21. if (ned.size() > 0) {
    22. emit DataXml(ned);
    23. exit(0);
    24. }
    25. }
    26. void DavListDir::SetUrl( QUrl u )
    27. {
    28. urltogrep = QUrl(u);
    29. jobb = new HTTP_propfind(urltogrep); /* QHttp first setup header .... */
    30. connect(jobb, SIGNAL(done(bool)), this, SLOT(grepdata()));
    31. }
    32. void DavListDir::run()
    33. {
    34. if (!urltogrep.isValid()) {
    35. quit();
    36. return;
    37. }
    38. jobb->start(); /* QHttp start request */
    39. exec();
    40. forever{
    41. if (isFinished()) {
    42. emit grepdata();
    43. }
    44. };
    45. }
    To copy to clipboard, switch view to plain text mode 
    Last edited by patrik08; 20th May 2007 at 22:30.

  22. #20
    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: QThread exec proplem to stop...

    Quote Originally Posted by marcel View Post
    It will finish, but only if he calls quit() outside the thread ...
    It probably won't emit finished() then.

    Oh, BTW QThread::quit() is not virtual, neither is exit.
    Every slot is "implicitely" virtual if redeclared in a subclass. That's a side effect of how signals and slot mechanism works.

    So I'm not sure how correct it is to reimplement it. Anyway, if qt uses your class, it will call the base class version.
    No, it'll call the "youngest" implementation that has been declared as a slot. Of course this only applies to a situation when the method is called as a result of signal emission and not directly.

  23. The following user says thank you to wysota for this useful post:

    marcel (20th May 2007)

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.