class_docstr: Extends QProgressDialog:
  
    * Adds context management so the dialog may be used in `with` statements
    * Allows nesting multiple progress dialogs
  
  Example::
  
      with ProgressDialog("Processing..", minVal, maxVal) as dlg:
          # do stuff
          dlg.setValue(i)   ## could also use dlg += 1
          if dlg.wasCanceled():
              raise Exception("Processing canceled by user")
docstr: ============== ================================================================
  **Arguments:**
  labelText      (required)
  cancelText     Text to display on cancel button, or None to disable it.
  minimum
  maximum
  parent       
  wait           Length of time (im ms) to wait before displaying dialog
  busyCursor     If True, show busy cursor until dialog finishes
  disable        If True, the progress dialog will not be displayed
                 and calls to wasCanceled() will always return False.
                 If ProgressDialog is entered from a non-gui thread, it will
                 always be disabled.
  nested         (bool) If True, then this progress bar will be displayed inside
                 any pre-existing progress dialogs that also allow nesting.
  ============== ================================================================
docstr_tok: ["==============","================================================================","*","*","Arguments",":","*","*","labelText","(","required",")","cancelText","Text","to","display","on","cancel","button",",","or","None","to","disable","it",".","minimum","maximum","parent","wait","Length","of","time","(","im","ms",")","to","wait","before","displaying","dialog","busyCursor","If","True",",","show","busy","cursor","until","dialog","finishes","disable","If","True",",","the","progress","dialog","will","not","be","displayed","and","calls","to","wasCanceled","(",")","will","always","return","False",".","If","ProgressDialog","is","entered","from","a","non-gui","thread",",","it","will","always","be","disabled",".","nested","(","bool",")","If","True",",","then","this","progress","bar","will","be","displayed","inside","any","pre-existing","progress","dialogs","that","also","allow","nesting",".","==============","================================================================"]
code: def __init__(
      self,
      labelText,
      minimum=0,
      maximum=100,
      cancelText="Cancel",
      parent=None,
      wait=250,
      busyCursor=False,
      disable=False,
      nested=False,
  ):
      """
      ============== ================================================================
      **Arguments:**
      labelText      (required)
      cancelText     Text to display on cancel button, or None to disable it.
      minimum
      maximum
      parent
      wait           Length of time (im ms) to wait before displaying dialog
      busyCursor     If True, show busy cursor until dialog finishes
      disable        If True, the progress dialog will not be displayed
                     and calls to wasCanceled() will always return False.
                     If ProgressDialog is entered from a non-gui thread, it will
                     always be disabled.
      nested         (bool) If True, then this progress bar will be displayed inside
                     any pre-existing progress dialogs that also allow nesting.
      ============== ================================================================
      """
      # attributes used for nesting dialogs
      self.nestedLayout = None
      self._nestableWidgets = None
      self._nestingReady = False
      self._topDialog = None
      self._subBars = []
      self.nested = nested
  
      # for rate-limiting Qt event processing during progress bar update
      self._lastProcessEvents = None
  
      isGuiThread = (
          QtCore.QThread.currentThread()
          == QtCore.QCoreApplication.instance().thread()
      )
      self.disabled = disable or (not isGuiThread)
      if self.disabled:
          return
  
      noCancel = False
      if cancelText is None:
          cancelText = ""
          noCancel = True
  
      self.busyCursor = busyCursor
  
      QtWidgets.QProgressDialog.__init__(
          self, labelText, cancelText, minimum, maximum, parent
      )
  
      # If this will be a nested dialog, then we ignore the wait time
      if nested is True and len(ProgressDialog.allDialogs) > 0:
          self.setMinimumDuration(2**30)
      else:
          self.setMinimumDuration(wait)
  
      self.setWindowModality(QtCore.Qt.WindowModality.WindowModal)
      self.setValue(self.minimum())
      if noCancel:
          self.setCancelButton(None)
  
imports: from time import perf_counter
  from ..Qt import QtCore, QtGui, QtWidgets
label_desc: Use image node_id 1 to create a new ProgressDialog object from inherited base classes: QtWidgets with example: obj = ProgressDialog(labelText, minimum, maximum, cancelText, parent, wait, busyCursor, disable, nested)