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 810 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.
  • 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