Results 1 to 9 of 9

Thread: Problem with QGraphicsScene, QGraphicsProxyWidget, and setting widget focus

  1. #1
    Join Date
    Mar 2010
    Posts
    7
    Thanks
    1
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Angry Problem with QGraphicsScene, QGraphicsProxyWidget, and setting widget focus

    First, a user-level description of my problem:

    I wrote a popup window that hovers when a user right-clicks on a triangle mesh. The popup window appears correctly. However, the popup does not handle click and move events correctly, and instead they are passed through to the open gl window. (For example, attempting to move the popup rotates the scene.)

    Now the code:

    I wrote a QGraphicsView and attached a custom QGraphicsScene to it. The custom QGraphicsScene overrides keyboard and mouse callbacks.

    To implement my right-click popup window, I created a minimal custom proxy class. It looks like this:

    Qt Code:
    1. class ProxyWidget : public QGraphicsProxyWidget {
    2. public:
    3. ProxyWidget(QGraphicsItem *parent = 0, Qt::WindowFlags flags = 0) : QGraphicsProxyWidget(parent, flags) {
    4. setFocusPolicy(Qt::StrongFocus);
    5. }
    6. };
    To copy to clipboard, switch view to plain text mode 

    My popup widget class is named "SelectionPopup." To initialize the proxy class, I do this:

    Qt Code:
    1. void SelectionPopup::initProxy() {
    2. m_proxy = new ProxyWidget(NULL, Qt::Tool);
    3. m_proxy->setWidget(this);
    4. MainWindow::ptrGraphcsView()->scene()->addItem(m_proxy);
    5.  
    6. MainWindow::ptrGraphcsView()->scene()->setActiveWindow(m_proxy);
    7. m_proxy->setFocus();
    8. }
    To copy to clipboard, switch view to plain text mode 

    Then in my overridden setVisible method, I set the proxy widget's focus like so:

    Qt Code:
    1. void SelectionPopup::setVisible(bool visible) {
    2. if (visible) {
    3. MainWindow::ptrGraphcsView()->scene()->setActiveWindow(m_proxy);
    4. m_proxy->setFocus();
    5. }
    6. else {
    7. MainWindow::ptrGraphcsView()->scene()->setActiveWindow(0);
    8. }
    9. }
    To copy to clipboard, switch view to plain text mode 

    So, as I said above, after the setVisible call, the popup appears beautifully, but I am unable to click on or move it. The mouse events are passed straight to the QGraphicsScene event handlers.

    Does someone know what is going on? With a debugger I can see that within the QGraphicsScene, "focusItem()" returns the proxy widget. However the program behaves as if the opengl widget still has focus.

    How can I change the code so that the proxy window behaves correctly when in focus, and (also when the proxy widget is in focus) QGraphicsScene ignores mouse input? Do I need to implement event handling with a custom QGlWidget? Do I need to set some additional flags in my QGraphicsScene class?

    Any help is appreciated and I will gladly provide more information if needed. Thanks.

  2. #2
    Join Date
    Feb 2007
    Location
    Karlsruhe, Germany
    Posts
    469
    Thanks
    17
    Thanked 90 Times in 88 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Problem with QGraphicsScene, QGraphicsProxyWidget, and setting widget focus

    I'm not sure. But I think the default handlers of the scene dispatch scene events to the items. And then when a proxy item recieves a sceneEvent it dispatches a normal event to the embedded widget?

    So try and remove your scene handlers.

    Joh

  3. #3
    Join Date
    Mar 2010
    Posts
    7
    Thanks
    1
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Problem with QGraphicsScene, QGraphicsProxyWidget, and setting widget focus

    Thank you for your reply. Do you mean try to remove the mouse event handlers in QGraphicsScene? If so, I tried that. The mouse focus still did not get passed to my proxy widget.

    I'm not sure. But I think the default handlers of the scene dispatch scene events to the items. And then when a proxy item recieves a sceneEvent it dispatches a normal event to the embedded widget?

    So try and remove your scene handlers.

  4. #4
    Join Date
    Feb 2007
    Location
    Karlsruhe, Germany
    Posts
    469
    Thanks
    17
    Thanked 90 Times in 88 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Problem with QGraphicsScene, QGraphicsProxyWidget, and setting widget focus

    Ok. And you removed it fully? So that the base classes implementation gets called.

    Another thing. You are setting the focus to the proxy. Have you tried to set it to the embedded widget?

    But mouse events have not much to do with the focus anyhow. I do know that I got that working.
    But I can't see your error right now.

    Joh

  5. #5
    Join Date
    Feb 2007
    Location
    Karlsruhe, Germany
    Posts
    469
    Thanks
    17
    Thanked 90 Times in 88 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Problem with QGraphicsScene, QGraphicsProxyWidget, and setting widget focus

    Oh and have you set the Qgraphicsitem flag ItemIsFocusable?

    proxy.setFlag(QGraphicsItem::ItemIsFocusable,true) ;

    Joh

  6. #6
    Join Date
    Mar 2010
    Posts
    7
    Thanks
    1
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Problem with QGraphicsScene, QGraphicsProxyWidget, and setting widget focus

    Hi Joh,

    Yep I tried setting the ItemIsFocusable flag.

    (And yep I tried removing the mouse move event handlers completely.)

    Oh and have you set the Qgraphicsitem flag ItemIsFocusable?

    proxy.setFlag(QGraphicsItem::ItemIsFocusable,true) ;

  7. #7
    Join Date
    Feb 2007
    Location
    Karlsruhe, Germany
    Posts
    469
    Thanks
    17
    Thanked 90 Times in 88 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Problem with QGraphicsScene, QGraphicsProxyWidget, and setting widget focus

    Could you create a small test project, just a view, scene, and add a widget to it and try handling its mouse events.

    No time to do it myself, right now.

    Joh

  8. #8
    Join Date
    Mar 2010
    Posts
    7
    Thanks
    1
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Problem with QGraphicsScene, QGraphicsProxyWidget, and setting widget focus

    Yep, I'll try creating a small test project this week. But first I'll try moving all mouse/keyboard events out of QGraphicsView and into QGraphicsScene.

    Ian

  9. #9
    Join Date
    Mar 2010
    Posts
    7
    Thanks
    1
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Problem with QGraphicsScene, QGraphicsProxyWidget, and setting widget focus

    OK, finally got the code working correctly.

    In terms of focus, the key piece of missing functionality that I added is checking for a focus item in QGraphicsScene event handlers. Specifically, if the graphics scene has a focus item, the code ignores the event and instead calls the default QGraphicsScene event handler. The mouse move event excerpt is below.

    Qt Code:
    1. void MyGraphicsScene::mouseMoveEvent(QGraphicsSceneMouseEvent *event) {
    2. if(!focusItem()) { //only handle events if no proxy items are in focus
    3. //rotate openGL scene, etc
    4. }
    5. else {
    6. QGraphicsScene::mouseMoveEvent(event); //call this so that proxy widget will receive event
    7. }
    8. }
    To copy to clipboard, switch view to plain text mode 

    Before (when the code did not check for a focus item) the openGL scene would rotate correctly when no popup was displayed. However, when the popup was displayed and the user tried to move it, the openGL scene would rotate rather than correctly transferring focus to the popup and moving that instead.

    Then, even after I fixed the above problem I ran into an additional issue: calling QDialog::show() and QGraphicsProxyWidget::setFocus() messed up the openGL state. The result was that the QGraphicsScene::drawBackround() code produced artifacts/garbage once the proxy popup was opened.

    To fix that problem I added beginNativePainting() and endNativePainting() calls to the drawBackground() definition (which I should have had in place before anyways).

    Qt Code:
    1. void MyGraphicsScene::drawBackground(QPainter *painter, const QRectF &)
    2. {
    3. painter->beginNativePainting();
    4. ...
    5. painter->endNativePainting();
    6. }
    To copy to clipboard, switch view to plain text mode 

Similar Threads

  1. Replies: 10
    Last Post: 10th November 2010, 04:12
  2. Problem setting central Widget layout
    By frenk_castle in forum Newbie
    Replies: 2
    Last Post: 26th September 2009, 17:43
  3. Adding QGraphicsProxyWidget items into QGraphicsScene
    By yagabey in forum Qt Programming
    Replies: 3
    Last Post: 21st November 2008, 07:33
  4. Focus issues / Setting multiple focus
    By ComputerPhreak in forum Qt Programming
    Replies: 1
    Last Post: 16th February 2007, 07:09
  5. Setting focus on Canvas
    By Kapil in forum Qt Programming
    Replies: 10
    Last Post: 17th May 2006, 13:55

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.