PDA

View Full Version : Draw line on image using QPainter



Qt Coder
23rd June 2010, 10:07
I m using Qt 4.6.2 on windows xp

I need to draw horizontal ,vertical lines and an arc over the image .


My code is

#include <QtGui>

QPixmap pixmap;
QPainter painter;
QPen DarkGray((QColor::QColor(69,86,96)),1);

pixmap.load(QString::fromUtf8(":/BiFold/Images/Plane.PNG"));
painter.begin(&pixmap);
painter.setPen(DarkGray);
painter.drawLine(250,300,500,300);
painter.end();
ui->lbl_plane->setGeometry(QRect(100,150,611,301));
ui->lbl_plane->setPixmap(pixmap);


But only image is displayed ,no line is drawn....

high_flyer
23rd June 2010, 13:00
you can only draw in a paintEvent().

JohannesMunk
23rd June 2010, 13:22
You just need to setup your pixmap before you assign the painter:



#include <QtCore>
#include <QtGui>

int main(int argc, char *argv[])
{
QApplication a(argc, argv);

QLabel l;

QPixmap pixmap;
pixmap.load(QString::fromUtf8("E:/2010-02-25_112406.png"));

QPainter painter(&pixmap);
QPen Red((QColor::QColor(255,0,0)),1);
painter.setPen(Red);
painter.drawLine(50,50,250,250);
l.setPixmap(pixmap);
l.show();

return a.exec();
}


Joh

high_flyer
23rd June 2010, 14:26
@Joh,
did you try the code you posted?
This code should not work.
At the very least in runtime a Qt warning should be printed, saying that QPainter can not be used outside the paintEvent().

JohannesMunk
23rd June 2010, 14:40
Sure I tried it! That's why I posted it as a complete application.

It doesn't show any warnings on the console, either. Why should it not be possible to use a QPainter on an 'offline' QPixMap?

Joh

high_flyer
23rd June 2010, 15:02
you are right, QPixmap is not a widget.
Sorry.

JohannesMunk
23rd June 2010, 15:08
Aah! Allright! That was the source of the confusion!

Yes, and not beeing able to draw onto a widget outside the paintEvent makes perfect sense.

Hope we didn't confuse the OP :->

Joh

Qt Coder
24th June 2010, 07:36
I m still not able to draw line on image

My code is


QPixmap pixmap;

QPen GreenPen((QColor::QColor (0,255,0,255)),1);

ui->lbl_plane->setGeometry(QRect(100,150,611,301));
pixmap.load(QString::fromUtf8(":/BiFold/Images/Plane.PNG"));
ui->lbl_plane->resize(pixmap.size());

QPainter painter(&pixmap);
painter.setPen(GreenPen);
painter.drawLine(250,300,500,300);
ui->lbl_plane->setPixmap(pixmap);
ui->lbl_plane->show();

The image format is "Format_RGB32"

what I m missing?

high_flyer
24th June 2010, 08:25
give your pixmap a size.

Qt Coder
24th June 2010, 09:01
I have added line
QPixmap pixmap(533,292); which is my image size to above code but still no line is drawn on image....

high_flyer
24th June 2010, 09:28
try adding painter.end() after the drawLine().

high_flyer
24th June 2010, 09:33
Try the following code.
Its works I tested it.
Once it works for you see what it is you are doing wrong:


int main(int argc, char *argv[])
{
QApplication a(argc, argv);

QLabel l;
QPixmap pixmap(500,500);
QPainter painter(&pixmap);
QPen Red((QColor::QColor(255,0,0)),1);
painter.setPen(Red);
painter.drawLine(50,50,250,250);
l.setPixmap(pixmap);
l.show();

return a.exec();
}

Qt Coder
24th June 2010, 09:57
It works for me also ...

But only if I dont add image to pixmap.

as soon as I add image
pixmap.load(QString::fromUtf8(":/BiFold/Images/Plane.PNG")); it shows only image no red line..

high_flyer
24th June 2010, 10:04
show your full code.

Qt Coder
24th June 2010, 10:57
Doorcontrol1 is a QDialog in which I need to show that image and lines.


main.cpp
#include <QtGui/QApplication>
#include <QtCore>
#include "bifold.h"

int main(int argc, char *argv[])
{
QApplication a(argc, argv);

BiFold w;
w.show();
return a.exec();
}


bifold.h


#ifndef BIFOLD_H
#define BIFOLD_H
#include <QMainWindow>

namespace Ui {
class BiFold;
}

class DoorControl1;

class BiFold : public QMainWindow {
Q_OBJECT
public:
BiFold(QWidget *parent = 0);
~BiFold();

DoorControl1 *ODoorControl1;

protected:
void changeEvent(QEvent *e);

private:
Ui::BiFold *ui;
};

#endif // BIFOLD_H

bifold.cpp


#include "bifold.h"
#include "ui_bifold.h"
#include "doorcontrol1.h"
#include <QMessageBox>

BiFold::BiFold(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::BiFold)
{
ui->setupUi(this);
removeToolBar(ui->mainToolBar); //Removes tool bar from main window

ODoorControl1 = new DoorControl1(this);
ODoorControl1->setWindowFlags( Qt::FramelessWindowHint );


}

BiFold::~BiFold()
{
delete ui;
}

void BiFold::changeEvent(QEvent *e)
{
QMainWindow::changeEvent(e);
switch (e->type()) {
case QEvent::LanguageChange:
ui->retranslateUi(this);
break;
default:
break;
}
}


doorcontrol1.h

#ifndef DOORCONTROL1_H
#define DOORCONTROL1_H

#include <QDialog>

namespace Ui {
class DoorControl1;
}

class DoorControl1 : public QDialog {
Q_OBJECT
public:
DoorControl1(QWidget *parent = 0);
~DoorControl1();
void DrawStuff();


protected:
void changeEvent(QEvent *e);
void paintEvent(QPaintEvent *event);

private:
Ui::DoorControl1 *ui;
};

#endif // DOORCONTROL1_H


doorcontrol1.cpp
#include <QtGui>
#include <QtCore>
#include <QMessageBox>
#include "doorcontrol1.h"
#include "ui_doorcontrol1.h"

DoorControl1::DoorControl1(QWidget *parent) :
QDialog(parent),
ui(new Ui::DoorControl1)
{
ui->setupUi(this);
DrawStuff();
}

DoorControl1::~DoorControl1()
{
delete ui;
}

void DoorControl1::changeEvent(QEvent *e)
{
QDialog::changeEvent(e);
switch (e->type()) {
case QEvent::LanguageChange:
ui->retranslateUi(this);
break;
default:
break;
}
}

void DoorControl1::paintEvent(QPaintEvent *event )
{

}

void DoorControl1::DrawStuff()
{

ui->lbl_plane->setGeometry(QRect(100,150,611,301));

QPixmap pixmap(500,500);
pixmap.load(QString::fromUtf8(":/BiFold/Images/Plane.PNG"));

QPainter painter(&pixmap);
ui->lbl_plane->resize(pixmap.size());

QPen Red((QColor::QColor(255,0,0)),1);
painter.setPen(Red);
painter.drawLine(250,300,500,300);
painter.end();
ui->lbl_plane->setPixmap(pixmap);
ui->lbl_plane->show();



}

JohannesMunk
24th June 2010, 10:58
Can't you put your code into something simpler? Just one class, and without an UI-File, that you didn't provide!

Reducing complexity often helps to find problems in the first place, so you might even solve it yourself!

Johannes

PS: "Cross posting" meant, that you posted, while I was writing my message. After I posted mine.. I saw your new message and changed mine .. to "cross posting". After I read your message, I edited again :->

Qt Coder
24th June 2010, 11:06
what is mean by "Cross posting :-> " ?????

high_flyer
24th June 2010, 11:17
you reimplemented the paintEvent() in your dialog, and left it blank.
So your dialog does not do any painting,I am not sure if this will cause its children not to draw as well.
Delete the paintEvent() re implementation and see if this helps.

Qt Coder
24th June 2010, 11:34
I have removed reimplementation of paintEvent () from header as well as source file

but still no line is drawn on image .....

high_flyer
24th June 2010, 11:37
in BiFold construcotr add:
ODoorControl1->show();

Qt Coder
24th June 2010, 11:46
It's already showing DoorControl1 Dialog with Plane's image...

still as you said I added ODoorControl1->show(); in Bifold constructor ,but no line still drawn..

high_flyer
24th June 2010, 11:56
you have to simplify and go step at a time.
Put your dialog in main, and show it.
See if you get the line drawn then.

Qt Coder
24th June 2010, 12:15
I have added draw line code in main.cpp itself but still it only shows image and no line is drawn

main.cpp
#include <QtGui/QApplication>

#include <QtCore>
#include <QtGui>
#include <QLabel>
//#include "bifold.h"


int main(int argc, char *argv[])
{
QApplication a(argc, argv);

// BiFold w;
// w.show();
QLabel l;
QPixmap pixmap(500,500);
pixmap.load(QString::fromUtf8(":/BiFold/Images/Plane.PNG"));

QPainter painter(&pixmap);
l.resize(pixmap.size());


QPen Red((QColor::QColor(255,0,0)),1);
painter.setPen(Red);
painter.drawLine(250,300,500,300);
painter.end();
l.setPixmap(pixmap);
l.show();
return a.exec();
}

Qt Coder
25th June 2010, 07:19
Is this a fault of my image,but I tried changing the image still no line is drawn..

I read in documentation of QPainter "Painting on a QImage with the format QImage::Format_Indexed8 is not supported."


But my image format is QImage::Format_RGB32.


I m not able to upload image here,it says "upload failed"


pls show me right direction ,I cannot proceed my work if this issues is not solved.

ChrisW67
25th June 2010, 08:03
Are you sure that your resource file path is good?

Your code with some minor tweaks and a local file:


#include <QtCore>
#include <QtGui>
#include <QDebug>

int main(int argc, char *argv[])
{
QApplication app(argc, argv);

QLabel l;
QPixmap pixmap;

bool goodLoad = pixmap.load(QString::fromUtf8("./test.png"));
qDebug() << goodLoad << pixmap.isNull() << pixmap.size() << pixmap.depth();

QPainter painter(&pixmap);
QPen Red((QColor::QColor(255,0,0)),1);
painter.setPen(Red);
painter.drawLine(40, 40, 200, 280);
painter.end();

pixmap.save("./test2.png");

l.setPixmap(pixmap);
l.show();

return app.exec();
}

Input is:
4840
Output is:


true false QSize(240, 320) 24

and
4839

Edit: the forum converted the PNG files to JPG

Qt Coder
25th June 2010, 09:21
Finally the line is visible over the image

The co-ordinates I used for drawing line were main culprit here
painter.drawLine(250,300,500,300);


also

qDebug() << goodLoad << pixmap.isNull() << pixmap.size() << pixmap.depth();

shows

true false QSize(533, 292) 32

if I use ur co-ordinate,

painter.drawLine(40, 40, 200, 280);

line is drawn.....

Qt Coder
25th June 2010, 11:56
My next query is

Can we directly paint QDialog ?

I need to draw some arcs, squares and lines on QDialog

high_flyer
25th June 2010, 12:11
You can paint on any widget, but only in a paintEvent().

Manobala
13th July 2015, 11:45
hai to every one am new to qt actually am trying to draw line on image (qpixmap),i had tried all coeds u have given above but still i didnt get the result plz can any one give full code to me thanking you and sorry for my bad english

cskumar
11th August 2015, 12:09
How to drag that line over the image?
I tried to drag. But it does not update.