Stopping Processes on Application Close



  • Hi

    Not sure if the following has been answered before, couldn't find much help anywhere.
    If an application has a process running, how can it be forced to stop. I.e. even with a boolean flag, when the user clicks the x close button on the MainWindow.

    I.E.
    Example below:

    bool IsRunning;

    void MainWindow::TestProcess()
    {
    IsRunning = true;
    while (IsRunning)
    {
    qApp->processEvents();
    }
    }

    the above is not the actual code writen, but shows the problem I have, I have a timeout that would stop the process, but this only happens will the application is running. The process is locked if the application is closed by the user via the x close window button.

    Writing in QT Creator 5.3 on Ubuntu 14.04.

    Thanks
    Cryterion



  • Here's a better example : -

    mainwindow.h

    @#ifndef MAINWINDOW_H
    #define MAINWINDOW_H

    #include <QMainWindow>
    #include <QTimer>

    namespace Ui {
    class MainWindow;
    }

    class MainWindow : public QMainWindow
    {
    Q_OBJECT

    public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
    void Init();

    private slots:
    void Timer1Timedout();

    private:
    Ui::MainWindow *ui;
    bool LockedState;
    QTimer *Timer1;

    };

    #endif // MAINWINDOW_H
    @

    Main.cpp

    @#include "mainwindow.h"
    #include <QApplication>

    int main(int argc, char *argv[])
    {
    QApplication a(argc, argv);
    MainWindow w;
    w.show();
    w.Init();

    return a.exec&#40;&#41;;
    

    }
    @

    mainwindow.cpp

    @#include "mainwindow.h"
    #include "ui_mainwindow.h"

    MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
    {
    ui->setupUi(this);
    }

    MainWindow::~MainWindow()
    {
    delete Timer1;
    delete ui;
    }

    void MainWindow::Timer1Timedout()
    {
    LockedState = false;
    }

    void MainWindow::Init()
    {
    Timer1 = new QTimer(this);
    connect(Timer1, SIGNAL(timeout()), this, SLOT(Timer1Timedout()));
    Timer1->setInterval(10000);
    Timer1->start();
    ui->label->setText("App is in Locked State to exit by User");
    LockedState = true;
    while (LockedState)
    qApp->processEvents();
    ui->label->setText("App is in Unlocked State to exit by User");
    }
    @


  • Lifetime Qt Champion

    Hi and welcome to devnet,

    If I may, you should avoid this kind of logic in your GUI application. Can you tell us what you would like to achieve ? So we can help start on the right foot



  • Hi

    I'm doing an app thhat requires other hardware to be availablebto it, undrr normal conditions, this will be no problem, however, my point is that I can find a way to stop the process (if running) on a user closing the app via the 'x' button. To me, it's common problem on linux and windows.



  • It sounds like you're asking for a way to know when the application is about to quit so that some sort of cleanup can occur. Whether that cleanup is resetting a piece of hardware, signaling an external process, or something else is an application-specific detail.

    "QCoreApplication::aboutToQuit()":http://qt-project.org/doc/qt-5/qcoreapplication.html#aboutToQuit sounds like what you want.



  • Exactly, i have timers and qextserial port that remain running, and transmitting, after the application closes


  • Lifetime Qt Champion

    Can you share the code of the thread using the serial port and timer ?



  • For some reason, couldn't get QextSerialPort running in a new app, but here's the snippet of code used, the app waits 10secs for a response, if no response, it moves on. My point being that if user closes the app during the 10 sec delay, the timer and serial port remain running, with the data packet being sent out on each cycle.Closing via a push button gets into a routine that a full cleanup can be done, but the 'x' OS close button does not call any function that I can find.

    mainwindow.h

    @
    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H

    #include <QMainWindow>
    #include "Qextserialport/qextserialport.h"
    #include "qtimer.h"
    //#include "qdesktopwidget.h"

    namespace Ui {
    class MainWindow;
    }

    class MainWindow : public QMainWindow
    {
    Q_OBJECT

    public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
    void InitSystem();

    private:
    Ui::MainWindow *ui;
    QTimer *CommsTimer;
    QextSerialPort *PLCSerialPort;
    QTimer *DelayTimer;

    unsigned int MSDelayTime;
    bool GotRxCommand;
    bool GotRxDataSize;
    bool PLCIsOnline;
    unsigned char RXInPtr;
    unsigned char RXOutPtr;
    
    bool StartSerialComms();
    bool WaitForPLCOnline();
    void DelayMilliSeconds(unsigned int MS);
    void ResetRxData();
    

    };

    #endif // MAINWINDOW_H
    @

    main.cpp

    @
    #include "mainwindow.h"
    #include <QApplication>

    int main(int argc, char *argv[])
    {
    QApplication a(argc, argv);
    MainWindow w;
    w.show();
    w.InitSystem();

    return a.exec&#40;&#41;;
    

    }
    @

    mainwindow.cpp

    @
    #include "mainwindow.h"
    #include "ui_mainwindow.h"

    MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
    {
    ui->setupUi(this);
    }

    MainWindow::~MainWindow()
    {
    delete ui;
    }

    void MainWindow::InitSystem()
    {
    DelayTimer = new QTimer(this);
    connect(DelayTimer, SIGNAL(timeout()), this, SLOT(DelayTimerTimeout()));
    DelayTimer->setInterval(10);
    DelayTimer->start();

    PLCSerialPort = 0;
    CommsTimer = 0;
    if (!StartSerialComms())
    {
        ui->InitSystemTextBox->insertPlainText("Serial Comms Failed to Open!!!\r\n");
    }
    ui->InitSystemTextBox->insertPlainText("Contacting PLC...\r\n");
    if (!WaitForPLCOnline())
    {
        ui->InitSystemTextBox->insertPlainText("PLC Failed to Respond!!!\r\n");
        ui->InitSystemTextBox->insertPlainText("Still Trying, Please check Communications Link!!!\r\n");
    }
    

    }

    bool MainWindow::WaitForPLCOnline()
    {
    unsigned char Count;

    Count = 0;
    PLCIsOnline = false;
    while ((!PLCIsOnline) && (Count < 10))
    {
        DelayMilliSeconds(1000);
        Count++;
    }
    return PLCIsOnline;
    

    }

    void MainWindow::DelayMilliSeconds(unsigned int MS)
    {
    MS /= 10;
    MSDelayTime = MS;
    while (MSDelayTime)
    {
    qApp->processEvents();
    }
    }

    bool MainWindow::StartSerialComms()
    {
    bool Result;

    Result = false;
    if (!PLCSerialPort)
    {
        PLCSerialPort = new QextSerialPort(QLatin1String("/dev/ttyUSB0"), QextSerialPort::EventDriven);
        connect(PLCSerialPort, SIGNAL(readyRead()), this, SLOT(onDataAvailable()));
    }
    if (!CommsTimer)
    {
        CommsTimer = new QTimer(this);
        connect(CommsTimer, SIGNAL(timeout()), this, SLOT(CommsOutTime()));
        CommsTimer->setInterval(250);
    }
    RXInPtr = 0;
    RXOutPtr = 0;
    ResetRxData();
    PLCIsOnline = false;
    PLCSerialPort->setBaudRate(BAUD9600);
    PLCSerialPort->setDataBits(DATA_8);
    PLCSerialPort->setFlowControl(FLOW_OFF);
    PLCSerialPort->setStopBits(STOP_1);
    PLCSerialPort->setParity(PAR_NONE);
    PLCSerialPort->setTimeout(3000);
    if (PLCSerialPort->open(QIODevice::ReadWrite))
    {
        CommsTimer->start();
        Result = true;
    }
    return Result;
    

    }

    void MainWindow::ResetRxData()
    {
    GotRxCommand = false;
    GotRxDataSize = false;
    }
    @


  • Lifetime Qt Champion

    It really looks like an overly complicated way to do this initialization. And is it really working ?

    @
    void MainWindow::DelayMilliSeconds(unsigned int MS)
    {
    MS /= 10;
    MSDelayTime = MS;
    while (MSDelayTime) << when should that stop ?
    {
    qApp->processEvents();
    }
    }@

    You should consider using a little state machine


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.