Unsolved How to draw over an old picture in QGraphicsScene
-
@Mikeeeeee said in How to draw over an old picture in QGraphicsScene:
QPainter myPainter; // Со
it should be
QPainter myPainter(this); -
If I do so in a class inherited from QGraphicsScene, I get an error: no matching constructor for initialization of 'QPainter'
and if I prescribe void paintEvent(QPaintEvent *event); to the main class, it automatically fires 1 time when the application is loaded, 1 time when the left mouse button is pressed and no longer works. -
@Mikeeeeee
QGraphicsScene do not have paintEvent so that is why its not working.
Normally one would use a custom widget and simply insert into scene. -
Made such class.
How to add x and y coordinates?
How to call void widgetForPainter::paintEvent(QPaintEvent *event) when clicking on a widget?.h
#ifndef WIDGETFORPAINTER_H #define WIDGETFORPAINTER_H #include "QWidget" #include "QPainter" #include "QPen" #include "QDebug" class widgetForPainter: public QWidget { public: widgetForPainter(); ~widgetForPainter() {;}; QPen myPen; int x,y; private slots: void paintEvent(QPaintEvent *event); public slots: void paintPoint(int x1,int y1); }; #endif // WIDGETFORPAINTER_H
.cpp
#include "widgetforpainter.h" widgetForPainter::widgetForPainter() { //Pen myPen.setWidth(20); myPen.setColor(Qt::green); //myPen.setColor(QColor(255, 0, 0, 10)); myPen.setCapStyle(Qt::RoundCap); myPen.setStyle(Qt::SolidLine); } void widgetForPainter::paintEvent(QPaintEvent *event) { Q_UNUSED(event); QPainter myPainter; // Создаём объект отрисовщика myPainter.setPen(myPen); myPainter.drawPoint(x,y); myPainter.drawEllipse(x, y, x+50, x+50); qDebug()<<x<<y; } void widgetForPainter::paintPoint(int x1, int y1) { QPainter myPainter; // Создаём объект отрисовщика myPainter.setPen(myPen); myPainter.drawPoint(x1,y1); myPainter.drawEllipse(x1, y1, x+50, x+50); qDebug()<<x1<<y1; }
In the constructor of the main class did:
newGraphicsView = new graphicsView(); newGraphicsView->setScene(scene); ui->verticalLayout->addWidget(newGraphicsView); widgetForPainter *myWidgetForPainter = new widgetForPainter(); ui->verticalLayout->addWidget(myWidgetForPainter);
Probably in the paint void Scene::mousePressEvent(QGraphicsSceneMouseEvent *event) need to add widget For void Painter::paintPoint(int x1, int y1) but how to do it?
-
This example works. Could you help me with the right code in my project.
-
@Mikeeeeee said in How to draw over an old picture in QGraphicsScene:
How to add x and y coordinates?
Come on, in the same way: override mousePressEvent as before.
-
Found such class. Is it possible to make it not the main class?
.h#ifndef WIDGET_H #define WIDGET_H #include <QWidget> #include <QPainter> #include <QMouseEvent> #include <QEvent> #include <QFileDialog> #include <QImage> #include <QPixmap> namespace Ui { class Widget; } class Widget : public QWidget { Q_OBJECT public: explicit Widget(QWidget *parent = 0); ~Widget(); bool eventFilter(QObject *obj, QEvent *event); private slots: void on_open_clicked(); void on_save_clicked(); void on_R_valueChanged(int value); void on_G_valueChanged(int value); void on_B_valueChanged(int value); void on_pen_dial_valueChanged(int value); void on_pushButton_8_clicked(); private: QPen pen; QPen pen2; QPixmap pixmap; QPixmap pixman; QPoint lastPoint; int r; int g; int b; Ui::Widget *ui; }; #endif // WIDGET_H
.cpp
#include "widget.h" #include "ui_widget.h" Widget::Widget(QWidget *parent) : QWidget(parent), ui(new Ui::Widget) { ui->setupUi(this); pixmap = QPixmap(ui->label->width(),ui->label->height()); pixmap.fill(); pen = QPen( QBrush( Qt::black), 5.0f ); r = 0; g = 0; b = 0; ui->label->setPixmap(pixmap); ui->label->installEventFilter(this); ui->red_color->installEventFilter(this); ui->orange_color->installEventFilter(this); ui->yellow_color->installEventFilter(this); ui->green_color->installEventFilter(this); ui->blue_color->installEventFilter(this); ui->purple_color->installEventFilter(this); ui->pushButton_8->installEventFilter(this); ui->R->installEventFilter(this); ui->G->installEventFilter(this); ui->B->installEventFilter(this); ui->setcolor->installEventFilter(this); ui->pen_dial->installEventFilter(this); ui->clear_pixmap->installEventFilter(this); ui->red_color->setStyleSheet("Background-color: red;"); ui->orange_color->setStyleSheet("Background-color: #ffa500"); ui->yellow_color->setStyleSheet("Background-color: yellow"); ui->green_color->setStyleSheet("Background-color: green"); ui->blue_color->setStyleSheet("Background-color: blue"); ui->purple_color->setStyleSheet("Background-color: #C400AB"); pen2 = QPen(QBrush(Qt::black), 61.0f); QBrush st(QColor(Qt::black),Qt::Dense7Pattern); pixman = QPixmap(ui->label_3->width(),ui->label_3->height()); pixman.fill(); QPainter p2(&pixman); p2.setPen(Qt::SolidLine); p2.setBrush(st); p2.drawRect(0,0,ui->label_3->width(),ui->label_3->height()); p2.end(); ui->label_3->setPixmap(pixman); //this->setFixedSize(this->width(), this->height()); } Widget::~Widget() { delete ui; } bool Widget::eventFilter(QObject *obj, QEvent *event) { if(obj == ui->label and event->type() == QEvent::MouseButtonPress) { QMouseEvent *mous = (QMouseEvent*)event; QPainter p(&pixmap); p.setPen(pen); p.drawPoint(mous->pos()); p.end(); lastPoint = mous->pos(); ui->label->setPixmap(pixmap); } if(obj == ui->label and event->type() == QEvent::MouseMove) { QMouseEvent *mous = (QMouseEvent*)event; QPainter p(&pixmap); p.setPen(pen); p.drawLine(lastPoint,mous->pos()); p.end(); lastPoint = mous->pos(); ui->label->setPixmap(pixmap); } if(obj == ui->red_color and event->type() == QEvent::MouseButtonPress) pen.setColor(Qt::red); if(obj == ui->orange_color and event->type() == QEvent::MouseButtonPress) pen.setColor(QColor(255, 128, 0)); if(obj == ui->yellow_color and event->type() == QEvent::MouseButtonPress) pen.setColor(Qt::yellow); if(obj == ui->green_color and event->type() == QEvent::MouseButtonPress) pen.setColor(Qt::green); if(obj == ui->blue_color and event->type() == QEvent::MouseButtonPress) pen.setColor(Qt::blue); if(obj == ui->purple_color and event->type() == QEvent::MouseButtonPress) pen.setColor(QColor(196, 0, 171)); if(obj == ui->setcolor and event->type() == QEvent::MouseButtonPress) { bool ok = true; r = ui->lineEdit->text().toInt(&ok,10); g = ui->lineEdit_2->text().toInt(&ok,10); b = ui->lineEdit_3->text().toInt(&ok,10); if((r <= 255 or g <= 255 or b <= 255)) pen.setColor(QColor(r,g,b)); else ui->info->text() = "Введены неверные значения"; } if(obj == ui->pen_dial and event->type() == QEvent::MouseButtonPress and QEvent::MouseMove) { } if(obj == ui->clear_pixmap and event->type() == QEvent::MouseButtonPress) { pixmap.fill(QColor(Qt::white)); ui->label->setPixmap(pixmap); } if(obj == ui->label_3 and event->type() == QEvent::MouseButtonPress) { pen.setBrush(Qt::Dense5Pattern); ui->label->setPixmap(pixmap); } } void Widget::on_open_clicked() { QString file; file = QFileDialog::getOpenFileName(this,tr("Открыть файл"),tr("Картинка.jpg"),tr("JPG (*.jpg)")); pixmap.load(file); } void Widget::on_save_clicked() { QString file; file = QFileDialog::getSaveFileName(this,tr("Сохранить файл"),tr("Картинка.jpg"),tr("JPG (*.jpg")); pixmap.save(file); } void Widget::on_R_valueChanged(int value) { pen.setColor(QColor(value,ui->B->value(),ui->G->value())); ui->Value_1->setNum(value); } void Widget::on_G_valueChanged(int value) { pen.setColor(QColor(ui->R->value(),value,ui->G->value())); ui->Value_2->setNum(value); } void Widget::on_B_valueChanged(int value) { pen.setColor(QColor(ui->R->value(),ui->B->value(),value)); ui->Value_3->setNum(value); } void Widget::on_pen_dial_valueChanged(int value) { pen.setWidthF(value); ui->label_2->setNum(value); } void Widget::on_pushButton_8_clicked() { }
-
@Mikeeeeee said in How to draw over an old picture in QGraphicsScene:
Is it possible to make it not the main class?
I don't understand this question.
What is a "main class"? -
I have a MainWindow class, class for QLabel the ImageViewer. How to use the widget class code to draw in ImageViewer?
-
@Mikeeeeee said in How to draw over an old picture in QGraphicsScene:
How to use the widget class code to draw in ImageViewer?
Like any other widget
-
But how? Do I have to transfer the code of their Widget class to the MainWindow class ?
-
@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".
-
@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?
-
@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 -
@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"; }
-
@Mikeeeeee After getting new coordinates you can call https://doc.qt.io/qt-5/qwidget.html#update to trigger paint event.