Exemplo n.º 1
0
class LoadingDialog(QDialog):
    def __init__(self, title, maximum, parent=None):
        super(LoadingDialog, self).__init__(parent)
        #self.setAttribute(Qt.WA_DeleteOnClose)

        self._may_close = False

        layout = QVBoxLayout()
        layout.addWidget(QLabel("Loading...", self))
        self.progress = QProgressBar(self)
        self.progress.setMinimum(0)
        self.progress.setMaximum(maximum)
        layout.addWidget(self.progress)

        self.setWindowTitle(title)
        self.setLayout(layout)

    @Slot(int)
    def update(self, value):
        self.progress.setValue(value)

    @Slot(int)
    def done(self, r):
        self._may_close = True
        super(LoadingDialog, self).done(r)

    def closeEvent(self, event):
        if self._may_close:
            super(LoadingDialog, self).closeEvent(event)
        else:
            event.ignore()
Exemplo n.º 2
0
class ProgressBar(QWidget):
    style = """
    QProgressBar
    {
        border: 2px solid grey;
        border-radius: 5px;
        text-align: center;
    }
    """

    def __init__(self, parent=None, title=None, minimum=0, maximum=1, value=0):
        super(ProgressBar, self).__init__(parent)
        layout = QGridLayout(self)

        self.progressbar = QProgressBar(self)
        self.progressbar.setMinimum(minimum)
        self.progressbar.setMaximum(maximum)
        self.progressbar.setValue(value)
        self.progressbar.setStyleSheet(self.style)
        self.label = QLabel("")
        self.label.setStyleSheet("Qlabel { font-size: 20px }")
        self.label.setAlignment(QtCore.Qt.AlignCenter)

        self.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        self.setFixedSize(256, 64)
        # self.progressbar.setValue(1)
        layout.addWidget(self.progressbar, 0, 0)
        layout.addWidget(self.label, 0, 0)
        self.setLayout(layout)

        if title:
            self.setWindowTitle(title)

    def setValue(self, value):
        self.progressbar.setValue(value)

    def setMaximumValue(self, value):
        self.progressbar.setMaximum(value)

    def incrementValue(self, increment=1):
        self.progressbar.setValue(self.progressbar.value() + increment)

    def onStart(self):
        self.setWindowFlags(QtCore.Qt.WindowStaysOnTopHint)
        self.show()
        # self.setWindowState(self.windowState() | QtCore.Qt.WindowActive)

    def onFinished(self):
        self.hide()

    def updateIndicatorText(self, string):
        self.label.setText(string)
Exemplo n.º 3
0
class ProgressView(QWidget):
    """
    :type batch_manager: CalculationManager
    """
    def __init__(self, parent, batch_manager):
        QWidget.__init__(self, parent)
        self.calculation_manager = batch_manager
        self.whole_progress = QProgressBar(self)
        self.whole_progress.setMinimum(0)
        self.whole_progress.setMaximum(1)
        self.whole_progress.setFormat("%v of %m")
        self.whole_progress.setTextVisible(True)
        self.part_progress = QProgressBar(self)
        self.part_progress.setMinimum(0)
        self.part_progress.setMaximum(1)
        self.part_progress.setFormat("%v of %m")
        self.whole_label = QLabel("All batch progress:", self)
        self.part_label = QLabel("Single batch progress:", self)
        self.logs = ExceptionList(self)
        self.logs.setToolTip("Logs")
        self.task_que = QListWidget()
        self.process_num_timer = QTimer()
        self.process_num_timer.setInterval(1000)
        self.process_num_timer.setSingleShot(True)
        self.process_num_timer.timeout.connect(self.change_number_of_workers)
        self.number_of_process = QSpinBox(self)
        self.number_of_process.setRange(1, multiprocessing.cpu_count())
        self.number_of_process.setValue(1)
        self.number_of_process.setToolTip(
            "Number of process used in batch calculation")
        self.number_of_process.valueChanged.connect(
            self.process_num_timer_start)
        layout = QGridLayout()
        layout.addWidget(self.whole_label, 0, 0, Qt.AlignRight)
        layout.addWidget(self.whole_progress, 0, 1, 1, 2)
        layout.addWidget(self.part_label, 1, 0, Qt.AlignRight)
        layout.addWidget(self.part_progress, 1, 1, 1, 2)
        lab = QLabel("Number of process:")
        lab.setToolTip("Number of process used in batch calculation")
        layout.addWidget(lab, 2, 0)
        layout.addWidget(self.number_of_process, 2, 1)
        layout.addWidget(self.logs, 3, 0, 1, 3)
        layout.addWidget(self.task_que, 0, 4, 0, 1)
        layout.setColumnMinimumWidth(2, 10)
        layout.setColumnStretch(2, 1)
        self.setLayout(layout)
        self.preview_timer = QTimer()
        self.preview_timer.setInterval(1000)
        self.preview_timer.timeout.connect(self.update_info)

    def new_task(self):
        self.whole_progress.setMaximum(
            self.calculation_manager.calculation_size)
        if not self.preview_timer.isActive():
            self.update_info()
            self.preview_timer.start()

    def update_info(self):
        res = self.calculation_manager.get_results()
        for el in res.errors:
            if el[0]:
                QListWidgetItem(el[0], self.logs)
            ExceptionListItem(el[1], self.logs)
            if (state_store.report_errors and parsed_version.is_devrelease
                    and not isinstance(el[1][0], SegmentationLimitException)
                    and isinstance(el[1][1], tuple)):
                with sentry_sdk.push_scope() as scope:
                    scope.set_tag("auto_report", "true")
                    sentry_sdk.capture_event(el[1][1][0])
        self.whole_progress.setValue(res.global_counter)
        working_search = True
        for i, (progress, total) in enumerate(res.jobs_status):
            if working_search and progress != total:
                self.part_progress.setMaximum(total)
                self.part_progress.setValue(progress)
                working_search = False
            if i < self.task_que.count():
                item = self.task_que.item(i)
                item.setText("Task {} ({}/{})".format(i, progress, total))
            else:
                self.task_que.addItem("Task {} ({}/{})".format(
                    i, progress, total))
        if not self.calculation_manager.has_work:
            print(
                "[ProgressView.update_info]",
                self.calculation_manager.has_work,
                self.calculation_manager.batch_manager.has_work,
                self.calculation_manager.writer.writing_finished(),
            )
            self.part_progress.setValue(self.part_progress.maximum())
            self.preview_timer.stop()
            logging.info("Progress stop")

    def process_num_timer_start(self):
        self.process_num_timer.start()

    def update_progress(self, total_progress, part_progress):
        self.whole_progress.setValue(total_progress)
        self.part_progress.setValue(part_progress)

    def set_total_size(self, size):
        self.whole_progress.setMaximum(size)

    def set_part_size(self, size):
        self.part_progress.setMaximum(size)

    def change_number_of_workers(self):
        self.calculation_manager.set_number_of_workers(
            self.number_of_process.value())
Exemplo n.º 4
0
class ProgressDialog(QDialog):
    """Progress dialog.

    Parameters
    ----------
    label - string or list of strings
    task - QThread or list of QThread (implementing task interface)
    parent - QObject
    """

    canceled = Signal()

    def __init__(self, label, task, parent=None):
        """Constructor."""
        super().__init__(parent)
        self._label = label
        self._task = task

        if (isinstance(self._label, (list, tuple)) and
                isinstance(self._task, (list, tuple)) and
                len(self._label) == len(self._task)) or \
                (isinstance(self._label, str) and
                 isinstance(self._task, QThread)):
            pass
        else:
            raise ValueError()

        self._setup_ui()

    def _setup_ui(self):
        self.layout = QVBoxLayout()

        self.dlg_label = QLabel(self)
        self.cur_item_label = QLabel(self)
        self.progress_bar = QProgressBar(self)
        self.cancel = QPushButton('Cancel', self)

        self.layout.addWidget(self.dlg_label)
        self.layout.addWidget(self.cur_item_label)
        self.layout.addWidget(self.progress_bar)
        self.layout.addWidget(self.cancel)

        self.setLayout(self.layout)

        # Set initial value
        self.progress_bar.setValue(0)

        # Set progress bar limits and connect signals
        self.progress_bar.setMinimum(0)
        if hasattr(self._task, '__iter__'):
            self.dlg_label.setText(self._label[0])
            self._task[0].currentItem.connect(self.cur_item_label.setText)
            self._task[0].itemDone.connect(self.inc_value)
            pb_max = self._task[0].size()
            for i in range(1, len(self._task)):
                self._task[i].currentItem.connect(self.cur_item_label.setText)
                self._task[i].itemDone.connect(self.inc_value)
                self._task[i - 1].completed.connect(self._update_label)
                self._task[i - 1].completed.connect(self._task[i].start)
                pb_max += self._task[i].size()
            self.progress_bar.setMaximum(pb_max)
            self._task[-1].completed.connect(lambda: self._exit_dlg(1))
        else:
            self.dlg_label.setText(self._label)
            self._task.currentItem.connect(self.cur_item_label.setText)
            self._task.itemDone.connect(self.inc_value)
            self._task.completed.connect(lambda: self._exit_dlg(1))
            self.progress_bar.setMaximum(self._task.size())

        self.cancel.pressed.connect(self.canceled.emit)
        self.canceled.connect(lambda: self._exit_dlg(0))
        self.progress_bar.valueChanged.connect(self._is_finished)

    def _update_label(self):
        next_idx = self._label.index(self.dlg_label.text()) + 1
        if next_idx < len(self._label):
            self.dlg_label.setText(self._label[next_idx])

    def _exit_dlg(self, result):
        if hasattr(self._task, '__iter__'):
            for task in self._task:
                task.exit_task()
            self._wait_task(self._task[-1])
            self._task[-1].deleteLater()
        else:
            self._task.exit_task()
            self._wait_task(self._task)
            self._task.deleteLater()
        if result == 1:
            self.accept()
        elif result == 0:
            self.reject()

    def _wait_task(self, task):
        init = time.time()
        try:
            while task.isRunning():
                time.sleep(0.1)
                if time.time() - init > 10:
                    self._exit_dlg(0)
                    raise Exception('Thread will not leave')
        except RuntimeError:
            pass

    def _is_finished(self):
        if self.progress_bar.value() == self.progress_bar.maximum():
            self._exit_dlg(1)

    def set_value(self, value):
        """Set progress bar value."""
        self.progress_bar.setValue(value)

    def inc_value(self):
        """Increase value."""
        self.progress_bar.setValue(self.progress_bar.value()+1)

    def exec_(self):
        """Override."""
        if hasattr(self._task, '__iter__'):
            self._task[0].start()
        else:
            self._task.start()
        return super().exec_()
Exemplo n.º 5
0
class MainDialog(DialogBase):
    """Main dialog for the anaconda navgator updater."""
    # Signals
    sig_application_updated = Signal()
    sig_ready = Signal()

    # Class variables
    PACKAGE = 'anaconda-navigator'
    WIDTH = 450
    HEIGHT = 200

    def __init__(self, latest_version=None, prefix=None):
        """Main dialog for the anaconda navgator updater."""
        super(MainDialog, self).__init__()

        # Variables
        self.api = CondaAPI()
        self.prefix = prefix or os.environ.get('CONDA_PREFIX',
                                               self.api.ROOT_PREFIX)
        self.info = {}
        self.first_run = True
        self.setup_ready = False
        self.busy = False
        self.up_to_date = False
        self.error = False
        self.success = False
        self.status = ''
        self.current_version = None
        self.latest_version = latest_version
        self.style_sheet = load_style_sheet()
        self.timer = QTimer()
        self.timer_2 = QTimer()
        self._windows_appusermodelid = None

        # Widgets
        self.message_box = None  # For testing
        self.label_icon = QSvgWidget()
        self.label_message = LabelBase(
            "There's a new version of Anaconda Navigator available. "
            "We strongly recommend you to update.")

        self.label_status = LabelBase('')
        self.progress_bar = QProgressBar()
        self.button_cancel = ButtonNormal('Dismiss')
        self.button_update = ButtonPrimary('Update now')
        self.button_launch = ButtonPrimary('Launch Navigator')

        # Widgets setup
        if WIN:
            self._windows_appusermodelid = set_windows_appusermodelid()

        self.setMinimumSize(self.WIDTH, self.HEIGHT)
        self.label_message.setAlignment(Qt.AlignLeft | Qt.AlignTop)
        self.label_message.setWordWrap(True)
        self.label_status.setWordWrap(True)
        self.button_update.setAutoDefault(True)
        self.button_launch.setAutoDefault(True)
        self.button_cancel.setFocusPolicy(Qt.NoFocus)
        self.timer.setInterval(1000)
        self.timer_2.setInterval(5000)
        self.progress_bar.setTextVisible(False)
        self.progress_bar.setStyleSheet(self.style_sheet)
        self.label_icon.load(images.ANACONDA_LOGO)
        self.label_icon.setMaximumSize(QSize(64, 64))
        self.label_icon.setMinimumSize(QSize(64, 64))
        self.setWindowTitle('Anaconda Navigator Updater')
        self.progress_bar.setMaximumWidth(self.WIDTH / 3)
        self.setMinimumWidth(self.WIDTH)
        self.setMaximumWidth(self.WIDTH)
        self.setMinimumHeight(self.HEIGHT)

        # Layouts
        layout_status = QHBoxLayout()
        layout_status.addWidget(self.label_status)
        layout_status.addWidget(SpacerHorizontal())
        layout_status.addWidget(self.progress_bar)

        layout_text = QVBoxLayout()
        layout_text.addWidget(self.label_message)
        layout_text.addStretch()
        layout_text.addWidget(SpacerVertical())
        layout_text.addLayout(layout_status)

        layout_icon = QVBoxLayout()
        layout_icon.addWidget(self.label_icon)
        layout_icon.addStretch()

        layout_top = QHBoxLayout()
        layout_top.addLayout(layout_icon)
        layout_top.addWidget(SpacerHorizontal())
        layout_top.addLayout(layout_text)

        layout_buttons = QHBoxLayout()
        layout_buttons.addStretch()
        layout_buttons.addWidget(self.button_cancel)
        layout_buttons.addWidget(SpacerHorizontal())
        layout_buttons.addWidget(self.button_update)
        layout_buttons.addWidget(self.button_launch)

        layout = QVBoxLayout()
        layout.addLayout(layout_top)
        layout.addWidget(SpacerVertical())
        layout.addWidget(SpacerVertical())
        layout.addStretch()
        layout.addLayout(layout_buttons)

        self.setLayout(layout)

        # Signals
        self.button_update.clicked.connect(self.install_update)
        self.button_cancel.clicked.connect(self.reject)
        self.button_launch.clicked.connect(self.launch)
        self.timer.timeout.connect(self.refresh)
        self.timer_2.timeout.connect(self.check_conditions)

        # Setup
        self.timer.start()
        self.timer_2.start()
        self.check_conditions()
        self.refresh()

    def check_conditions(self):
        """Check every 5 seconds installed packages in case codna was used."""
        packages = self.api.linked(prefix=self.prefix)
        package = [p for p in packages if self.PACKAGE in p]
        if package:
            n, v, b = self.api.split_canonical_name(package[0])
            self.current_version = v
        else:
            self.current_version = None

        if self.latest_version is None:
            worker_search = self.api.search(self.PACKAGE,
                                            platform=self.api.get_platform())
            worker_search.sig_finished.connect(self._search_callback)
        else:
            worker = self.api.info()
            worker.sig_finished.connect(self.setup)
            self.check_versions()

    def check_versions(self):
        """Check if navigator is up to date."""
        if self.latest_version and self.current_version:
            from distutils.version import LooseVersion
            cur_ver = LooseVersion(self.current_version)
            lat_ver = LooseVersion(self.latest_version)
            self.up_to_date = cur_ver >= lat_ver
        else:
            self.up_to_date = False

    def _search_callback(self, worker, output, error):
        """Setup the widget."""
        if isinstance(output, dict):
            packages = output.get(self.PACKAGE, [])
            versions = [package.get('version') for package in packages]
            unique_versions = []
            for version in versions:
                if version not in unique_versions:
                    unique_versions.append(version)
            if unique_versions:
                self.latest_version = unique_versions[-1]

        self.check_versions()
        worker = self.api.info()
        worker.sig_finished.connect(self.setup)

        self.refresh()

    def setup(self, worker, info, error):
        """Setup the widget."""
        self.info = info
        self.setup_ready = True
        self.sig_ready.emit()
        self.refresh()

        if self.button_update.isVisible():
            self.button_update.setFocus()

        if self.button_launch.isVisible():
            self.button_launch.setFocus()

    def update_style_sheet(self):
        """Update custom CSS style sheet."""
        self.style_sheet = load_style_sheet()
        self.setStyleSheet(self.style_sheet)

    def refresh(self):
        """Refresh enabled/disabled status of widgets."""
        current_version = 'Not installed'
        if self.current_version:
            current_version = self.current_version

        latest_version = '-'
        if self.latest_version:
            latest_version = self.latest_version

        main_message = (
            "Current version:    &nbsp;&nbsp;&nbsp;&nbsp;<i>{0}</i><br>"
            "Available version: &nbsp;&nbsp;<b>{1}</b><br>").format(
                current_version, latest_version)

        message = self.status
        running = self.check_running()
        self.button_launch.setVisible(False)

        if not self.setup_ready:
            self.button_update.setDisabled(True)
            self.progress_bar.setVisible(True)
            message = 'Updating index...'
            self.update_status(message)
        elif self.busy:
            self.button_update.setDisabled(True)
            self.progress_bar.setVisible(True)
        else:
            self.progress_bar.setVisible(False)

            if running:
                message = 'Please close Anaconda Navigator before updating.'
                self.button_update.setDisabled(running)
            elif not running:
                self.button_update.setDisabled(False)
                if self.success and self.current_version:
                    message = 'Anaconda Navigator was updated successfully.'
                    self.button_update.setVisible(False)
                    self.button_launch.setVisible(True)
                elif self.up_to_date:
                    message = 'Anaconda Navigator is already up to date.'
                    self.button_update.setVisible(False)
                    self.button_launch.setVisible(True)
                elif not self.error:
                    self.button_update.setVisible(True)
                    if self.current_version:
                        message = ('An update for Anaconda Navigator is now '
                                   'available.')
                        self.button_update.setText('Update now')
                    else:
                        message = (
                            'Anaconda Navigator is available for install.')
                        self.button_update.setText('Install now')

            if self.error:
                self.button_update.setDisabled(False)
                message = 'Cannot update Anaconda Navigator, <b>{0}</b>'
                message = message.format(self.error)

        self.label_status.setText(message)
        self.label_message.setText(main_message)

    def update_status(self, status='', value=-1, max_val=-1):
        """Update progress bar and message status."""
        if status:
            self.status = status
            self.label_status.setText(status)
            if value < 0 and max_val < 0:
                self.progress_bar.setRange(0, 0)
            else:
                self.progress_bar.setMinimum(0)
                self.progress_bar.setMaximum(max_val)
                self.progress_bar.setValue(value)

    def check_running(self):
        """Check if Anaconda Navigator is running."""
        # Create file lock
        lock = filelock.FileLock(NAVIGATOR_LOCKFILE)
        try:
            running = False
            with lock.acquire(timeout=0.01):
                pass
        except filelock.Timeout:
            running = True
        return running

    # --- Conda actions and helpers
    # -------------------------------------------------------------------------
    def partial_output_ready(self, worker, output, error):
        """Handle conda partial output ready."""
        self.busy = True
        # print(type(output))
        # print(output)

        # Get errors and data from ouput if it exists
        fetch = None
        if output and isinstance(output, dict):
            fetch = output.get('fetch')
            max_val = output.get('maxval', -1)
            value = output.get('progress', -1)

        if fetch:
            status = 'Fetching <b>{0}</b>...'.format(fetch)
            self.update_status(status=status, max_val=max_val, value=value)

    def output_ready(self, worker, output, error):
        """Handle conda output ready."""
        self.check_conditions()

        # Get errors and data from ouput if it exists
        error_text = output.get('error', '')
        exception_type = output.get('exception_type', '')
        exception_name = output.get('exception_name', '')
        success = output.get('success')
        actions = output.get('actions', {})
        # op_order = output.get('op_order', [])
        # action_check_fetch = actions.get('CHECK_FETCH', [])
        # action_rm_fetch = actions.get('RM_FETCHED', [])
        # action_fetch = actions.get('FETCH', [])
        # action_check_extract = actions.get('CHECK_EXTRACT', [])
        # action_rm_extract = actions.get('RM_EXTRACTED', [])
        # action_extract = actions.get('EXTRACT', [])
        # action_unlink = actions.get('UNLINK', [])
        action_link = actions.get('LINK', [])
        # action_symlink_conda = actions.get('SYMLINK_CONDA', [])

        self.busy = False

        # Get errors from json output
        if error_text or exception_type or exception_name or not success:
            self.error = exception_name
            self.success = False
            self.up_to_date = False
        elif success and action_link:
            self.sig_application_updated.emit()
            self.error = None
            self.success = True
            self.up_to_date = False
        elif success:
            self.success = False
            self.error = None
            self.up_to_date = True

        worker.lock.release()
        self.refresh()

    def install_update(self):
        """Install the specified version or latest version of navigator."""
        self.busy = True
        self.refresh()
        # conda_prefix = self.info.et('conda_prefix')
        # root_prefix = self.info.et('root_prefix')
        navigator_prefixes = [
            # os.path.join(self.api.ROOT_PREFIX, 'envs', '_navigator_'),
            # os.path.join(self.api.ROOT_PREFIX, 'envs', '_conda_'),
            self.prefix,
        ]
        for prefix in navigator_prefixes:
            if self.api.environment_exists(prefix=prefix):
                break

        if self.latest_version:
            pkgs = ['{0}=={1}'.format(self.PACKAGE, self.latest_version)]
        else:
            pkgs = [self.PACKAGE.format(self.latest_version)]

        # Lock Navigator
        lock = filelock.FileLock(NAVIGATOR_LOCKFILE)
        lock.acquire()
        worker = self.api.install(prefix=prefix, pkgs=pkgs)
        worker.lock = lock
        worker.sig_partial.connect(self.partial_output_ready)
        worker.sig_finished.connect(self.output_ready)
        self.refresh()

        if self.prefix == self.api.ROOT_PREFIX:
            name = 'root'
        else:
            name = os.path.basename(self.prefix)

        self.button_launch.setFocus()
        if self.current_version:
            msg = 'Updating package on <b>{0}</b>...'.format(name)
        else:
            msg = 'Installing package on <b>{0}</b>...'.format(name)
        self.update_status(msg)

    def launch(self):
        """Launch Anaconda Navigator."""
        leave_path_alone = True
        root_prefix = self.api.ROOT_PREFIX
        prefix = self.prefix
        command = ['anaconda-navigator']

        # Use the app bundle on OSX
        if MAC:
            command = ['open', os.path.join(prefix, 'Anaconda-Navigator.app')]

        launch_cmd(
            prefix,
            command,
            leave_path_alone,
            package_name='anaconda-navigator-app',
            root_prefix=root_prefix,
        )
        self.close()

    # --- Qt Overrides
    # -------------------------------------------------------------------------
    def reject(self):
        """Override Qt method."""
        if self.busy:
            msg_box = MessageBoxQuestion(title='Quit Navigator Updater?',
                                         text='Anaconda Navigator is being '
                                         'updated. <br><br>'
                                         'Are you sure you want to quit?')

            if msg_box.exec_():
                super(MainDialog, self).reject()
        else:
            super(MainDialog, self).reject()
Exemplo n.º 6
0
class ProgressView(QWidget):
    """
    :type batch_manager: CalculationManager
    """
    def __init__(self, parent, batch_manager):
        super().__init__(parent)
        self.task_count = 0
        self.calculation_manager = batch_manager
        self.whole_progress = QProgressBar(self)
        self.whole_progress.setMinimum(0)
        self.whole_progress.setMaximum(1)
        self.whole_progress.setFormat("%v of %m")
        self.whole_progress.setTextVisible(True)
        self.part_progress = QProgressBar(self)
        self.part_progress.setMinimum(0)
        self.part_progress.setMaximum(1)
        self.part_progress.setFormat("%v of %m")
        self.whole_label = QLabel("All batch progress:", self)
        self.part_label = QLabel("Single batch progress:", self)
        self.cancel_remove_btn = QPushButton("Remove task")
        self.cancel_remove_btn.setDisabled(True)
        self.logs = ExceptionList(self)
        self.logs.setToolTip("Logs")
        self.task_view = QListView()
        self.task_que = QStandardItemModel(self)
        self.task_view.setModel(self.task_que)
        self.process_num_timer = QTimer()
        self.process_num_timer.setInterval(1000)
        self.process_num_timer.setSingleShot(True)
        self.process_num_timer.timeout.connect(self.change_number_of_workers)
        self.number_of_process = QSpinBox(self)
        self.number_of_process.setRange(1, multiprocessing.cpu_count())
        self.number_of_process.setValue(1)
        self.number_of_process.setToolTip(
            "Number of process used in batch calculation")
        self.number_of_process.valueChanged.connect(
            self.process_num_timer_start)
        self.progress_item_dict = {}
        layout = QGridLayout()
        layout.addWidget(self.whole_label, 0, 0, Qt.AlignRight)
        layout.addWidget(self.whole_progress, 0, 1, 1, 2)
        layout.addWidget(self.part_label, 1, 0, Qt.AlignRight)
        layout.addWidget(self.part_progress, 1, 1, 1, 2)
        lab = QLabel("Number of process:")
        lab.setToolTip("Number of process used in batch calculation")
        layout.addWidget(lab, 2, 0)
        layout.addWidget(self.number_of_process, 2, 1)
        layout.addWidget(self.logs, 3, 0, 2, 3)
        layout.addWidget(self.task_view, 0, 4, 4, 1)
        layout.addWidget(self.cancel_remove_btn, 4, 4, 1, 1)
        layout.setColumnMinimumWidth(2, 10)
        layout.setColumnStretch(2, 1)
        self.setLayout(layout)
        self.preview_timer = QTimer()
        self.preview_timer.setInterval(1000)
        self.preview_timer.timeout.connect(self.update_info)
        self.task_view.selectionModel().currentChanged.connect(
            self.task_selection_change)
        self.cancel_remove_btn.clicked.connect(self.task_cancel_remove)

    def task_selection_change(self, new, old):
        task: CalculationProcessItem = self.task_que.item(
            new.row(), new.column())
        if task is None:
            self.cancel_remove_btn.setDisabled(True)
            return
        self.cancel_remove_btn.setEnabled(True)
        if task.is_finished():
            self.cancel_remove_btn.setText(f"Remove task {task.num}")
        else:
            self.cancel_remove_btn.setText(f"Cancel task {task.num}")

    def task_cancel_remove(self):
        index = self.task_view.selectionModel().currentIndex()
        task: CalculationProcessItem = self.task_que.item(
            index.row(), index.column())
        if task.is_finished():
            self.calculation_manager.remove_calculation(task.calculation)
            self.task_que.takeRow(index.row())
        else:
            self.calculation_manager.cancel_calculation(task.calculation)
        print(task)

    def new_task(self):
        self.whole_progress.setMaximum(
            self.calculation_manager.calculation_size)
        if not self.preview_timer.isActive():
            self.update_info()
            self.preview_timer.start()

    def update_info(self):
        res = self.calculation_manager.get_results()
        for el in res.errors:
            if el[0]:
                QListWidgetItem(el[0], self.logs)
            ExceptionListItem(el[1], self.logs)
            if (state_store.report_errors and parsed_version.is_devrelease
                    and not isinstance(el[1][0], SegmentationLimitException)
                    and isinstance(el[1][1], tuple)):
                with sentry_sdk.push_scope() as scope:
                    scope.set_tag("auto_report", "true")
                    sentry_sdk.capture_event(el[1][1][0])
        self.whole_progress.setValue(res.global_counter)
        working_search = True
        for uuid, progress in res.jobs_status.items():
            calculation = self.calculation_manager.calculation_dict[uuid]
            total = len(calculation.file_list)
            if uuid in self.progress_item_dict:
                item = self.progress_item_dict[uuid]
                item.update_count(progress)
            else:
                item = CalculationProcessItem(calculation, self.task_count,
                                              progress)
                self.task_count += 1
                self.task_que.appendRow(item)
                self.progress_item_dict[uuid] = item

            if working_search and progress != total:
                self.part_progress.setMaximum(total)
                self.part_progress.setValue(progress)
                working_search = False
        if not self.calculation_manager.has_work:
            self.part_progress.setValue(self.part_progress.maximum())
            self.preview_timer.stop()
            logging.info("Progress stop")

    def process_num_timer_start(self):
        self.process_num_timer.start()

    def update_progress(self, total_progress, part_progress):
        self.whole_progress.setValue(total_progress)
        self.part_progress.setValue(part_progress)

    def set_total_size(self, size):
        self.whole_progress.setMaximum(size)

    def set_part_size(self, size):
        self.part_progress.setMaximum(size)

    def change_number_of_workers(self):
        self.calculation_manager.set_number_of_workers(
            self.number_of_process.value())
Exemplo n.º 7
0
class SteeringDisplay(Display):
    def __init__(self, parent=None, macros=None, args=[]):
        super(SteeringDisplay, self).__init__(parent=parent,
                                              macros=macros,
                                              args=args)
        self._live_orbit = None
        self.setup_ui()

    def ui_filename(self):
        return None

    def ui_filepath(self):
        return None

    def setup_ui(self):
        self.setWindowTitle("Steering Panel")
        self.draw_timer = QTimer(self)
        self.draw_timer.setInterval(int(1000 / 5))
        self.setLayout(QVBoxLayout())
        self.current_progress = 0
        self.total_progress = 0
        self.loading_label = QLabel(self)
        self.progress_bar = QProgressBar(self)
        self.progress_bar.setMinimum(0)
        self.progress_bar.setMaximum(100)
        self.x_magnet_list = None
        self.layout().addStretch()
        self.layout().addWidget(self.loading_label)
        self.layout().addWidget(self.progress_bar)
        self.layout().addStretch()
        position_scale = 2.0
        self.orbit_view = OrbitView(parent=self,
                                    axis="x",
                                    name="X Orbit",
                                    label="X Orbit",
                                    units="mm",
                                    ymin=-position_scale,
                                    ymax=position_scale,
                                    draw_timer=self.draw_timer)
        self.orbit_view.hide()
        self.layout().addWidget(self.orbit_view)
        self.layout().setStretchFactor(self.orbit_view, 1)
        QTimer.singleShot(50, self.initialize_orbit)

    @Slot()
    def initialize_orbit(self):
        QApplication.instance().processEvents(
        )  #Need to call processEvents to make the status bar message show up before the live orbit connection stuff starts.
        orbit = Orbit.lcls_bpms(auto_connect=False, parent=self)
        self.x_magnet_list = MagnetList("X", "xcor_list.json", parent=self)
        self.total_progress = orbit.progress_total(
        ) + self.x_magnet_list.progress_total()
        num_pvs = orbit.pv_count() + self.x_magnet_list.pv_count()
        self.loading_label.setText("Connecting to {} PVs...".format(num_pvs))
        self.loading_label.setAlignment(Qt.AlignCenter)
        self.progress_bar.setMaximum(self.total_progress)
        orbit.connectionProgress.connect(self.increment_progress)
        self.x_magnet_list.connectionProgress.connect(self.increment_progress)
        orbit.connect()
        orbit.name = "Live Orbit"
        self.live_orbit = orbit
        self.initialize_magnet_lists()
        self.connection_complete()

    @Slot()
    def increment_progress(self):
        self.current_progress += 1
        self.progress_bar.setValue(self.current_progress)

    @Slot()
    def connection_complete(self):
        self.layout().removeWidget(self.progress_bar)
        self.layout().removeWidget(self.loading_label)
        self.progress_bar.deleteLater()
        self.loading_label.deleteLater()
        self.orbit_view.show()

    def initialize_magnet_lists(self):
        self.x_magnet_list.connect()
        self.orbit_view.set_magnet_list(self.x_magnet_list)
        self.orbit_view.show_magnet_views(True)

    @property
    def live_orbit(self):
        return self._live_orbit

    @live_orbit.setter
    def live_orbit(self, new_live_orbit):
        if new_live_orbit == self._live_orbit:
            return
        self._live_orbit = new_live_orbit
        self.orbit_view.set_orbit(self._live_orbit, reset_range=False)