Pavel Pereverzev
Pavel Pereverzev

Reputation: 499

Completely stop running pyqt5 application

I want my pyqt app stop whenever I press "cancel" button. For instance this app should be looping features from two tables. I can set a trigger that will always will check it's condition (true/false) depending on pressing the "cancel" button. But is there any way to set the global trigger which will stop application process in any position of code?

import time
import sys
from PyQt5 import QtCore, QtWidgets, QtGui
from PyQt5.QtWidgets import (QApplication, QWidget, QToolTip, QPushButton, QMessageBox, QTreeWidget, QTreeWidgetItem, QProgressBar, QLabel)

class Pio(QWidget):
    def __init__(self):
        super().__init__()

        self.initUI()
    def initUI(self):

        self.launch = False

        self.pbar = QProgressBar(self)
        self.pbar.setGeometry(20,20,400,50)

        self.okButton = QPushButton(self)
        self.okButton.setGeometry(80, 20, 100, 50)
        self.okButton.move(20, 80)
        self.okButton.setText('launch')

        self.cncl = QPushButton(self)
        self.cncl.setGeometry(300, 20, 100, 50)
        self.cncl.move(320, 80)
        self.cncl.setText('cancel')

        self.okButton.clicked.connect(self.start_loop)
        self.cncl.clicked.connect(self.break_loop)
        self.show()

    def start_loop(self):
        if not self.launch:
            self.launch = True
            print ('started!')
            self.loop_numbers()


    def break_loop(self): 
        print ('canceled!')
        if self.launch:
            print ('work in progress....')
            self.launch = False


    def loop_numbers(self):
        print ('running')

        'action #1 that takes a lot of time '
        'action #2 that also takes a lot of time'

        for n in range(101):
            if self.launch:
                self.pbar.setValue(n)
                time.sleep(0.01)
                QtCore.QCoreApplication.processEvents()

        for n in range(11):
            if self.launch:
                self.pbar.setValue(n*10)
                time.sleep(0.05)
                QtCore.QCoreApplication.processEvents()

if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = Pio()
    sys.exit(app.exec_())

If I move self.launch to the beginning of loop_numbers() and once loop is started it will be running whe whole process.

Upvotes: 0

Views: 1275

Answers (1)

Isma
Isma

Reputation: 15180

The application will close automatically when the last window is closed so you can try by changing QWidget for QMainWindow and simply call close from your cancel button.

import sys
import time

from PyQt5 import QtCore
from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton, QProgressBar


class Pio(QMainWindow):
    def __init__(self):
        super().__init__()

        self.initUI()

    def initUI(self):

        self.launch = False

        self.pbar = QProgressBar(self)
        self.pbar.setGeometry(20, 20, 400, 50)

        self.okButton = QPushButton(self)
        self.okButton.setGeometry(80, 20, 100, 50)
        self.okButton.move(20, 80)
        self.okButton.setText('launch')

        self.cncl = QPushButton(self)
        self.cncl.setGeometry(300, 20, 100, 50)
        self.cncl.move(320, 80)
        self.cncl.setText('cancel')

        self.okButton.clicked.connect(self.start_loop)
        self.cncl.clicked.connect(self.break_loop)

    def start_loop(self):
        if not self.launch:
            self.launch = True
            print('started!')
            self.loop_numbers()

    def break_loop(self):
        print('canceled!')
        if self.launch:
            print('work in progress....')
            self.launch = False

        # Close window and exit application
        self.close()

    def loop_numbers(self):
        print('running')
        'action #1 that takes a lot of time '
        'action #2 that also takes a lot of time'

        for n in range(101):
            if self.launch:
                self.pbar.setValue(n)
                time.sleep(0.01)
                QtCore.QCoreApplication.processEvents()

        for n in range(11):
            if self.launch:
                self.pbar.setValue(n * 10)
                time.sleep(0.05)
                QtCore.QCoreApplication.processEvents()


if __name__ == '__main__':
    app = QApplication(sys.argv)
    mainWindow = Pio()
    mainWindow.show()
    sys.exit(app.exec_())

Upvotes: 1

Related Questions