PDA

View Full Version : Simple Mdi question



slqh
20th September 2011, 23:53
Hello.
I have a MDI area with a menu.
that i created like this.



setupUi(this);
mdiArea = new QMdiArea;
mdiArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded );
mdiArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
setCentralWidget(mdiArea);

setWindowTitle(tr("MDI"));
setUnifiedTitleAndToolBarOnMac(true);


When one of hte options is clicked i create a window like this.



frmUserProfile *b = new frmUserProfile;
mdiArea->addSubWindow(b);
b->exec();


Then from that window i want to open a second one when the user clicks on a button.
the problem is that mdiArea does not exist there and if i do



frmTest *t = new frmTest(this);
t->exec();
delete t;


The window is shown outside of the mdi area.

One workaround i found is to use a signal to make the mainwindow open frmTest, but it looks like a ugly thing to do and I'm sure other problems will arise from that method.

How can i fix the problem of Qdialogs appearing outside the MDIarea?
I realize that maybe this is more of a c++ problem than a Qt one, sorry for that.

Thanks!

ChrisW67
21st September 2011, 02:57
The grandparent of the first widget, if it exists, can be cast to QMdiArea to add another widget... or you can emit a signal and have the main window add the new child. The second option is more flexible, e.g. if the sub window widget is used standalone also.

I don't know what you expect to happen when you call exec() on the child widget after adding it to the MDI area. The QDialog::exec() call is used to obtain a modal dialog, which is not particularly consistent with MDI, and breaks a simple test program on my machine.

slqh
21st September 2011, 04:07
ChrisW67 thanks for your response.
i will try to clarify why I'm using exec there.

The intended usage is something like this.

The user clicks on the menu.
A form is created where a list of the products is show wich has a button to create a new one.
That new form should block the product list to prevent the user from clicking tome other stuff on THAT parent form only. not to prevent him or her to open other unrelated things from the menu.

With mi current approach the third form appears outside the mdi area.
i don't know what are you referring to when you say that it breaks your test program, here compiles and runs fine, but maybe as I'm just a beginner something is not behaving as it should and I can't notice.

i think i will go with the signal/slot approach and prevent the user from using the intended parent widget by hiding it.

gojkovicde
14th December 2012, 10:07
I know it's been more than a year since the last post, but I don't think I should open another threat because of that.


The grandparent of the first widget, if it exists, can be cast to QMdiArea to add another widget...

Can you be more specific about how to do that? Maybe a short example would help..

What I have is QMainWIndow as a parent, QMdiArea as a central widget. User opens form2 from the menu bar, and its added to QMdiSubWindow. If the users clicks the button on form2, it should open form3 and it should be added to QMdiSubWindow also.

Thank you for your help,
Dejan

gojkovicde
16th December 2012, 18:32
Anyone ?
Dejan

ChrisW67
16th December 2012, 22:12
I think you should prefer using a signal. Here is one of many ways to organise this:


#include <QtGui>

class PushButton: public QPushButton
{
Q_OBJECT
public:
PushButton(QWidget *p = 0): QPushButton(p) {
connect(this, SIGNAL(clicked()), SLOT(doClicked()));
}

private slots:
void doClicked() {
QTextEdit *edit = new QTextEdit(this); // could be any widget
emit addAnotherMdiChild(edit);
}

signals:
void addAnotherMdiChild(QWidget *child);
};


class MainWindow: public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *p = 0): QMainWindow(p) {
m_area = new QMdiArea(this);
setCentralWidget(m_area);

PushButton *button = new PushButton(this);
button->setText("Add another widget");
connect(button, SIGNAL(addAnotherMdiChild(QWidget *)), SLOT(doAddAnotherMdiChild(QWidget *)));
doAddAnotherMdiChild(button);
}

public slots:
void doAddAnotherMdiChild(QWidget *child) {
(void) m_area->addSubWindow(child);
child->show();
}

private:
QMdiArea *m_area;
};


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

MainWindow w;
w.show();
return app.exec();
}
#include "main.moc"

gojkovicde
17th December 2012, 15:28
Thank you for the advice and example, I'll get into details of it as soon as I can..
Dejan