How to draw over an old picture in QGraphicsScene



  • But how? Do I have to transfer the code of their Widget class to the MainWindow class ?


  • Qt Champions 2018

    @Mikeeeeee You have to include the header file of that widget in your MainWindow, C++ basics.



  • It's not that simple. The class addresses .ui . I didn't create the right label in the designer. And main.cpp I have not created a class object and cannot access "this".


  • Qt Champions 2018

    @Mikeeeeee Then change the code of that class, so it does not use .ui file (add needed widgets manually).
    "And main.cpp I have not created a class object and cannot access "this"" - well, you have to create an instance of the widget, how else do you want to use it?



  • I decided to transfer the functionality of the class to the class "MainWindow". The "Image Viewer" class has the function "bool Image Viewer::eventFilter(QObject *obj, QEvent *event)". In the class "MainWindow" I need a function to draw "bool eventFilter(QObject obj, QEvent event);" if I add it I get an error: "undefined reference to `MainWindow::eventFilter(QObject, QEvent)'". How can this be corrected?


  • Qt Champions 2018

    @Mikeeeeee said in How to draw over an old picture in QGraphicsScene:

    How can this be corrected?

    Well, you have to define MainWindow::eventFilter(QObject, QEvent)...



  • I append 2 images on QLabel

        QImage mapImage(":/Images/Images/mapMain.png");
        myImageViewer->setImage(mapImage);
        QImage base(":/Images/Images/mapMain.png"); // set to some file/size
        QImage overlay(":/Images/Images/mapTop.png");  // set to some file/size
        QPainter paint(&base);
        paint.drawImage(0,0,overlay);
        myImageViewer->imageLabel->setPixmap(QPixmap::fromImage(base));
        ui->verticalLayout->addWidget(myImageViewer);
    
        //Pen
        myPen.setWidth(20);
        myPen.setColor(Qt::green);
        //myPen.setColor(QColor(255, 0, 0, 10));
        myPen.setCapStyle(Qt::RoundCap);
        myPen.setStyle(Qt::SolidLine);
        myImageViewer->installEventFilter(this);
    

    In the Mainwindow constructor, I wrote:

        QPixmap myPixmap;
        QPen myPen;
        QPoint lastPoint;
        bool eventFilter(QObject *obj, QEvent *event);
    

    And wrote such eventFilter:

    bool MainWindow::eventFilter(QObject *obj, QEvent *event)
    {
        qDebug()<<"eventFilter";
        if(obj == myImageViewer and event->type() == QEvent::MouseButtonPress)
        {
            qDebug()<<" QEvent::MouseButtonPress";
            QMouseEvent *mous = (QMouseEvent*)event;
            QPainter p(&myPixmap);
            p.setPen(myPen);
            p.drawPoint(mous->pos());
            p.end();
            lastPoint = mous->pos();
            myImageViewer->imageLabel->setPixmap(myPixmap);
        }
        if(obj == myImageViewer and event->type() == QEvent::MouseMove)
        {
            QMouseEvent *mous = (QMouseEvent*)event;
            QPainter p(&myPixmap);
            p.setPen(myPen);
            p.drawLine(lastPoint,mous->pos());
            p.end();
            lastPoint = mous->pos();
            myImageViewer->imageLabel->setPixmap(myPixmap);
        }
    }
    

    When eventfilter is triggered, the picture disappears and a white screen appears. And Qt gives an error message:

    QEvent::MouseButtonPress
    QPainter::begin: Paint device returned engine == 0, type: 2
    QPainter::setPen: Painter not active
    QPainter::drawPoints: Painter not active
    QPainter::end: Painter not active, aborted


  • Qt Champions 2018

    @Mikeeeeee Why do you paint in eventFilter?!
    You already were told to paint in paintEvent.
    In eventFilter you only store needed information (like x/y).



  • But in the example that I showed you drawing eventfilter occurs, and if you do so, then paintEvent works only a couple of times and then for some reason no longer works.

    void MainWindow::paintEvent(QPaintEvent *event)
    {
        qDebug()<<"paintEvent";
    }
    

  • Qt Champions 2018

    @Mikeeeeee After getting new coordinates you can call https://doc.qt.io/qt-5/qwidget.html#update to trigger paint event.



  • It turns out to draw in eventFilter, but it was necessary to add this line to the constructor.

    myPixmap  = QPixmap(myImageViewer->image.width(),myImageViewer->image.height());
    

    I draw so:

    bool MainWindow::eventFilter(QObject *obj, QEvent *event)
    {
        if(obj == myImageViewer and event->type() == QEvent::MouseButtonPress)
        {
            qDebug()<<" QEvent::MouseButtonPress";
            QMouseEvent *mous = (QMouseEvent*)event;
            QPainter p(&myPixmap);
            p.setPen(myPen);
            p.drawPoint(mous->pos());
            p.end();
            lastPoint = mous->pos();
            myImageViewer->imageLabel->setPixmap(myPixmap);
        }
    }
    
    

    But when drawing the picture disappears and the screen turns black. How to fix? Can I set the drawing on the QImage overlay(":/Images/Images/mapTop.png");?



  • And if I do so, the screen becomes white.

    myPixmap.fill();
    

    How to make myPixmap transparent?


  • Lifetime Qt Champion

    myPixmap.fill(Qt::transparent);



  • Thanks. Do so:

        myPixmap  = QPixmap(myImageViewer->image.width(),myImageViewer->image.height());
        myPixmap.fill(Qt::transparent);
        myPixmap = QPixmap(":/Images/Images/mapTop.png");
    

    But after drawing the picture disappears :

    myImageViewer->setImage(mapImage);
    

    How to get myPixmap the images:":/Images/Images/mapMain.png" and ":/Images/Images/mapTop.png" , but draw only on:
    ":/Images/Images/mapTop.png"?


  • Lifetime Qt Champion

    @Mikeeeeee
    You mean draw myPixmap on mapImage and then
    show the combined image with myImageViewer->setImage(mapImage); ?
    Thats like before where we combined them.



  • This post is deleted!


  • Yes.The background will be mapImage, and I want to draw on it, with the ability to erase and make transparent Qpixmap. You may need to use: void QPixmap::setMask(const Bitmap &mask)



  • Tried to do so, but got an error: reference to type 'const QBitmap' could not bind to an lvalue of type 'QBitmap *'

        QBitmap *myQBitmap = new QBitmap();
        myQBitmap->fromImage(mapImage);
        myPixmap.setMask(myQBitmap);
    

  • Lifetime Qt Champion

    @Mikeeeeee Please, read the documentation.

    QBitmap::fromImage is a static method. You're using it wrong.
    QPixmap::setMask takes a const reference to a QBitmap, not a pointer.



  • But how to set 2 images and draw on top image?


Log in to reply
 

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