PDA

View Full Version : How I could Tell Qpainter where is his Area of Painting...



j0rt4g4
25th November 2008, 15:56
I made a GUI with designer.
I got a QWidget object called "areadibujo" that has and predetermined area.
Now the problem is that I dont know how to tell "QPainter" that his Space is That one.

Which is the way to tell it that?

Could be QPainterPath? how i could implemented ? I got days within this.
Am I doing something wrong? any ideas?:confused::confused::crying:

No one?

j0rt4g4
26th November 2008, 15:03
Is my question wrong formulated ? :S

high_flyer
26th November 2008, 15:41
What it is you want to do?
ANY widget that you can see is painted by QPainter.
If you want to change the way a particular widget is being drawn, you should overload the paintEvent() of that widget.

j0rt4g4
26th November 2008, 17:15
I got a image like this:

http://img444.imageshack.us/img444/8058/fractalszg2.th.png (http://img444.imageshack.us/my.php?image=fractalszg2.png)

In the Center of this image there's a widget called "areadibujo",
I want to paint ON this area, but I dont know how to do it.

I want to create a code that read a file data
(%f %f ) insert it on a array
a[i] b[i]

And use the array to do some math, and get the points on areadibujo but I guess I'm confused with parents.

Well here's my code:
main.cpp:

#include <QApplication>
#include "fractal.h"
#include "renderarea.h"

int main(int argc, char *argv[])
{
QApplication app(argc, argv);
fractal *dialog = new fractal;
//renderarea *dialog= new renderarea;

dialog->show();
return app.exec();
}


fractal.h


#ifndef __FRACTAL_H__
#define __FRACTAL_H__
#include "ui_fractals.h"


class fractal : public QWidget, private Ui::Fractals
{
Q_OBJECT

public:
fractal(QWidget *parent = 0);
void updateBrush();

public slots:
void setOpenFileName();
void QPaintEvent(QPainter *event);
};


#endif // __FRACTAL_H__


fractal.cpp

#include <QtGui>
#include <QFile>
#include <QGLWidget>
#include <QtOpenGL>
#include "fractal.h"

void tidyFile(QIODevice *inDevice, QIODevice *outDevice)
{
QTextStream in(inDevice);
QTextStream out(outDevice);

int endlCount = 0;
QChar ch;

while (!in.atEnd()) {
in >> ch;

if (ch == '\n') {
++endlCount;
}
}
// out << endl;
}


fractal::fractal(QWidget *parent){
setupUi(this);
connect( toolButton, SIGNAL( clicked() ), this, SLOT( setOpenFileName() ) );
connect( boton_aceptar, SIGNAL( clicked() ), this, SLOT( QPaintEvent(QPainter *event) ) );
}


void fractal::setOpenFileName()
{
QFileDialog::Options options;
options |=QFileDialog::ShowDirsOnly;


QString selectedFilter;
QString fileName = QFileDialog::getOpenFileName(this,
tr("QFileDialog::getOpenFileName()"),
lineEdit->text(),
tr("Todos (*);;Data (*.txt)"),
&selectedFilter,
options);
if (!fileName.isEmpty())
lineEdit->setText(fileName);

QFile infile;
QFile outfile;
infile.open(stdin, QFile::ReadOnly);
outfile.open(stdout, QFile::WriteOnly);
tidyFile(&infile,&outfile);
QTextStream in(&infile);
QTextStream out(&outfile);
int endlCount = 0;
QChar ch;
while (!in.atEnd()) {
in >> ch;
if (ch == '\n') {
++endlCount;
}
}
}

void fractal::QPaintEvent(QPainter *event){
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing, true);
painter.setPen(QPen(Qt::black, 15, Qt::SolidLine, Qt::RoundCap,
Qt::MiterJoin));
painter.setBrush(QBrush(Qt::blue, Qt::DiagCrossPattern));
painter.drawPie(80, 80, 400, 240, 60 * 16, 270 * 16);
}

I hope I wasn't wasting my time as I hope...

spirit
26th November 2008, 17:19
it is wrong


void fractal::QPaintEvent(QPainter *event)

must be


void fractal::paintEvent(QPaintEvent *event) {
//draw something
}


and then you must draw what you want

j0rt4g4
26th November 2008, 17:43
Ok I made Corrections and IT DRAWS :) (thank you very much)... But It is painting on the BIG Widget (mainwindow) and It is not ON the widget called (areadibujo).



If you want to change the way a particular widget is being drawn, you should overload the paintEvent() of that widget

Could you tell me how I do that in here ?
Thank you very much

spirit
26th November 2008, 17:45
is this "areadibujo" independent? if yes then you have to override paintEvent of this widget.

j0rt4g4
26th November 2008, 17:53
mmm I guess it is a son of "Fractals"


http://img221.imageshack.us/img221/6932/nuevo1cv8.th.jpg (http://img221.imageshack.us/my.php?image=nuevo1cv8.jpg)

Isnt it easier make it independient?, T.T because I dont know how to do it independient eighter... (:S what a noobie guy)....:mad: I'm trying .

spirit
26th November 2008, 18:09
yep. so you can do next: install event filter for this widget and handle paint event and draw what you need, e.g.


Test::Test(QWidget *parent)
: QMainWindow(parent)
{
QVBoxLayout *vbl = new QVBoxLayout();
QWidget *w = new QWidget;
m_drawer = new QWidget();
m_drawer->installEventFilter(this);//set event filter

vbl->addWidget(m_drawer);
vbl->addWidget(new QWidget);
w->setLayout(vbl);

setCentralWidget(w);
}

bool Test::eventFilter(QObject *o, QEvent *e)
{
if (o == m_drawer && e->type() == QEvent::Paint) {//process paint event of needed widget
QPainter painter(m_drawer);
painter.setPen(Qt::blue);
painter.setFont(QFont("Arial", 30));
painter.drawText(m_drawer->rect(), Qt::AlignCenter, "Qt");
return true;
}
return QMainWindow::eventFilter(o, e);
}

j0rt4g4
26th November 2008, 19:01
Like this?

ui_Fractals.h:


QT_BEGIN_NAMESPACE

class Ui_Fractals
{
public:
QWidget *layoutWidget;
QHBoxLayout *horizontalLayout_4;
QVBoxLayout *verticalLayout_2;
QHBoxLayout *horizontalLayout_3;
QLabel *label_Archivo;
QLineEdit *lineEdit;
QToolButton *toolButton;
QWidget *areadibujo;
QVBoxLayout *verticalLayout;
QHBoxLayout *horizontalLayout;
QLabel *Iterations;
QSpinBox *spinbox_ite;
QSlider *iterator_hslider;
QSpacerItem *verticalSpacer;
QHBoxLayout *horizontalLayout_2;
QPushButton *boton_aceptar;
QPushButton *boton_salir;

void setupUi(QWidget *Fractals)
{
if (Fractals->objectName().isEmpty())
Fractals->setObjectName(QString::fromUtf8("Fractals"));
Fractals->resize(605, 408);
layoutWidget = new QWidget(Fractals);
layoutWidget->setObjectName(QString::fromUtf8("layoutWidget"));
layoutWidget->setGeometry(QRect(10, 10, 579, 382));
horizontalLayout_4 = new QHBoxLayout(layoutWidget);
horizontalLayout_4->setObjectName(QString::fromUtf8("horizontalLayout_4"));
horizontalLayout_4->setContentsMargins(0, 0, 0, 0);
verticalLayout_2 = new QVBoxLayout();
verticalLayout_2->setObjectName(QString::fromUtf8("verticalLayout_2"));
horizontalLayout_3 = new QHBoxLayout();
horizontalLayout_3->setObjectName(QString::fromUtf8("horizontalLayout_3"));
label_Archivo = new QLabel(layoutWidget);
label_Archivo->setObjectName(QString::fromUtf8("label_Archivo"));

horizontalLayout_3->addWidget(label_Archivo);

lineEdit = new QLineEdit(layoutWidget);
lineEdit->setObjectName(QString::fromUtf8("lineEdit"));
lineEdit->setEnabled(false);
lineEdit->setMinimumSize(QSize(280, 0));
lineEdit->setDragEnabled(false);

horizontalLayout_3->addWidget(lineEdit);

toolButton = new QToolButton(layoutWidget);
toolButton->setObjectName(QString::fromUtf8("toolButton"));
toolButton->setMinimumSize(QSize(25, 20));
toolButton->setCheckable(false);
toolButton->setPopupMode(QToolButton::DelayedPopup);
toolButton->setArrowType(Qt::NoArrow);

horizontalLayout_3->addWidget(toolButton);


verticalLayout_2->addLayout(horizontalLayout_3);

areadibujo = new QWidget(layoutWidget);
areadibujo->setObjectName(QString::fromUtf8("areadibujo"));
areadibujo->setMinimumSize(QSize(350, 350));
areadibujo->setMaximumSize(QSize(500, 500));
areadibujo->setAutoFillBackground(false);
areadibujo->installEventFilter(this); ////////////////////////////here!:confused::confused:


verticalLayout_2->addWidget(areadibujo);


horizontalLayout_4->addLayout(verticalLayout_2);

verticalLayout = new QVBoxLayout();
verticalLayout->setObjectName(QString::fromUtf8("verticalLayout"));
horizontalLayout = new QHBoxLayout();
horizontalLayout->setObjectName(QString::fromUtf8("horizontalLayout"));
Iterations = new QLabel(layoutWidget);
Iterations->setObjectName(QString::fromUtf8("Iterations"));

horizontalLayout->addWidget(Iterations);

spinbox_ite = new QSpinBox(layoutWidget);
spinbox_ite->setObjectName(QString::fromUtf8("spinbox_ite"));
spinbox_ite->setEnabled(true);
spinbox_ite->setMinimumSize(QSize(30, 0));
spinbox_ite->setMinimum(100000);
spinbox_ite->setMaximum(1000000);
spinbox_ite->setSingleStep(1000);
spinbox_ite->setValue(100000);

horizontalLayout->addWidget(spinbox_ite);

iterator_hslider = new QSlider(layoutWidget);
iterator_hslider->setObjectName(QString::fromUtf8("iterator_hslider"));
iterator_hslider->setEnabled(true);
iterator_hslider->setMouseTracking(true);
iterator_hslider->setMinimum(100000);
iterator_hslider->setMaximum(1000000);
iterator_hslider->setSingleStep(1000);
iterator_hslider->setPageStep(100000);
iterator_hslider->setValue(100000);
iterator_hslider->setTracking(true);
iterator_hslider->setOrientation(Qt::Horizontal);

horizontalLayout->addWidget(iterator_hslider);


verticalLayout->addLayout(horizontalLayout);

verticalSpacer = new QSpacerItem(20, 40, QSizePolicy::Minimum, QSizePolicy::Expanding);

verticalLayout->addItem(verticalSpacer);

horizontalLayout_2 = new QHBoxLayout();
horizontalLayout_2->setObjectName(QString::fromUtf8("horizontalLayout_2"));
boton_aceptar = new QPushButton(layoutWidget);
boton_aceptar->setObjectName(QString::fromUtf8("boton_aceptar"));

horizontalLayout_2->addWidget(boton_aceptar);

boton_salir = new QPushButton(layoutWidget);
boton_salir->setObjectName(QString::fromUtf8("boton_salir"));

horizontalLayout_2->addWidget(boton_salir);


verticalLayout->addLayout(horizontalLayout_2);


horizontalLayout_4->addLayout(verticalLayout);


retranslateUi(Fractals);
QObject::connect(boton_salir, SIGNAL(clicked()), Fractals, SLOT(close()));
QObject::connect(spinbox_ite, SIGNAL(valueChanged(int)), iterator_hslider, SLOT(setValue(int)));
QObject::connect(iterator_hslider, SIGNAL(valueChanged(int)), spinbox_ite, SLOT(setValue(int)));

QMetaObject::connectSlotsByName(Fractals);
} // setupUi

void retranslateUi(QWidget *Fractals)
{
Fractals->setWindowTitle(QApplication::translate("Fractals", "Fractals", 0, QApplication::UnicodeUTF8));
label_Archivo->setText(QApplication::translate("Fractals", "Archivo:", 0, QApplication::UnicodeUTF8));
toolButton->setText(QApplication::translate("Fractals", "...", 0, QApplication::UnicodeUTF8));
Iterations->setText(QApplication::translate("Fractals", "Iterations", 0, QApplication::UnicodeUTF8));
boton_aceptar->setText(QApplication::translate("Fractals", "&Aceptar", 0, QApplication::UnicodeUTF8));
boton_salir->setText(QApplication::translate("Fractals", "&Salir", 0, QApplication::UnicodeUTF8));
Q_UNUSED(Fractals);
} // retranslateUi

};

namespace Ui {
class Fractals: public Ui_Fractals {};
} // namespace Ui

QT_END_NAMESPACE


bool areadibujo::eventFilter(QObject *o, QEvent *e) //////////and here:confused::confused:
{
if(o == areadibujo && e->type() == QEvent::Paint){
QPainter painter(areadibujo);
painter.setPen(Qt::blue);
painter.setFont(QFont("Arial",30));
painter.drawText(areadibujo->rect(), Qt::AlignCenter,"Probando");
return true;
}
return Ui_Fractals::eventFilter(o,e);
}

#endif // UI_FRACTALS_H

spirit
26th November 2008, 19:17
no, not in generated h-file. you should install filter in that widget for which you set up ui, i.e.


fractal::fractal(QWidget *parent)
: QWidget(parent)
{
setupUi(this);
areadibujo->installEventFilter(this);
connect( toolButton, SIGNAL( clicked() ), this, SLOT( setOpenFileName() ) );
}

j0rt4g4
26th November 2008, 19:46
Welll...... It runs but doesn't show anything...
I did it like this :

main.cpp

#include <QApplication>
#include "fractal.h"

int main(int argc, char *argv[])
{
QApplication app(argc, argv);
fractal *dialog = new fractal;
//renderarea *dialog= new renderarea;

dialog->show();
return app.exec();
}

fractal.h:

#ifndef __FRACTAL_H__
#define __FRACTAL_H__
#include "ui_fractals.h"


class fractal : public QWidget, private Ui::Fractals
{
Q_OBJECT

public:
fractal(QWidget *parent = 0);
void updateBrush();
// bool eventFilter(QObject *o, QEvent *e);
public slots:
void setOpenFileName();
void paintEvent(QPaintEvent *event);
bool eventFilter(QObject *o, QEvent *e);
};


#endif // __FRACTAL_H__


fractal.cpp:

#include <QFile>
#include <QGLWidget>
#include <QtOpenGL>
#include "fractal.h"

void tidyFile(QIODevice *inDevice, QIODevice *outDevice)
{
QTextStream in(inDevice);
QTextStream out(outDevice);

int endlCount = 0;
QChar ch;

while (!in.atEnd()) {
in >> ch;

if (ch == '\n') {
++endlCount;
}
}
// out << endl;
}


fractal::fractal(QWidget *parent){
setupUi(this);
areadibujo->installEventFilter(this);
connect( toolButton, SIGNAL( clicked() ), this, SLOT( setOpenFileName() ) );
connect( boton_aceptar, SIGNAL( clicked() ), this, SLOT( QPaintEvent(QPainter *event) ) );
}


void fractal::setOpenFileName()
{
QFileDialog::Options options;
options |=QFileDialog::ShowDirsOnly;


QString selectedFilter;
QString fileName = QFileDialog::getOpenFileName(this,
tr("QFileDialog::getOpenFileName()"),
lineEdit->text(),
tr("Todos (*);;Data (*.txt)"),
&selectedFilter,
options);
if (!fileName.isEmpty())
lineEdit->setText(fileName);

QFile infile;
QFile outfile;
infile.open(stdin, QFile::ReadOnly);
outfile.open(stdout, QFile::WriteOnly);
tidyFile(&infile,&outfile);
QTextStream in(&infile);
QTextStream out(&outfile);
int endlCount = 0;
QChar ch;
while (!in.atEnd()) {
in >> ch;
if (ch == '\n') {
++endlCount;
}
}
}

void fractal::paintEvent(QPaintEvent *event){
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing, true);
painter.setPen(QPen(Qt::black, 15, Qt::SolidLine, Qt::RoundCap,
Qt::MiterJoin));
painter.setBrush(QBrush(Qt::blue, Qt::DiagCrossPattern));
painter.setPen(QPen(Qt::red, 5, Qt::SolidLine, Qt::RoundCap,Qt::MiterJoin));

painter.translate(100.0,100.0);
painter.drawPie(0, 0, 300, 300, 60 * 16, 270 * 16);
painter.drawEllipse(30,30,60,60);

}

bool fractal::eventFilter(QObject *o, QEvent *e)
{
if (o == areadibujo && e->type() == QEvent::Paint) {//process paint event of needed widget
QPainter painter(areadibujo);
painter.setPen(Qt::blue);
painter.setFont(QFont("Arial", 30));
painter.drawText(areadibujo->rect(), Qt::AlignCenter, "Qt");
return true;
}
return fractal::eventFilter(o, e);
}

spirit
26th November 2008, 19:50
comment fractal::paintEvent and replace this snippet return fractal::eventFilter(o, e); with QWidget::eventFilter(o ,e);

wysota
26th November 2008, 20:02
Maybe it would be advised to at least take a brief look at the documentation of methods you are using?

spirit
26th November 2008, 20:06
look at this example in the attach, it should help you.

j0rt4g4
26th November 2008, 20:17
Ok I did that:
return fractal::eventFilter(o, e); with return QWidget::eventFilter(o ,e);

Finally solved.
Now how I can print what a QTextStream is reading in stdout?
(in the console)
Because I'm not sure that is opening and reading the file the way must be.
There are the first 2 implementation on the fractal.cpp.
Im trying to read a text file, with this format in C#
"0.065\t0.555\t0.5\n"

I tried counting lines first to know the number of items in array (I know this is not necessary in Qt because I should have used "array.append()" ) and make the QString a Qdouble making a "cast"...

I have been a week trying to do this for myself, and I got lot's and lot's of doubts.... I apologyze for asking that much... But If I knew I wouldn't ask...

j0rt4g4
26th November 2008, 20:20
Maybe it would be advised to at least take a brief look at the documentation of methods you are using?

I did that and I got all classes of QT what I'm ussing printed. But I was trying to go out of all my doubts YELLING FOR HELP...
I have many of examples printed but I dont want to bother but I want to learn... So I ask.
I'm sorry... :o:o:o

wysota
26th November 2008, 20:25
So don't print ALL, read the ones you need. If you have too much reference, you'll get lost in it. Focus on one task at a time.

j0rt4g4
26th November 2008, 20:28
look at this example in the attach, it should help you.

I look this example ... The event was a protected type of fractal :)...
Thanks you very much for helping me.

I had that doubt for long time ago. But I'm sure it must be a easier way to do the things, but I'm doing the best of I can with my knowledge. I don't wanna be this noob anymore :P :)


So don't print ALL, read the ones you need. If you have too much reference, you'll get lost in it. Focus on one task at a time.

I printed the ones I think I would use for this. And I read them too. But the way is mading by walking through it . Finally, I want to thank you for your advise I would keep it in mind.

Sometimes reference is old (Qt3) and must be "correctly traslade" for working on Qt4, I have like 1 moths reading about this (Qt4.4.1 & Qt4.4.3, and I'm moving from C# languague to C++, I will learn, but be pacient), sometimes I got confused but testing is the way to get out of doubts.

wysota
26th November 2008, 20:54
All reference you may need is in your Qt Assistant. Just launch the application and enjoy. No need to browse any Qt3 docs.