Results 1 to 20 of 20

Thread: Getting focus of a QWidget inside a QGraphicsScene

  1. #1
    Join Date
    Mar 2012
    Location
    Germany
    Posts
    17
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Getting focus of a QWidget inside a QGraphicsScene

    Hello,

    I'm working on a project where I have a QGraphicsScene with QWidgets on it.
    I add the QWidgets with QGraphicsScene::addWidget().

    However there are a few flaws and I can't seem to find a solution inside the Documentation alone.
    First, It seems that I can't move the widgets. They are always centered. Resizing works, but I can't move them. Weird?

    Then my main problem is that I can't get "their" focus. I'm developing on KDE and Widgets with focus get a highlighted border, this
    is not the case for my QWidgets inside my QGraphicsScene. I'm trying to click on them or tab through the widgets. But neither works. Is there a reason for it?

    I would like to provide code, but first I would have to make an example, since my project's code is a bit hard to understand.

  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: Getting focus of a QWidget inside a QGraphicsScene

    ==========================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 2012
    Location
    Germany
    Posts
    17
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: Getting focus of a QWidget inside a QGraphicsScene

    That's not possible. I'm not using QGraphicsItems inside my QGraphicsScene, but QWidgets.

    Edit:

    Ok, I'm setting the flags now via QGraphicsProxyWidgets. However, it makes no difference at all...

    Here example code:
    Qt Code:
    1. // Here I store my QGraphicsScene widgets...
    2. std::vector <QGraphicsProxyWidget*> proxy_for_mywidgetclass;
    3. std::vector <MyWidgetClass*> mywidgets;
    4.  
    5. // Now I call a function to fill the vectors
    6. void MySuperWindow::draw_widget(SomeOtherClass object )
    7. {
    8. MyWidgetClass *widget = new MyWidgetClass(object, 200, 150);
    9. QGraphicsProxyWidget *widgetproxy = MyScene->addWidget(widget);
    10.  
    11. widgetproxy->setFlag(QGraphicsItem::ItemIsSelectable); // Also tried
    12. widgetproxy->setFlag(QGraphicsItem::ItemIsMovable); // this and
    13. widgetproxy->setFlag(QGraphicsItem::ItemIsFocusable); // this
    14.  
    15. mywidgets.push_back(widget);
    16. proxy_for_mywidgetclass.push_back(widgetproxy);
    17. }
    To copy to clipboard, switch view to plain text mode 

    One widget shows up on my scene, I can resize it, but neither move nor adding labels on it etc.
    And I can't get the focus.
    Last edited by jovin; 13th March 2012 at 22:14.

  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: Getting focus of a QWidget inside a QGraphicsScene

    What happens if you just use a Qt widget (say a QPushButton) and not your own custom widget - can you move it then?

    EDIT:
    I am not sure about this - but try not parenting your widget - see if it helps.
    ==========================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 2012
    Location
    Germany
    Posts
    17
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: Getting focus of a QWidget inside a QGraphicsScene

    I tried it with QPushButton, resizing works and the button itself works, but again, I can't move it.

    Qt Code:
    1. QPushButton *pushy = new QPushButton;
    2. pushy->setGeometry(23, 100, 200, 120);
    To copy to clipboard, switch view to plain text mode 
    The position won't change at all, but the size.

    I'm not sure if I understand you. You mean I should leave QWidget *parent = 0 ?
    If so, I'm already doing it.

  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: Getting focus of a QWidget inside a QGraphicsScene

    I'm not sure if I understand you. You mean I should leave QWidget *parent = 0 ?
    If so, I'm already doing it.
    Not in the code you posted:
    Qt Code:
    1. MyWidgetClass *widget = new MyWidgetClass(object, 200, 150);
    To copy to clipboard, switch view to plain text mode 

    I'll have to look on an example of my own, but can't at the moment.
    I'll try later and see if I can help you further.
    ==========================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
    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: Getting focus of a QWidget inside a QGraphicsScene

    After trying - indeed, the widget items do not adhere to the same move policy as regular items. (it did surprise me)
    I imagine that this is done on purpose, since regular widgets on regular forms don't move around.
    You could try to subclass or install an eventFilter() and catch the move events - and call the QGraphicsItem implementation there.
    Or read really carefully the docs, maybe there is some flag somewhere that can control this behavior with out sub classing or installing an eventFilter().
    ==========================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.

  8. #8
    Join Date
    Mar 2012
    Location
    Germany
    Posts
    17
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: Getting focus of a QWidget inside a QGraphicsScene

    That's nasty.
    If I set the size for QGraphicsScene (instead of leaving it uninitialized at 0,0 and thus it's not able to move, I guess?) to the size of the QGraphicsView
    it's possible to move the widgets again.

    Qt Code:
    1. myscene = new QGraphicsScene(QRect(0, 0, 800, 600), this);
    To copy to clipboard, switch view to plain text mode 

    Now, there is one problem left. My widgets are still unable to get focused.
    And I'm already using a Proxy, tried all flags and got them moving again.

  9. #9
    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: Getting focus of a QWidget inside a QGraphicsScene

    If I set the size for QGraphicsScene (instead of leaving it uninitialized at 0,0 and thus it's not able to move, I guess?) to the size of the QGraphicsView
    it's possible to move the widgets again.
    In my test application I did initialize the scene rect, but not to the views size - and the widget item stil didn't move.
    I am interested how you came to the idea to try it?
    My widgets are still unable to get focused.
    Just to make sure we both mean the same with "focused" - what do you mean by "focused"?
    Again, I'll have to test it, and I can do it only much later.
    ==========================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.

  10. #10
    Join Date
    Mar 2012
    Location
    Germany
    Posts
    17
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: Getting focus of a QWidget inside a QGraphicsScene

    Quote Originally Posted by high_flyer View Post
    In my test application I did initialize the scene rect, but not to the views size - and the widget item stil didn't move.
    I am interested how you came to the idea to try it?
    After a long google orgy I found a hint, because someone had a similiar problem with the always "centered widgets", though
    I don't know where I found it anymore.

    Just to make sure we both mean the same with "focused" - what do you mean by "focused"?
    Again, I'll have to test it, and I can do it only much later.
    Hmm. I mean that the widget is selected, gets a blue border in KDE terms.
    But I think since QPushButtons work (it's getting a blue border around the button when I push), a simple subclass of QWidget (like mine) will not show that they are
    "focused".

    I want my widget to have a visible effect when it's focused.

    I thought setting the flag, would do so.

  11. #11
    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: Getting focus of a QWidget inside a QGraphicsScene

    I tried what you said with setting the scene to the views geometry, but it didn't help my widget item to move...
    Could you post your initialization code?
    That is interesting.
    Here is mine:
    Qt Code:
    1. pView->show();
    2. pView->resize(300,300);
    3.  
    4. QGraphicsScene* pScene = new QGraphicsScene(QRect(0,0,300,300),pView);
    5. QGraphicsProxyWidget *pProx = pScene->addWidget(new QPushButton("test"));
    6. pProx->setFlag(QGraphicsItem::ItemIsMovable);
    7. pView->setScene(pScene);
    8.  
    9. pView->update();
    To copy to clipboard, switch view to plain text mode 

    I want my widget to have a visible effect when it's focused.
    This might be a window manager issue.
    The same code as above but with a QTextEdit under windows, produces a QTextEdit that is showing a light blue border when focused, which gets gray when the widget loses focus.
    ==========================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.

  12. #12
    Join Date
    Mar 2012
    Location
    Germany
    Posts
    17
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: Getting focus of a QWidget inside a QGraphicsScene

    My initialization code looks the same, except that my scene parent isn't the QGraphicsView, but my QMainWindow.
    I dunno why it works for me, if it isn't because of the different parents.

    Hmm. I will try out other widgets and post my results.

    You really helped me a lot. I have to thank you.

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

    Default Re: Getting focus of a QWidget inside a QGraphicsScene

    I don't have any problems with focusing a widget using the following code:

    Qt Code:
    1. #include <QtGui>
    2.  
    3. int main(int argc, char **argv) {
    4. QApplication app(argc, argv);
    5. QGraphicsScene scene(QRect(-100, -200, 500, 400));
    6. view.setScene(&scene);
    7. QGraphicsProxyWidget *w = scene.addWidget(new QLineEdit);
    8. //w->setFlag(QGraphicsItem::ItemIsMovable); // doesn't work anyway since the widget gets input events
    9. view.show();
    10. return app.exec();
    11. }
    To copy to clipboard, switch view to plain text mode 

    If you are using a custom widget, did you set a focus policy on it?
    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.


  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: Getting focus of a QWidget inside a QGraphicsScene

    @wysota - can you get widgets items to be movable in the scene?

    @jovin - you are welcome
    I lern that way too!
    I will try the thing with parenting the scene and let you know.
    ==========================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
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,368
    Thanks
    3
    Thanked 5,017 Times in 4,793 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Getting focus of a QWidget inside a QGraphicsScene

    Quote Originally Posted by high_flyer View Post
    @wysota - can you get widgets items to be movable in the scene?
    No. The widget steals mouse events. One would need to reimplement mouse events in the view to prevent that. I was trying the OP's idea but it didn't work for me.
    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.


  16. #16
    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: Getting focus of a QWidget inside a QGraphicsScene

    The widget steals mouse events. One would need to reimplement mouse events in the view to prevent that.
    In the view?
    I would expect in the widget - since the mouse events go through the proxy to the widget, which I guess then consumes it.
    I'd expect that if the widget returns 'false' on the event handler the proxy could continue to act on the event with its regular graphics item behavior...
    Am I wrong with this theory?
    ==========================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.

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

    Default Re: Getting focus of a QWidget inside a QGraphicsScene

    Quote Originally Posted by high_flyer View Post
    In the view?
    Yes.
    I would expect in the widget - since the mouse events go through the proxy to the widget, which I guess then consumes it.
    But for the events to reach the proxy, they have to go through the view And since it's the item that handles the ItemIsMovable flag, you'd have to reimplement the proxy widget or catch the event earlier.

    I'd expect that if the widget returns 'false' on the event handler the proxy could continue to act on the event with its regular graphics item behavior...
    Am I wrong with this theory?
    I think you are wrong. Yesterday I thought the same so I checked with a widget (QGroupBox, I think) that doesn't handle mouse events (so it should ignore the event) and it was not movable.

    Let's look at the code...

    Qt Code:
    1. void QGraphicsItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
    2. {
    3. if (event->button() == Qt::LeftButton && (flags() & ItemIsSelectable)) {
    4. bool multiSelect = (event->modifiers() & Qt::ControlModifier) != 0;
    5. if (!multiSelect) {
    6. if (!d_ptr->selected) {
    7. if (QGraphicsScene *scene = d_ptr->scene) {
    8. ++scene->d_func()->selectionChanging;
    9. scene->clearSelection();
    10. --scene->d_func()->selectionChanging;
    11. }
    12. setSelected(true);
    13. }
    14. }
    15. } else if (!(flags() & ItemIsMovable)) {
    16. event->ignore();
    17. }
    18. if (d_ptr->isWidget) {
    19. // Qt::Popup closes when you click outside.
    20. QGraphicsWidget *w = static_cast<QGraphicsWidget *>(this);
    21. if ((w->windowFlags() & Qt::Popup) == Qt::Popup) {
    22. event->accept();
    23. if (!w->rect().contains(event->pos()))
    24. w->close();
    25. }
    26. }
    27. }
    To copy to clipboard, switch view to plain text mode 

    Qt Code:
    1. void QGraphicsProxyWidget::mousePressEvent(QGraphicsSceneMouseEvent *event)
    2. {
    3. Q_D(QGraphicsProxyWidget);
    4. #ifdef GRAPHICSPROXYWIDGET_DEBUG
    5. qDebug() << "QGraphicsProxyWidget::mousePressEvent";
    6. #endif
    7. d->sendWidgetMouseEvent(event);
    8. }
    To copy to clipboard, switch view to plain text mode 

    See? QGraphicsProxyWidget unconditionally transfers the event to the widget.

    However if you ignore it (as you suggested) the proxy should ignore it as well:
    Qt Code:
    1. void QGraphicsProxyWidgetPrivate::sendWidgetMouseEvent(QGraphicsSceneHoverEvent *event)
    2. {
    3. QGraphicsSceneMouseEvent mouseEvent(QEvent::GraphicsSceneMouseMove);
    4. mouseEvent.setPos(event->pos());
    5. mouseEvent.setScreenPos(event->screenPos());
    6. mouseEvent.setButton(Qt::NoButton);
    7. mouseEvent.setButtons(0);
    8. mouseEvent.setModifiers(event->modifiers());
    9. sendWidgetMouseEvent(&mouseEvent);
    10. event->setAccepted(mouseEvent.isAccepted());
    11. }
    To copy to clipboard, switch view to plain text mode 

    ... but the event won't reach the code responsible for moving the item which was overridden by reimplementing mouse events in the proxy widget. So again, it's either subclassing QGraphicsProxyWidget or QGraphicsView.

    This also explains that setting the scene size to whatever the OP set it couldn't have made the items move
    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.


  18. #18
    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: Getting focus of a QWidget inside a QGraphicsScene

    However if you ignore it (as you suggested) the proxy should ignore it as well:
    I see.
    Indeed - in such a case I would probably go for changing the proxy like so:
    Qt Code:
    1. void QGraphicsProxyWidget::mousePressEvent(QGraphicsSceneMouseEvent *event)
    2. {
    3. Q_D(QGraphicsProxyWidget);
    4. #ifdef GRAPHICSPROXYWIDGET_DEBUG
    5. qDebug() << "QGraphicsProxyWidget::mousePressEvent";
    6. #endif
    7. d->sendWidgetMouseEvent(event);
    8.  
    9. QGraphicsItem::mousePressEvent(event); //This should then allow the regular QGraphicsItem behaviour - I'd think... (specially as int the code you posted QGrphicsItem is not checking if the event is already accepted or not.
    10.  
    11. }
    To copy to clipboard, switch view to plain text mode 

    But I'm writing from work (currently, sadly not working on a Qt project), and have little time to think it through, I might be well missing stuff..
    But if you can try it, I'd appreciate it if you shared the results!
    ==========================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.

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

    Default Re: Getting focus of a QWidget inside a QGraphicsScene

    Subclassing the proxy is definitely a good approach but it then prevents you from using QGraphicsScene::addWidget(). It's all just a matter of personal preferences.
    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.


  20. #20
    Join Date
    Mar 2012
    Location
    India
    Posts
    102
    Thanks
    4
    Qt products
    Qt4 Qt/Embedded
    Platforms
    Unix/X11

    Default Re: Getting focus of a QWidget inside a QGraphicsScene

    Hi jovin,

    I am trying something very similar. But neither my resizing works nor the moving. When I click on the widget the widget takes the mouse press event. Could you post your code or upload a zip. It would be very kind of you.

    Charvi.

Similar Threads

  1. DirectFB and no focus QWidget OSD
    By zidagar in forum Qt for Embedded and Mobile
    Replies: 0
    Last Post: 17th February 2012, 11:22
  2. Replies: 8
    Last Post: 9th July 2010, 00:37
  3. Focus frame inside QComboBox list
    By alpinista in forum Qt Programming
    Replies: 2
    Last Post: 13th November 2009, 14:30
  4. QGLWidget inside QGraphicsScene/View
    By h123 in forum Qt Programming
    Replies: 3
    Last Post: 10th January 2009, 08:46
  5. Focus on a QWidget item in a QWidget
    By vycke in forum Qt Programming
    Replies: 10
    Last Post: 7th January 2008, 21:00

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.