当前项目设计窗口是Dialog的,修改需求:
1、添加一个MainWindow窗口,并让其在程序启动时首先显式:
2、在主窗口中定义菜单,通过菜单选项能够进入到添加学生信息的界面。
1、添加MainWindow窗口:
2、设置当前显式为主窗口
当前决定Dialog窗口先启动的代码在main.cpp中:
1 #include "addstudents.h" 2 #include <QApplication> 3 4 int main(int argc, char *argv[]) 5 { 6 QApplication a(argc, argv); 7 8 AddStudents w; //Dialog 9 w.show(); 10 11 return a.exec(); 12 }
需要修改为:
1 #include "addstudents.h" 2 #include <QApplication> 3 #include "MainWindow.h" //包含头 4 5 int main(int argc, char *argv[]) 6 { 7 QApplication a(argc, argv); 8 /***********/ 9 MainWindow w; 10 w.show(); 11 12 return a.exec(); 13 }
简单的设计主窗口界面:
3、创建主窗口的菜单,然后通过菜单进入添加学生信息的Dialog窗口:
3.1:添加菜单,以及菜单的选项
主窗口与对话框的区别:主窗口带有菜单栏,可以进行菜单创建,而Dialog不行。
效果:
3.2:代码实现,当点击“学生管理菜单”中的Add_Students菜单项时,能够弹出Dialog窗口来添加学生信息。
有两个基本的实现方式:
1、效果:显式的Dialog窗口始终位于最前面,且主窗口当前不能响应什么操作,阻塞在Dialog窗口,等Dialog窗口退出之后,才能继续响应主窗口的操作。
1 MainWindow::MainWindow(QWidget *parent) : 2 QMainWindow(parent), 3 ui(new Ui::MainWindow) 4 { 5 ui->setupUi(this); 6 7 //连接创建的菜单到槽 8 connect(this->ui->actionAdd_Students,SIGNAL(triggered()),this,SLOT(show_my_Dialog())); 9 } 10 11 12 //这里的actionAdd_Students就是添加学生信息的菜单项,当点击它时,发出的信号是triggered(),而不是button控件的clicked() 13 14 //这里接收对象难道不应该是Dialog对象吗?为什么是主窗口? 15 /* 16 看槽函数定义在哪个类里面,这里的接收对象就是哪个 17 */
1 void MainWindow::show_my_Dialog(){ 2 //创建我的Dialog对象 3 AddStudents a; 4 a.exec(); 5 } 6 7 /* 8 为什么这里的写法不像main.cpp中的写法: 9 void MainWindow::show_my_Dialog(){ 10 //创建我的Dialog对象 11 AddStudents a; 12 a.show(); 13 } 14 15 因为,这里的a是一个局部的变量,在栈上分配的空间,show调用完成之后,函数结束,那么a的对象空间被释放——即窗口消失。 16 需要保证a的生命周期不会再show_my_Dialog调用结束之后就释放掉了,可以有多种方式实现,比如: 17 1:AddStudents a = new AddStudents(); //需要手动释放,麻烦 18 2:将AddStudents a声明为主窗口类的数据成员,那么当主窗口生命周期内,a始终存在的。 19 3:就是上面的方式,调用a.exec(),让程序阻塞在a窗口 20 */
演示效果:
2、将Dialog窗口声明为主窗口的数据成员:
1 #ifndef MAINWINDOW_H 2 #define MAINWINDOW_H 3 4 #include <QMainWindow> 5 #include "addstudents.h" 6 7 namespace Ui { 8 class MainWindow; 9 } 10 11 class MainWindow : public QMainWindow 12 { 13 Q_OBJECT 14 15 public: 16 explicit MainWindow(QWidget *parent = nullptr); 17 ~MainWindow(); 18 19 private slots: 20 void show_my_Dialog(); 21 22 private: 23 Ui::MainWindow *ui; 24 AddStudents* AS; //Dialog窗口 25 }; 26 27 #endif // MAINWINDOW_H
1 MainWindow::MainWindow(QWidget *parent) : 2 QMainWindow(parent), 3 ui(new Ui::MainWindow) 4 { 5 ui->setupUi(this); 6 7 AS = new AddStudents(); //窗口创建 8 9 //连接创建的菜单到槽 10 connect(this->ui->actionAdd_Students,SIGNAL(triggered()),this,SLOT(show_my_Dialog())); 11 } 12 13 MainWindow::~MainWindow() 14 { 15 delete ui; 16 delete AS; //释放 17 }
此时槽函数只需要简单的show出来就行了,不用担心槽函数调用完成之后Dialog窗口不见的情况
1 void MainWindow::show_my_Dialog(){ 2 AS->show(); 3 }
效果展示:
当主窗口关闭时,惊奇的发现Dialog未关闭,难道数据成员空间不应该被释放了吗?为什么没有消失呢?
只有一种原因:点击关闭主窗口时,并没有释放掉当主窗口对象空间,看看析构函数是否被调用,事实如此,点击关闭主窗口之后,主窗口虽然消失,但是未调用析构函数,而再去关闭Dialog窗口时,发现主窗口的析构函数被调用了。
1 MainWindow::~MainWindow() 2 { 3 delete ui; 4 qDebug()<<"主窗口完成退出"; 5 }
原因:
当前Dialog是MainWindow的子对象,按照析构顺序,应该是Dialog的析构先调用,再是MainWindow析构调用,当关闭主窗口时,Dialog窗口并没有消失,说明子对象并没有析构,所以主窗口的析构不会被调用。
那么,为什么关闭主窗口时,Dialog没有消失呢?
<待续....>