Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

How to write a closing prompt?



  • It takes a long time to close the program.How to write a closing prompt?


  • Qt Champions 2019

    Can you please be a little bit more precise about your problem? Don't understand what you really want. If you want to show an Image during exit you can take a look at QSplashScreen or simply show a QLabel.



  • @Christian-Ehrlicher said in How to write a closing prompt?:

    QSplashScreen

    I wrote a program in Qt.It take a little long time during it exits.I want to display a widget with prompts in closeEvent.But it can't.


  • Lifetime Qt Champion

    @Source

    Can you show your code?



  • @aha_1980
    waitwidget.h

    #pragma once

    #include <QWidget.h>

    class WaitWidgetData;
    class WaitWidget : public QWidget
    {
    Q_OBJECT
    public:
    explicit WaitWidget(QWidget *parent = nullptr);
    virtual ~WaitWidget();

    protected:
    void showEvent(QShowEvent *event);

    private:
    WaitWidgetData *d;
    };

    waitwidget.cpp

    #include "waitwidget.h"
    #include "circlewait.h"

    #include <QThread>
    #include <QWaitCondition>

    #include <QVBoxLayout>
    #include <QLabel>

    class WaitWidgetData
    {
    public:
    WaitWidgetData() :
    circleWait(nullptr),
    thread(this)
    {
    }

    CircleWait *circleWait;
    
    class WaitThread : public QThread
    {
    public:
        WaitThread(WaitWidgetData *data) :
            QThread(),
            d(data),
            quit(false)
        {}
        ~WaitThread()
        {
            stopThread();
        }
    
        void startThread()
        {
            QMutexLocker locker(&mutex);
            quit = false;
            if (!isRunning())
                start();
            else
                cond.wakeOne();
        }
        void stopThread()
        {
            mutex.lock();
            quit = true;
            cond.wakeOne();
            mutex.unlock();
            wait();
        }
    
        void run();
    
    protected:
        QMutex mutex;
        QWaitCondition cond;
        bool quit;
    
        WaitWidgetData *d;
    };
    
    WaitThread thread;
    
    friend class WaitThread;
    

    };

    WaitWidget::WaitWidget(QWidget *parent) :
    QWidget(parent),
    d(new WaitWidgetData)
    {
    setWindowFlags(Qt::FramelessWindowHint);
    setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint);
    setAttribute(Qt::WA_NoSystemBackground, false);
    setAttribute(Qt::WA_TranslucentBackground, true);

    QHBoxLayout *layout = new QHBoxLayout;
    layout->setMargin(0);
    layout->setSpacing(0);
    layout->addStretch();
    d->circleWait = new CircleWait(this);
    d->circleWait->setColor(QColor(46, 194, 163));
    d->circleWait->setClockwise(false);
    layout->addWidget(d->circleWait);
    QLabel *labelWait = new QLabel(tr("The program is shutting down, please wait..."), this);
    QFont font = labelWait->font();
    font.setBold(true);
    font.setPointSize(20);
    labelWait->setFont(font);
    layout->addWidget(labelWait);
    layout->addStretch();
    
    QVBoxLayout *mainLayout = new QVBoxLayout(this);
    mainLayout->setContentsMargins(10, 5, 10, 5);
    mainLayout->setSpacing(0);
    mainLayout->addStretch();
    mainLayout->addLayout(layout);
    mainLayout->addStretch();
    

    }
    WaitWidget::~WaitWidget()
    {
    delete d;
    d = nullptr;
    }

    void WaitWidget::showEvent(QShowEvent *event)
    {
    QWidget::showEvent(event);

    d->thread.startThread();
    

    }

    //---------------------------------------------------------------------
    void WaitWidgetData::WaitThread::run()
    {
    while (!quit)
    {
    d->circleWait->update();

        QThread::msleep(500);
    }
    

    }

    closeEvent

    void MainWindow::closeEvent(QCloseEvent *event)
    {
    QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));

    WaitWidget *waitWidget = new WaitWidget;
    waitWidget->show();
    
    ModuleManager::removeAll();
    
    QApplication::restoreOverrideCursor();
    
    waitWidget->close();
    waitWidget->deleteLater();
    
    event->accept();
    

    }


  • Qt Champions 2019

    @Source said in How to write a closing prompt?:

    d->circleWait = new CircleWait(this);
    ...
    void WaitWidgetData::WaitThread::run()
    {
    d->circleWait->update();

    You're updating a Widget from within a thread which is not the main gui thread - this will create problems sooner or later. See QThread documentation on how to pass data between threads.
    And since your thread only calls update() which does not more than creating an update event (and therefore the repainting is delayed) the thread is useless.



  • @Christian-Ehrlicher
    The thread is not the issue.The issue is how I can display the WaitWidget on top of the MainWindow. I write:
    setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint);
    But is doesn't work.


  • Qt Champions 2019

    You have a thread issue for sure.
    Regarding the widget not showing up - there is not eventloop inbetween the creation and (defered) deletion of WaitWidget - so Qt is unable to process the events and can't show anything.



  • @Christian-Ehrlicher
    Can you show me an example? Thank you very much!


Log in to reply