I am fairly new to Qt and I am completely stuck at this point. My only option was to turn to the experts. I have designed a GUI that will load an image into a Qlabel on a QMainWindow. I then want to draw multiple points on the image itself. However, what seems to be happening is that the point is being drawn behind the image and I don't know how to draw the point on top of the image.
My Code:
main.cpp
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 <QMouseEvent>
//Declaring the external Variables
extern QString name;
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
void on_actionOpen_triggered();
void on_actionDraw_2_triggered();
void on_actionCreate_2_triggered();
void mousePressEvent(QMouseEvent* event);
void paintEvent(QPaintEvent* e);
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "createdialog.h"
#include <QMouseEvent>
#include <qpainter.h>
#include <QFileDialog>
#include <QLabel>
#include <Qimage>
#include <QPaintDevice>
#include <QDebug>
#include <boost/filesystem.hpp>
#include <boost/filesystem/path.hpp>
#include <boost/system/config.hpp>
#include "iostream"
using namespace std;
QString fileName;
QString name;
int drawFlag=0;
int paintFlag=0;
int xCord = 0; //mouse click x location
int yCord = 0; //mouse click y loaction
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_actionOpen_triggered()
{
//Opening a dialog box to search for the images
QFileDialog dialog(this);
dialog.setNameFilter(tr("Images (*.png *.xpm *.jpg)"));
dialog.setViewMode(QFileDialog::Detail);
fileName = QFileDialog::getOpenFileName(this, tr("Open File"),
"C:/", tr("Images (*.png *.xpm *.jpg)"));
//Pulling just the file name out of the file path
std::string filename = fileName.toStdString();
boost::filesystem::path p(filename);
name = QString::fromStdString(p.stem().string());
//Checking to see if the file name is empty
if (!fileName.isEmpty()) {
QImage img(fileName);
int width = img.width();
int height = img.height();
MainWindow::showMaximized();
ui->label->setGeometry(0,0,width,height); //Setting the label to the size of the image
ui->label->setPixmap(QPixmap::fromImage(img)); //Inserting the image into the label
}
else{
ui->label->setText("Error");
}
}
void MainWindow::mousePressEvent(QMouseEvent* event)
{
//If the draw flag is set record mouse press events
if(drawFlag==1){
if(event->button() == Qt::LeftButton){
xCord = event->x();
yCord = event->y();
std::cout << "x-location: " << xCord << endl;
std::cout << "y-location: " << yCord << endl;
paintFlag=1;
update();
}
}
}
void MainWindow::paintEvent(QPaintEvent* e)
{
QMainWindow::paintEvent(e);
//When the paint flag is set then paint
if(paintFlag==1){
QPainter painter(this);
QPen paintpen(Qt::red);
paintpen.setWidth(10);
QPoint p1;
p1.setX(xCord);
p1.setY(yCord);
painter.setPen(paintpen);
painter.drawPoint(p1);
}
}
void MainWindow::on_actionDraw_2_triggered()
{
drawFlag=1;
}
Any advice is very much appreciated. Thank you!
The main window is drawn before its child widgets are drawn. Drawing the main window is actually just drawing the gray background.
That means your MainWindow::paintEvent()
calls the base class implementation (QMainWindow::paintEvent()
) to draw the gray background, and then draws a point on top of the gray background. After the ``paintEvent()` returns, Qt draws all child widget, including the label, on top of that, thus drawing over the gray background and over your point.
Potential solutions:
QLabel::setPixmap()
, draw the point on the QImage - QPainter
can draw on QImage
as well, not just on QWidget
.QImage image("path/to/image/img.png");
QPainter painter(&image);
QPen pen;
pen.setWidth(20);
pen.setColor(Qt::red);
painter.setPen(pen);
painter.drawPoint(5,5);
painter.end();
label->setPixmap(QPixmap::fromImage(image));
QLabel
(name it e.g. LabelWithPointOnTop) and override paintEvent()
in your subclass, then put an instance of your subclass instead of QLabel
into your layout.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With