Как прервать запущенный метод, при нажатии кнопки

Как прервать запущенный метод (в моем случае add_str_num), при нажатии кнопки Отмена(pushButton2).

я сделал с помощью stop, для него добавил метод click где он меняет свое значение на True и в методе добавил условие по которому метод прекращает работать. Не знаю почему оно не работает, как нужно сделать?

import design
import sys
import os
from PyQt5 import QtWidgets
from PyQt5.QtWidgets import QFileDialog

class Example(QtWidgets.QMainWindow, design.Ui_MainWindow):
    def __init__(self):
        super().__init__()
        self.setupUi(self)

        self.input_file = ''
        self.stop = False

        self.btn.clicked.connect(self.select_a_file)
        self.pushButton1.clicked.connect(self.add_str_num)
        self.pushButton2.clicked.connect(self.click)

    def select_a_file(self):
        self.file_input, _ = QFileDialog.getOpenFileName(self, 'Выбор файла', '')
        self.label.setText(self.file_input)

    def click(self):
        self.stop = True

    def add_str_num(self):

        self.step = 0
        num = 100000
        pace = 100 / num
        with open(self.file_input) as f:
            text = f.read()
            for i in range(num):
                text += str(i) + 'helloworld'
                self.step += pace
                self.progressBar.setValue(round(self.step))

                if self.stop:
                    self.stop = false
                    self.progressBar.setValue(0)
                    return

        with open(self.file_input, 'w') as p:
            p.write(text)
def main():
    app = QtWidgets.QApplication(sys.argv)
    window = Example()
    window.show()
    app.exec_()

if __name__ == '__main__':
    main()

вот design.py:

# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'C:/Users/PC/1/design.ui'
#
# Created by: PyQt5 UI code generator 5.14.2
#
# WARNING! All changes made in this file will be lost!


from PyQt5 import QtCore, QtGui, QtWidgets


class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(165, 148)
        MainWindow.setMinimumSize(QtCore.QSize(165, 148))
        MainWindow.setMaximumSize(QtCore.QSize(165, 148))
        MainWindow.setStyleSheet("background-color: rgb(0, 0, 0);\n"
"background-color: rgb(35, 75, 255);")
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.label = QtWidgets.QLabel(self.centralwidget)
        self.label.setGeometry(QtCore.QRect(60, 10, 91, 21))
        self.label.setStyleSheet("background-color: rgb(255, 255, 255);")
        self.label.setText("")
        self.label.setObjectName("label")
        self.btn = QtWidgets.QPushButton(self.centralwidget)
        self.btn.setGeometry(QtCore.QRect(10, 10, 41, 31))
        self.btn.setStyleSheet("background-color: rgb(255, 255, 255);")
        self.btn.setObjectName("btn")
        self.progressBar = QtWidgets.QProgressBar(self.centralwidget)
        self.progressBar.setGeometry(QtCore.QRect(60, 40, 101, 21))
        self.progressBar.setStyleSheet("color: rgb(255, 255, 255);")
        self.progressBar.setProperty("value", 0)
        self.progressBar.setObjectName("progressBar")
        self.pushButton2 = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton2.setGeometry(QtCore.QRect(60, 100, 91, 23))
        self.pushButton2.setStyleSheet("background-color: rgb(255, 255, 255);")
        self.pushButton2.setObjectName("pushButton2")
        self.pushButton1 = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton1.setGeometry(QtCore.QRect(60, 70, 91, 23))
        self.pushButton1.setStyleSheet("background-color: rgb(255, 255, 255);")
        self.pushButton1.setObjectName("pushButton1")
        MainWindow.setCentralWidget(self.centralwidget)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.btn.setText(_translate("MainWindow", "Select \n"
" a file"))
        self.pushButton2.setText(_translate("MainWindow", "Отмена"))
        self.pushButton1.setText(_translate("MainWindow", "Start"))

введите сюда описание изображения

как можно обойтись без многопоточности?


Ответы (1 шт):

Автор решения: S. Nick

Все можно сделать. Вам дали много советов, самый правильный освоит многопоточность! По использованию многопоточности опубликовано много постов, поэтому надо не бояться, а читать и пробовать!

Но если вам так хочется без многопоточности, тогда QTimer вам в помощь. Я также добавил некоторые правильный вещи. Пробуйте.

import sys
import os
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QFileDialog


#from design import Ui_MainWindow
class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(165, 148)
        MainWindow.setMinimumSize(QtCore.QSize(165, 148))
        MainWindow.setMaximumSize(QtCore.QSize(165, 148))
        MainWindow.setStyleSheet("background-color: rgb(0, 0, 0);\n"
"background-color: rgb(35, 75, 255);")
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.label = QtWidgets.QLabel(self.centralwidget)
        self.label.setGeometry(QtCore.QRect(60, 10, 91, 21))
        self.label.setStyleSheet("background-color: rgb(255, 255, 255);")
        self.label.setText("")
        self.label.setObjectName("label")
        self.btn = QtWidgets.QPushButton(self.centralwidget)
        self.btn.setGeometry(QtCore.QRect(10, 10, 41, 31))
        self.btn.setStyleSheet("background-color: rgb(255, 255, 255);")
        self.btn.setObjectName("btn")
        self.progressBar = QtWidgets.QProgressBar(self.centralwidget)
        self.progressBar.setGeometry(QtCore.QRect(60, 40, 101, 21))
        self.progressBar.setStyleSheet("color: rgb(255, 255, 255);")
        self.progressBar.setProperty("value", 0)
        self.progressBar.setObjectName("progressBar")
        self.pushButton2 = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton2.setGeometry(QtCore.QRect(60, 100, 91, 23))
        self.pushButton2.setStyleSheet("background-color: rgb(255, 255, 255);")
        self.pushButton2.setObjectName("pushButton2")
        self.pushButton1 = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton1.setGeometry(QtCore.QRect(60, 70, 91, 23))
        self.pushButton1.setStyleSheet("background-color: rgb(255, 255, 255);")
        self.pushButton1.setObjectName("pushButton1")
        MainWindow.setCentralWidget(self.centralwidget)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.btn.setText(_translate("MainWindow", "Select \n"
" a file"))
        self.pushButton2.setText(_translate("MainWindow", "Отмена"))
        self.pushButton1.setText(_translate("MainWindow", "Start"))


class Example(QtWidgets.QMainWindow, Ui_MainWindow):
    def __init__(self):
        super().__init__()
        self.setupUi(self)

        self.input_file = ''
        self.stop = False

        self.btn.clicked.connect(self.select_a_file)
        self.pushButton1.clicked.connect(self.add_str_num)
        self.pushButton2.clicked.connect(self.stop_click)

        self.file_input = None                                              # +++
        self.text = ''                                                      # +++
        self.timer = QtCore.QTimer(self)                                    # QTimer
        self.timer.setInterval(5)                                           # QTimer setInterval
        self.timer.timeout.connect(self._timeout)                           # QTimer self._timeout

    def select_a_file(self):
        self.file_input, _ = QFileDialog.getOpenFileName(self, 'Выбор файла', '')
        self.label.setText(self.file_input)

    def stop_click(self):
        if not self.timer.isActive():                                       # QTimer isActive
            msg = QtWidgets.QMessageBox.information(None, 'Message', 'Расчет не был запущен, отменять нечего.')
            return
        self.timer.stop()                                                   # QTimer stop
        self.progressBar.setValue(0)
        with open(self.file_input, 'w') as p:
            p.write(self.text)

    def add_str_num(self):
        if not self.file_input:
            msg = QtWidgets.QMessageBox.information(None, 'Message', 'Выберите файл для чтения.')
            return
        with open(self.file_input) as f:
            self.text = f.read()
        self.step = 0
        self.num = 10000 #0
        self.pace = 100 / self.num
        self.i = 0
        self.timer.start()                                                   # QTimer start

    def _timeout(self):                                                      # +++ !!!
        if self.i < self.num:
            self.text += str(self.i) + ' helloworld\n'                       # + \n
            self.step += self.pace
            self.i += 1
            self.progressBar.setValue(round(self.step))
        else:
            self.stop_click()


def main():
    app = QtWidgets.QApplication(sys.argv)
    window = Example()
    window.show()
    app.exec_()

if __name__ == '__main__':
    main()   

введите сюда описание изображения

→ Ссылка