@satioidou2se

Как остановить выполнение процесса в PyQt5?

Итак, есть некоторый код.
main.py
import sys
import os

from PyQt5.QtCore import Qt
from PyQt5 import QtWidgets
from PyQt5.QtWidgets import QFileDialog, QMessageBox
import form

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

		self.input_path = ''
		self.output_path = ''

		self.btn_1.clicked.connect(self.launch_clicked)
		self.btn_2.clicked.connect(self.launch_clicked)
		self.btn_3.clicked.connect(self.choice_clicked)
		self.btn_4.clicked.connect(self.choice_clicked)
		# self.btn_5.clicked.connect(self.stop)  кнопка отмены
		self.lineEdit.textChanged.connect(self.nullify_progress)
		self.lineEdit_2.textChanged.connect(self.nullify_progress)

	def input_file_selection(self):
		self.input_path, _ = QFileDialog.getOpenFileName(self, 'Выберите файл', '')
		# file_name = os.path.basename(self.input_path)
		self.lineEdit.setText(self.input_path)

	def output_file_selection(self):
		self.output_path, _ = QFileDialog.getOpenFileName(self, 'Выберите файл', '')
		# file_name = os.path.basename(self.output_path)
		self.lineEdit_2.setText(self.output_path)

	def progress(self):
		self.step += self.move
		self.progressBar.setValue(round(self.step))

	def message_box(self, text):
		msg = QMessageBox()
		msg.setWindowTitle('Error!')
		msg.setText(text)
		msg.setIcon(QMessageBox.Information)
		msg.exec_()

	def nullify_progress(self):
		self.progressBar.setValue(0)

	def choice_clicked(self):
		sender = self.sender()
		self.progressBar.setValue(0)
		if (sender.text() == "Выбрать \n"" исходный \n"" файл"):
			self.input_file_selection()
		else:
			self.output_file_selection()

	def launch_clicked(self):
		sender = self.sender()
		if self.lineEdit.text() == '':
			self.message_box('Нет исходного файла.\nЗаполните пустые поля')
		elif self.lineEdit_2.text() == '':
			self.message_box('Нет результирующего файла.\nЗаполните пустые поля')
		elif (not os.path.isfile(self.lineEdit.text())):
			self.message_box('Неправильный путь исходного файла \nили такого файла не существует.')
		elif (not os.path.isfile(self.lineEdit_2.text())):
			self.message_box('Неправильный путь результирующего файла \nили такого файла не существует')
		else:
			if (sender.text() == "Добавить\n" " в архив"):
				self.pack()			
			else:
				self.unpack()

	def pack(self):
		
		self.step = 0
		with open(self.lineEdit.text(), 'rb') as f:
			byte_arr = f.read()

		res = bytearray()
		count = 1

		
		self.move = (50 / (len(byte_arr) - 1))

		if len(byte_arr) == 0:
			return(res)

		for i in range(len(byte_arr) - 1):
			if byte_arr[i] == byte_arr[i + 1]:
				count += 1

			if byte_arr[i] != byte_arr[i + 1]:
				res.append(count)
				res.append(byte_arr[i])
				count = 1

			if count == 256:
				res.append(255)
				res.append(byte_arr[i])
				count = 1

			self.progress()

		res.append(count)
		res.append(byte_arr[-1])
		count = 0
		count_2 = 0
		res_2 = bytearray()
		flag = True
		self.move = 50 / (len(res)/2)
		for i in range(0, len(res), 2):
			if res[i] == 1:
				count += 1
				if flag:
					count_2 = i + 1
					flag = False
					res_2.append(0)
				if count == 255:
					res_2.append(255)
					for i in range(count):
						res_2.append(res[count_2])
						count_2 += 2
					flag = True
					count = 0
			if res[i] != 1:
				if flag == False:
					res_2.append(count)
					for j in range(count):
						res_2.append(res[count_2])
						count_2 += 2
					flag = True
					count = 0
					res_2.append(res[i])
					res_2.append(res[i + 1])
					count_2 += 2
				else:
					res_2.append(res[i])
					res_2.append(res[i + 1])
					count_2 += 2
			if i == len(res) - 2 and flag == False:
				res_2.append(count)
				for i in range(count):
					res_2.append(res[count_2])
					count_2 += 2

			self.progress()


		with open(self.lineEdit_2.text(), 'wb') as p:
			p.write(res_2)

	def unpack(self):

		self.step = 0
		with open(self.lineEdit.text(), 'rb') as f:
			byte_arr = f.read()
		res = bytearray()
		i = 0
		self.move = 100 / len(byte_arr)
		try:
			while i != len(byte_arr):
				if byte_arr[i] == 0:
					i += 1
					self.progress()
					for j in range(byte_arr[i]):
						i += 1
						res.append(byte_arr[i])
						self.progress()
					i += 1
					self.progress()
				
				else:
					i += 1
					self.progress()
					for j in range(byte_arr[i - 1]):
						res.append(byte_arr[i])
						self.progress()
					i += 1
					self.progress()
		except IndexError:
			pass

		with open(self.lineEdit_2.text(), 'wb') as p:
			p.write(res)
	



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


if __name__ == '__main__':
	main()


Сама программа запаковывает некоторым методом(что не суть важно) любые файлы и распаковывает их тем же методом(pack, unpack соответственно). Необходимо как то научить её останавливать процесс распаковки по нажатию кнопки отмена(т.е. чтобы и processBar переставал заполняться и сам процесс запаковки\распаковки приостанавливался). С помощью чего это можно реализовать и как собственно это сделать без мультипотока(это важно!)? Пытался как то с setEnabled поиграться и с threading, используя один поток. Но никак не выходит:(
  • Вопрос задан
  • 800 просмотров
Пригласить эксперта
Ответы на вопрос 1
@Andy_U
Вот тут есть вариант с использованием QApplication.processEvents().
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы