简体   繁体   中英

Opening a modal window in qt 4.8.6

I'm working on a simple program for installing wow addons and need some help with having the main window open a preferences window. I'm rather new to Qt and struggling a bit with the documentation. I did some looking around on stackoverflow, but still am a bit stuck on getting things in the right area.

edit: added in error message.

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
Q_OBJECT

public:
   explicit MainWindow(QWidget *parent = 0);
   ~MainWindow();

private:
  Ui::MainWindow *ui;
};

#endif // MAINWINDOW_H

preferences.h

#ifndef PREFERENCES_H
#define PREFERENCES_H

#include <QDialog>

namespace Ui {
class Preferences;
}

class Preferences : public QDialog
{
Q_OBJECT

public:
   explicit Preferences(QWidget *parent = 0);
   ~Preferences();

private:
   Ui::Preferences *ui;
};

#endif // PREFERENCES_H

main.cpp

#include "mainwindow.h"
#include "preferences.h"
#include <QApplication>

int main(int argc, char *argv[])
{
   QApplication a(argc, argv);
   MainWindow w;
   w.show();

   return a.exec();
}


void MainWindow::on_Preferences_triggered()
{
   Preferences = new PreferencesDialog(this);
   Preferences->show();
}

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "preferences.h"
#include <QtGui/QDialog>

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

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

preferences.cpp

#include "preferences.h"
#include "ui_preferences.h"

Preferences::Preferences(QWidget *parent) :
QDialog(parent),
ui(new Ui::Preferences)
{
  ui->setupUi(this);
}

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

Error Received error: no'void MainWindow::on_Preferences_triggered()' member function declared in class 'MainWindow'

I put the mainwindow.ui file on pastebin as it was to jumbled up here because of the tooltips added.

http://pastebin.com/ZXrDxZXz

In general, if you want your dialog to be modal, use QDialog::exec(). If you want a modeless dialog, use QDialog::show(). You can use show() to display a modal dialog too by setting the modal property to true.

I've fixed up your code so that it compiles and runs. First, the compiler error you're getting is exactly what it says: you've implemented a function MainWindow::on_Preferences_triggered() that you haven't declared in your class definition. But there are some other issues. I'll start with the main.cpp file:

#include "mainwindow.h"
#include "preferences.h"
#include <QApplication>

int main(int argc, char *argv[])
{
  QApplication a(argc, argv);
  MainWindow w;
  w.resize(200,200);
  w.show();

  return a.exec();
}


/* Move this to mainwindow.cpp
void MainWindow::on_Preferences_triggered()
{
  Preferences = new PreferencesDialog(this);
  Preferences->show();
}*/

I commented out the on_Preferences_triggered function, because it should be moved to the mainwindow.cpp file, where the rest of the MainWindow class is implemented. I also resized the MainWindow instance you created in the main() function.

On to mainwindow.h:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

#include "preferences.h"

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
Q_OBJECT

public:
  explicit MainWindow(QWidget *parent = 0);
  ~MainWindow();

private:
  /* add a function to set up a menubar/menu (you could do this in the constructor instead) */

  void setupMenus();


  /* Your main window doesn't need an instance of Ui::MainWindow, it IS an instance*/
  //Ui::MainWindow *ui;

  /* It needs a Preferences instance, though */
  Preferences *pref;


private slots:
  void on_Preferences_triggered();


};

#endif // MAINWINDOW_H

First, in both your Preferences and MainWindow definitions, you have instances of Preferences and MainWindow, respectively. I'm not sure why you did that, but I don't think it's what you want. MainWindow needs a Preferences instance (which I added), but I don't think either class needs an instance of itself.

Next, I added your on_Preferences_triggered() function as a slot. You'll need this. Finally, I added a setupMenus() function, which sets up the menubar, though you could do this in your constructor if you wanted to.

mainwindow.cpp:

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

/* Move this to mainwindow.h */
//#include "preferences.h"
#include <QtGui/QDialog>
#include <QMenuBar>
#include <QAction>
#include <QMenu>
#include <QLabel>

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

  /* initialize your preferences window */
  pref = new Preferences(this);

  /* add a menubar with a menu that will allow you to open the preferences windwow */
  setupMenus();

  /* You need a central widget: */
  setCentralWidget(new QLabel("Central widget", this));

}

MainWindow::~MainWindow()
{
  //delete ui;

  /* You can explicitly delete the Preferences pointer, but Qt will take care of it, since its parent is this  */
}

void MainWindow::setupMenus()
{
  QMenu *menu = menuBar()->addMenu(tr("&Menu"));
  QAction *prefAction = new QAction("Show preferences", this);

  /* Crucial: connect the action's triggered signal to your on_Preferences_triggered slot */
  connect(prefAction, SIGNAL(triggered()), this, SLOT(on_Preferences_triggered()));

  menu->addAction(prefAction);
}

void MainWindow::on_Preferences_triggered()
{
  /*Preferences = new PreferencesDialog(this);
  Preferences->show();*/
  pref->show();
  pref->setModal(true);
}

According to the documentation, a QMainWindow without a central widget isn't supported... so I added a QLabel as a placeholder. The rest of the constructor is pretty self-explanatory... allocate your Preferences pointer, call setupMenus.

The setupMenus function does the important work. The menubar is created the first time you call menuBar(), so I called it and added a menu. Then I created a QAction which will be used to show your preferences dialog. To do this, you NEED to connect the action's triggered() signal to your on_Preferences_triggered() slot.

The on_Preferences_triggered() slot is pretty much what you had, except it doesn't create a Preferences instance (it could though... you could keep what you had). An important point here: I used pref->show() to pop up the dialog, then made it modal with pref->setModal(true). You could instead have used pref->exec(). But read Kuba Ober's comment below.

Then, in preferences.h:

#ifndef PREFERENCES_H
#define PREFERENCES_H

#include <QDialog>

namespace Ui {
class Preferences;
}

class Preferences : public QDialog
{
Q_OBJECT

public:
  explicit Preferences(QWidget *parent = 0);
  ~Preferences();

private:
  void setupDialog();

  /* Preferences doesn't need an instance of Preferences */
  //Ui::Preferences *ui;
};

#endif // PREFERENCES_H

I added a setupDialog() function, and again, got rid of the instance of Preferences, because I think you don't need it.

And preferences.cpp:

#include "preferences.h"
//#include "ui_preferences.h"

#include <QVBoxLayout>
#include <QLabel>

Preferences::Preferences(QWidget *parent) :
QDialog(parent)
//ui(new Ui::Preferences)
{
  //ui->setupUi(this);
  setupDialog();

}

Preferences::~Preferences()
{
  //delete ui;
}

void Preferences::setupDialog()
{
  QVBoxLayout *layout = new QVBoxLayout(this);

  layout->addWidget(new QLabel("Preferences Dialog"));
}

I just created a dummy layout with a dummy QLabel in the setupDialog function.

Also... I commented out your #include "ui_preferences.h" and "ui_mainwindow.h" statements, because you didn't include this code. Not sure what you'd done in those headers, or whether they were important.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM