PDA

View Full Version : Problem with comunication between widgets



laabor
2nd May 2010, 13:46
Hi
I'm trying to create very simple (training) program for viewing pictures. The idea is to create application with one window that contains one button and another widget to paint the picture on it. So when i click the button image appears in designated area. Now, I have created class "paintarea" then I put QWidget on the form and promoted that widget to "paintarea". And that is where I got stuck. I don't know how to connect the QPushButton that is on the QMAinWIndow "form", with that promoted widget, so that if I click the button, then the signal sends a message to custom widget with fileName to be loaded ?? I hope I didn't confuse You to much. Below is my code of this app. All help will be very appreciated. Sorry for poor english.

mainwindow.h


#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QtGui/QMainWindow>
#include <QPushButton>

namespace Ui
{
class mainwindow;
}

class mainwindow : public QMainWindow
{
Q_OBJECT

public:
mainwindow(QWidget *parent = 0);
~mainwindow();

private:
Ui::mainwindow *ui;
QPushButton *button;

public slots:
void send_signal();
};

#endif // MAINWINDOW_H


mainwindow.cpp


#include "mainwindow.h"
#include "ui_mainwindow.h"

mainwindow::mainwindow(QWidget *parent)
: QMainWindow(parent), ui(new Ui::mainwindow)
{
ui->setupUi(this);

button = new QPushButton;
button = ui->button;

connect (button,SIGNAL (clicked()),this,SLOT (send_signal()));
}

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

void mainwindow::send_signal()
{
paint_space->load_image("/home/xxx/picture.jpeg");
}


paintarea.h


#ifndef PAINTAREA_H
#define PAINTAREA_H

#include <QWidget>
#include <QPainter>
#include <QPixmap>

class paintarea : public QWidget
{
Q_OBJECT
public:
paintarea(QWidget *parent = 0);
void load_image(const QString &fileName);

protected:
void paintEvent(QPaintEvent *event);
QPixmap image;
bool status;
};

#endif // PAINTAREA_H


paintarea.cpp



#include "paintarea.h"

paintarea::paintarea (QWidget *parent) :
QWidget(parent)
{
//QPixmap image;
// image = new QPixmap;
status = false ;
}

void paintarea::paintEvent(QPaintEvent *event)
{
if(status)
{
QPainter painter(this);
painter.drawPixmap(0,0,image);
//painter.drawRect(0,0,30,40);

}

}

void paintarea::load_image(const QString &fileName)
{

image.load(fileName);
status = true ;

}

Lykurg
2nd May 2010, 13:52
you don't have to create a new button since the ui loader does that for you. You can access it as you do via ui->button. So just use that in your connect statement instead your temporary pointer:
connect(ui->button, SIGNAL/*...*/);
And for simply displaying an image, you can use QLabel.

laabor
3rd May 2010, 14:29
Thanks for help, but now I have new problem. I have added two QLabels, one on my QMainWindow widget and second on "paintArea" widget. Now what I want to do is change text on both of them, but from within "paintArea.h" class. I have tried quite a few things, but can't get this to work ?? A bit of code eplaining what i wabt to acomplish:


#include "paintarea.h"

paintarea::paintarea (QWidget *parent) :
QWidget(parent)
{

status = false ;

}

void paintarea::paintEvent(QPaintEvent *event)
{
if(status)
{
QPainter painter(this);
painter.drawPixmap(0,0,image);


}

}

void paintarea::load_image(const QString &fileName)
{


image.load(fileName);

status = true ;
update();
// this->label->setText(image.width()); <---- that doesn't work, but this is example what i want to do, and I know I need first convert "image.width()" to string
//ui->label_2->setText(image.height()); <---- also not woking
}


I know I need to declare somehow this "ui" but not sure exactly how, where ?

Talei
3rd May 2010, 15:04
In paintarea, if image load suceed emit signal, connect that signal from mainwindows. Each time that signal is emited slot (in mainwindow) will fire up, something like this:
mainwindow:

connect( pArea, SIGNAL(mySIGNAL(int)), this, SLOT(updateLABEL(int)));
paintarea must be on the stack i.e. paintarea *pArea; (include paintarea.h in mainWindow.h)

in mainWindow.cpp add

private slots:
void updateLABEL(int);
and:

void MainWindow::updateLABEL(int w)
{
//update label text
this->ui->label->setText( QVariant(w).toString() );
}

int paintarea.cpp:


void paintarea::load_image(const QString &fileName)
{


image.load(fileName);

status = true ;
update();
// this->label->setText(image.width()); <---- that doesn't work, but this is example what i want to do, and I know I need first convert "image.width()" to string
//ui->label_2->setText(image.height()); <---- also not woking

//emit signal if image load suceed
emit mySIGNAL( image.width());
}

int paintarea.h:

signals:
void mySIGNAL( int );

Best luck

axeljaeger
6th May 2010, 10:05
Why does it not work?

laabor
8th May 2010, 12:19
I've made changes recommended by Talei, but still no luck all I can get is "Program finished unexpectedly, exited with code 0". There is no other errors in compilation. Any ideas why that's no working ? new code :
mainwindow.h


#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QtGui/QMainWindow>
#include <QPushButton>
#include <paintarea.h>

namespace Ui
{
class mainwindow;
}

class mainwindow : public QMainWindow
{
Q_OBJECT

public:
mainwindow(QWidget *parent = 0);
~mainwindow();



private:
Ui::mainwindow *ui;
QPushButton *button;
paintarea *parea;

public slots:
void send_signal();


private slots:
void updateLabel(int);

};

#endif // MAINWINDOW_H


mainwindow.cpp


#include "mainwindow.h"
#include "ui_mainwindow.h"

mainwindow::mainwindow(QWidget *parent)
: QMainWindow(parent), ui(new Ui::mainwindow)
{
ui->setupUi(this);

button = new QPushButton;
button = ui->button;

paintarea *parea;

connect (button,SIGNAL (clicked()),this,SLOT (send_signal()));
connect (parea, SIGNAL(mySignal(int)), this, SLOT(updateLabel(int)));
}


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

void mainwindow::send_signal()
{
ui->paint_space->load_image("/home/laabor/Pictures/test.jpeg");
}

void mainwindow::updateLabel(int w)
{
this->ui->label->setText(QVariant(w).toString());
}

paintarea.h


#ifndef PAINTAREA_H
#define PAINTAREA_H

#include <QWidget>
#include <QPainter>
#include <QPixmap>
#include <QLabel>

class paintarea : public QWidget
{
Q_OBJECT
public:
paintarea(QWidget *parent = 0);
void load_image(const QString &fileName);

protected:
void paintEvent(QPaintEvent *event);
QPixmap image;
QLabel label;
bool status;

signals:
void mySignal(int);
};

#endif // PAINTAREA_H

paintarea.cpp


#include "paintarea.h"

paintarea::paintarea (QWidget *parent) :
QWidget(parent)
{

status = false ;


}

void paintarea::paintEvent(QPaintEvent *event)
{
if(status)
{
QPainter painter(this);
painter.drawPixmap(0,0,image);


}

}

void paintarea::load_image(const QString &fileName)
{


image.load(fileName);
status = true ;
update();

emit mySignal(image.width());

}

axeljaeger
8th May 2010, 12:22
The program very like crashes in line 15 of mainwindow.cpp because of access to unitialized variable parea.

Also I do not understand what you want to do in line 9 & 10 of mainwindow.cpp.

tbscope
8th May 2010, 12:30
Some changes I would make to your code:


#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QtGui/QMainWindow>
#include <QPushButton>
#include <paintarea.h>

namespace Ui
{
class mainwindow;
}

class mainwindow : public QMainWindow
{
Q_OBJECT

public:
mainwindow(QWidget *parent = 0);
~mainwindow();



private:
Ui::mainwindow *ui;
//QPushButton *button; <---- Not necessary, ui->button is what you need.
paintarea *parea;

public slots:
void send_signal();


private slots:
void updateLabel(int);

};

#endif // MAINWINDOW_H


#include "mainwindow.h"
#include "ui_mainwindow.h"

mainwindow::mainwindow(QWidget *parent)
: QMainWindow(parent), ui(new Ui::mainwindow)
{
ui->setupUi(this);

//button = new QPushButton;
//button = ui->button; <--- Not needed, it adds no functionality.

paintarea *parea;

// connect (button,SIGNAL (clicked()),this,SLOT (send_signal()));
connect(ui->button, SIGNAL(clicked()), this, SLOT(send_signal()));
connect (parea, SIGNAL(mySignal(int)), this, SLOT(updateLabel(int)));
}


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

void mainwindow::send_signal()
{
ui->paint_space->load_image("/home/laabor/Pictures/test.jpeg");
}

void mainwindow::updateLabel(int w)
{
//this->ui->label->setText(QVariant(w).toString()); <--- Incorrect! You have to define a QVariant first, or use static functions.
ui->label->setText(QString::number(w));
}

laabor
8th May 2010, 13:07
I'v found solution, it turned out to be very easy:


#include "mainwindow.h"
#include "ui_mainwindow.h"

mainwindow::mainwindow(QWidget *parent)
: QMainWindow(parent), ui(new Ui::mainwindow)
{
ui->setupUi(this);




connect (ui->button,SIGNAL (clicked()),this,SLOT (send_signal()));
connect (ui->paint_space, SIGNAL(mySignal(int)), this, SLOT(updateLabel(int)));
}


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

void mainwindow::send_signal()

{
QString fileName = QFileDialog::getOpenFileName(this);
ui->paint_space->load_image(fileName);


}

void mainwindow::updateLabel(int w)
{
ui->label->setText("poszlo");
}