27

I want to make a simple 'About' modal dialog, called from Help->About application menu. I've created a modal dialog window with QT Creator (.ui file).

What code should be in menu 'About' slot?

Now I have this code, but it shows up a new modal dialog (not based on my about.ui):

void MainWindow::on_actionAbout_triggered()
{
    about = new QDialog(0,0);
    about->show();
}

Thanks!

frogatto
  • 28,539
  • 11
  • 83
  • 129
Michael Zelensky
  • 2,012
  • 3
  • 29
  • 37

2 Answers2

43

You need to setup the dialog with the UI you from your .ui file. The Qt uic compiler generates a header file from your .ui file which you need to include in your code. Assumed that your .ui file is called about.ui, and the Dialog is named About, then uiccreates the file ui_about.h, containing a class Ui_About. There are different approaches to setup your UI, at simplest you can do

#include "ui_about.h"

...

void MainWindow::on_actionAbout_triggered()
{
    about = new QDialog(0,0);

    Ui_About aboutUi;
    aboutUi.setupUi(about);

    about->show();
}

A better approach is to use inheritance, since it encapsulates your dialogs better, so that you can implement any functionality specific to the particular dialog within the sub class:

AboutDialog.h:

#include <QDialog>
#include "ui_about.h"

class AboutDialog : public QDialog, public Ui::About {
    Q_OBJECT

public:
    AboutDialog( QWidget * parent = 0);
};

AboutDialog.cpp:

AboutDialog::AboutDialog( QWidget * parent) : QDialog(parent) {

    setupUi(this);

    // perform additional setup here ...
}

Usage:

#include "AboutDialog.h"

...

void MainWindow::on_actionAbout_triggered() {
    about = new AboutDialog(this);
    about->show();
}

In any case, the important code is to call the setupUi() method.

BTW: Your dialog in the code above is non-modal. To show a modal dialog, either set the windowModality flag of your dialog to Qt::ApplicationModal or use exec() instead of show().

Andreas Fester
  • 36,091
  • 7
  • 95
  • 123
  • Thank you, Andreas! Going the simplest way for the moment... The fact is that the ui_about.h was not created, and it is not preset now. So the project with the code you specified first, doesn't compile. Is there a way to create ui_about.h manually?.. – Michael Zelensky Oct 29 '12 at 07:26
  • 1
    You can manually create it with `uic about.ui -o ui_about.h`. But your build system should take care of it - make sure that `FORMS=about.ui` is included in your `.pro` file. – Andreas Fester Oct 29 '12 at 07:30
  • Do you have any strange entries in the .pro file? There was a similar issue some time ago with resource files not being created: http://stackoverflow.com/questions/12380171/qmake-not-generating-binary-resource-files/12431570#12431570 – Andreas Fester Oct 29 '12 at 07:45
  • no, everything is fine in my .pro: FORMS += mainwindow.ui \ about.ui – Michael Zelensky Oct 29 '12 at 07:48
  • I created ui_about.h from command shell, but when compiling I still get errors: 'about' was not declared in this scope – Michael Zelensky Oct 29 '12 at 07:49
  • In the first line of the slot: about = new QDialog(0,0); – Michael Zelensky Oct 29 '12 at 07:59
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/18704/discussion-between-andreas-and-michael-zelensky) – Andreas Fester Oct 29 '12 at 08:01
  • After manual creating the ui_about.h (automatic creation is still another open issue), and after defining about in the first line of the slot: QDialog *about = new QDialog(0,0); all works now! – Michael Zelensky Oct 29 '12 at 08:19
  • I managed to get a vtable error when implementing this solution. It turns out I had to run `qmake` on my project since qt creator occasionally forgets to: https://forum.qt.io/topic/11994/error-undefined-reference-to-vtable-for-myclass – NuclearPeon Feb 22 '17 at 17:32
  • Thanks for the answer. For the future users I would like to mention that I have encountered link errors corrected with the @Trevor Hickey [answer](https://stackoverflow.com/questions/14170770/unresolved-external-symbol-public-virtual-struct-qmetaobject-const-thiscal/27647049). Do not forget to add the _moc_ file in to the project.Thank you! – Darkmoor Mar 30 '18 at 13:22
8

For modal dialogs, you should use exec() method of QDialogs.

about = new QDialog(0, 0);

// The method does not return until user closes it.
about->exec();

// In this point, the dialog is closed.

Docs say:

The most common way to display a modal dialog is to call its exec() function. When the user closes the dialog, exec() will provide a useful return value.


Alternative way: You don't need a modal dialog. Let the dialog show modeless and connect its accepted() and rejected() signals to appropriate slots. Then you can put all your code in the accept slot instead of putting them right after show(). So, using this way, you wouldn't actually need a modal dialog.

frogatto
  • 28,539
  • 11
  • 83
  • 129