Results 1 to 4 of 4

Thread: QPainter over Pixmap problem

  1. #1
    Join Date
    Jun 2013
    Posts
    11
    Thanks
    1
    Qt products
    Qt5
    Platforms
    MacOS X Windows

    Default QPainter over Pixmap problem

    Hi

    My intent is to have the user be able to draw a rounded dot using the Cursor over an Bitmap image displayed in the background. The Rounded dot remains on the screen and forms a line following
    the Cursor movement (when Mouse is pressed). Drawing terminates when Mouse is Released.

    In the program, I am using a Label to load the Bitmap and have the Label added to a layout and the layout to the Main window. I use setCentralWidget to place the label in the
    center area of the MainWindow for esoteric purposes. When user presses Mouse, I activate PaintEvent and the latter will attempt to draw the rounded dot.

    The problem is that the QPainter does not draw over the Bitmap. Note that it draws over the status and menu bar area of MainWindow correctly. If I comment out the Pixmap to label code, the QPainter draws across the entire screen. I realize I did not use QPainter to draw Bitmap as well the a rounded dot - instead I attempted to use Label to load the bitmap. The latter seemed a convenient way since I want the PaintEvent to focus on drawing lines/dots etc over the Bitmap without worrying about the Bitmap.

    My question is can I actually do it this way successfully ? I have tried many combinations of MainWindow setAttributes and setting Pixmap and Label settings to no avail. Appreciate your help.

    Thanks

    Sean

    ------------------------mainwindow.cpp----------------------------------------------------------

    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    #include <QDebug>
    #include <QtWidgets>
    #include <QtGui>
    #include <QtCore>
    #include <QDebug>
    #include <QPixmap>
    #include <QLayout>
    #include <QLabel>

    MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
    {
    QString bmp_filename;
    QPixmap *pm;

    ui->setupUi(this);

    //Setup Attribute for drawing
    this->setAttribute(Qt::WA_OpaquePaintEvent);

    // Setup Boolean to indicate User is dragging Cursor and thus OK for PaintEvent to Draw
    drawing = false;

    /*
    * Setup Layout, Label
    * Attach Label to Layout
    * Setup Layout to WIndow and set it as the central Widget
    */
    layout = new QGridLayout(this);
    lbl = new QLabel(this);
    lbl->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
    layout->addWidget(lbl, 0, 0);
    this->setLayout(layout);
    setCentralWidget(lbl);

    /*
    * Setup filename for Bitma and create a Pixmap
    */
    bmp_filename = "C:/Users/syiu/VideoAd/QT/Test_Paint_Bitmap/images/test.bmp";
    pm = new QPixmap(bmp_filename, 0, 0);

    /*
    * Bring the Pixmap to scale of the Window's dimensions and set this Pixmap to Label
    */
    lbl->setPixmap(pm->scaled(this->width(), this->height(), Qt::KeepAspectRatioByExpanding, Qt::FastTransformation));
    }

    MainWindow::~MainWindow()
    {
    delete ui;
    }
    void MainWindow:aintEvent(QPaintEvent *event)
    {
    if (!drawing)
    return;
    QPainter painter(this);
    QPen pen(Qt::green, 4, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin);
    painter.setPen(pen);

    painter.drawPoint(current_pos);
    }



    void MainWindow::mousePressEvent(QMouseEvent *event)
    {
    drawing = true;

    }

    void MainWindow::mouseReleaseEvent(QMouseEvent *event)
    {
    qDebug() << "Main Window MouseRelease Event";
    drawing = false;
    }

    void MainWindow::mouseMoveEvent(QMouseEvent *event)
    {
    current_pos = event->pos();
    this->repaint();
    }

    -------------- main.cpp ------------------------------
    #include "mainwindow.h"
    #include <QApplication>

    int main(int argc, char *argv[])
    {
    QApplication a(argc, argv);
    MainWindow w;
    w.show();

    return a.exec();
    }

    -------------------- mainwindow.h -----------------------------------------------------
    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H

    #include <QMainWindow>
    #include <QtCore>
    #include <QtGui>
    #include <QPoint>
    #include <QLabel>
    #include <QLayout>

    namespace Ui {
    class MainWindow;
    }

    class MainWindow : public QMainWindow
    {
    Q_OBJECT
    QPoint current_pos;
    bool drawing;
    QGridLayout *layout;
    QLabel *lbl;


    public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

    private:
    Ui::MainWindow *ui;

    protected:
    void mousePressEvent(QMouseEvent *event);
    void mouseReleaseEvent(QMouseEvent *event);
    void mouseMoveEvent(QMouseEvent *event);
    void paintEvent(QPaintEvent *event);
    };

    #endif // MAINWINDOW_H

  2. #2
    Join Date
    Mar 2011
    Location
    Hyderabad, India
    Posts
    1,882
    Thanks
    3
    Thanked 452 Times in 435 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows
    Wiki edits
    15

    Default Re: QPainter over Pixmap problem

    You will have to implement QLabel's paintEvent(), and also store the points so that they are persistent

    mainwindow.h
    Qt Code:
    1. #ifndef MAINWINDOW_H
    2. #define MAINWINDOW_H
    3.  
    4. #include <QMainWindow>
    5. #include <QtCore>
    6. #include <QtGui>
    7. #include <QPoint>
    8. #include <QLabel>
    9. #include <QLayout>
    10.  
    11. namespace Ui {
    12. class MainWindow;
    13. }
    14.  
    15. class MainWindow : public QMainWindow
    16. {
    17. Q_OBJECT
    18. QGridLayout *layout;
    19. QLabel *lbl;
    20.  
    21.  
    22. public:
    23. explicit MainWindow(QWidget *parent = 0);
    24. ~MainWindow();
    25.  
    26. private:
    27. Ui::MainWindow *ui;
    28. };
    29.  
    30. class Label : public QLabel
    31. {
    32. QList<QPoint> current_pos; //<<<<<<<<<<<<<<<<
    33. bool drawing;
    34.  
    35. public:
    36. explicit Label(QWidget * parent);
    37.  
    38. protected:
    39. void mousePressEvent(QMouseEvent *event);
    40. void mouseReleaseEvent(QMouseEvent *event);
    41. void mouseMoveEvent(QMouseEvent *event);
    42. void paintEvent(QPaintEvent *event);
    43. };
    44.  
    45. #endif // MAINWINDOW_H
    To copy to clipboard, switch view to plain text mode 

    mainwindow.cpp
    Qt Code:
    1. #include "mainwindow.h"
    2. #include "ui_mainwindow.h"
    3. #include <QDebug>
    4. #include <QtWidgets>
    5. #include <QtGui>
    6. #include <QtCore>
    7. #include <QDebug>
    8. #include <QPixmap>
    9. #include <QLayout>
    10. #include <QLabel>
    11.  
    12. MainWindow::MainWindow(QWidget *parent) :
    13. QMainWindow(parent),
    14. ui(new Ui::MainWindow)
    15. {
    16. QString bmp_filename;
    17. QPixmap *pm;
    18.  
    19. ui->setupUi(this);
    20.  
    21. //Setup Attribute for drawing
    22. this->setAttribute(Qt::WA_OpaquePaintEvent);
    23.  
    24. /*
    25.   * Setup Layout, Label
    26.   * Attach Label to Layout
    27.   * Setup Layout to WIndow and set it as the central Widget
    28.   */
    29. layout = new QGridLayout(this);
    30. lbl = new Label(this); //<<<<<<<<<<<<<<<<<<<<<<
    31. lbl->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
    32. layout->addWidget(lbl, 0, 0);
    33. this->setLayout(layout);
    34. setCentralWidget(lbl);
    35.  
    36. /*
    37.   * Setup filename for Bitma and create a Pixmap
    38.   */
    39. bmp_filename = "C:/Users/syiu/VideoAd/QT/Test_Paint_Bitmap/images/test.bmp";
    40. pm = new QPixmap(bmp_filename, 0, 0);
    41.  
    42. /*
    43.   * Bring the Pixmap to scale of the Window's dimensions and set this Pixmap to Label
    44.   */
    45. lbl->setPixmap(pm->scaled(this->width(), this->height(), Qt::KeepAspectRatioByExpanding, Qt::FastTransformation));
    46. }
    47.  
    48. MainWindow::~MainWindow()
    49. {
    50. delete ui;
    51. }
    52.  
    53. Label::Label(QWidget * parent)
    54. : QLabel(parent)
    55. {
    56. // Setup Boolean to indicate User is dragging Cursor and thus OK for PaintEvent to Draw
    57. drawing = false;
    58. }
    59.  
    60. void Label::paintEvent(QPaintEvent *event)
    61. {
    62. QLabel::paintEvent(event); //<<<<<<<<<<<<<<<
    63. if (!drawing)
    64. return;
    65. QPainter painter(this);
    66. QPen pen(Qt::green, 4, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin);
    67. painter.setPen(pen);
    68.  
    69. foreach(QPoint point, current_pos) //<<<<<<<<<<<<<<<
    70. painter.drawPoint(point);
    71. }
    72.  
    73. void Label::mousePressEvent(QMouseEvent *event)
    74. {
    75. drawing = true;
    76. }
    77.  
    78. void Label::mouseReleaseEvent(QMouseEvent *event)
    79. {
    80. qDebug() << "Main Window MouseRelease Event";
    81. drawing = false;
    82. }
    83.  
    84. void Label::mouseMoveEvent(QMouseEvent *event)
    85. {
    86. current_pos << event->pos(); //<<<<<<<<<<<<<<<<<
    87. this->repaint();
    88. }
    To copy to clipboard, switch view to plain text mode 
    When you know how to do it then you may do it wrong.
    When you don't know how to do it then it is not that you may do it wrong but you may not do it right.

  3. #3
    Join Date
    Jun 2013
    Posts
    11
    Thanks
    1
    Qt products
    Qt5
    Platforms
    MacOS X Windows

    Default Re: QPainter over Pixmap problem

    Thanks for your insights. It works for me now

    I tried something additional - instead of storing in the Label Qlist and having to replay the whole QList on a Label PaintEvent, I tried to no avail to manipulate the Label's Painter setCompositionMode to QPainter::CompostionMode_xxxx so that it would Paint the rounded dot over the existing Bitmap while leaving the trail of lines behind.
    All combinations failed.

    Anyone who have insights whether this can be done ?

    Thanks

    Sean

  4. #4
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: QPainter over Pixmap problem

    What you want is not drawing on the widget, but into a pixmap.

    So instead of the repaint() call in the code example of Santosh Reddy, you get the pixmap(), create a painter on it, paint onto it and then set the pixmap on the label again (this will trigger a label update).

    Obviously you don't need to overwrite paintEvent() anymore.

    Cheers,
    _

Similar Threads

  1. Replies: 1
    Last Post: 27th April 2012, 15:01
  2. Replies: 1
    Last Post: 19th April 2011, 11:17
  3. QPainter::begin: Cannot paint on a null pixmap
    By sabeesh in forum Qt Programming
    Replies: 5
    Last Post: 27th July 2010, 18:03
  4. QPainter ouside of paintEvent with a pixmap
    By bitChanger in forum Qt Programming
    Replies: 10
    Last Post: 22nd March 2006, 19:45

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.