多界面切换技巧——Qt

前言

微信中需要很多界面之间的相互切换,比如各种聊天对话框的转换。这么多的界面是怎么实现切换的,而内存大小稳定在一定的水平下,而不是界面的一直随着界面的增长而增长。

我写了类似的微信的东西,我算了算大概有三十左右个界面,而且还没写完。若全部实例化,那将会挺大的,而且也不合适,有的界面出现的频率并不是很大,若只因出现了一次,就一直保存着这块内存,很浪费。所以我想了个解决办法,可能不是最优化的,但是也是有些作用的。

 

思路及代码

界面切换,我用的是QStackedWidget,因为我只是部分界面切换,这个还是比较好用的。

我的思路就是:将界面进行标号,分为常用和不常用的,若是不常用的,若被切换掉后就将此移除,继而删除。

界面标号,我用到了QObject的方法setProperty来携带数据,通过此数据进行区分。

数据,我自定义了一个结构体

struct LevelValue {
  int iLevel;     //界面等级 
  int iFormType; //界面类型(0聊天/1工作/2联系人/3我的)
};
Q_DECLARE_METATYPE(LevelValue)

每个界面都进行属性设置

    //设置界面等级
    LevelValue data;
    data.iLevel=2;
    data.iFormType=0;
    QVariant var=QVariant::fromValue(data);
    this->setProperty("LevelValue",var);

然后,在界面切换时,判断上一个界面的是否需删除,上一个界面我通过指针QWidget* m_pPreWidget来保存。

m_pPreWidget=nullptr;
connect(ui->formStacked,SIGNAL(currentChanged(int)),this,SLOT(stackedCurrentChanged(int)));

void MainWidget::stackedCurrentChanged(int index)
{

    if(m_pPreWidget!=nullptr)
    {
         QVariant var=m_pPreWidget->property("LevelValue");
         if(!var.canConvert<LevelValue>())
             return;
         LevelValue level=var.value<LevelValue>();
         if(level.iLevel==3)
         {//暂定当界面等级为三级时需移除
             //容器移除
             QString name=m_nameIndexMap.key((long)m_pPreWidget);
             m_nameIndexMap.remove(name);
             //界面移除
             ui->formStacked->removeWidget(m_pPreWidget);
             m_pPreWidget->deleteLater();
         }
    }
    m_pPreWidget=ui->formStacked->currentWidget();
}

 后续中,我发现我有的界面虽然属于不常用、要删除的行列,但是他需要再切换回来,所以我又增加一容器来保存需要再切换的界面(即不能删除的界面),若上一个界面包含在此容器内,那么则不用删除。所以这个完整的代码是:

void MainWidget::stackedCurrentChanged(int index)
{
    //最新界面容器更新
    QWidget* pCurWidget=ui->formStacked->widget(index);
    //LevelValue *data=(LevelValue*)pCurWidget->userData(Qt::UserRole);
    QVariant var=pCurWidget->property("LevelValue");

    if(var.canConvert<LevelValue>())
    {
        LevelValue data=var.value<LevelValue>();
        int iType=data.iFormType;
        m_latestForms[iType]=pCurWidget;
    }

    //删除无用的
    if(m_pPreWidget!=nullptr)
    {
        //判断是否是其他模块最新界面,是则不能删除
        bool iflag=false;
        foreach(QWidget* pWidget,m_latestForms)
        {
            if(pWidget==m_pPreWidget)
            {
                iflag=true;
                break;
            }
        }
        if(!iflag)
        {
            //LevelValue *level=(LevelValue*)m_pPreWidget->userData(Qt::UserRole);
            QVariant var=m_pPreWidget->property("LevelValue");
            if(!var.canConvert<LevelValue>())
                return;
            LevelValue level=var.value<LevelValue>();
            if(level.iLevel==3)
            {//暂定当界面等级为三级时需移除
                //容器移除
                QString name=m_nameIndexMap.key((long)m_pPreWidget);
                m_nameIndexMap.remove(name);
                //界面移除
                ui->formStacked->removeWidget(m_pPreWidget);
                m_pPreWidget->deleteLater();
            }
        }
    }
    m_pPreWidget=ui->formStacked->currentWidget();
}

 

结束语

第一次做这么多界面之间的切换,后续若算法优化,将继续更新,修改,看到的大佬有更好的东西,希望不啬赐教。

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值