一、界面跳转
具体实例为注册界面向登录界面的跳转。有两种实现方法。
(1)信号和槽
思路:注册界面向登录界面发送一个自定义信号,使登录界面接收到信号能够调用自己的show()。
关键代码:
//registerWindow.h
.......
signals:
void subSignal();
public slots:
void returnToLogin();
......
//registerWindow.cpp
void returnToLogin()
{
emit subSignal();
this->close();
}
//loginWindow.cpp
connect(regist,SIGNAL(subSignal()),this,SLOT(show()));
(2)多态中的指针
思路:在登录界面设置一个注册界面的指针变量,通过父指针QWidget作为函数参数,将自己传递给注册界面,从而实现在注册界面对登录界面的show()的调用。(这里的界面都是继承自QWidget类)
关键代码:
//loginWindow.h
......
private:
registerWindow *r;
......
//registerWindow.h
......
protected:
void setLoginWindow(QWidget *);
.......
//loginWindow.cpp
r->setLoginWindow(this);
二、
setAttribute(Qt::WA_DeleteOnClose) 与QT的内存回收
Qt是以对象树的形式来实现对垃圾的收集。父类拥有并维护者一颗对象树。例如一个窗体类构造函数格式是这样:xxx(QWidget *parent = 0),这里的parent就是父类的指针,即是把此类对象注册到父类的对象树中,当父类的对象释放时,对象树的对象也会释放,这样就不需要手动释放。
听起来很抽象,我有点不确定是不是和我理解的那样通过调用children的析构来达成的这样连锁释放,如果是从属关系(类的成员那种)的话,是否也构成child和parent关系?
为了搞明白我做了个例子:
//Widget.cpp
~Widget()
{
qDebug()<<"delete all";
}// QLineEditPassword.cpp
~ QLineEditPassword()
{
qDebug()<<"delete pwd_edit";
}//RegisterWindow.cpp
~RegisterWindow()
{
qDebug()<<"delete regist";
}//loginWindow.cpp
toRegisterWin()
{
RegisterWin *r=new RegisterWin();
connect(regist,SIGNAL(subSignal()),this,SLOT(show())); //此处为页面跳转信号和槽的例子
this->hide();
QLineEditPassword *p=new QLineEditPassword (this);
r->show();
}//main.cpp
LoginWindow l;
l.show();
在进过“登录界面点击按钮跳转注册界面,再跳转回来,最后关闭程序”这样的操作后,控制台得到的结果如下:
//当注册界面跳转回登录界面时
//当关闭登录界面时
delete login
delete all
delete pwd_edit
根据结果我们可以得出几个结论:
①login在释放内存的时候先调用自己的析构然后是父类的析构最后是成员函数的析构。那我大概推测类和其从属(一时想不到更好的词)的成员大概也是构成类父子关系。
②我们可以看到registerWin的析构并没有被调用,结合①这只能说明registerWindow和loginWindow并没有构成父子关系。对比“ RegisterWin *r=new RegisterWin();”和“ QLineEditPassword *p=new QLineEditPassword (this);”可知,在构造的时候registerWindow并没有将loginWindow作为parent指针传入。即并不是所有于类内声明定义的对象都能与类构成从属关系。必须在构造的时候,将类作为parent指针传入才行。且这些从属的成员释放的时候是等到loginWindow调用close()的时候一并释放的。
③那这些不属于从属关系的对象new了却无法依赖机制自动释放,那就还是得我们手动释放,那要怎么释放呢?总不可能在toRegisterWin()里最后添加一句delete r吧。我们当然希望是通过按扭触发的关闭事件来释放内存,于是,就有了setAttribute(Qt::WA_DeleteOnClose)。这个设置的作用就是在调用close()的时候,立刻触发delete回收内存。对于这种体制外且又不能马上delete的顽固分子最好不过,修改后的控制台结果如下:
//当注册界面跳转回登录界面时
delete regist
delete all
//当关闭登录界面时
delete login
delete all
delete pwd_edit