Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Add QWidgets movable to QGraphicsView
Forum Updated to NodeBB v4.3 + New Features

Add QWidgets movable to QGraphicsView

Scheduled Pinned Locked Moved Solved General and Desktop
11 Posts 3 Posters 3.8k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • NiagarerN Offline
    NiagarerN Offline
    Niagarer
    wrote on last edited by Niagarer
    #1

    Hi,
    I want to place QGraphicsItems in my QGraphicsScene with some little widgets like a spin box or a color dialog (like this:
    https://bitbucket-assetroot.s3.amazonaws.com/repository/Radzbd/4008374530-Capture.PNG?Signature=8VGhdzlYxNVYU0uoLL3x2oQIXH0%3D&Expires=1517141176&AWSAccessKeyId=AKIAIQWXW6WLXMB5QZAQ&versionId=P9veTjLXRJSEYq9lCji1zTidPNk5aXQL)
    So I first tried to place a widget into the scene without any QGraphicsItems.
    The problem is, every answer, I found in the forums, just creates a new window (when trying with QColorDialog) (it closes instatly, but it is there) and I can't set the color in a color dialog f.ex. When I click on it, the mousePress-call just goes to the QgraphicsView, so I can not interact with the widget, except with the mouse wheel.
    I tried this code:

    void GraphWidget::mousePressEvent(QMouseEvent *event){ // class GraphWidget : public QGraphicsView
        QColorDialog *_dialog = new QColorDialog;
        _dialog->setOption(QColorDialog::NoButtons, true);
        _dialog->show();
        QGraphicsProxyWidget *proxyWidget = scene()->addWidget(_dialog);
    
        QGraphicsView::mouseMoveEvent(event);
    }
    

    but as I said, I can't interact with the dialog.

    Is there any example or sth. showing, how to do what I want to? I cound not find one. I am missing something, but every answer in every forum is diferent, but actually no one works for me so far.
    Thanks for answers!

    1 Reply Last reply
    0
    • mrjjM Offline
      mrjjM Offline
      mrjj
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Hi
      you are not giving the dialog a parent and it will show as window then.
      ColorDialog *_dialog = new QColorDialog; (no parent)
      so when you call show() it will show shortly
      But you are using
      QGraphicsProxyWidget so not sure why you cant interact with it.

      NiagarerN 1 Reply Last reply
      0
      • mrjjM mrjj

        Hi
        you are not giving the dialog a parent and it will show as window then.
        ColorDialog *_dialog = new QColorDialog; (no parent)
        so when you call show() it will show shortly
        But you are using
        QGraphicsProxyWidget so not sure why you cant interact with it.

        NiagarerN Offline
        NiagarerN Offline
        Niagarer
        wrote on last edited by
        #3

        @mrjj
        Ok, thanks!
        So what should be the parent? When I give the QGraphicsView as parent, it still opens that window and I can't give the scene(), or the mainwindow as parent.

        mrjjM 1 Reply Last reply
        0
        • NiagarerN Niagarer

          @mrjj
          Ok, thanks!
          So what should be the parent? When I give the QGraphicsView as parent, it still opens that window and I can't give the scene(), or the mainwindow as parent.

          mrjjM Offline
          mrjjM Offline
          mrjj
          Lifetime Qt Champion
          wrote on last edited by
          #4

          @Niagarer
          Hi
          I think you are supposed to insert the proxy, not the dialog to scene.
          like

          QColorDialog *_dialog = new QColorDialog;
          _dialog->setOption(QColorDialog::NoButtons, true);
          QGraphicsProxyWidget *proxyWidget = new QGraphicsProxyWidget;
          proxyWidget->setWidget(_dialog);
          scene()->addItem(proxyWidget);
          _dialog->show();
          
          NiagarerN 1 Reply Last reply
          0
          • mrjjM mrjj

            @Niagarer
            Hi
            I think you are supposed to insert the proxy, not the dialog to scene.
            like

            QColorDialog *_dialog = new QColorDialog;
            _dialog->setOption(QColorDialog::NoButtons, true);
            QGraphicsProxyWidget *proxyWidget = new QGraphicsProxyWidget;
            proxyWidget->setWidget(_dialog);
            scene()->addItem(proxyWidget);
            _dialog->show();
            
            NiagarerN Offline
            NiagarerN Offline
            Niagarer
            wrote on last edited by Niagarer
            #5

            I just found the solution for the problem with the interaction with the widget. I forgot to ask

            if(!itemAt(event->pos()){
                // place dialog ...
            }
            

            in the MousePressEvent in GraphWidget (so every time I clicked, it placed a new one, before I was able to modify the old one).
            Now the dialog receives everything.
            But well still with a short opening window...

            @mrjj
            Hm, doesn't work here. When I do it this way and call _dialog->show(); before I set it to the proxy's widget, I have the short opening and closing window. When I do it like in your example (calling it after setting it to the proxy's widget), it opens a blank new window, that even does not close automatically

            1 Reply Last reply
            0
            • mrjjM Offline
              mrjjM Offline
              mrjj
              Lifetime Qt Champion
              wrote on last edited by
              #6

              Hi
              Try
              _dialog-> setWindowFlags(Qt::Widget);

              NiagarerN 1 Reply Last reply
              0
              • mrjjM mrjj

                Hi
                Try
                _dialog-> setWindowFlags(Qt::Widget);

                NiagarerN Offline
                NiagarerN Offline
                Niagarer
                wrote on last edited by
                #7

                @mrjj
                Hi
                It unfortunately still opens that window :/

                D 1 Reply Last reply
                0
                • mrjjM Offline
                  mrjjM Offline
                  mrjj
                  Lifetime Qt Champion
                  wrote on last edited by
                  #8

                  Hi
                  try to give it a parent on creation then

                  QGraphicsProxyWidget *proxyWidget = new QGraphicsProxyWidget; // make first
                  QColorDialog *_dialog = new QColorDialog(proxyWidget);
                  _dialog-> setWindowFlags(Qt::Widget);
                  ....

                  NiagarerN 1 Reply Last reply
                  0
                  • mrjjM mrjj

                    Hi
                    try to give it a parent on creation then

                    QGraphicsProxyWidget *proxyWidget = new QGraphicsProxyWidget; // make first
                    QColorDialog *_dialog = new QColorDialog(proxyWidget);
                    _dialog-> setWindowFlags(Qt::Widget);
                    ....

                    NiagarerN Offline
                    NiagarerN Offline
                    Niagarer
                    wrote on last edited by Niagarer
                    #9

                    Ok, thanks.
                    But I can't use a QGraphicsProxywidget* as a QWidget* (because QGraphicsProxyWidget is not a QWidget class).
                    That causes this error, when I try to use a QGraphicsProxyWidget as parent for the QColorDialog:

                    error: invalid user-defined conversion from 'QGraphicsProxyWidget*' to 'const QColor&' [-fpermissive]
                                 QColorDialog *_dialog = new QColorDialog(proxyWidget);
                                                                                     ^
                    
                     error: invalid conversion from 'QGraphicsProxyWidget*' to 'QRgb {aka unsigned int}' [-fpermissive]
                                 QColorDialog *_dialog = new QColorDialog(proxyWidget);
                                                                                     ^
                    

                    Because QColorDialog() expects a QWidget as parent

                    1 Reply Last reply
                    0
                    • NiagarerN Niagarer

                      @mrjj
                      Hi
                      It unfortunately still opens that window :/

                      D Offline
                      D Offline
                      Devopia53
                      wrote on last edited by
                      #10

                      @Niagarer said in Add QWidgets movable to QGraphicsView:

                      It unfortunately still opens that window :/

                      I have a tricky method for that problem. like this:

                      auto    widget = new QWidget;
                      auto    dialog = new QColorDialog;
                      
                      dialog->setOption(QColorDialog::NoButtons, true);
                      widget->setLayout(new QHBoxLayout);
                      widget->layout()->addWidget(dialog);
                      scene()->addWidget(widget);
                      

                      Tested by Qt 5.10/Windows 7

                      NiagarerN 1 Reply Last reply
                      3
                      • D Devopia53

                        @Niagarer said in Add QWidgets movable to QGraphicsView:

                        It unfortunately still opens that window :/

                        I have a tricky method for that problem. like this:

                        auto    widget = new QWidget;
                        auto    dialog = new QColorDialog;
                        
                        dialog->setOption(QColorDialog::NoButtons, true);
                        widget->setLayout(new QHBoxLayout);
                        widget->layout()->addWidget(dialog);
                        scene()->addWidget(widget);
                        

                        Tested by Qt 5.10/Windows 7

                        NiagarerN Offline
                        NiagarerN Offline
                        Niagarer
                        wrote on last edited by Niagarer
                        #11

                        Works perfectly fine
                        Thank you!

                        So, with this code you can place any QWidget independent in a QGraphicsScene:
                        (with a QGraphicsProxyWidget, because usually you want to scale the widget and change the position of it in the scene)

                                    auto widget = new QWidget;
                                    auto dialog = new QColorDialog;
                                    auto proxy = new QGraphicsProxyWidget;
                        
                                    dialog->setOption(QColorDialog::NoButtons, true);
                                    widget->setLayout(new QHBoxLayout);
                                    widget->layout()->addWidget(dialog);
                                    proxy->setWidget(widget);
                                    scene()->addItem(proxy); // important: if you want to use a proxy, use scene()->addItem() not addWidget()
                        

                        I will update later, because I have a version of a program here, where I actually don't add the widget with the specific scene()->addSth()-command to the scene, but it actually works. I will update this post once, I got time to understand it :)
                        update
                        I found two ways of adding proxies to a QGraphicsScene. You can either create a proxy, set its widget (like above) and add it to the scene, or you create a proxy with a QGraphicsItem as parent! Very often, the widgets placed in the scene are attached to QGraphicsItems placed in the scene. If this is your case, create the proxy like this

                        MyItemClass::MyItemClass()
                        {
                            QGraphicsProxyWidget *proxy = new QGraphicsProxyWidget(this);
                            //                                                  ^^^^^^^^^^
                            QLineEdit *widget = new QLineEdit
                            proxy->setWidget(widget);
                        
                            width = widget->width()*proxy->scale();
                            height = widget->height()*proxy->scale();
                        
                            myProxy->setPos(-width/2, -height/2); // place it centered over the item
                        }
                        

                        This does things for you: You don't have to add the proxy to the scene yourself, Qt does it for you here. And another important (and nice) thing here is, that the position of the proxy now is related to the QGraphicsItem's. So when you call

                        proxy->setPos(0, 0);
                        

                        the proxy with the widget will always be with the top left corner at the center of the item, no matter where you drag the item at.

                        One little ugly thing here is, that you will get in trouble with a QColorDialog, because the QColorDialog normally opens a new window. You can use the same feature here, but you should create it like áDevopia53 wrote:

                        @Devopia53 said in Add QWidgets movable to QGraphicsView:

                        I have a tricky method for that problem. like this:

                        auto    widget = new QWidget;
                        auto    dialog = new QColorDialog;
                        
                        dialog->setOption(QColorDialog::NoButtons, true);
                        widget->setLayout(new QHBoxLayout);
                        widget->layout()->addWidget(dialog);
                        // ( scene()->addWidget(widget); ) not if you do: 
                        //     auto proxy = new QGraphicsProxyWidget(myQGraphicsItem);
                        //     proxy->setWidget(widget);
                        

                        Tested by Qt 5.10/Windows 7

                        1 Reply Last reply
                        1

                        • Login

                        • Login or register to search.
                        • First post
                          Last post
                        0
                        • Categories
                        • Recent
                        • Tags
                        • Popular
                        • Users
                        • Groups
                        • Search
                        • Get Qt Extensions
                        • Unsolved