Results 1 to 17 of 17

Thread: how to execute a QsqlQuery on a different thread ?

  1. #1
    Join Date
    Dec 2012
    Posts
    197
    Thanks
    25
    Thanked 41 Times in 33 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default how to execute a QsqlQuery on a different thread ?

    hello there ,
    was wondering what is the best way to execute a QsqlQuery on a different thread so that the GUI doesn't freeze
    should i make a class that inhirits Qthread and connect to the data base in the run method and do the query ?
    can emit a signal from the GUI class containing the input of the query ( example number ) and catch that signal when emitted in the thread then
    do the query ?
    or should i try another way ? maybe conecting the method that is repsonsible for the query to a thread by the thread started signal ?

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

    Default Re: how to execute a QsqlQuery on a different thread ?

    Clone the database connection, open it, run your query, close and remove the connection. Everything apart cloning has to be done from the thread that is to execute the query.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  3. #3
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: how to execute a QsqlQuery on a different thread ?

    If you want to use signal/slots to communicate from the GUI to the worker thread then you'll need a QThread that runs an event loop.

    You start by creating a QObject subclass that has the receiver slot and that slot does the database query.

    You create an instance of QThread and an instance of this new class and then use moveToThread() to make it run in the worker thread.

    The slot then gets invoked in the context of the worker thread.

    Cheers
    _

  4. #4
    Join Date
    Dec 2012
    Posts
    197
    Thanks
    25
    Thanked 41 Times in 33 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: how to execute a QsqlQuery on a different thread ?

    Quote Originally Posted by anda_skoa View Post
    If you want to use signal/slots to communicate from the GUI to the worker thread then you'll need a QThread that runs an event loop.

    You start by creating a QObject subclass that has the receiver slot and that slot does the database query.

    You create an instance of QThread and an instance of this new class and then use moveToThread() to make it run in the worker thread.

    The slot then gets invoked in the context of the worker thread.
    _
    Thanks for the reply
    my problem is that , i have a class the represents the GUI , a button in it, when pressed it opens a dialog
    now in this dialog i get the user input through line edit , and i have a button , when pressed i want to execute the query
    so should i connect to the database in the main GUI ? or in the class subcalssing QObject ?
    the other problem is that if i start the thread on pressing the button in the dialog , the thread will get destroyed before doing the query
    where to create the intsnance of the class subclassing QObject ?
    since my query takes parameters , i should pass them to the Thread. How to do that ? Signals and Slots are not doing the job properly in my case

  5. #5
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: how to execute a QsqlQuery on a different thread ?

    Quote Originally Posted by toufic.dbouk View Post
    so should i connect to the database in the main GUI ? or in the class subcalssing QObject ?
    I would do it in the qobject class, in the slot that executes the query or in a slot connected to the thread's started signal.

    Quote Originally Posted by toufic.dbouk View Post
    the other problem is that if i start the thread on pressing the button in the dialog , the thread will get destroyed before doing the query
    Why would it? The default implementation of QThread::run() runs an event loop. it doesn't finish until QThread::exit() is called.

    Quote Originally Posted by toufic.dbouk View Post
    where to create the intsnance of the class subclassing QObject ?
    When you create the thread. Since you want to directly connect the dialog to the query slot, before you create the dialog or even when you create the applicatIons' main GUI.

    Quote Originally Posted by toufic.dbouk View Post
    since my query takes parameters , i should pass them to the Thread. How to do that ? Signals and Slots are not doing the job properly in my case
    Signals can transport parameters to the slot.
    Does it work if you do not use a thread and have the query class instance in the main thread?

    Cheers,
    _

  6. #6
    Join Date
    Dec 2012
    Posts
    197
    Thanks
    25
    Thanked 41 Times in 33 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: how to execute a QsqlQuery on a different thread ?

    Quote Originally Posted by anda_skoa View Post
    Signals can transport parameters to the slot.
    Does it work if you do not use a thread and have the query class instance in the main thread?
    _
    everything works fine without the use of threads.
    i mean it doesnt work when i send the parameters through signals and slot and then save them as attributes in the QObject class , then when i try to use the attributes in the QsqlQuerry like binding it ( in the QObject class ) , the app crashes

    i will try what you said concerning the threads even though i tried something close to that , and get back to you
    i really appreciate your help. Thanks.


    Added after 1:


    gonna update you with what i have changed :

    class X : Main GUI, when button pressed creates an instance of class Y ( dialog )
    class Y : dialog that opens when a button pressed from CLASS X : *method onButtonPressed*( create instance of CLASS Z , call *method1 setup* , start the thread)
    class Z sub-classing QObject : *method1 setup*( connecting the threads started SIGNAL to execute SLOT PLUS opening connection with database )
    *method2 execute*( do query )

    okay so first of all , the execute slot connected to the thread Started SIGNAL is never executed.
    when i move the content of the execute method to the setup method , the code executes but the GUI still freezes.
    the statement : query.exec(); takes around 20 sec to execute and that's when the whole GUI freezes .
    Last edited by toufic.dbouk; 9th September 2013 at 14:49.

  7. #7
    Join Date
    Dec 2012
    Posts
    197
    Thanks
    25
    Thanked 41 Times in 33 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: how to execute a QsqlQuery on a different thread ?

    im connecting the start method of the thread in the QObject class ( CLASS Z in the previous post)
    Qt Code:
    1. void QueryThread::setupThread(QThread &qryThread)
    2. {
    3. qDebug () << "method invoked";
    4. connect(&qryThread,SIGNAL(started()),this,SLOT(executeQuery()));
    5. }
    To copy to clipboard, switch view to plain text mode 

    and im setting it up here in another class ( CLASS Y in the previous post)
    Qt Code:
    1. QueryThread qryThread;
    2. qryThread.setupThread(qThread);
    3. qryThread.moveToThread(&qThread);
    4. qThread.start();
    To copy to clipboard, switch view to plain text mode 
    i dont get why this isnt working ? the method is never invoked
    NOTE: QThread qThread; is a public attribute in CLASS Y

  8. #8
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: how to execute a QsqlQuery on a different thread ?

    Does the qryThread object live long enough?

    Here it appears to be created on the stack of some function.

    Cheers,
    _

  9. The following user says thank you to anda_skoa for this useful post:

    toufic.dbouk (9th September 2013)

  10. #9
    Join Date
    Dec 2012
    Posts
    197
    Thanks
    25
    Thanked 41 Times in 33 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: how to execute a QsqlQuery on a different thread ?

    Quote Originally Posted by anda_skoa View Post
    Does the qryThread object live long enough?

    Here it appears to be created on the stack of some function.
    _
    i created it on heap and with a couple of other fixes problem got solved
    i dont how i missed that...

    but still why does the query.exec() take 20 sec or more to execute ? is there a fast way to retrieve a data from a 2 mill record database

    why cant we great a GUI in the thread ? like if i want to just show a tableView

    i wanna show the result of the query done by the thread in a GUI table
    i was hoping to do somethinh simple like :
    Qt Code:
    1. model->setQuery(Pqry);
    2. QTableView *view = new QTableView;
    3. view->setModel(model);
    4. view->show();
    To copy to clipboard, switch view to plain text mode 
    Last edited by toufic.dbouk; 9th September 2013 at 22:55.

  11. #10
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: how to execute a QsqlQuery on a different thread ?

    Quote Originally Posted by toufic.dbouk View Post
    but still why does the query.exec() take 20 sec or more to execute ? is there a fast way to retrieve a data from a 2 mill record database
    Always depends on the query and the database.
    If you query something that is not indexed, it will take longer.
    If your query contains instructions to sort the result, it will take longer.
    Some databases are less optimal for huge datasets, some have different backends for different kinds of loads, etc.

    Quote Originally Posted by toufic.dbouk View Post
    why cant we great a GUI in the thread ? like if i want to just show a tableView
    UI resources are usually not protected against concurrent access, some systems can't even do that natively.
    Additional to that Qt will handle events in the thread that an object belongs to, so creating UI from different threads would lead to two threads processing user events.
    Which would lead to highly unpredictable execution paths.

    Quote Originally Posted by toufic.dbouk View Post
    i wanna show the result of the query done by the thread in a GUI table
    i was hoping to do somethinh simple like :
    Qt Code:
    1. model->setQuery(Pqry);
    2. QTableView *view = new QTableView;
    3. view->setModel(model);
    4. view->show();
    To copy to clipboard, switch view to plain text mode 
    You could try creating the model in the thread, then move it to the GUI thread and set it on the view there.
    Might be necessary to wait with the move/set until the query is done.

    Cheers,
    _

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

    toufic.dbouk (10th September 2013)

  13. #11
    Join Date
    Dec 2012
    Posts
    197
    Thanks
    25
    Thanked 41 Times in 33 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: how to execute a QsqlQuery on a different thread ?

    Thanks for the explanation it helps a lot.

    Quote Originally Posted by anda_skoa View Post
    You could try creating the model in the thread, then move it to the GUI thread and set it on the view there.
    Might be necessary to wait with the move/set until the query is done.
    i actually dont have enough practice background with threads so i don't how to do that...
    any help from you would be way more than appreciated. such as more explanation or a reference or a code snippet

    Best Regards.


    Added after 17 minutes:


    Hello anda_skoa,
    i managed to show the result in the GUI thread by the following:
    emit a signal holding the QSqlQuery after the QSqlQuery.exec() is done
    catch it in the dialog Classs ( because thats where i create the instance of the class subclassing QObject " worker thread ")
    send a signal from the dialog class holding the QSqlQuery to the GUI thread and set the result in a table view

    this is working fine , not slow at all ...
    but im not sure if that's the right way of doing this

    i would like to hear from you on this and tell me the way you proposed because im sure it would be more efficient
    You could try creating the model in the thread, then move it to the GUI thread and set it on the view there.
    Might be necessary to wait with the move/set until the query is done.
    Thanks a lot for your time and for your extremely helpful replies , i have learned a lot from this thread.
    Last edited by toufic.dbouk; 10th September 2013 at 16:04.

  14. #12
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: how to execute a QsqlQuery on a different thread ?

    Sounds fine to me, even better then my previous idea actually.

    Cheers,
    _

  15. #13
    Join Date
    Dec 2012
    Posts
    197
    Thanks
    25
    Thanked 41 Times in 33 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: how to execute a QsqlQuery on a different thread ?

    Thank you so much for your time
    its actually working great and fast without a single freeze
    ill work more on it and ill get back to this thread or a new thread , if i need any further help
    enjoy your day friend.

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

    Default Re: how to execute a QsqlQuery on a different thread ?

    I don't know how internals of QSqlQuery work but I believe that for some backends the query can still call some database functions after it is executed (e.g. when iterating over results, next results can be fetched from the database on the fly) thus accessing it from a thread different than where the query was executed could result in undefined behaviour. I would be very careful about this.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  17. #15
    Join Date
    Dec 2012
    Posts
    197
    Thanks
    25
    Thanked 41 Times in 33 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: how to execute a QsqlQuery on a different thread ?

    Hi Wysota,
    im actually aware of that because i tried printing the result by iterating over the QSqlQuery when catching the emited signal by :
    Qt Code:
    1. while(query.next())
    2. {
    3. qDebug() << query.value(2).toString();
    4. }
    To copy to clipboard, switch view to plain text mode 

    but i guess im just accesing the sent result from the worker thread so i dont think you can do more than seeing the result with that query
    thanks for pointing it out. and if you have any other idea on how to do that please let me know.
    i know you posted the first reply on this thread :
    Clone the database connection, open it, run your query, close and remove the connection. Everything apart cloning has to be done from the thread that is to execute the query.
    but i dont how to do that so i went through the other option by anda_skoa which turned out to work properly and efficiently
    if you explain about your way of doing that im ready to try it and get back to you on this post.
    Best Regards.

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

    Default Re: how to execute a QsqlQuery on a different thread ?

    Quote Originally Posted by toufic.dbouk View Post
    and if you have any other idea on how to do that please let me know.
    A custom model that performs sql queries in a thread (if needed), converts the data to the format operated by the model, transfers the data to the model's thread and updates the model. This is something you have to implement yourself, of course.

    but i dont how to do that so i went through the other option by anda_skoa which turned out to work properly and efficiently
    Today it works but from now on upon every crash or disfunction of your project you'll be wondering whether the database is causing that...
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


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

    toufic.dbouk (11th September 2013)

  20. #17
    Join Date
    Dec 2012
    Posts
    197
    Thanks
    25
    Thanked 41 Times in 33 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: how to execute a QsqlQuery on a different thread ?

    Hello,
    Quote Originally Posted by wysota View Post
    Today it works but from now on upon every crash or disfunction of your project you'll be wondering whether the database is causing that...
    i will test the project , since its not a big project , i might be able to have a thorough testing and if it crashed or failed to function properly ill implement your way of doing it
    which is quite good i guess in my case
    Best Regards.

Similar Threads

  1. Replies: 2
    Last Post: 9th April 2013, 09:15
  2. Replies: 1
    Last Post: 25th October 2012, 15:10
  3. QSqlQuery does not execute
    By weixj2003ld in forum Qt Programming
    Replies: 7
    Last Post: 11th July 2012, 12:13
  4. Replies: 1
    Last Post: 18th July 2011, 12:12
  5. Replies: 16
    Last Post: 7th October 2009, 08:17

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
  •  
Qt is a trademark of The Qt Company.