学生管理系统(2:添加主界面窗口)

时间:2024-03-11 15:12:25

当前项目设计窗口是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没有消失呢?

<待续....>