窗口和动作
本章我们将会学习怎样设置Main Window类的菜单和工具栏动作。

File->New File or Project...
Applications->Qt Gui Application->Choose...
我们选着默认的MainWindow类

点击'Continue'然后点击'Finish' 你会看到main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
从代码中我们看到有一个附带的MainWidow类,一下是头文件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
注意,这里有一个叫UI的名字空间,而MainWindow就在它的作用域中。同时,在这个头文件中声明了一个指向UI::MainWindow的私有成员ui。
现在双击mainwindow.ui文件来打开Designer设置菜单和动作。双击'Type Here'

键入File

再双击File下的'Type Here',键入'New Window'然后回车。

注意到上图底部的动作编辑器(Action Editor)中,一个叫做actionNew_Window的动作被创建了。 我们可以将底部动作编辑器中的actionNew_Window拖到工具栏中

或者在动作编辑器中右击,选择"Go to slot..."

然后选择triggered()然后点击OK

然后Qt Creator会自动的在mainwindow.cpp中显示变化:
void MainWindow::on_actionNew_Window_triggered()
{
}
就这样,我们通过两种方式分别工具栏和菜单栏设置了触发器,当我们点击它们时动作就会被触发。 现在我们来运行代码:

无论我们是点击工具栏的New Window还是菜单栏的都不会有反应,这是因为我们在MainWindow::on_actionNew_Window_triggered()中什么也没写。
通过动作触发来打开一个对话框(Dialog)
右击主窗口project->Add New->Qt->Qt Designer Class->Dialog without Buttons

最后project看起来是这样

多出了三个文件dialog.h和dialog.cpp以及dialog.ui。 下面我们将为被触发的事件添加适当的代码。
模态对话框 (Modal Dialog)
模态是一个属性,这个属性决定show()函数弹出的对话框是模态的还是非模态的。
This property holds whether show() should pop up the dialog as modal or modeless.
By default, this property is false and show() pops up the dialog as modeless. Setting his property to true is equivalent to setting QWidget::windowModality to Qt::ApplicationModal.
exec() ignores the value of this property and always pops up the dialog as modal.
默认情况下这个属性的值是
false此时show()弹出的对话框是非模态的。设置这个值等价于对Qt::ApplicationModal设置QWidget::windModality。exec()则会忽略这个属性的值并且弹出的对话框总是模态的。
简单来说,模态的对话框会阻止用户与此程序的其它窗口交流,非模态对话框则不会,就这里来说,弹出的对话框在主窗口的上面,这个对话框会使你点击不到主窗口。
模态对话框
修改mainwindow.cpp:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "dialog.h" // 包含新的头文件
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
// 增加事件处理代码
void MainWindow::on_actionNew_Window_triggered()
{
Dialog dialog;
//dialog.setModal(true); // not necessary, exec() will ignore this property
dialog.exec();
}
现在运行这个程序:

非模态对话框
现在讲mainwindow.cpp修改成下面这样:
void MainWindow::on_actionNew_Window_triggered()
{
Dialog dialog;
//dialog.setModal(false); not necessary, default value of modal is false
dialog.show();
}
再次运行,点击'New Window'会发现没有反应。只是因为对于非模态对话框,控制权任然在主窗口上。以上代码中,当on_actionNew_Window_triggered()被调用时dialog对象被创建,而这个函数调用之后这个对象就被销毁了!
为此,我们可以在mainwindow.h中添加一个指向Dialog对象的指针变量作为MainWindow类的私有成员:
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include "dialog.h" // 包含都文件
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
void on_actionNew_Window_triggered();
private:
Ui::MainWindow *ui;
Dialog *dialog; // 添加变量
};
#endif // MAINWINDOW_H
mainwindow.cpp
void MainWindow::on_actionNew_Window_triggered()
{
dialog = new Dialog(this); // memory leak
dialog->show();
}
再次运行:

注意:由于没有释放创建对话框的内存,所以存在内泄露!