Qt窗口切换--原始指针 VS Boos方式
来源:互联网 发布:小程序模板源码下载 编辑:程序博客网 时间:2024/05/12 07:54
这两天在做Qt多窗口切换测试,上一篇博客,也说明了一种切换的方式,不过上一种有较强耦合性,为什么呢,就是在主窗口的.h或.cpp里面必须包含子窗口的头文件,才行。
那么想要做低耦合,就是A窗口和B窗口不互相包含,怎么办呢?
方法一:我首先,想到的是在A窗口类中定义一个B窗口的基指针以及获取B窗口指针的函数,为啥用基指针呢,原因就是不想再去包含B窗口头文件,因为AB两个窗口都继承自QWidget,所以我可以AB两个类都定义一个存对方窗口指针的变量和获取对方窗口的函数。那么在主函数中我定义两个变量后,再相互传一下指针,不就可以解决互访问题了!!
widget(主窗口)
// widget.h
#ifndef WIDGET_H#define WIDGET_H
#include <QWidget>namespace Ui {class Widget;}
class Widget : public QWidget{ Q_OBJECT public: explicit Widget(QWidget *parent = 0); ~Widget(); void GetChildWinPtr(QWidget *window);//获取子窗口指针函数private slots: void on_pushButton_clicked();
private: Ui::Widget *ui; QWidget *child; //存储子窗口指针};
#endif // WIDGET_H//widget.cpp
#include "widget.h"#include "ui_widget.h"#include <QDebug>
Widget::Widget(QWidget *parent) : QWidget(parent), ui(new Ui::Widget){ ui->setupUi(this); setWindowTitle("Main Window"); qDebug() << "construct main";}
Widget::~Widget(){ delete ui; qDebug() << "delete main";}void Widget::GetChildWinPtr(QWidget* window){ child = window;}void Widget::on_pushButton_clicked(){ this->close(); child->show();
}
child(子窗口)
//child.h
#ifndef CHILD_H#define CHILD_H
#include <QWidget>#include <boost/shared_ptr.hpp>
namespace Ui {class Child;}
class Child : public QWidget{ Q_OBJECT public: explicit Child(QWidget *parent = 0); ~Child(); void GetMainWinPtr(QWidget* window);//获取主窗口指针函数 void GetMainWinPtr(boost::shared_ptr<QWidget> window);private slots: void on_pushButton_clicked();
private: Ui::Child *ui; QWidget *main;//主窗口指针};
#endif // CHILD_H//child.cpp
#include "child.h"#include "ui_child.h"#include <QDebug>
Child::Child(QWidget *parent) : QWidget(parent), ui(new Ui::Child){ ui->setupUi(this); setWindowTitle("Child Window"); qDebug() <<"construct child";}
Child::~Child(){ delete ui; qDebug() <<"delete child";}
void Child::GetMainWinPtr(QWidget* window){ main = window;}void Child::on_pushButton_clicked(){ this->close(); main->show();}
main.cpp
#include <QtGui/QApplication>#include "widget.h"#include "child.h"#include <QDebug>#include <boost/shared_ptr.hpp>#include <boost/smart_cast.hpp>
int main(int argc, char *argv[]){ QApplication a(argc, argv);
Widget w;
Child cld;
w.GetChildWinPtr(&cld);
cld.GetMainWinPtr(&w);
w.show();
//也可以用new的方式来建立两个窗口,不过会造成内存泄漏 return a.exec();}
这样可以解决问题,但注意,主窗口和子窗口不能成父子关系!!!!!!!
方法二:boost::shared_ptr方式
child
//child.h
#ifndef CHILD_H#define CHILD_H
#include <QWidget>#include <boost/shared_ptr.hpp>
namespace Ui {class Child;}
class Child : public QWidget{ Q_OBJECT public: explicit Child(QWidget *parent = 0); ~Child(); //void GetMainWinPtr(QWidget *window); void GetMainWinPtr(boost::shared_ptr<QWidget> window);private slots: void on_pushButton_clicked();
private: Ui::Child *ui; //QWidget * main; boost::shared_ptr<QWidget> main;};
#endif // CHILD_H //child.cpp
#include "child.h"#include "ui_child.h"#include <QDebug>
Child::Child(QWidget *parent) : QWidget(parent), ui(new Ui::Child){ ui->setupUi(this); qDebug()<< "construct a child";}
Child::~Child(){ delete ui; qDebug()<< "delete a child";}
void Child::GetMainWinPtr(boost::shared_ptr<QWidget> window){ main = window;}/*void Child::GetMainWinPtr(QWidget *window){ main = window;}*/void Child::on_pushButton_clicked(){ close(); main->show();}
widget
//widget.h
#ifndef WIDGET_H#define WIDGET_H
#include <QWidget>#include <boost/shared_ptr.hpp>namespace Ui {class Widget;}
class Widget : public QWidget{ Q_OBJECT public: explicit Widget(QWidget *parent = 0); ~Widget(); void GetChildWinPtr(QWidget * window); void GetChildWinPtr(boost::shared_ptr<QWidget> window);private slots: void on_pushButton_clicked();
private: Ui::Widget *ui; //QWidget * child; boost::shared_ptr<QWidget> child;};
#endif // WIDGET_H
//widget.cpp
#include "widget.h"#include "ui_widget.h"#include <QDebug>
Widget::Widget(QWidget *parent) : QWidget(parent), ui(new Ui::Widget){ ui->setupUi(this); qDebug()<< "construct a main";}
Widget::~Widget(){ delete ui; qDebug()<< "delete a main";}/*void Widget::GetChildWinPtr(QWidget *window){ child = window;}*/
void Widget::GetChildWinPtr(boost::shared_ptr<QWidget> window){ child = window;}
void Widget::on_pushButton_clicked(){ close(); child->show();}
main.cpp
#include "widget.h"#include <QApplication>#include "child.h"#include <boost/shared_ptr.hpp>
int main(int argc, char *argv[]){ QApplication a(argc, argv); /* Widget w; Child cld; w.GetChildWinPtr(&cld); cld.GetMainWinPtr(&w); w.show(); */ boost::shared_ptr<Widget> m_main(new Widget); boost::shared_ptr<Child> m_child(new Child); m_main->GetChildWinPtr(boost::dynamic_pointer_cast<QWidget>(m_child)); m_child->GetMainWinPtr(boost::dynamic_pointer_cast<QWidget>(m_main)); m_main->show(); a.exec(); m_main->GetChildWinPtr(boost::shared_ptr<QWidget>()); m_child->GetMainWinPtr(boost::shared_ptr<QWidget>()); return 0;}
注意,main函数后半节,m_main->GetChildWinPtr(boost::shared_ptr<QWidget>());必须要再传一个空shared_ptr进去,因为child和widget类中分别还有个shared_ptr变量,用于保存两个窗口指针,虽然当主函数执行完后,主函数中保存两个窗口指针的shared_ptr变量,释放了,但引用计数只是减了1,由于child和widget类中还有shared_ptr,没有被 释放,所以child和widget指针不会释放。因此,在这里传个boost::shared_ptr<QWidget>()空的shared_ptr给child和widget类中的指针,从而使它们释放掉两个child和widget指针。因为赋空操作,引用计数将直接变为0。
方法三:boost::function+bind形式,这种方法不用传指针
child
//child.h
#ifndef CHILD_H#define CHILD_H
#include <QWidget>//#include <boost/shared_ptr.hpp>#include <boost/function.hpp>
namespace Ui {class Child;}
class Child : public QWidget{ Q_OBJECT Q_OBJECTpublic: explicit Child(QWidget *parent = 0); ~Child(); //void GetMainWinPtr(QWidget *window); //void GetMainWinPtr(boost::shared_ptr<QWidget> window); void SetOnMainWinShow(boost::function<void()> m_main);private slots: void on_pushButton_clicked();private: class impl; impl * m_impl;private: Ui::Child *ui; //QWidget * main; //boost::shared_ptr<QWidget> main;};
#endif // CHILD_H
//child.cpp
#include "child.h"#include "ui_child.h"#include <QDebug>
class Child::impl{public: boost::function<void()> m_main_show;};Child::Child(QWidget *parent) : QWidget(parent), ui(new Ui::Child){ ui->setupUi(this); m_impl = new impl(); qDebug()<< "construct a child";
}
Child::~Child(){ delete ui; qDebug()<< "delete a child";}
void Child::SetOnMainWinShow(boost::function<void ()> m_main){ m_impl->m_main_show = m_main;}
/*void Child::GetMainWinPtr(QWidget *window){ main = window;}*/void Child::on_pushButton_clicked(){ close(); //main->show(); if(m_impl->m_main_show) m_impl->m_main_show();}
widget
//widget.h
#ifndef WIDGET_H#define WIDGET_H
#include <QWidget>#include <boost/shared_ptr.hpp>#include <boost/function.hpp>
namespace Ui {class Widget;}
class Widget : public QWidget{ Q_OBJECT public: explicit Widget(QWidget *parent = 0); ~Widget(); void GetChildWinPtr(QWidget * window); void GetChildWinPtr(boost::shared_ptr<QWidget> window); void SetOnChildWinPtr(boost::function<void()> m_child);private slots: void on_pushButton_clicked();
private: Ui::Widget *ui; //QWidget * child; //boost::shared_ptr<QWidget> child;private: class impl; impl *m_impl;};
#endif // WIDGET_H//widget.cpp
#include "widget.h"#include "ui_widget.h"#include <QDebug>class Widget::impl{public: boost::function<void()> m_child_show;};Widget::Widget(QWidget *parent) : QWidget(parent), ui(new Ui::Widget){ ui->setupUi(this); m_impl = new impl(); qDebug()<< "construct a main";}
Widget::~Widget(){ delete ui; qDebug()<< "delete a main";}/*void Widget::GetChildWinPtr(QWidget *window){ child = window;}*/
void Widget::SetOnChildWinPtr(boost::function<void ()> m_child){ m_impl->m_child_show = m_child;}
void Widget::on_pushButton_clicked(){ close(); //child->show(); if(m_impl->m_child_show) m_impl->m_child_show();}
main.cpp
#include "widget.h"#include <QApplication>#include "child.h"#include <boost/shared_ptr.hpp>#include <boost/bind.hpp>#include <QDebug>int main(int argc, char *argv[]){ QApplication a(argc, argv); /* Widget w; Child cld; w.GetChildWinPtr(&cld); cld.GetMainWinPtr(&w); w.show();w.show(); */ /* boost::shared_ptr<Widget> m_main(new Widget); boost::shared_ptr<Child> m_child(new Child); m_main->GetChildWinPtr(boost::dynamic_pointer_cast<QWidget>(m_child)); m_child->GetMainWinPtr(boost::dynamic_pointer_cast<QWidget>(m_main)); m_main->show(); a.exec(); m_main->GetChildWinPtr(boost::shared_ptr<QWidget>()); m_child->GetMainWinPtr(boost::shared_ptr<QWidget>()); */ boost::shared_ptr<Widget> m_main(new Widget); boost::shared_ptr<Child> m_child(new Child); m_main->SetOnChildWinShow(boost::bind(&Child::show,m_child)); m_child->SetOnMainWinShow(boost::bind(&Widget::show,m_main));//bind会返回一个函数对象,里面保存一个对象拷贝,这个对象,再赋值给最底层的function,所以最底层的function里面存放了,shared_ptr的拷贝,所以应用计数为2,不会析构
m_main->show(); qDebug() << m_main.use_count(); a.exec(); m_main->SetOnChildWinShow(boost::function<void()>());//手动赋值,function对象为空,从而使其释放掉里面保存的shared_ptr拷贝 m_child->SetOnMainWinShow(boost::function<void()>()); return 0;}
- Qt窗口切换--原始指针 VS Boos方式
- 【Qt开发】窗口切换
- qt窗口切换
- QT实现多窗口切换
- QT实现多窗口切换
- Qt多窗口切换程序
- Qt多窗口切换程序
- Qt mac sdl窗口指针
- 使用Qt Designer和手动编写代码两种方式实现多窗口切换程序(Qt基础)
- Qt 子窗口父窗口切换,窗口间传值
- VS+QT实现语言自动切换
- Qt+VS多个版本切换
- QT学习笔记----窗口的相互切换
- 6410 QT窗口切换显示绿色
- QT实现多窗口之间的切换
- qt中实现多窗口切换
- Qt窗口主题样式切换功能
- Qt 多窗口的相互切换
- 设计模式之桥模式(Bridge)
- MySQL中多表删除方法
- 郑州java 三年大约什么价
- 应用升级至iOS 7,开发者应避免五件事
- 快速配置 Samba 将 Linux 目录映射为 Windows 驱动器,用于跨平台编程
- Qt窗口切换--原始指针 VS Boos方式
- spring整合struts2具体步骤
- css相关问题
- 搭建安卓平台时产生的错误
- intel dpdk api test程序讲解 (dpdk库测试模块)
- 简单Linux C线程池
- AcDbObjectId、AcDbHandle与AcDbStub之间的关系
- Anyevent::SNMP实例
- python下的MySQLdb使用