Results 1 to 10 of 10

Thread: Using a qt dependent library in a Qt application

  1. #1
    Join Date
    Dec 2012
    Posts
    7
    Thanks
    2
    Qt products
    Qt4
    Platforms
    Windows

    Default Using a qt dependent library in a Qt application

    Hi all,

    I am creating an application which uses Qt for the GUI. Inside this application, I am trying to launch a 3rd party library (OpenRAVE) which also uses Qt for its GUI. I am initializing OpenRAVE from a button press in my application. However, this is causing errors, namely:

    QPixmap: It is not safe to use pixmaps outside the GUI thread
    QApplication::exec: Must be called from the main thread

    I gather from this that I can't call OpenRAVE from inside my Qt application. It must be called from the main method of my program, right? The problem is, I'm not sure how to approach this. The functionality I am looking for is that OpenRAVE should only launch at the request of the user.

    I'll be grateful if anyone could help or point me in the right direction.

    Thanks

    Talha

  2. #2
    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: Using a qt dependent library in a Qt application

    It seems that some code that needs to run in the main thread is being executed in a worker thread.

    How does the slot of your button look like, the code that initializes the library?

    Cheers,
    _

  3. #3
    Join Date
    Dec 2012
    Posts
    7
    Thanks
    2
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Using a qt dependent library in a Qt application

    Yes it is being run on a worker thread. My problem is I'm not sure how to make it run on the main thread whilst also allowing the user to dictate when it is run. Here is the code for initializing the library:

    Qt Code:
    1. // Function for running the GUI of the library
    2. void setViewer(EnvironmentBasePtr penv, const std::string& viewername)
    3. {
    4. ViewerBasePtr viewer = RaveCreateViewer(penv,viewername);
    5. BOOST_ASSERT(!!viewer);
    6. // attach it to the environment:
    7. penv->Add(viewer);
    8. // finally call the viewer's infinite loop (this is why a separate thread is needed)
    9. bool showgui = true;
    10. viewer->main(showgui);
    11. }
    12.  
    13. //Helper function for initializing the library
    14. void oRave()
    15. {
    16. //int num = 1;
    17. std::string scenefilename = "C:/Program Files (x86)/OpenRAVE/share/openrave-0.8/data/lab1.env.xml";
    18. std::string viewername = "qtcoin";
    19.  
    20. RaveInitialize(true); // start openrave core
    21. EnvironmentBasePtr penv = RaveCreateEnvironment(); // create the main environment
    22. RaveSetDebugLevel(5);
    23. boost::thread thviewer(boost::bind(setViewer,penv,viewername));
    24. penv->Load(scenefilename); // load the scene
    25. thviewer.join(); // wait for the viewer thread to exit
    26. penv->Destroy(); // destroy
    27. }
    28.  
    29. // THIS IS THE SLOT
    30. void
    31. MainWindow::loadMeshFile(){
    32.  
    33. oRave();
    34. }
    To copy to clipboard, switch view to plain text mode 

  4. #4
    Join Date
    Sep 2011
    Posts
    1,241
    Thanks
    3
    Thanked 127 Times in 126 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Using a qt dependent library in a Qt application

    You can't have two independent Qt GUIs because either they are on the same thread and will block each other, or they are on different threads and Qt will assert.
    If you have a problem, CUT and PASTE your code. Do not retype or simplify it. Give a COMPLETE and COMPILABLE example of your problem. Otherwise we are all guessing the problem from a fabrication where relevant details are often missing.

  5. #5
    Join Date
    Dec 2012
    Posts
    7
    Thanks
    2
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Using a qt dependent library in a Qt application

    So are you saying that it is impossible to have 2 Qt GUIs running at the same time? Because I can get the library to run using QProcess::Start(). It's just that I don't have enough control over the library's functionality using this method. Also, what do you mean by "Qt will assert"? I'm not familiar with this terminology.

  6. #6
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Using a qt dependent library in a Qt application

    "Qt will assert" means that your application (when running in debug mode) will halt with an error (the assert) because Qt won't allow two GUI threads to run simultaneously. In release mode, the program will probably simply crash.

    I don't know anything about OpenRave. Is is a library? In that case, it won't have a GUI thread, because libraries depend on the client program to supply that. Your problem is probably that you are trying to use the library from within a thread, and the Qt GUI can run only on the GUI thread (which your main() and its QApplication::exec() are providing).

    Find a way to connect to the OpenRave GUI from within your application's GUI thread, not outside it.

    Qt Code:
    1. // finally call the viewer's infinite loop (this is why a separate thread is needed)
    2. bool showgui = true;
    3. viewer->main(showgui);
    To copy to clipboard, switch view to plain text mode 

    You are probably mistaken about this (the thread part), if OpenRave is a library and not an application (executable).

  7. #7
    Join Date
    Dec 2012
    Posts
    7
    Thanks
    2
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Using a qt dependent library in a Qt application

    Quote Originally Posted by d_stranz View Post

    Qt Code:
    1. // finally call the viewer's infinite loop (this is why a separate thread is needed)
    2. bool showgui = true;
    3. viewer->main(showgui);
    To copy to clipboard, switch view to plain text mode 

    You are probably mistaken about this (the thread part), if OpenRave is a library and not an application (executable).
    OpenRave is a full fledged application with its own Qt GUI but it can also be used as a library inside an application. The code that I presented above is taken from one of the examples in OpenRave. The only difference is that I am using a Qt GUI for my own application as well.

    Is it possible to add a Qt application as a widget inside my application?

  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: Using a qt dependent library in a Qt application

    The way this looks is that viewer->main() runs the Qt event loop.

    Since the rest of Qt doesn't care how the event loop got started, you could just use that call instead of the usual app.exec().

    Given that this function also gets the commandline arguments, it is potentially also creating the QApplication object.

    There are two options:
    1) check if the library has an option not to create the application object. In this case you can create it yourself and do the application initialization as usual.
    2) if the library's design is really broken and there is no way around it creating the QApplication object, it will have to do that and you put your initialization code in a slot that is run after the event loop has started up.

    Cheers,
    _

  9. #9
    Join Date
    Dec 2012
    Posts
    7
    Thanks
    2
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Using a qt dependent library in a Qt application

    Quote Originally Posted by anda_skoa View Post
    2) if the library's design is really broken and there is no way around it creating the QApplication object, it will have to do that and you put your initialization code in a slot that is run after the event loop has started up.
    _
    Can you elaborate on this option? I'm now letting the library create the QApplication object and start its GUI in the main thread. I am then initializing my program in a secondary thread, otherwise it won't respond, without a QApplication object. Now I am just calling for my MainWindow to be shown. However, this is causing the program to crash. I don't understand how I should put it in a slot as you mentioned. And what comprises the event loop?


    Thanks

  10. #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: Using a qt dependent library in a Qt application

    Lets assume your main function looks like this
    Qt Code:
    1. int main( int argc, char ** argv)
    2. {
    3. RaveInitialize(true); // start openrave core
    4. EnvironmentBasePtr penv = RaveCreateEnvironment(); // create the main environment
    5. RaveSetDebugLevel(5);
    6. penv->Load(scenefilename); // load the scene
    7.  
    8. ViewerBasePtr viewer = RaveCreateViewer(penv,viewername);
    9. BOOST_ASSERT(!!viewer);
    10. // attach it to the environment:
    11. penv->Add(viewer);
    12.  
    13. bool showgui = true;
    14. viewer->main(showgui);
    15.  
    16. penv->Destroy(); // destroy
    17. }
    To copy to clipboard, switch view to plain text mode 

    So what you need is a slot that can be called in a delayed fashion, i.e. once the event loop is runnning

    Qt Code:
    1. class AppInitializer : public QObject
    2. {
    3. Q_OBJECT
    4.  
    5. public:
    6. explicit AppInitializer( QObject *parent = 0 ) : QObject( parent ) {}
    7.  
    8. public Q_SLOTS:
    9. void initialize();
    10. };
    To copy to clipboard, switch view to plain text mode 

    Inside initialize() you create your main window and show it.

    In the main function you add this
    Qt Code:
    1. // ....
    2. penv->Add(viewer);
    3.  
    4. // create app initializer and schedule delayed initialization
    5. AppInitializer appInit;
    6. QMetaObject::invokeMethod( &appInit, "initialize", Qt::QueuedConnection );
    7.  
    8. bool showgui = true;
    9. viewer->main(showgui);
    10. // ....
    To copy to clipboard, switch view to plain text mode 

    Cheers,
    _

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

    talha (21st December 2012)

Similar Threads

  1. Add platform dependent path into pro file problem
    By alizadeh91 in forum Qt Programming
    Replies: 5
    Last Post: 7th October 2012, 01:06
  2. Replies: 5
    Last Post: 3rd October 2012, 15:14
  3. Scale dependent display of graphics Item
    By aalexei in forum Qt Programming
    Replies: 0
    Last Post: 17th February 2011, 23:32
  4. Platform dependent source files: what is best?
    By ucomesdag in forum Qt Programming
    Replies: 5
    Last Post: 27th November 2006, 18:52
  5. Replies: 3
    Last Post: 27th February 2006, 05:51

Tags for this Thread

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.