當前項目設計窗口是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沒有消失呢?
<待續....>