Problems with QGraphicsView subclassing



  • Hi everybody,

    I'm having some problems subclassing QGraphicsView. I'm trying to reimplement the following functions:

    QGraphicsView::mouseMoveEvent(QMouseEvent *event)
    QGraphicsView::paintEvent(QPaintEvent *)

    I have a Dialog and what I have to do is display a chart and some other buttons, and when I move the mouse on the chart I want to draw a Cursor. I have read in some topics that the best way to do that is subclassing QGraphicsView and reimplement the two functions above. So here is my code. I take example from this topic for the subclass http://www.qtcentre.org/threads/8749-Subclassing-QGraphicsView

    @
    customgv.h
    @
    #include <QGraphicsView>
    #include <QMouseEvent>

    class QWidget;

    class customgv : public QGraphicsView
    {
    Q_OBJECT

    public:
    QPoint mousePoint;
    void mouseMoveEvent(QMouseEvent * event);
    void paintEvent(QPaintEvent *);

    public:
    customgv(QWidget *parent= NULL);
    ~customgv();
    };
    @

    customgv.cpp

    @

    #include <QtGui>
    #include "customgv.h"

    customgv::customgv(QWidget* parent)
    : QGraphicsView(parent)
    {

    setGeometry(5,5,500,500);
    setMouseTracking(true);
    

    }

    customgv::~customgv()
    {

    }

    void customgv::mouseMoveEvent(QMouseEvent *event)
    {

    mousePoint = event->pos();
    update();
    

    }

    void customgv::paintEvent(QPaintEvent *)
    {

    QPainter painter(this);
    
    painter.setPen(QPen(Qt::black, 1));
    painter.drawLine(mousePoint.x(),this->geometry().bottom() , mousePoint.x(),this->geometry().top());
    

    }
    @
    chart.cpp
    @

    //in the constructor of my new dialog chart.cpp i simply do this
    //custom is defined as a pointer to my subclass in chart.h like customgv *custom
    custom = new customgv(this);
    QChartView *chartView = new QChartView(chart,custom);

    @

    The problem is that the mouseMoveEvent is not working, when I move the mouse on the chart nothing happens and in debugging it never entries in the function. The only error qt gives me is the following:

    QWidget::paintEngine: Should no longer be called
    QPainter::begin: Paint device returned engine == 0, type: 1
    QPainter::setPen: Painter not active

    this error appears only when I open the dialog that includes my QGraphicsView subclass.
    Of course I am missing something but I can't understand what.

    Thank you all in advance.


  • Moderators

    @davidesalvetti
    your biggest mistake is that you do not call the base class implementation which (basically - unless you know what you are doing) you always should do when subclassing event-handlers - or virtual functions.

    void customgv::mouseMoveEvent(QMouseEvent *event)
    {
    mousePoint = event->pos();
    update();
    QGraphicsView::mouseMoveEvent(event);
    }
    

    Also i think reimplementing drawForeground() is more what you want rather than paintEvent():

    void customgv::drawForeground(QPainter * painter, const QRectF & rect)
    {
         QGraphicsView::drawForeground(painter, rect);
    
        painter.setPen(QPen(Qt::black, 1));
        painter.drawLine(mousePoint.x(),this->geometry().bottom() , mousePoint.x(),this->geometry().top());
    }
    


  • @raven-worx

    Thanks for your anwer.

    I'm sorry, I forgot to say that I already tried adding the base class implementation, but the mouseMoveEvent didn't work, that's why I tried without that line, but of course it's not correct.

    I understand your second advice, I will use drawForeground() instead of paintEvent() in the future.

    Anyway I tried to modify all my code as you said, but mouseMoveEvent doesn't work. I tried debugging and putting a break in the mouseMoveEvent function, but it never breaks.

    I'm wondering if subclassing QGraphicsView is correct for my purpose. Maybe I have to subclass QChartView?



  • If you want a specific cursor while over the chart, it would make sense to have the chart as a separate GraphicsItem. Create your own QGraphicsItem for the chart with your paint code, and use "setCursor" to define which cursor should be visible.

    Subclassing QGraphicsView should not be necessary at all in this case.



  • @Asperamanca
    Thank you for the answer.

    what I really need is not only to change the cursor while i'm over the chart, I need to draw a vertical Line on the chart that follow the mouse position, and when i click the mouse the line has to be fixed at that particular position.

    For this purpose I think I need a QGraphicsView that contain the QChartView, create the QChart and then create a GraphicsItem to draw the line. Am I wrong? Shoul I do something different?

    Any advice is appreciated.



  • @davidesalvetti
    QChart derives from QGraphicsWidget and thus indirectly from QGraphicsItem. I personally don't know QChart (so I don't know whether it's the right class for you to display what you want to display), but in any case, I would much rather suclass QChart (always making sure you call the base class methods when you replace a method), and put your logic in there.

    For example, reimplement paint, call the base class painting code first, then draw the vertical line where you need it.



  • Thank you a lot for your answer. I will try to find a solution based on your advices. Thanks again!


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.