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
    评论
Android弹窗dialog可以通过使用PopupWindow和Dialog来实现。PopupWindow是一个在屏幕上方显示的浮动控件,而Dialog是一个模态对话框。对于PopupWindow的使用,可以通过创建一个布局文件,然后在代码中使用PopupWindow类来显示该布局。而对于Dialog使用,可以通过创建一个AlertDialog.Builder对象,设置对话框的标题、内容和按钮等属性,最后调用show()方法显示对话框。 下面是一个使用PopupWindow的示例代码: ```java // 创建PopupWindow对象 PopupWindow popupWindow = new PopupWindow(context); // 设置要显示的布局 View view = LayoutInflater.from(context).inflate(R.layout.popup_layout, null); popupWindow.setContentView(view); // 设置PopupWindow的宽度和高度 popupWindow.setWidth(ViewGroup.LayoutParams.WRAP_CONTENT); popupWindow.setHeight(ViewGroup.LayoutParams.WRAP_CONTENT); // 设置PopupWindow的背景 popupWindow.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT)); // 设置PopupWindow是否可点击 popupWindow.setTouchable(true); // 设置PopupWindow是否获取焦点 popupWindow.setFocusable(true); // 设置PopupWindow的位置 popupWindow.showAtLocation(anchorView, Gravity.CENTER, 0, 0); ``` 下面是一个使用Dialog的示例代码: ```java // 创建AlertDialog.Builder对象 AlertDialog.Builder builder = new AlertDialog.Builder(context); // 设置对话框的标题 builder.setTitle("提示"); // 设置对话框的内容 builder.setMessage("这是一个对话框"); // 设置对话框的按钮 builder.setPositiveButton("确定", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { // 点击确定按钮的逻辑处理 } }); builder.setNegativeButton("取消", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { // 点击取消按钮的逻辑处理 } }); // 创建并显示对话框 AlertDialog dialog = builder.create(); dialog.show(); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值