PDA

View Full Version : Passing Pixmaps between MainWindow and Dialog



ramstormrage
14th April 2008, 07:14
Good day people.

Im an undergraduate student whose thesis is an Image Viewer to be used for Plant Disease Assessment. I am using Qt4 for this project.

I would like to ask about how to pass QImage objects from the MainWindow to a dialog. Specifically, i would like to display the current QImage object from my main window to a brightness control dialog (to be shown as a preview).

wysota
14th April 2008, 08:00
Provide a custom method in the dialog class taking a pixmap as an argument and make the method assign the image to the label (or other widget) used to display it.

ramstormrage
14th April 2008, 08:48
Provide a custom method in the dialog class taking a pixmap as an argument and make the method assign the image to the label (or other widget) used to display it.

Im so sorry wysota, but I dont quite get what you are suggesting.

Are you suggesting that I code a function that accepts pixmaps (or has another QImage object that would hold the copy of the object in the main window?), and then put the "clone" pixmap to the Image preview label in the dialog?

Please bear with me..:(

wysota
14th April 2008, 11:49
class MyDialog : public QDialog {
Q_OBJECT
public:
MyDialog(QWidget *parent=0) : QDialog(parent){
QVBoxLayout *l = new QVBoxLayout(this);
label = new QLabel;
l->addWidget(label);
}
void setPixmap(const QPixmap &px){
label->setPixmap(px);
}
private:
QLabel *label;
};

ramstormrage
15th April 2008, 13:54
Hello wysota,

Thanks for replying. I tried the above code, and in addition i used the below code when calling the dialog:



void MainWindow::show_brightnessDialog()
{
brDialog *dialog = new brDialog(this);
dialog->show();
dialog->setPixmap(QPixmap::fromImage(image));
}


It compiled successfully then I tried to load a jpeg image. When I invoke the brDialog, the whole program quits to the desktop without any error. How come?

I also forgot to mention that the image preview label (prevLabel) is a tad small and i want the image to fit inside so should I add a QScrollArea widget to hold the QLabel prevLabel?

wysota
15th April 2008, 14:31
You probably have an invalid pointer somewhere. Use a debugger to find out.

ramstormrage
15th April 2008, 15:35
Could the QImage image object be the problem?

I think after I load the file using the below code, the image object somehow gets destroyed after the function. What do you think?


void MainWindow::open()
{
QString fileName = QFileDialog::getOpenFileName(this,tr("Open File"), QDir::currentPath(), tr("Image Files (*.jpg *.jpeg *.bmp *.gif *.png)"));
if (!fileName.isEmpty()) {
QImage image(fileName);
if (image.isNull()) {
QMessageBox::critical(this, tr("Image View"), tr("Cannot load %1.").arg(fileName));
return;
}
imageLabel->setPixmap(QPixmap::fromImage(image));
scaleFactor = 1.0;
closeAction->setEnabled(true);
imageLabel->adjustSize();

imagelabFile.convertToRGBImage(image); //If loading is ok, create an imagelabfile copy of the QImage
brightnessAction->setEnabled(true);
QMessageBox::information(this, tr("Successful Conversion"),tr("ImageLab image loaded. Ready for processing."));
}
}

wysota
15th April 2008, 15:45
Could the QImage image object be the problem?
I don't think so.


I think after I load the file using the below code, the image object somehow gets destroyed after the function. What do you think?
I'd say imageLabel might be NULL or uninitialized.

I really suggest to use a debugger to find out. Why guess if you can check it out?

ramstormrage
15th April 2008, 15:51
Sorry but Im not familiar with using a debugger for a Qt application. Could you kindly walk me through?

wysota
15th April 2008, 16:11
Are you familiar with using a debugger for a non-Qt application? It's exactly the same...

ramstormrage
16th April 2008, 06:18
Hello again wysota,

Thanks for replying.

Hmm.. No Im not familiar with any debugger.. I have gdb here, then I tried to run my release.. I proceeded up to the point where I invoke my brightnessDialog.. Then the expected happens, the program suddenly quits.. GDB reported that program exited with error code 01, meaning abnormal termination right?

What should I be checking right now? Sorry for the troubles..

wysota
16th April 2008, 08:54
Get a backtrace (bt command in gdb). Oh, and make sure the application is compiled in debug mode.

ramstormrage
18th April 2008, 08:09
Hello again wysota,

Thanks for replying.
I tried to get a backtrace but gdb told me there were 'No Backtrace.'. And yup, its already compiled in debug mode.

wysota
18th April 2008, 09:00
In that case it probably didn't crash or you did something incorrectly. Could you explain step by step what you did and what results you get after each step starting from launching the application?

ramstormrage
18th April 2008, 09:13
Ok..Before I run gdb I navigate first to the directory where the program is located.

1. In the console, I type gdb then proceed with "pwd" command to double check the working directory.
<gdb> -> Working directory ....
2. I type "file GUI.exe" then press return
<gdb> -> Reading symbols from gui.exe .. done.
3. I type "run" then press return
<gdb> -> Starting program ...
4. In the program, I use the file dialog to select a jpeg image in My Documents folder.
5. After loading, the picture, my program responds with a Info box.
<gdb> -> Still blank..
6. Then I use the Adjust Brightness option from the Tools Menu.
7. Program quits unexpectedly.
<gdb> -> Program exited with code 01.
8. I type "bt".
<gdb> -> No stack.

ramstormrage
18th April 2008, 09:14
I didnt get a segmentation fault btw..

wysota
18th April 2008, 16:39
I didnt get a segmentation fault btw..

Yes, I can see that. My guess is your program asserted. It seems you didn't build it in debug mode (in terms of debugging info being embedded into your app) after all. Please double check that. You can set a breakpoint in the function you expect to cause problems and manually step through the code to see where it breaks.

ramstormrage
18th April 2008, 16:59
Hello again, Thanks for replying..
Ok I'll try that..

Anyways, my previous hunch was right, the QImage image object gets destroyed after the MainWindow::open() function. In the showBrightnessDialog(), I tried to put another
QImage image(fileName); and it proceeded and displayed the pixmap inside the label as planned.

Just to need know why? Any ideas?

wysota
18th April 2008, 19:17
If the image object was going out of scope, you wouldn't be able to compile the application. It's not a heap based object, it can't be deleted "somewhere in the meantime". The image might be null, but that by itself wouldn't cause your application to crash unless you tried to iterate its pixels or something.

ramstormrage
19th April 2008, 05:55
It seems you didn't build it in debug mode (in terms of debugging info being embedded into your app) after all. Please double check that.

Hello again,
I need help again on this one.
If I need to build the application in debug mode, I should include -g flag during compilation right? But I let qmake do the compiling for me.

This is how i compile my program in debug mode (after I Built Debug Libraries)
qmake -project
qmake GUI.pro "CONFIG+=debug"
make

Am I doing something wrong?

wysota
19th April 2008, 09:40
No, it's fine. You can check if the resulting makefile has proper flags, if you want to be sure. I really suggest you try stepping through the code from within the debugger.

ramstormrage
19th April 2008, 16:04
EDIT: Sorry, I stepped through the program, I found that the program halts somewhere within this function.

void brDialog::createImage(QImage &imag)
{
beforeLabel->setPixmap(QPixmap::fromImage(imag));
imagafterRGB = fileHandler.convertToRGBImage(imag);

//imagafter = fileHandler.convertToQImage(imagafterRGB);
afterLabel->setPixmap(QPixmap::fromImage(imagafter));
}


DOUBLE_EDIT:
Hello wysota,

I traced the program for a while and I experimented on different codes, and I found that the QImage image object from a while back really gets destroyed if i dont reinitialize it with QImage image(fileName) before I pass it to brDialog::createImage()

Now the problem is why? And is there another way to avoid this without reinitializing the image object?



void MainWindow::adjustBrightness()
{
brDialog dialog(this);
//QImage image(fileName); <-- can I avoid this or maybe I dont have a choice?
dialog.createImage(image);
dialog.exec();
}


Thank you for your patience..

wysota
19th April 2008, 18:06
Find out where you lose your image. It's certainly somewhere before adjustBrightness is called. Currently you don't "reinitialize" the image but create a local variable with the same name. If you do the same elsewhere then simply your member variable "image" never gets initialized.

ramstormrage
19th April 2008, 18:58
If you do the same elsewhere then simply your member variable "image" never gets initialized.
So that means its not correct to use QImage image(QString fileName) whenever I need to pass images to dialogs?

Is there another way to "permanently" initialize a QImage object from a file?

EDIT:
Hmm, I cant seem to find where in the code does the image object get lost, you see, I tried to clear and repaint the image on QLabel imageLabel until the end of MainWindow::open(), and it still exists.

And then I tried to repaint the image inside the below function, just to try if image is still valid, and it is..


void MainWindow::closeImage()
{
imageLabel->clear();
closeAction->setEnabled(false);
imageLabel->setPixmap(QPixmap::fromImage(image));
}

Now in my current project, these are the only functions inside the mainwindow.cpp file:
1. constructor
2. createMenus()
3. createActions()
4. open()
5. closeImage()
6. adjustBrightness()

I cant seem to find where image gets lost.

wysota
19th April 2008, 19:52
So that means its not correct to use QImage image(QString fileName) whenever I need to pass images to dialogs?
Yes, that's correct - it's incorrect.


Is there another way to "permanently" initialize a QImage object from a file?

Substitute
QImage image(filename) with
image = QImage(filename);

ramstormrage
20th April 2008, 11:51
Finally!!

After 25 posts, we got the correct code! Thanks for the help.. I cant thank you enough..
Haha!
Now, to do something about this blasted HEAP problems Ive been getting..

ramstormrage
20th April 2008, 12:24
Ok heap problems gone.

I forgot to ask this earlier but how to do I pass the modified image back to the MainWindow?
I created a method in MainWindow that accepts the modified image, but how do I call it from the dialog?

wysota
20th April 2008, 12:29
Oh come on, man. None of your problems are related to Qt - every problem you have is about C++ and code design. We are not here to teach you C++! Try making a method similar to the one I suggested in my very first post in this thread (or a second one, I don't remember) just going the other way round.

ramstormrage
20th April 2008, 14:32
Ok thank you very much wysota, I learned plenty of stuff.

Anyways, for the sake of other people that'll possibly view this thread, here's a possible solution.



void MainWindow::adjust()
{
adjustDialog dialog(this); //Invoke modal Adjust Brightness Dialog
dialog.createImage(image); //Pass current image object to dialog
if (dialog.exec()){
image = dialog.submitImg(); //Overwrite current image with mod. image
refreshImage();
}
}

QImage adjustDialog::submitImg()
{
return ModifiedQImageObject; //Returns modified image to MainWindow
}