在QT中使用对象树(object tree)来组织和管理所有的QObject类及其子类的对象。
在QObject中存在一个children(),返回的类型为const QObjectList,存储着以它为父类的子对象,
在QObject中可以存储多个子对象。
设置父类的方法:
- 在创建对象时,直接添加父类
- 使用setParent()函数设置父类
例如:
QPushButton *pub=new QPushButton(this);//设置了父类
QPushButton *pub1=new QPushButton;
pub1->setParent(this);//设置了父类
对象树模型为:
其内容主要为:
在堆区创建对象时,如果对象的父亲为object派生下来的类或者object派生下来的子类,那么将不用管理内存释放的操作,将对象放到对象树中,这种做法简化了内存回收机制。
内存释放的过程:
- 正常情况下,最后被创建出来的会先被析构掉。
- 特殊情况,当子类对象先创建,父类对象后创建时,会出现错误
正确的创建方法:先创建父类,后创建子对象
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QPushButton p1;//创建一个按钮
Widget w;
p1.setParent(&w);//设置父类
w.show();
return a.exec();
}
如果你不设置父类,也可以自己手动释放内存。
- delete() 直接释放内存
- deleteLater() 释放一个event()信号,在下一个循环中收到这个信号时释放内存
- 优点:可以在未删除前完成一些操作
- 缺点:有可能内存释放不及时
为了避免麻烦的话,非主窗口尽量还是使用new在 堆中开辟空间,可以不用主动delete,并且尽量在创建对象时设置好父类。
QDialog的对话框
QDialog类是所有对话框窗口类的基类。对话框窗口是一个经常用来完成短小任务或者和用户进行简单交互的顶层窗口。
窗口分为模态和非模态:
- 模态:弹出对话框时 不可以对其他窗口进行操作 (阻塞)exec()
- 非模态:弹出对话框时可以对其他窗口操作 show()
方式 | 功能 |
show() | 非模态显示 |
exec() | 模态显示 |
setModel(true);show() | 模态显示 |
三者的区别:
- show() 两个框一起出现,且可以相互对框操作
- exec() 先出现模态框,关闭模态框后,出现另一个框
- setModel(true);show() 两个框一其出现,单只能先处理完模态框,才能操作另一个框
模态:exec():弹出对话框时,不可以对其他窗口进行操作
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
setFixedSize(600,600);
QDialog *dg1=new QDialog;
dg1->resize(400,400);//设置窗口大小
dg1->exec();//模态
}
非模态:show():弹出窗口是可以对其他窗口操作
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
setFixedSize(600,600);
QDialog *dg1=new QDialog;
dg1->resize(400,400);//设置窗口大小
dg1->show();
}
可以用show()来实现模态:
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
setFixedSize(600,600);
QDialog *dg1=new QDialog;
dg1->resize(400,400);//设置窗口大小
dg1->setModal(true);
dg1->show();
参考资料: