qt关于弹窗dialog的使用技巧(QSharedPoint、多弹窗)

QSharedPointer

可以使用QSharedPointer进行管理,初始化方式为 

QSharedPointer<类名> A;    // 创建对象

A = QSharedPointer<类名>(new 类名(参数), &QObject::deleteLater);    // 初始化

具体的可以查看qt文档QSharedPointer Class | Qt Core 5.15.17

QSharedPointer属于智能指针,他是一个共享指针,会在父类界面析构时,自动释放指针的内存,也就是说会在父界面关闭时将弹出的界面也一起关闭掉。

但是有一个问题,如果我弹出的界面,我自己关闭了,此时指针指向空,但是QSharedPoint并不会自动检测指针内部情况,也就是说,他不知道指针已经为空,因此在关闭父界面时,会尝试释放指向为空的指针,会报错。

怎么解决呢?

目前我对于继承自QDialog的弹窗已经有了解决办法,在创建弹窗的界面里,连接弹窗关闭的信号

// 假设指针为A

connect(A.get(), &QDialog::finished, [&] {A.clear();});

这样子,就可以在弹窗关闭的时候,手动释放掉指针。

(目前我对于继承QWidget的弹窗没有具体的解决办法,如果要使用QSharedPoint管理,最好继承自QDialog,或者就只能手动去自己编写管理界面的代码,很繁琐会增加大量代码量)

多个主题框架一样的弹窗

方法一:widget加载

我们在编写程序时,有时会遇到这样的情况:同一个程序有n多个弹窗,这些弹窗底部的按钮,顶部的标题栏基本都一样,只有中间部分的内容不一样。

这个时候,我刚开始傻傻地还一个一个ctrl c、ctrl v,这样不仅很麻烦,而且代码也不美观,一样的代码每个弹窗都得写一份,但是记住c++的特性:继承、封装、多态!

面对上述这种情况,我们可以先创建一个主题框架(如包含标题栏、底部按钮、中间一个空白的添加了布局的widget)的ui界面,可以根据自己的需求对标题、按钮等在构造函数或者写一个函数中通过子类调用来定义。

这就不需要例子了吧o.O

至于为什么中间要个widget呢,因为在布局中有一个函数:addWidget,在widget中也有一个函数:void QWidget::setupUi(QWidget *widget) // 为指定的widget设置一个ui界面,所以我们需要一个widget。

因此,我们继续在基类中写一个函数,用来给widget中的布局设置addWidget


protected:
    template<typename UI>
    void setupUi(UI& contentUi, bool resize = true) {
        contentView = new QWidget(baseTips.widget_tips);
        baseTips.verticalLayout_tips->addWidget(contentView);
        contentUi.setupUi(contentView);    // 给contentView设置contentUi界面
        if (resize) {
            resizeWindow();    // 自己根据需求考虑是否需要根据内部内容改变弹窗大小
        }
    }


protected:
    Ui::BaseTips baseTips;
    QWidget *contentView;   // dialog中的切换界面

这一下基本就完成了,只需用在子类中调用setupUi(子类的ui)即可,特殊情况下(如有固定的widget加载),可以重载一个,只需用直接加入指定的widget(代码中contentView)

    template<typename W>
    void setupUi(W* contentWidget, bool resize = true) {
        contentView = contentWidget;
        baseUi.content_layout->addWidget(contentView);
        if (resize) {
            resizeWindow();
        }
    }

同样的,如果要连续切换,但是一直创建对象很麻烦,也可以通过删除加载的子类ui,重新加载新的子类ui解决:这里举例是如何删除加载的ui的

void deleteUi() {
    if (contentView) {
        baseTips.verticalLayout_tips->removeWidget(contentView);
        delete contentView;
    }
}

至此,应该能完成大部分的工作,如有错误或纰漏请指出。

方法二:QStackedWidget

在Qt中有这么一个控件:StackedWidget,其作用是切换此容器内的界面,跟上一个方法类似,先创建一个主体框架,但是内部显示的控件换成StackedWidget,然后在其中将需要的界面全部加载进去,根据需求一个一个调出来就是了(个人不太推荐这种方法,因为这往往意味着同一个弹窗,他所占的内存远远大于第一种方法)

这里就不举例了(因为懒),官方的StackedWidget实在是不好用,不得不说一句我主管yyds自己写的框架!

emmm,暂时就这些吧,欢迎探讨交流!

  • 11
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值