Итак, есть некоторый код.
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, используя один поток. Но никак не выходит:(