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. Interactive bezier spline editing within a mainwindow UI
Qt 6.11 is out! See what's new in the release blog

Interactive bezier spline editing within a mainwindow UI

Scheduled Pinned Locked Moved Unsolved General and Desktop
11 Posts 4 Posters 348 Views 2 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.
  • L Offline
    L Offline
    lukester88
    wrote last edited by
    #1

    Hey guys,

    I want to add a widget into my mainwindow UI where the user can drag the control points of a cubic bezier curve to reshape it how they see fit. I envision that this would involve some kind of QPainterPath instance tied with some mouse event logic. And I know that QPainterPath has a cubicTo function which creates a cubic bezier curve where you input the end point and control points, so I'm wondering if I could link up the mouse event logic to those control points to move the bezier around. As you can see I have a basic idea, but I have hit a wall with the little details and am having trouble understanding how all of this connects and how to properly implement this. If anyone can offer a solution for how to accomplish this, I would appreciate it dearly.

    I don't really have any code to share because I haven't been able to get the QPainterPath to work with my UI :(
    Any guidance would be greatly appreciated.

    ~Luke

    1 Reply Last reply
    0
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote last edited by
      #2

      Hi,

      One way you can do that is using the Qt Graphics View framework.
      Create a custom QGraphicsItem that you will use to move the curve's reference points and a QPainterPath based on them.

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      1 Reply Last reply
      1
      • L Offline
        L Offline
        lukester88
        wrote last edited by
        #3

        Thank you for the reply! I am aware of the availability of QGraphicsItem and QPainterPath. I have read through the documentation but am having trouble figuring out how to get started on implementing this into an existing mainwindow UI. Is it possible you could please provide an example and explanation? Thanks again.

        JonBJ 1 Reply Last reply
        0
        • L Offline
          L Offline
          lukester88
          wrote last edited by
          #4

          Also, I am using Qt 6 with C++, and usually do all my coding in the Qt Creator IDE.

          1 Reply Last reply
          0
          • L lukester88

            Thank you for the reply! I am aware of the availability of QGraphicsItem and QPainterPath. I have read through the documentation but am having trouble figuring out how to get started on implementing this into an existing mainwindow UI. Is it possible you could please provide an example and explanation? Thanks again.

            JonBJ Offline
            JonBJ Offline
            JonB
            wrote last edited by
            #5

            @lukester88 said in Interactive bezier spline editing within a mainwindow UI:

            am having trouble figuring out how to get started on implementing this into an existing mainwindow UI.

            • In Designer from the toolbox at the left, section Display Widgets, drag a Graphics View onto the central widget in your MainWindow. This is a widget, just like all the other widgets there (e.g. Label, Line Edit, Frame etc.), so you can put it wherever you could put those and do all the usual layout stuff and so on. This gives you a QGraphicsView widget named graphicsView.

            • A QGraphicsView needs a QGraphicsScene as its "model", but you cannot create that from Designer. Somewhere in your code --- probably in the MainWindow constructor after the ui->setupUi(this) --- create a new QGraphicsScene and assign it to the QGraphcisView via graphicsView->setScene().

            • Now you have a graphics view with a graphics scene behind it. You can start creating your QGraphicsItems and adding them onto the scene. They will be visualized in the view. You can do whatever to the scene or view to alter its look and behaviour.

            1 Reply Last reply
            0
            • L Offline
              L Offline
              lukester88
              wrote last edited by
              #6

              Thank you! I ended spending some time today learning the basics of QGraphicsView and QPainter. I am able to get as far as plotting a cubic bezier using the cubicTo() function from QPainterPath, and then sending that path to the QGraphicsScene to be viewed in QGraphicsView. However, my next problem is getting mouse events to work. I have read the documentation on the QGraphicsView mouse event system, and it looks like Qt recommends subclassing a QWidget to create a custom graphics view class where I would override the virtual mouse event functions. I understand the basic idea, but can you explain how I would go about retrieving and using mouse event data from the QGraphicsView? Thank you

              JonBJ 1 Reply Last reply
              0
              • T Offline
                T Offline
                thomaskennedie
                Banned
                wrote last edited by
                #7
                This post is deleted!
                1 Reply Last reply
                0
                • L lukester88

                  Thank you! I ended spending some time today learning the basics of QGraphicsView and QPainter. I am able to get as far as plotting a cubic bezier using the cubicTo() function from QPainterPath, and then sending that path to the QGraphicsScene to be viewed in QGraphicsView. However, my next problem is getting mouse events to work. I have read the documentation on the QGraphicsView mouse event system, and it looks like Qt recommends subclassing a QWidget to create a custom graphics view class where I would override the virtual mouse event functions. I understand the basic idea, but can you explain how I would go about retrieving and using mouse event data from the QGraphicsView? Thank you

                  JonBJ Offline
                  JonBJ Offline
                  JonB
                  wrote last edited by JonB
                  #8

                  @lukester88

                  • To access the mouse you will need to use mousePressEvent() and mouseMoveEvent() methods. These are available on both the QGraphicsView and QGraphicsScene. A mouse event is sent first to the view and then to its scene. In both cases these are virtual protected methods. That means you have to subclass the view/scene to intercept them.

                  • If you wanted to use them at the view level you would need to create your own QGraphicsView subclass. Since you want to use Designer you would need to use its promotion feature to create a subclassed QGraphicsView at design-time.

                  • However, I think you will be happy using them at the QGraphicsScene level, where they have been translated into a QGraphicsSceneMouseEvent. So you will need to create your own subclass of QGraphicsScene to override the methods. Since you assign the scene to the view in your own code it's easy to just assign your subclassed instance. In those overridden methods you do whatever to the points of your curve.

                  • If you need to see mouse events on a QGraphicsItem, like @SGaist mentioned, then similarly there are the same methods on those and you would subclass the items you add to the scene.

                  So to repeat: I think you will want to use mouse events on the graphics items or scene rather than on the view.

                  P.S.
                  Just came across how to use mouse move event for QGraphicsScene? from years ago. Might be worth looking at.

                  1 Reply Last reply
                  0
                  • L Offline
                    L Offline
                    lukester88
                    wrote last edited by
                    #9

                    Thank you! I have been working on implementing this method in my code, and I think I am 99% of the way there. I have created a subclass of QGraphicsScene. However, I am running into a segmentation fault when running the debugger, and when I try to run the application, it terminates abnormally and doesn't show the UI.

                    1 Reply Last reply
                    0
                    • L Offline
                      L Offline
                      lukester88
                      wrote last edited by
                      #10

                      custom class header:

                      
                      
                      
                      class customGraphicsScene : public QGraphicsScene {
                      
                          Q_OBJECT
                      
                      protected:
                      
                          void mousePressEvent(QGraphicsSceneMouseEvent *event) override;
                      
                      };
                      
                      

                      class source file:

                      
                      
                      void customGraphicsScene::mousePressEvent(QGraphicsSceneMouseEvent *event) {
                          if (event->button() == Qt::LeftButton) {
                              qDebug() << "clicked!";
                          }
                      }
                      

                      mainwindow implementation:

                      
                      
                      MainWindow::MainWindow(QWidget *parent)
                          : QMainWindow(parent)
                          , ui(new Ui::MainWindow)
                      {
                          ui->setupUi(this);
                      
                          customGraphicsScene *customScene;
                      
                          ui->graphicsView_2->setScene(customScene);   
                      }
                      
                      MainWindow::~MainWindow()
                      {
                          delete ui;
                      }
                      
                      JonBJ 1 Reply Last reply
                      0
                      • L lukester88

                        custom class header:

                        
                        
                        
                        class customGraphicsScene : public QGraphicsScene {
                        
                            Q_OBJECT
                        
                        protected:
                        
                            void mousePressEvent(QGraphicsSceneMouseEvent *event) override;
                        
                        };
                        
                        

                        class source file:

                        
                        
                        void customGraphicsScene::mousePressEvent(QGraphicsSceneMouseEvent *event) {
                            if (event->button() == Qt::LeftButton) {
                                qDebug() << "clicked!";
                            }
                        }
                        

                        mainwindow implementation:

                        
                        
                        MainWindow::MainWindow(QWidget *parent)
                            : QMainWindow(parent)
                            , ui(new Ui::MainWindow)
                        {
                            ui->setupUi(this);
                        
                            customGraphicsScene *customScene;
                        
                            ui->graphicsView_2->setScene(customScene);   
                        }
                        
                        MainWindow::~MainWindow()
                        {
                            delete ui;
                        }
                        
                        JonBJ Offline
                        JonBJ Offline
                        JonB
                        wrote last edited by JonB
                        #11

                        @lukester88 said in Interactive bezier spline editing within a mainwindow UI:

                        customGraphicsScene *customScene;
                        
                        ui->graphicsView_2->setScene(customScene);  
                        

                        Think about it! customScene is just a pointer to some customGraphicsScene (and an uninitialized pointer at that). You have not allocated any actual customGraphicsScene instance for it to point it. I did say earlier:

                        create a new QGraphicsScene and assign it to the QGraphcisView via graphicsView->setScene().

                        you need to:

                        customGraphicsScene *customScene = new customGraphicsScene(this);
                        ui->graphicsView_2->setScene(customScene);
                        

                        But a couple of points:

                        • Your customGraphicsScene *customScene is a local variable in the MainWindow constructor. Once that exits the local variable no longer exists, you have allocated a customGraphicsScene but you really can no longer get at it to do anything! You will want that pointer to be a member variable in your MainWindow class.

                        • class customGraphicsScene : public QGraphicsScene: make all your classes start with an uppercase letter. All Qt's do, and this is standard practice for C++. Your variables, such as [now] CustomGraphicsScene *customScene, should indeed start with a lowercase letter.

                        1 Reply Last reply
                        0

                        • Login

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