zoukankan      html  css  js  c++  java
  • 想让一个Widget成为模态,我们只需要对其设置setAttribute(Qt::WA_ShowModal, true);

    想让一个Widget成为模态,我们只需要对其设置:

    setAttribute(Qt::WA_ShowModal, true);

    注意:这是QWidget的成员函数 ,也就是说,QWidget可以显示为模态或非模态!

    setWindowModality

    除了直接调用setAttribute外,QWidget 提供了一个易用的函数,来设置窗体的模态。其源码如下:

    void QWidget::setWindowModality(Qt::WindowModality windowModality)
    {
        data->window_modality = windowModality;
        // setModal_sys() will be called by setAttribute()
        setAttribute(Qt::WA_ShowModal, (data->window_modality != Qt::NonModal));
        setAttribute(Qt::WA_SetWindowModality, true);
    }

    注意:该函数的参数取值:NonModal、WindowModal、ApplicationModal 分别对应默认情况下的

    • QDialog::show()
    • QDialog::open()
    • QDialog::exec()

    如果你没有使用QDialog::open()的需求,你可能也不需要该函数。

    setModal

    除了QWidget提供的成员,QDialog 提供了 setModal 的成员函数,我们看看其代码:

    void QDialog::setModal(bool modal)
    {
        setAttribute(Qt::WA_ShowModal, modal);
    }

    不用解释了吧?我们要显示模态对话框,只需要类似下面的代码:

    QDialog * dlg = new QDialog();
    dlg->setAttribute(Qt::WA_ShowModal, true);
    dlg->show();

    exec()

    有问题是不?为啥exec() 直接可以显示模态对话框呢?看QDialog源代码吧

    int QDialog::exec()
    {
        Q_D(QDialog);
    ...
        setAttribute(Qt::WA_ShowModal, true);
    ...
        show();
    ...
        QEventLoop eventLoop;
        (void) eventLoop.exec(QEventLoop::DialogExec);
    ...
    }

    看到答案没:exec() 先设置modal属性,而后调用 show() 显示对话框,最后启用事件循环

    事件循环

    Qt 程序时事件驱动的,每个程序,我们需要调用 QApplication::exec() 来启用事件循环。

    int QCoreApplication::exec()
    {
    ...
        QEventLoop eventLoop;
        int returnCode = eventLoop.exec();
    ...
        return returnCode;
    }

    用前面的 QDialog::exec() 一样,都是调用的 QEventLoop::exec()

    int QEventLoop::exec(ProcessEventsFlags flags)
    {
        Q_D(QEventLoop);
    ...
        while (!d->exit)
            processEvents(flags | WaitForMoreEvents | EventLoopExec);
    ...
        return d->returnCode;
    }

    bool QEventLoop::processEvents(ProcessEventsFlags flags)
    {
        Q_D(QEventLoop);
        if (!d->threadData->eventDispatcher)
            return false;
        if (flags & DeferredDeletion)
            QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete);
        return d->threadData->eventDispatcher->processEvents(flags);
    }

    进一步:这将调用平台相关的函数,比如在windows下

    bool QGuiEventDispatcherWin32::processEvents(QEventLoop::ProcessEventsFlags flags)
    {
        if (!QEventDispatcherWin32::processEvents(flags))
            return false;
        if (configRequests)                        // any pending configs?
            qWinProcessConfigRequests();
        return true;
    }

    事件循环和线程没有必然的联系,事件循环可以用在QThread中,而且从Qt4.4开始,QThread的run函数默认就调用了自己的事件循环。

    对与QDialog来说,当它自己的QEventLoop启用时,主程序的 QEventLoop 当然是处于暂停状态了。说到底,就是两个死循环,一个在内,一个在外,只有里面的退出后,外边的循环才会执行。不过由于两个循环执行的命令是基本一样的,都是调用并处理程序收到的各种事件,所以,可能变得不容易理解

    http://doc.qt.io/qt-4.8/qwidget.html

  • 相关阅读:
    form表单提交target属性使用
    window.showModalDialog
    mybaits中date类型显示时分秒(orcle数据库)
    mybatis中in查询
    偷懒的inline-block解决方法
    10. python单元测试(一)
    9. Request & 爬虫
    8. 类与对象
    7. python异常处理&异常基类学习
    6. IO及文件操作
  • 原文地址:https://www.cnblogs.com/findumars/p/6696912.html
Copyright © 2011-2022 走看看