• 8.QT-对话框(模态与非模态)


    对话框介绍

    • 对话框是于用户进行简易交互的顶层窗口
    • QDialog是Qt中所有对话框窗口的父类,是一种容器类型的组件
    • QDialog继承于QWidget类,如下图所示:

     

     

     

     

    QWidget和QDialog有什么不同

    QDialog:

    • QDialog是定制了窗口式样的特殊的QWidget
    • QDialog只能作为专用的交互窗口
    • QDialog不能作为子部件,嵌入其它容器中

    QWidget:

    • QWidget如果没有父组件,则将会成为一个主窗口,
    • QWidget如果有父组件,则将成为其父组件的子部件,嵌入到其父组件里

     

    代码试验: QWidget和QDialog区别

    代码1:

    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
    
        QWidget w;
        w.resize(300,300);
    
        QDialog d(&w);
        d.resize(150,150);
    
        w.show();
        d.show();
    
        return a.exec();
    }

    效果:

     

    可以看到,对话框始终都是作为独立的交互窗口

    代码2:

    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
    
        QWidget w1;
        w1.resize(300,300);
    
        QWidget w2(&w1);
        w2.resize(150,150);
    
        w1.show();
        w2.show();
    
        return a.exec();
    }

    效果:

     

    可以看到只出现了一个窗口,并没有出现第二个窗口

     

    对话框类型

    模态对话框

    • 属于阻塞式调用,指没有关闭该对话框之前,是无法与其它任何窗口进行交互的
    • 用于依赖用户选择的场合,比如:选项设置,消息提示,字体设置等
    • 在栈上创建模态对话框是最简单常用的方式
    • 使用exec()进入对话框的消息循环,从而实现阻塞式调用

    实验代码:

    int main(int argc, char *argv[])
    {
    
        QApplication a(argc, argv);
    
        QWidget w;
        w.resize(300,300);
    w.show(); QDialog d(
    &w); d.resize(150,150); d.exec(); //进入对话框d的消息循环,从而实现阻塞式调用 return a.exec(); }

    非模态对话框  

    • 属于非阻塞调用,指出现该对话框时,也可以与父窗口进行交互
    • 用于特殊功能设置的场合,比如:查找操作
    • 一般情况下非模态对话框需要在堆上创建,避免自动被摧毁
    • 非模态对话框需要通过setAttribute()成员函数指定Qt::WA_DeleteOnClose属性
    • Qt::WA_DeleteOnClose表示:退出窗口后,让Qt自动摧毁这个对话框
    • 使用show()来显示对话框窗口,从而实现非阻塞调用

    实验代码:

    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
    
        QWidget w;
        w.resize(300,300);
        w.show();
    
        QDialog  *d = new QDialog(&w);
    
        d->setAttribute(Qt::WA_DeleteOnClose);
        d->resize(150,150);
        d->show();                
    
        return a.exec();
    }

    混合模态对话框

    • 在非模态对话框的基础上调用QDialog::setModal(true)成员函数实现

    实验代码:

    int main(int argc, char *argv[])
    {
    
        QApplication a(argc, argv);
    
        QWidget w;
        w.resize(300,300);
        w.show();
    
        QDialog  *d = new QDialog(&w);
        d->setAttribute(Qt::WA_DeleteOnClose);
        d->setModal(true);               
        d->resize(150,150);
        d->show();
    
        return a.exec();
    }

    对话框返回值处理

    • 只有模态对话框才有返回值概念
    • QDialog::exec()的返回值作为交互结果

      -使用void QDialog::done ( int r ) 作为交互结果,将r值返回给exec()

      -返回值为QDialog::Accepted时,表示用户操作成功

      -返回值为QDialog::Rejected时,表示用户操作失败

      -也可以自定义返回数值

    非模态示例-制作查找对话框

    由于查找对话框每次打开时,都会有上次状态的内容,所以需要用到QSharedPointer动态指针

    QFindDialog对话框:

    class QFindDialog : public QDialog
    {
    private:
        QLabel label;
        QLineEdit edit;
        QPushButton ButtonFind;
        QPushButton ButtonCancel;
        QCheckBox   CkBoxCase;
        QGroupBox   GrpBoxDir;
        QRadioButton PreButton;
        QRadioButton NextButton;
        QGridLayout  GLayout;
        QHBoxLayout  HBLayout;
    public:
        QFindDialog(QWidget* parent=0);
    };
    
    
    QFindDialog::QFindDialog(QWidget *parent) :
        QDialog(parent,Qt::WindowCloseButtonHint|Qt::Drawer),
        label("查找内容:",this),
        edit(this),
        ButtonFind("查找下一个",this),
        ButtonCancel("取消",this),
        CkBoxCase("区分大小写",this),
        GrpBoxDir("方向",this),
        PreButton("向上",this),
        NextButton("向下",this),
        GLayout(this),
        HBLayout(this)
    {
        PreButton.setChecked(true);
        HBLayout.addWidget(&PreButton);
        HBLayout.addWidget(&NextButton);
        GrpBoxDir.setLayout(&HBLayout);       //将单选按钮添加到QGroupBox分组框
        GLayout.setSpacing(5);
        GLayout.addWidget(&label,0,0);
        GLayout.addWidget(&edit,0,1);
        GLayout.addWidget(&ButtonFind,0,2);
        GLayout.addWidget(&CkBoxCase,1,0);
        GLayout.addWidget(&GrpBoxDir,1,1);
        GLayout.addWidget(&ButtonCancel,1,2);
        this->setLayout(&GLayout);
      
        setWindowTitle("查找");
    }

    widget窗口文件:

    class Widget : public QWidget
    {
        Q_OBJECT
    private :
        QPushButton btn;
        QSharedPointer<QFindDialog> FindDialog;   //动态指针
    private slots:
        void onclickedbtn();
    public:
        explicit Widget();
    };
    
    Widget::Widget():
        btn("查找",this),
        FindDialog(new QFindDialog(this))
    {
         connect(&btn,SIGNAL(clicked()),this,SLOT(onclickedbtn()));
        
    }
    void Widget::onclickedbtn() { FindDialog->show(); //显示查找对话框 }
    效果:





    
    
  • 相关阅读:
    Docker入门(windows版),利用Docker创建一个Hello World的web项目
    SpringBoot集成JWT实现token验证
    Jedis的基本操作
    Java动态代理详解
    SpringBoot利用自定义注解实现通用的JWT校验方案
    递归——汉诺塔问题(python实现)
    Datatable删除行的Delete和Remove方法的区别
    C# DEV使用心得
    总结
    安装插件时
  • 原文地址:https://www.cnblogs.com/lifexy/p/8922050.html
Copyright © 2020-2023  润新知