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


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

    <待续....>

    内在的趣味,表面的繁琐
  • 相关阅读:
    Python 获取学校图书馆OAPC账号对应的身份证号码
    利用Python获取ZOJ所有题目的名字
    android wifi Beacon帧解析
    比较skb_clone和skb_cpoy
    查找链表的中间节点
    linux wifi wpa_cli及hostapd_cli命令总结
    android wifi I2C总线
    android wifi P2P CONNECT, INVITE和JOIN流程选择
    android wifi ANR问题分析总结
    android 编译代码注意事项
  • 原文地址:https://www.cnblogs.com/data1213/p/10802881.html
Copyright © 2020-2023  润新知