PDA

View Full Version : Wierd behaviour after resizing child dialogue



KaKa
15th March 2007, 23:14
By the QT designer, I made this QMainWindow, who has a button, and when click the button, a child dialog will pop up.

At first when the MainWindow and the dialogue were produced at arround the same time, I had the dialogue in the center of the mainwindow. When I click on "X" to close the child dialogue , the dialogue shuts down but the mainwindow stays opened.

After a while, I found that the child dialogue size is too small, so I manually enlarged the size of the dialogue to more than even the mainwindow. Now this time whenever I close the child dialogue, the mainwindow will be closed after the childe is closed.

Now I resize the child dialogue back to the original header class. Biut the same problem stil l happens.


Anyone has any idea what how to solve this problem?


Thanks thanks a lot.

wysota
16th March 2007, 09:47
Maybe the application crashes? Could you check that?

KaKa
17th March 2007, 09:31
Hello,

thanks for replying. I actually have three buttons, directing to three different dialogs. and only the first one on the left will have such strange behaviour even before resizing.

Does it have anything to do with the main button of the widget or something? I am totally new to this, so idea might be totally off track, so

Thanks!!!

wysota
17th March 2007, 10:06
Can we see the code?

KaKa
17th March 2007, 10:33
It is generated by the Designer. But I will still post the code here, see if it helps:


#ifndef UI_NEW311_H
#define UI_NEW311_H

#include <QtCore/QVariant>
#include <QtGui/QAction>
#include <QtGui/QApplication>
#include <QtGui/QButtonGroup>
#include <QtGui/QHBoxLayout>
#include <QtGui/QMainWindow>
#include <QtGui/QPushButton>
#include <QtGui/QSpacerItem>
#include <QtGui/QStatusBar>
#include <QtGui/QToolBar>
#include <QtGui/QWidget>

class Ui_New311Class
{
public:
QWidget *centralWidget;
QWidget *widget;
QHBoxLayout *hboxLayout;
QPushButton *SimpDlg1;
QSpacerItem *spacerItem;
QPushButton *SimpDlg2;
QSpacerItem *spacerItem1;
QPushButton *SimpDlg3;
QToolBar *mainToolBar;
QStatusBar *statusBar;

void setupUi(QMainWindow *New311Class)
{
New311Class->setObjectName(QString::fromUtf8("New311Class"));
centralWidget = new QWidget(New311Class);
centralWidget->setObjectName(QString::fromUtf8("centralWidget"));
widget = new QWidget(centralWidget);
widget->setObjectName(QString::fromUtf8("widget"));
widget->setGeometry(QRect(80, 50, 423, 25));
hboxLayout = new QHBoxLayout(widget);
hboxLayout->setSpacing(6);
hboxLayout->setMargin(0);
hboxLayout->setObjectName(QString::fromUtf8("hboxLayout"));
SimpDlg1 = new QPushButton(widget);
SimpDlg1->setObjectName(QString::fromUtf8("SimpDlg1"));

hboxLayout->addWidget(SimpDlg1);

spacerItem = new QSpacerItem(81, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);

hboxLayout->addItem(spacerItem);

SimpDlg2 = new QPushButton(widget);
SimpDlg2->setObjectName(QString::fromUtf8("SimpDlg2"));

hboxLayout->addWidget(SimpDlg2);

spacerItem1 = new QSpacerItem(91, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);

hboxLayout->addItem(spacerItem1);

SimpDlg3 = new QPushButton(widget);
SimpDlg3->setObjectName(QString::fromUtf8("SimpDlg3"));

hboxLayout->addWidget(SimpDlg3);

New311Class->setCentralWidget(centralWidget);
mainToolBar = new QToolBar(New311Class);
mainToolBar->setObjectName(QString::fromUtf8("mainToolBar"));
mainToolBar->setOrientation(Qt::Horizontal);
New311Class->addToolBar(static_cast<Qt::ToolBarArea>(4), mainToolBar);
statusBar = new QStatusBar(New311Class);
statusBar->setObjectName(QString::fromUtf8("statusBar"));
New311Class->setStatusBar(statusBar);

retranslateUi(New311Class);

QSize size(600, 400);
size = size.expandedTo(New311Class->minimumSizeHint());
New311Class->resize(size);


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

void retranslateUi(QMainWindow *New311Class)
{
New311Class->setWindowTitle(QApplication::translate("New311Class", "New311", 0, QApplication::UnicodeUTF8));
SimpDlg1->setText(QApplication::translate("New311Class", "SimpDlg1", 0, QApplication::UnicodeUTF8));
SimpDlg2->setText(QApplication::translate("New311Class", "SimpDlg2", 0, QApplication::UnicodeUTF8));
SimpDlg3->setText(QApplication::translate("New311Class", "SimpDlg3", 0, QApplication::UnicodeUTF8));
Q_UNUSED(New311Class);
} // retranslateUi

};

namespace Ui {
class New311Class: public Ui_New311Class {};
} // namespace Ui

#endif

The above is the code for the main window, Now I paste the first dialog code below:


#ifndef UI_SIMPDLG1_H
#define UI_SIMPDLG1_H

#include <QtCore/QVariant>
#include <QtGui/QAction>
#include <QtGui/QApplication>
#include <QtGui/QButtonGroup>
#include <QtGui/QDialog>
#include <QtGui/QLabel>
#include <QtGui/QLineEdit>
#include <QtGui/QPushButton>

class Ui_simpDlg1Class
{
public:
QLabel *orders2;
QLabel *prime3itself;
QLabel *prime5itself;
QLabel *RestrLabel;
QPushButton *OK3;
QPushButton *Reset3;
QLineEdit *lineEdit_2;
QLineEdit *RestLineEdit;

void setupUi(QDialog *simpDlg1Class)
{
simpDlg1Class->setObjectName(QString::fromUtf8("simpDlg1Class"));
orders2 = new QLabel(simpDlg1Class);
orders2->setObjectName(QString::fromUtf8("orders2"));
orders2->setGeometry(QRect(30, 30, 313, 20));
prime3itself = new QLabel(simpDlg1Class);
prime3itself->setObjectName(QString::fromUtf8("prime3itself"));
prime3itself->setGeometry(QRect(350, 60, 20, 20));
prime5itself = new QLabel(simpDlg1Class);
prime5itself->setObjectName(QString::fromUtf8("prime5itself"));
prime5itself->setGeometry(QRect(30, 60, 12, 20));
RestrLabel = new QLabel(simpDlg1Class);
RestrLabel->setObjectName(QString::fromUtf8("RestrLabel"));
RestrLabel->setGeometry(QRect(30, 100, 187, 16));
OK3 = new QPushButton(simpDlg1Class);
OK3->setObjectName(QString::fromUtf8("OK3"));
OK3->setGeometry(QRect(310, 180, 75, 23));
Reset3 = new QPushButton(simpDlg1Class);
Reset3->setObjectName(QString::fromUtf8("Reset3"));
Reset3->setGeometry(QRect(230, 180, 75, 23));
lineEdit_2 = new QLineEdit(simpDlg1Class);
lineEdit_2->setObjectName(QString::fromUtf8("lineEdit_2"));
lineEdit_2->setGeometry(QRect(50, 60, 295, 20));
RestLineEdit = new QLineEdit(simpDlg1Class);
RestLineEdit->setObjectName(QString::fromUtf8("RestLineEdit"));
RestLineEdit->setGeometry(QRect(50, 130, 291, 20));

retranslateUi(simpDlg1Class);

QSize size(400, 300);
size = size.expandedTo(simpDlg1Class->minimumSizeHint());
simpDlg1Class->resize(size);


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

void retranslateUi(QDialog *simpDlg1Class)
{
simpDlg1Class->setWindowTitle(QApplication::translate("simpDlg1Class", "simpDlg1", 0, QApplication::UnicodeUTF8));
orders2->setText(QApplication::translate("simpDlg1Class", "Please input the orders ", 0, QApplication::UnicodeUTF8));
prime3itself->setText(QApplication::translate("simpDlg1Class", "-3'", 0, QApplication::UnicodeUTF8));
prime5itself->setText(QApplication::translate("simpDlg1Class", "5'-", 0, QApplication::UnicodeUTF8));
RestrLabel->setText(QApplication::translate("simpDlg1Class", "Please enter restrictions here(optional)", 0, QApplication::UnicodeUTF8));
OK3->setText(QApplication::translate("simpDlg1Class", "Ok", 0, QApplication::UnicodeUTF8));
Reset3->setText(QApplication::translate("simpDlg1Class", "Reset", 0, QApplication::UnicodeUTF8));
Q_UNUSED(simpDlg1Class);
} // retranslateUi

};

namespace Ui {
class simpDlg1Class: public Ui_simpDlg1Class {};
} // namespace Ui

#endif // UI_SIMPDLG1_H

wysota
17th March 2007, 13:02
I meant the code of the class implementing the dialog and the main window, not their ui.

KaKa
17th March 2007, 19:46
Well, the code for the code implementing the main window and dialog is very simple. only some event handlers for buttons. But I still paste it below:

1. Main Window:

#include "new311.h"
#include "SimpDlg1.h"
#include "SimpDlg2.h"
#include "SimpDlg3.h"

new311::new311(QWidget *parent, Qt::WFlags flags)
: QMainWindow(parent, flags)
{
ui.setupUi(this);
}

new311::~new311()
{

}


void new311::on_SimpDlg1_clicked()
{
SimpDlg1 dialog1(this);
dialog1.exec();
}

void new311::on_SimpDlg2_clicked()
{
SimpDlg2 dialog2(this);
dialog2.exec();
}

void new311::on_SimpDlg3_clicked()
{
SimpDlg3 dialog3(this);
dialog3.exec();
}


2. The dialog


#include <QDialog.h>
#include <qmessagebox.h>
#include "simpDlg1.h"
#include "simpDlg1Driver.h"
#include "ui_simpDlg1.h"


simpDlg1::simpDlg1(QWidget *parent)
: QDialog(parent)
{
ui.setupUi(this);
}

simpDlg1::~simpDlg1()
{
delete param1;
delete param2;
}


void simpDlg1::on_Reset3_clicked()
{
ui.lineEdit_2->clear();
ui.RestLineEdit->clear();
}

void simpDlg1::on_OK3_clicked()
{
param1=new QString();
*param1=ui.lineEdit_2->text();
simpDlg1Driver simpDriver=new simpDlg1Driver();
simpDriver.setsimpDlg1(this);
int success=simpDriver.checksimpDlg1(*param1);
if(success==1)
{
QMessageBox *warmessage=new QMessageBox(this);
warmessage->setText("Please enter a string");
warmessage->setIcon(QMessageBox::Critical);
warmessage->exec();
}
}

Thanks a lot!

wysota
17th March 2007, 22:16
Why do you use pointers here? What happens if you declare param1 and param2 as objects and not pointers to objects? If you need to modify some object, you can pass it by reference. You have a memory leak on the "warmessage" object. Does the application crash or simply close because last window gets closed? The code you have shown us shouldn't cause the main window to close, the only possibility I see is that the application crashed because an improper use of one of the pointers.

KaKa
18th March 2007, 10:17
It is actually because QString param1=new QString() insdead of QString *param1=new QString(); compiler will complain, saying that the new QString() returns a pointer which is not matching the type of param1 or something like that.

However, since you said it will cause memory leak, I guess I will change them to objects.

So by pass by reference you mean I can do this:
QString param1; &param1=new QString(); ?

Before my application just simply totally shuts done after I shuts done the first dialog, but now after adding a new child dialog to the first dialog, when this new dialog shut down, its two parents will freez, and an exception will be thrown.

Don't know if you still have clue of what my question is and what might be the explanation.

jpn
18th March 2007, 10:27
How about something like this:


class simpDlg1
{
...
private:
QString param1; // not QString*
QString param2; // not QString*
}

simpDlg1::~simpDlg1()
{
// delete param1; <-- no more needed
// delete param2; <-- no more needed
}

void simpDlg1::on_OK3_clicked()
{
param1=ui.lineEdit_2->text();
simpDlg1Driver simpDriver; // notice the difference
simpDriver.setsimpDlg1(this);
int success=simpDriver.checksimpDlg1(param1);
if(success==1)
{
QMessageBox warmessage(this); // notice the difference
warmessage.setText("Please enter a string");
warmessage.setIcon(QMessageBox::Critical);
warmessage.exec(); // blocks until the message is closed
}
}

Unlike Java, in C++ you don't create everything with "new". :)

KaKa
18th March 2007, 17:14
O wow. I get it now! Thanks!

KaKa
18th March 2007, 19:26
Sorry I have to reopen this question:

I tried the code jpn suggested, the code worked fine, but the problem is still there.

Also for those widgets, for example, the initialization of them, the formal way is

Wedgit awedgit=new Wedgit(* parent); or awdgit=Wedgit(*parent);?

Then this means the parent, has to be a pointer when instantiated? '

Then that means in the Child class, I will have to declare some pointers to Widget (that is the parents) so that means the memory leak is not preventable?

wysota
18th March 2007, 21:01
You don't have to declare anything.


class MyWidget : public QWidget {
public:
MyWidget(QWidget *parent =0 ) : QWidget(parent){
QLabel *lab = new QLabel(this); // current object (this) is set as the parent)
lab->setText("TEST");
}
};

int main(int argc, char **argv){
QApplication app(argc, argv);
MyWidget wgt;
wgt.show();
return app.exec();
}
When "wgt" is destroyed so are all its child QObjects (the label being one of them). No memory leak and no pointers declared (and no dangling pointers).

KaKa
18th March 2007, 22:10
:confused: :o

What I meant was actually
say in your example,
the MyWedgit, it is a child of another wedgit(for example YourWedigt, then when we initialize a MyWedgit object we have to use a pointer to YourWedgit as the first parameter. (I tried use simply an object instead of a pointer, and the compiler complained, either saying I cannot access the private object, or says cannot convert an object to a pointer).

The case you were showing me with "this", as the tool tip told me before, "this" was a pointer itself.

I guess I have created a bit too many classes to call one from another?

hope I made myself clear... and hope what I just written isn't something stupid...

KaKa
19th March 2007, 09:48
Actually never mind...the problem isn't that serious any more. As long as I wait until the QT evaluation warning panel disappear, and run my program, it doesn't show up any more.