Объект 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_())

0 ответов

Другие вопросы по тегам