def process_packages(self, action):
        """Install/uninstall packages"""
        if action == 'install':
            text, table = 'Installing', self.table
            if not self.get_packages_to_be_installed():
                return
        elif action == 'uninstall':
            text, table = 'Uninstalling', self.untable
        else:
            raise AssertionError
        packages = table.get_selected_packages()
        if not packages:
            return
        func = getattr(self.distribution, action)
        thread = Thread(self)
        for widget in self.children():
            if isinstance(widget, QWidget):
                widget.setEnabled(False)
        try:
            status = self.statusBar()
        except AttributeError:
            status = self.parent().statusBar()
        progress = QProgressDialog(self, Qt.FramelessWindowHint)
        progress.setMaximum(len(packages)) #  old vicious bug:len(packages)-1
        for index, package in enumerate(packages):
            progress.setValue(index)
            progress.setLabelText("%s %s %s..."
                                  % (text, package.name, package.version))
            QApplication.processEvents()
            if progress.wasCanceled():
                break
            if package in table.model.actions:
                try:
                    thread.callback = lambda: func(package)
                    thread.start()
                    while thread.isRunning():
                        QApplication.processEvents()
                        if progress.wasCanceled():
                            status.setEnabled(True)
                            status.showMessage("Cancelling operation...")
                    table.remove_package(package)
                    error = thread.error
                except Exception as error:
                    error = to_text_string(error)
                if error is not None:
                    pstr = package.name + ' ' + package.version
                    QMessageBox.critical(self, "Error",
                                         "<b>Unable to %s <i>%s</i></b>"
                                         "<br><br>Error message:<br>%s"
                                         % (action, pstr, error))
        progress.setValue(progress.maximum())
        status.clearMessage()
        for widget in self.children():
            if isinstance(widget, QWidget):
                widget.setEnabled(True)
        thread = None
        for table in (self.table, self.untable):
            table.refresh_distribution(self.distribution)
dataset/ETHPy150Open winpython/winpython/winpython/controlpanel.py/PMWindow.process_packages/original