Объект QProgressDialog AttributeError: объект «ProgressBar» не имеет атрибута «wasCanceled»
Я пытаюсь высушить программу PyQt, которая в разное время вызывает QProgressDialog. Вместо того, чтобы каждое вхождение вызывало вариант этого:
self.cat_progress = QProgressDialog(self.root)
self.cat_progress.setMinimumWidth(800)
self.cat_progress.setWindowTitle('Downloading Data')
self.cat_progress.setMinimumDuration(0)
self.cat_progress.setWindowModality(Qt.ApplicationModal)
self.cat_progress_label = QLabel('')
self.cat_progress.setLabel(self.cat_progress_label)
total_requests = 25
self.cat_progress.setMaximum(total_requests)
self.current_progress = 1
self.cat_progress.setValue(self.current_progress)
self.message_phase = 'Starting Collection'
self.progress_bar_max = 0
self.cat_progress_label.setText(self.message_phase)
Я сделал класс, чтобы каждый раз, когда нужен progressDialog, я мог использовать 3 строки вместо 20+.
class ProgressBar(QDialog):
def __init__(self, title, label, prog_max=100):
super().__init__()
self.progress = QProgressDialog(self)
self.progress.setMinimumWidth(600)
self.progress.setWindowTitle(title)
self.progress.setMinimum(0)
self.progress.setValue(0)
self.progress.setWindowModality(Qt.WindowModal)
self.progress.setMaximum(prog_max)
self.progress.setWindowFlag(Qt.WindowContextHelpButtonHint,False) # This removes the '?' from the dialog
self.progress.setStyleSheet("""
QProgressBar {
border: 2px solid grey;
border-radius: 5px;
text-align: center
}
QProgressBar::chunk {
background-color: rgb(139, 183, 240);
width: 25px
}
QPushButton {
border: 2px solid grey;
border-radius: 5px;
padding: 5% 8%;
}
""")
self.progress_label = QLabel(label)
self.progress.setLabel(self.progress_label)
def advance_progress(self, label):
self.progress_label.setText(label)
self.progress.setValue(self.progress.value() + 1)
def canceled(self):
self.stop_progress()
def stop_progress(self):
self.deleteLater()
Проблема в том, что одно использование полагалось на встроенную кнопку «Отмена».wasCanceled()
логическое значение. Поскольку программа выполняет цикл,if progress.wasCanceled(): ...start a different process
. Теперь, когдаprogress
из класса, а не напрямую из QProgressDialog, я получаюAttributeError: 'ProgressBar' object has no attribute 'wasCanceled'
. Нажатие этой кнопки приведет к выходу из диалогового окна, но оно не перейдет к следующему процессу, как мне нужно.
Я пытался добавить сигналы, подключить отмененную функцию, установить логическое значение userClicked и т. д. Некоторые вещи сломали Отмену, поэтому она просто сбрасывается и начинается снова, бесконечно, когда вы нажимаете кнопку «Отмена». Некоторые сами «нажали» кнопку (у меня был вывод оператора печати) во время выполнения цикла, но не остановили действие. Однажды до этого дошлоif
заявление и вспыхнуло само по себе.
Как сохранить это как объект, а также узнать, когда пользователь нажал «Отмена»?
Небольшая демонстрация, которая теперь работает! [ключ в том, чтобы наследоваться от правильного виджета и не вызывать новый экземпляр QProgressDialog]:
import sys
import time
from PyQt5.QtWidgets import QMainWindow, QApplication, QProgressDialog, QLabel, QPushButton
from PyQt5.QtCore import Qt
class ProgressBar(QProgressDialog):
def __init__(self, title, label, prog_max=100):
super().__init__()
self.setMinimumWidth(600)
self.setWindowTitle(title)
self.setMinimum(0)
self.setValue(0)
self.setWindowModality(Qt.WindowModal)
self.setMaximum(prog_max)
self.setStyleSheet("""
QProgressBar {
border: 2px solid grey;
border-radius: 5px;
text-align: center
}
QProgressBar::chunk {
background-color: rgb(139, 183, 240);
width: 25px
}
QPushButton {
border: 2px solid grey;
border-radius: 5px;
padding: 5% 8%;
}
""")
self.progress_label = QLabel(label)
self.setLabel(self.progress_label)
def advance_progress(self, label):
self.progress_label.setText(label)
self.setValue(self.value() + 1)
def canceled(self):
self.stop_progress()
def stop_progress(self):
self.deleteLater()
class Testing(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle('Testing Progress')
btn = QPushButton('Start progress bar')
btn.clicked.connect(self.run_progress)
self.setCentralWidget(btn)
def run_progress(self):
# Title, Label, setMaximum
progress = ProgressBar('Window Running Progress', 'Testing from Element', 30)
progress.advance_progress('Starting Scan ...')
i = 0
while i < 30:
print(i)
time.sleep(2)
progress.advance_progress(f'Counting {i}')
i += 1
if progress.wasCanceled():
alert('User Stopped!')
progress.stop_progress()
progress.stop_progress()
if __name__ == '__main__':
app = QApplication(sys.argv)
test = Testing()
test.show()
sys.exit(app.exec_())