Results 1 to 15 of 15

Thread: Multiple SoQt Viewers

  1. #1
    Join Date
    Mar 2007
    Posts
    7
    Qt products
    Qt3 Qt4
    Platforms
    Windows

    Default Multiple SoQt Viewers

    I need at least two SoQtExaminerViewer. Each viewer should have it's own window, own event handler method (e.g. mouse, keyboard) and scene graph.
    The problem I have now is that only one viewer is really working. For one viewer everything is fine and the right points get updated by a click. By not working I mean that clicking does not update the viewer where I clicked but instead the not active viewer gets updated. This is quite a little bit strange to me because the methods I use for updating the dispay and handling the mouse events are not the same for the viewers.

    Any ideas?

  2. #2
    Join Date
    Jan 2006
    Location
    Munich, Germany
    Posts
    4,714
    Thanks
    21
    Thanked 418 Times in 411 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default Re: Multiple SoQt Viewers

    impossible with out seeing the code.
    start with the signal slot connection and or the event handling code.
    the QThread::run() implementation would also help.
    ==========================signature=============== ==================
    S.O.L.I.D principles (use them!):
    https://en.wikipedia.org/wiki/SOLID_...iented_design)

    Do you write clean code? - if you are TDD'ing then maybe, if not, your not writing clean code.

  3. #3
    Join Date
    Mar 2007
    Posts
    7
    Qt products
    Qt3 Qt4
    Platforms
    Windows

    Default

    Posted wrong code. Sorry.

    My main stuff:
    Qt Code:
    1. int main(int argc, char *argv[])
    2. {
    3.  
    4. QWidget *mainwin = SoQt::init(argc, argv, argv[0]);
    5. if (mainwin==0)
    6. exit(1);
    7.  
    8. HBWindow*window=new HBWindow(mainwin,"HBWindow");
    9.  
    10. JEWindow*jew = new JointEditorWindow(0, "JEWindow");
    11. jew->showMaximized();
    12.  
    13. window->showMaximized();
    14.  
    15. //SoQt::show(mainwin);
    16. SoQt::mainLoop();
    17.  
    18. return 0;
    19. }
    To copy to clipboard, switch view to plain text mode 

    Then the HBWindow as well as the JEWindow are basically the same. The both are inherited from QMainWindow and create a layout and add some attributs etc. to it. JEWindow looks exactly the same. _viewer is globally defined to be a class of SkelDisplay(...)
    Qt Code:
    1. HBalanceWindow::HBalanceWindow
    2. (
    3. QWidget *parent, const char *name
    4. )
    5. : QMainWindow(parent,name)
    6. {
    7. // Creates the layout for the main window
    8. QWidget *main_window_layout = new QWidget;
    9. QHBoxLayout *layout = new QHBoxLayout;
    10. _viewer = new SkelDisplay(main_window_layout, this);
    11. _attributs = new AttributsWidget(main_window_layout, this);
    12. layout->addWidget(_viewer);
    13. layout->addWidget(_attributs);
    14. setCentralWidget(main_window_layout);
    15. main_window_layout->setLayout(layout);
    16. }
    To copy to clipboard, switch view to plain text mode 

    The more interesting part is probably inside the SkelDisplay(...) method. Here I create the SoQT Viewer as well as the callbacks. The callbacks are defined as static methods. There is no QtThread.

    Qt Code:
    1. SkelDisplay::SkelDisplay
    2. (
    3. QWidget *parent,
    4. QWidget *main_win
    5. )
    6. :
    7. QWidget(parent)
    8. {
    9. // Create the render view
    10. //
    11. _ivviewer = new SoQtExaminerViewer(this);
    12. _ivviewer->setBackgroundColor(SbColor(0., 0., 0.));
    13.  
    14. _iv_root = new SoSeparator;
    15. _iv_root->ref();
    16.  
    17. //Add some stuff to the _iv_root
    18. ...
    19.  
    20. _iv_root->addChild(complexity);
    21.  
    22. // Adds an event callback to catch mouse button hits
    23. //
    24. SoEventCallback *event_CB = new SoEventCallback;
    25. _iv_root->addChild(event_CB);
    26.  
    27. // Set up the event callback. We want to pass the object itself
    28. // as the callback func must be declared static
    29. event_CB->addEventCallback(SoMouseButtonEvent::getClassTypeId(),
    30. mouse_pressed_CB,
    31. this);
    32.  
    33. _ivviewer->setSceneGraph(_iv_root);
    34. .....
    35. }
    To copy to clipboard, switch view to plain text mode 

    I put some printf(...) statements so check if there is no confusion between the methods call. This seems to work. But at the end the update of the right window fails.

    Thanks.

  4. #4
    Join Date
    Jan 2006
    Location
    Munich, Germany
    Posts
    4,714
    Thanks
    21
    Thanked 418 Times in 411 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default Re: Multiple SoQt Viewers

    By not working I mean that clicking does not update the viewer where I clicked but instead the not active viewer gets updated.
    Qt Code:
    1. event_CB->addEventCallback(SoMouseButtonEvent::getClassTypeId(),
    2. mouse_pressed_CB,
    3. this);
    To copy to clipboard, switch view to plain text mode 
    Hmm... if getClassTypeId is static, then how will it deliver the correct Id?
    Can you show the inside of SoMouseButtonEvent::getClassTypeId()?
    ==========================signature=============== ==================
    S.O.L.I.D principles (use them!):
    https://en.wikipedia.org/wiki/SOLID_...iented_design)

    Do you write clean code? - if you are TDD'ing then maybe, if not, your not writing clean code.

  5. #5
    Join Date
    Mar 2007
    Posts
    7
    Qt products
    Qt3 Qt4
    Platforms
    Windows

    Default Re: Multiple SoQt Viewers

    Doesn't
    Qt Code:
    1. event_CB->addEventCallback(SoMouseButtonEvent::getClassTypeId(), mouse_pressed_CB, this);
    To copy to clipboard, switch view to plain text mode 
    not only tell to add a callback function to the hierarchy that will handle a mouse event? At least thats my understanding. Of course the other class does the same like but there the callback method has another name.

    The method that handles the mouse event looks like:
    Qt Code:
    1. static void mouse_pressed_CB
    2. (
    3. void *user_data,
    4. SoEventCallback *event_CB
    5. )
    6. {
    7. const SoEvent *event = event_CB->getEvent();
    8.  
    9. SkelDisplay*ui = (SkelDisplay*) user_data;
    10.  
    11. // Check for left mouse button being pressed
    12. //
    13. if (SO_MOUSE_PRESS_EVENT(event, BUTTON1))
    14. ui->mouse_button1_pressed(event);
    15. printf("aa\n");
    16. else if (SO_MOUSE_PRESS_EVENT(event, BUTTON2))
    17. ui->mouse_button2_pressed(event); //DAR
    18. else if (SO_MOUSE_PRESS_EVENT(event, BUTTON3))
    19. {
    20. if (ui->get_current_joint())
    21. ui->mouse_button3_pressed(event);
    22. else
    23. QMessageBox::about(ui, "Error", "Error");
    24. }
    25. }
    26.  
    27. void SkeletonDisplay::mouse_button1_pressed
    28. (
    29. const SoEvent *event
    30. )
    31. {
    32. }
    To copy to clipboard, switch view to plain text mode 
    Inside the mouse_button1_pressed I compute the distances based on the camera position to the points and select the one with the smallest distance. I have a printf(...) made for both mouse callback functions but could it happen that one overwrites the other, although they have different names?

  6. #6
    Join Date
    Jan 2006
    Location
    Munich, Germany
    Posts
    4,714
    Thanks
    21
    Thanked 418 Times in 411 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default Re: Multiple SoQt Viewers

    Doesn't
    Qt Code:
    1.
    event_CB->addEventCallback(SoMouseButtonEvent::getClassType Id(), mouse_pressed_CB, this);
    not only tell to add a callback function to the hierarchy that will handle a mouse event? At least thats my understanding.
    I don't know, its your code, and you didn't show it!
    And in that respect, since your code is Qt code also in your call back, may I ask why are you making all of this so complicated, and not using Qt's oh so convenient ready made functions?

    To deal with the problem, I suggest to strip the problem to parts.
    Go from the general to the specific of what you need to achieve and explain it in such part..
    One step at a time.

    Let me try to recap what I understood:
    You have two similar windows, and what is wrong about it, is when you click in one of them, the other gets updates with what should have been updates in the one you clicked in, is that correct?
    ==========================signature=============== ==================
    S.O.L.I.D principles (use them!):
    https://en.wikipedia.org/wiki/SOLID_...iented_design)

    Do you write clean code? - if you are TDD'ing then maybe, if not, your not writing clean code.

  7. #7
    Join Date
    Mar 2007
    Posts
    7
    Qt products
    Qt3 Qt4
    Platforms
    Windows

    Default Re: Multiple SoQt Viewers

    Unfortunately, there is already a big part written with this callback function and I have to take that code

    Probably, I expressed myself not clearly enough. Lets say you have two windows HBWindow which calls SkelDisplay and JEWindow which calls JEDisplay. Clicking with the mouse will always update the JEWindow still you have clicked in the HBWindow. But the JEWindow is fine. The window you create later in the main will be the one that is working properly with the mouse while the other isn't. What lets me conclude that it has something to be with the callbacks is that creating a list (QComboBox) for selecting the points works always fine.

    No idea if there can only be one callback for mouse handling....

    What would you suggest as the proper method for Qt4? What would be the proper way using SoQt and a mouse handler from Qt4?

  8. #8
    Join Date
    Jan 2006
    Location
    Munich, Germany
    Posts
    4,714
    Thanks
    21
    Thanked 418 Times in 411 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default Re: Multiple SoQt Viewers

    could you show addEventCallback()?

    The proper way to deal with mouse events in Qt is by reimplementing mousePressEvent() and friends.
    ==========================signature=============== ==================
    S.O.L.I.D principles (use them!):
    https://en.wikipedia.org/wiki/SOLID_...iented_design)

    Do you write clean code? - if you are TDD'ing then maybe, if not, your not writing clean code.

  9. #9
    Join Date
    Mar 2007
    Posts
    7
    Qt products
    Qt3 Qt4
    Platforms
    Windows

    Default Re: Multiple SoQt Viewers

    Here we go:
    Qt Code:
    1. void addEventCallback(SoType eventtype, SoEventCallbackCB * f,
    2. void * userdata = NULL);
    3.  
    4.  
    5. void
    6. SoEventCallback::addEventCallback(SoType eventtype, SoEventCallbackCB * f,
    7. void * userdata)
    8. {
    9. struct CallbackInfo cb;
    10. cb.func = f;
    11. cb.eventtype = eventtype;
    12. cb.userdata = userdata;
    13.  
    14. this->callbacks.append(cb);
    15. }
    To copy to clipboard, switch view to plain text mode 

    This comes from Coin3D SoEventCallback. I haven't implemented this myself!!

    I have just to re-implement for every QWidget the mousePressEvent(...) and it should work? If it would be so simple, I could think about it. But may be there are some problems with these SoQtExaminerViewer that intercepts the mousePressEvent(...). I will try, if this would do the job.

  10. #10
    Join Date
    Jan 2006
    Location
    Munich, Germany
    Posts
    4,714
    Thanks
    21
    Thanked 418 Times in 411 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default Re: Multiple SoQt Viewers

    I have just to re-implement for every QWidget the mousePressEvent(...) and it should work?
    Well, it depends what you mean with "should work".
    mousePressEvent() and the other event handlers will be called by Qt when a the relevant event happens (i.e pressing the mouse on the widget).
    In that event handler you can do anything you want that should happen in that event.
    So yes, that is as simple as that, didn't I say so?

    The question which is hard for me to answer is, how will it effect your code?.
    It seems to me, that your code is implementing an event loop and handler (don't forget that Qt's eent handling is working in parallel, which might be part of the problem) so if you go the Qt way, you will have to do adjustments - what is the extent of those adjustments, is hard for me to say.

    Is addEventCallback() static or not?
    Last edited by high_flyer; 10th December 2007 at 16:48.
    ==========================signature=============== ==================
    S.O.L.I.D principles (use them!):
    https://en.wikipedia.org/wiki/SOLID_...iented_design)

    Do you write clean code? - if you are TDD'ing then maybe, if not, your not writing clean code.

  11. #11
    Join Date
    Mar 2007
    Posts
    7
    Qt products
    Qt3 Qt4
    Platforms
    Windows

    Default Re: Multiple SoQt Viewers

    addEventCallback(...) is not static. What has to be static is the callback function you add when calling the method addEventCallback(...).
    I made some further tests. And for instance I would say that SoQt is not able to handle different SoQtExaminerViewer.

    Another problem I have remarked is that the SoQtExaminerViewer only appears when the parent is a QMainWindow. Otherwise, I t does not work for me. But it is possible to have several QMainWindow instances at the same time right?

  12. #12
    Join Date
    Jan 2006
    Location
    Munich, Germany
    Posts
    4,714
    Thanks
    21
    Thanked 418 Times in 411 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default Re: Multiple SoQt Viewers

    I made some further tests. And for instance I would say that SoQt is not able to handle different SoQtExaminerViewer.
    Well in Qt you can use an object as an event filter to other objects, so it should be possible to install and even filter in one window for the others, where you can then manually decided which event should go where.
    Have a look at installEventFilter

    But it is possible to have several QMainWindow instances at the same time right?
    At least I am not aware of anything that speaks against this possibility, but I would suggest that in such a case it would look like a bad design.
    Better sort out the event flow in your application.
    ==========================signature=============== ==================
    S.O.L.I.D principles (use them!):
    https://en.wikipedia.org/wiki/SOLID_...iented_design)

    Do you write clean code? - if you are TDD'ing then maybe, if not, your not writing clean code.

  13. #13
    Join Date
    Mar 2007
    Posts
    7
    Qt products
    Qt3 Qt4
    Platforms
    Windows

    Default Re: Multiple SoQt Viewers

    Thanks. I will probably use the EventFilter.
    The source of my problem is the Open Inventor implementation from SoQt/Coin3D. When you have two different hierarchies, a SoNode::getByName(...) seems not work properly. It is not ensured from which SoNode is returned. It can be from any hierarchy even if these hierarchies are in different classes and namespaces.

  14. #14
    Join Date
    Jan 2006
    Location
    Munich, Germany
    Posts
    4,714
    Thanks
    21
    Thanked 418 Times in 411 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default Re: Multiple SoQt Viewers

    The source of my problem is the Open Inventor implementation from SoQt/Coin3D. When you have two different hierarchies, a SoNode::getByName(...) seems not work properly. It is not ensured from which SoNode is returned. It can be from any hierarchy even if these hierarchies are in different classes and namespaces.
    Well this is quite abstract for me, since I don't know your code.
    Over a forum it is hard to look for problems in cases like these based on symptoms, because the complexity, and the inability to see the full code.
    You should try and debug your problem and reduce it to an specific problem domain, not a symptom.
    Probably then we will be more able to help.
    Good luck!
    ==========================signature=============== ==================
    S.O.L.I.D principles (use them!):
    https://en.wikipedia.org/wiki/SOLID_...iented_design)

    Do you write clean code? - if you are TDD'ing then maybe, if not, your not writing clean code.

  15. #15
    Join Date
    Nov 2006
    Location
    Shrewsbury, UK
    Posts
    97
    Thanks
    3
    Thanked 11 Times in 11 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Multiple SoQt Viewers

    Quote Originally Posted by Gawain View Post
    Posted wrong code. Sorry.
    .... _viewer is globally defined to be a class of SkelDisplay(...)
    From this I imply that you have something like this sitting on its own outside of a class declaration
    Qt Code:
    1. SkelDisplay _viewer;
    To copy to clipboard, switch view to plain text mode 

    If this is accurate, then you only have one instance of _viewer throughout your application. Every time you construct a window you reassign the _viewer to be a new SkelDisplay with a new SoQtExaminer, orphaning any previous objects refernced by _viewer. From your symptoms, this looks to be exactly what's happening.

    What happens if you make _viewer a member variable of HBalanceWindow?

    Pete

    p.s. You can tidy up your code by making "mouse_pressed_CB" a static method of SkelDisplay instead of being classless. The lets "mouse_pressed_CB" have access to the protected members of your "ui" object if it needs. I have done this with a similar OpenCASCADE callback and it works well. It also means you can use the same pattern and naming convention with other classes.

Similar Threads

  1. how to corss compile for windows in Linux
    By safknw in forum Qt Programming
    Replies: 24
    Last Post: 13th May 2006, 05:23

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.