class ProcessWithThreadsMixin:
    mutex = QMutex()

    def __init__(self):
        self.finish_thread_callback = None
        self.thread_list = []

    def set_loading_indicator(self):
        self.indicator = WaitingSpinner(self.view, True, True,
                                        Qt.ApplicationModal)

    def start_loading(self,
                      started_callback,
                      finished_callback,
                      with_indicator=True):
        self.finish_thread_callback = finished_callback
        if with_indicator:
            self.indicator.start()
        thread = Thread(started_callback, self.mutex)
        thread.finished.connect(self.stop_loading)
        thread.start()
        self.thread_list.append(thread)

    def stop_loading(self, error_text):
        self.indicator.stop()
        self.thread_list = [
            thread for thread in self.thread_list if not thread.isFinished()
        ]
        self.finish_thread_callback(error_text)
Example #2
0
    def __init__(self, width, height, parent, *args, **kwargs):
        super(MyMenu, self).__init__(*args, **kwargs)
        self.setStyleSheet("""background: #b4b4b4; color: black;""")

        self.parent = parent

        self.resize(width, height)

        self.main_layout = QtWidgets.QGridLayout()

        self.threadpool = QtCore.QThreadPool()
        self.wait = WaitingSpinner(self,
                                   True,
                                   True,
                                   QtCore.Qt.ApplicationModal,
                                   roundness=70.0,
                                   opacity=100.0,
                                   fade=70.0,
                                   radius=10.0,
                                   lines=12,
                                   line_length=10.0,
                                   line_width=5.0,
                                   speed=1.0,
                                   color=(0, 0, 0))

        self.setLayout(self.main_layout)
    def showEvent(self, event):  # pylint: disable=unused-argument, invalid-name
        """ Start movie, when it is shown. """

        # show version label
        if self._is_background_set:
            self._label = QtWidgets.QLabel(self)
            self._label.setText(WAQD_VERSION + "   ")
            self._label.setAlignment(Qt.AlignmentFlag(Qt.AlignBottom | Qt.AlignRight))
            self._label.setGeometry(0, 0, 800, 480)
            self._label.show()
        self._spinner = WaitingSpinner(self, centerOnParent=False, radius=30, roundness=60,
                                      line_length=20, line_width=6, speed=0.5, color=(15, 67, 116))
        if self._is_background_set:
            self._spinner.setGeometry(int(self.width()/2 - self._spinner.width()/2),
                                     int(self.height() - self._spinner.height() - 20),
                                     self._spinner.width(),
                                     self._spinner.height())
        else:
            self._spinner.setColor("white")
            self._spinner.setInnerRadius(40)
            self._spinner.setLineLength(40)
            self._spinner.setLineWidth(8)
            self._spinner.setTrailFadePercentage(90)
            self._spinner.setGeometry(int(self.width()/2 - self._spinner.width()/2),
                                      int(self.height()/2 - self._spinner.height()/2),
                                     self._spinner.width(),
                                     self._spinner.height())
        self._spinner.start()
Example #4
0
    def __init__(self, connection):
        super(JobList, self).__init__()
        self.connection = connection
        self.jobTableModel = JobTableModel()
        self.jobTableView = JobTableView(self.jobTableModel)
        #self.dbTable = config.DB.table("jobs")
        self.log = Logger(jobList=self)
        self.listJobs()
        self.tunnels = {}
        self.threadpool = QThreadPool()

        # Waiting spinner
        self.spinner = WaitingSpinner(self.jobTableView)
        self.spinner.setNumberOfLines(18)
        self.spinner.setInnerRadius(12)
        self.spinner.setLineLength(20)
        self.spinner.setLineWidth(5)

        # Init, but do not start timers before
        # a connection with the server is established
        self.timer = QTimer(self)
        self.timer.setInterval(1000)
        self.timer.timeout.connect(self.smartSync)

        self.elapsedTimer = QElapsedTimer()
        self.loaded = False
        self.jobsPending = True
Example #5
0
 def validate_imported_objects(self, imported_objects):
     self.spinner = WaitingSpinner(parent=None, roundness=80.0, opacity=10.0, fade=72.0, radius=10.0,
                              lines=12, line_length=12.0, line_width=4.0, speed=1.4, color=(0, 0, 0))
     self.spinner.setParent(self.multi_object_list_widget)
     self.validation_finished.connect(self.spinner.stop)  # signal used to stop timer in correct thread
     self.spinner.start()
     self.thread = Thread(target=self.validate_objects, args=imported_objects)
     self.thread.start()
Example #6
0
 def __init__(self, parent=None):
     super(Thread, self).__init__(parent)
     self.is_running = True
     self.spinner = WaitingSpinner(parent,
                                   roundness=70.0,
                                   opacity=15.0,
                                   fade=70.0,
                                   radius=10.0,
                                   lines=12,
                                   line_length=10.0,
                                   line_width=5.0,
                                   speed=1.0,
                                   color=(0, 0, 0))
Example #7
0
 def start_waiting(self):
     """
     """
     self.wait = WaitingSpinner(self,
                                True,
                                True,
                                QtCore.Qt.ApplicationModal,
                                roundness=70.0,
                                opacity=100.0,
                                fade=70.0,
                                radius=10.0,
                                lines=12,
                                line_length=10.0,
                                line_width=5.0,
                                speed=1.0,
                                color=(0, 0, 0))
     self.parent.btn_next.setEnabled(False)
     self.parent.btn_back.setEnabled(False)
     self.wait.start()
 def initialize_ui(self):
     label = QLabel("El resultado puede demorar varios minutos")
     spinner = WaitingSpinner(self,
                              roundness=70.0,
                              opacity=15.0,
                              fade=70.0,
                              radius=10.0,
                              lines=12,
                              line_length=10.0,
                              line_width=5.0,
                              speed=1.0,
                              color=(0, 0, 0))
     spinner.start()  # starts spinning
     cancel_button = QPushButton('Cancelar', self)
     cancel_button.clicked.connect(lambda: self.cancel())
     vbox = QVBoxLayout()
     vbox.addWidget(label)
     vbox.addWidget(spinner)
     vbox.addWidget(cancel_button)
     self.setLayout(vbox)
Example #9
0
class Thread(QThread):
    def __init__(self, parent=None):
        super(Thread, self).__init__(parent)
        self.is_running = True
        self.spinner = WaitingSpinner(parent,
                                      roundness=70.0,
                                      opacity=15.0,
                                      fade=70.0,
                                      radius=10.0,
                                      lines=12,
                                      line_length=10.0,
                                      line_width=5.0,
                                      speed=1.0,
                                      color=(0, 0, 0))

    def run(self):
        self.spinner.start()

    def stop(self):
        self.spinner.stop()
        self.is_running = False
        self.terminate()
Example #10
0
class AddRedditObjectDialog(QDialog, Ui_AddRedditObjectDialog):

    validation_finished = pyqtSignal()

    def __init__(self, list_model, parent=None):
        QDialog.__init__(self, parent=parent)
        self.setupUi(self)
        self.logger = logging.getLogger(f'DownloaderForReddit.{__name__}')
        self.settings_manager = injector.get_settings_manager()
        self.list_model = list_model
        self.setWindowTitle(f'Add {self.list_model.list_type.capitalize()}')
        self.single_add_label.setText(f'Enter new {self.list_model.list_type.lower()}')
        self.tab_widget.setCurrentIndex(0)

        self.download_on_add_checkbox.setChecked(self.settings_manager.download_on_add)
        self.download_on_add_checkbox.stateChanged.connect(
            lambda checked: setattr(self.settings_manager, 'download_on_add', checked))

        self.add_button.clicked.connect(self.add_object_to_list)
        self.remove_button.clicked.connect(self.remove_object_from_list)
        self.import_button.clicked.connect(self.import_list)
        self.dialog_button_box.accepted.connect(self.accept)
        self.dialog_button_box.rejected.connect(self.close)

        self.single_object_line_edit.setFocus()
        self.tab_widget.currentChanged.connect(self.tab_change)

        self.added = []
        self.imported = []

    def tab_change(self):
        if self.tab_widget.currentIndex() == 0:
            self.single_object_line_edit.setFocus()
        else:
            self.multi_object_line_edit.setFocus()

    def refresh_name_count(self):
        self.name_count_label.setText(str(self.multi_object_list_widget.count()))

    def add_object_to_list(self):
        name = self.multi_object_line_edit.text()
        self.added.append(name)
        self.multi_object_list_widget.addItem(name)
        self.multi_object_line_edit.clear()
        self.refresh_name_count()

    def remove_object_from_list(self):
        for index in self.multi_object_list_widget.selectedIndexes():
            self.multi_object_list_widget.takeItem(index.row())
        self.refresh_name_count()

    def import_list(self):
        file_path = self.get_import_file_path()
        if file_path is not None and os.stat(file_path).st_size > 0:
            if file_path.endswith('txt'):
                import_list = text_importer.import_list_from_text_file(file_path)
                self.added.extend(import_list)
                self.multi_object_list_widget.addItems(import_list)
            elif file_path.endswith('json'):
                imported_objects = json_importer.import_json(file_path)
                self.validate_imported_objects(imported_objects)

    def get_import_file_path(self):
        file_path = QFileDialog.getOpenFileName(self, 'Select Import File', system_util.get_data_directory(),
                                                'Text Files (*.txt *.json)')[0]
        if file_path is not None and file_path != '':
            if os.path.isfile(file_path):
                return file_path
            else:
                self.logger.error('Failed to import file.  File does not exist.', extra={'file_path': file_path})
                return None

    def validate_imported_objects(self, imported_objects):
        self.spinner = WaitingSpinner(parent=None, roundness=80.0, opacity=10.0, fade=72.0, radius=10.0,
                                 lines=12, line_length=12.0, line_width=4.0, speed=1.4, color=(0, 0, 0))
        self.spinner.setParent(self.multi_object_list_widget)
        self.validation_finished.connect(self.spinner.stop)  # signal used to stop timer in correct thread
        self.spinner.start()
        self.thread = Thread(target=self.validate_objects, args=imported_objects)
        self.thread.start()

    def validate_objects(self, *imported_objects):
        name_checker = reddit_utils.NameChecker(self.list_model.list_type)
        for ro in imported_objects:
            v_set = name_checker.check_reddit_object_name(ro.name)
            if v_set.valid:
                self.imported.append(ro)
                self.multi_object_list_widget.addItem(ro.name)
        self.validation_finished.emit()

    def accept(self):
        self.add_reddit_objects()
        super().accept()

    def add_reddit_objects(self):
        if self.tab_widget.currentIndex() == 0:
            name = self.single_object_line_edit.text()
            if name is not None and name != '':
                self.list_model.add_reddit_object(name)
        else:
            self.list_model.add_reddit_objects(self.added)
        self.add_imported_reddit_objects()

    def add_imported_reddit_objects(self):
        for ro in self.imported:
            self.list_model.add_complete_reddit_object(ro)

    def keyPressEvent(self, event):
        key = event.key()
        if key in (Qt.Key_Enter, Qt.Key_Return):
            if self.tab_widget.currentIndex() == 0:
                shift = QApplication.keyboardModifiers() == Qt.ShiftModifier
                if shift:
                    name = self.single_object_line_edit.text()
                    self.added.append(name)
                    self.multi_object_list_widget.addItem(name)
                    self.single_object_line_edit.clear()
                    self.tab_widget.setCurrentIndex(1)
                    self.refresh_name_count()
                else:
                    self.accept()
            else:
                self.add_object_to_list()
Example #11
0
    def init_ui(self):
        grid = QGridLayout()
        groupbox1 = QGroupBox()
        groupbox1_layout = QHBoxLayout()
        groupbox2 = QGroupBox()
        groupbox2_layout = QGridLayout()
        button_hbox = QHBoxLayout()
        self.setLayout(grid)
        self.setWindowTitle("QtWaitingSpinner Demo")
        self.setWindowFlags(Qt.Dialog)

        # SPINNER
        self.spinner = WaitingSpinner(self)

        # Spinboxes
        self.sb_roundness = QDoubleSpinBox()
        self.sb_opacity = QDoubleSpinBox()
        self.sb_fadeperc = QDoubleSpinBox()
        self.sb_lines = QSpinBox()
        self.sb_line_length = QDoubleSpinBox()
        self.sb_line_width = QDoubleSpinBox()
        self.sb_inner_radius = QDoubleSpinBox()
        self.sb_rev_s = QDoubleSpinBox()

        # set spinbox default values
        self.sb_roundness.setValue(70)
        self.sb_roundness.setRange(0, 9999)
        self.sb_opacity.setValue(15)
        self.sb_opacity.setRange(0, 9999)
        self.sb_fadeperc.setValue(70)
        self.sb_fadeperc.setRange(0, 9999)
        self.sb_lines.setValue(12)
        self.sb_lines.setRange(1, 9999)
        self.sb_line_length.setValue(10)
        self.sb_line_length.setRange(0, 9999)
        self.sb_line_width.setValue(5)
        self.sb_line_width.setRange(0, 9999)
        self.sb_inner_radius.setValue(10)
        self.sb_inner_radius.setRange(0, 9999)
        self.sb_rev_s.setValue(1)
        self.sb_rev_s.setRange(0.1, 9999)

        # Buttons
        self.btn_start = QPushButton("Start")
        self.btn_stop = QPushButton("Stop")
        self.btn_pick_color = QPushButton("Pick Color")
        self.btn_show_init = QPushButton("Show init args")

        # Connects
        self.sb_roundness.valueChanged.connect(self.set_roundness)
        self.sb_opacity.valueChanged.connect(self.set_opacity)
        self.sb_fadeperc.valueChanged.connect(self.set_fadeperc)
        self.sb_lines.valueChanged.connect(self.set_lines)
        self.sb_line_length.valueChanged.connect(self.set_line_length)
        self.sb_line_width.valueChanged.connect(self.set_line_width)
        self.sb_inner_radius.valueChanged.connect(self.set_inner_radius)
        self.sb_rev_s.valueChanged.connect(self.set_rev_s)

        self.btn_start.clicked.connect(self.spinner_start)
        self.btn_stop.clicked.connect(self.spinner_stop)
        self.btn_pick_color.clicked.connect(self.show_color_picker)
        self.btn_show_init.clicked.connect(self.show_init_args)

        # Layout adds
        groupbox1_layout.addWidget(self.spinner)
        groupbox1.setLayout(groupbox1_layout)

        groupbox2_layout.addWidget(QLabel("Roundness:"), *(1, 1))
        groupbox2_layout.addWidget(self.sb_roundness, *(1, 2))
        groupbox2_layout.addWidget(QLabel("Opacity:"), *(2, 1))
        groupbox2_layout.addWidget(self.sb_opacity, *(2, 2))
        groupbox2_layout.addWidget(QLabel("Fade Perc:"), *(3, 1))
        groupbox2_layout.addWidget(self.sb_fadeperc, *(3, 2))
        groupbox2_layout.addWidget(QLabel("Lines:"), *(4, 1))
        groupbox2_layout.addWidget(self.sb_lines, *(4, 2))
        groupbox2_layout.addWidget(QLabel("Line Length:"), *(5, 1))
        groupbox2_layout.addWidget(self.sb_line_length, *(5, 2))
        groupbox2_layout.addWidget(QLabel("Line Width:"), *(6, 1))
        groupbox2_layout.addWidget(self.sb_line_width, *(6, 2))
        groupbox2_layout.addWidget(QLabel("Inner Radius:"), *(7, 1))
        groupbox2_layout.addWidget(self.sb_inner_radius, *(7, 2))
        groupbox2_layout.addWidget(QLabel("Rev/s:"), *(8, 1))
        groupbox2_layout.addWidget(self.sb_rev_s, *(8, 2))

        groupbox2.setLayout(groupbox2_layout)

        button_hbox.addWidget(self.btn_start)
        button_hbox.addWidget(self.btn_stop)
        button_hbox.addWidget(self.btn_pick_color)
        button_hbox.addWidget(self.btn_show_init)

        grid.addWidget(groupbox1, *(1, 1))
        grid.addWidget(groupbox2, *(1, 2))
        grid.addLayout(button_hbox, *(2, 1))

        self.spinner.start()
        self.show()
Example #12
0
class Demo(QWidget):
    sb_roundness = None
    sb_opacity = None
    sb_fadeperc = None
    sb_lines = None
    sb_line_length = None
    sb_line_width = None
    sb_inner_radius = None
    sb_rev_s = None

    btn_start = None
    btn_stop = None
    btn_pick_color = None

    spinner = None

    def __init__(self):
        super().__init__()
        self.init_ui()

    def init_ui(self):
        grid = QGridLayout()
        groupbox1 = QGroupBox()
        groupbox1_layout = QHBoxLayout()
        groupbox2 = QGroupBox()
        groupbox2_layout = QGridLayout()
        button_hbox = QHBoxLayout()
        self.setLayout(grid)
        self.setWindowTitle("QtWaitingSpinner Demo")
        self.setWindowFlags(Qt.Dialog)

        # SPINNER
        self.spinner = WaitingSpinner(self)

        # Spinboxes
        self.sb_roundness = QDoubleSpinBox()
        self.sb_opacity = QDoubleSpinBox()
        self.sb_fadeperc = QDoubleSpinBox()
        self.sb_lines = QSpinBox()
        self.sb_line_length = QDoubleSpinBox()
        self.sb_line_width = QDoubleSpinBox()
        self.sb_inner_radius = QDoubleSpinBox()
        self.sb_rev_s = QDoubleSpinBox()

        # set spinbox default values
        self.sb_roundness.setValue(70)
        self.sb_roundness.setRange(0, 9999)
        self.sb_opacity.setValue(15)
        self.sb_opacity.setRange(0, 9999)
        self.sb_fadeperc.setValue(70)
        self.sb_fadeperc.setRange(0, 9999)
        self.sb_lines.setValue(12)
        self.sb_lines.setRange(1, 9999)
        self.sb_line_length.setValue(10)
        self.sb_line_length.setRange(0, 9999)
        self.sb_line_width.setValue(5)
        self.sb_line_width.setRange(0, 9999)
        self.sb_inner_radius.setValue(10)
        self.sb_inner_radius.setRange(0, 9999)
        self.sb_rev_s.setValue(1)
        self.sb_rev_s.setRange(0.1, 9999)

        # Buttons
        self.btn_start = QPushButton("Start")
        self.btn_stop = QPushButton("Stop")
        self.btn_pick_color = QPushButton("Pick Color")
        self.btn_show_init = QPushButton("Show init args")

        # Connects
        self.sb_roundness.valueChanged.connect(self.set_roundness)
        self.sb_opacity.valueChanged.connect(self.set_opacity)
        self.sb_fadeperc.valueChanged.connect(self.set_fadeperc)
        self.sb_lines.valueChanged.connect(self.set_lines)
        self.sb_line_length.valueChanged.connect(self.set_line_length)
        self.sb_line_width.valueChanged.connect(self.set_line_width)
        self.sb_inner_radius.valueChanged.connect(self.set_inner_radius)
        self.sb_rev_s.valueChanged.connect(self.set_rev_s)

        self.btn_start.clicked.connect(self.spinner_start)
        self.btn_stop.clicked.connect(self.spinner_stop)
        self.btn_pick_color.clicked.connect(self.show_color_picker)
        self.btn_show_init.clicked.connect(self.show_init_args)

        # Layout adds
        groupbox1_layout.addWidget(self.spinner)
        groupbox1.setLayout(groupbox1_layout)

        groupbox2_layout.addWidget(QLabel("Roundness:"), *(1, 1))
        groupbox2_layout.addWidget(self.sb_roundness, *(1, 2))
        groupbox2_layout.addWidget(QLabel("Opacity:"), *(2, 1))
        groupbox2_layout.addWidget(self.sb_opacity, *(2, 2))
        groupbox2_layout.addWidget(QLabel("Fade Perc:"), *(3, 1))
        groupbox2_layout.addWidget(self.sb_fadeperc, *(3, 2))
        groupbox2_layout.addWidget(QLabel("Lines:"), *(4, 1))
        groupbox2_layout.addWidget(self.sb_lines, *(4, 2))
        groupbox2_layout.addWidget(QLabel("Line Length:"), *(5, 1))
        groupbox2_layout.addWidget(self.sb_line_length, *(5, 2))
        groupbox2_layout.addWidget(QLabel("Line Width:"), *(6, 1))
        groupbox2_layout.addWidget(self.sb_line_width, *(6, 2))
        groupbox2_layout.addWidget(QLabel("Inner Radius:"), *(7, 1))
        groupbox2_layout.addWidget(self.sb_inner_radius, *(7, 2))
        groupbox2_layout.addWidget(QLabel("Rev/s:"), *(8, 1))
        groupbox2_layout.addWidget(self.sb_rev_s, *(8, 2))

        groupbox2.setLayout(groupbox2_layout)

        button_hbox.addWidget(self.btn_start)
        button_hbox.addWidget(self.btn_stop)
        button_hbox.addWidget(self.btn_pick_color)
        button_hbox.addWidget(self.btn_show_init)

        grid.addWidget(groupbox1, *(1, 1))
        grid.addWidget(groupbox2, *(1, 2))
        grid.addLayout(button_hbox, *(2, 1))

        self.spinner.start()
        self.show()

    def set_roundness(self):
        self.spinner.setRoundness(self.sb_roundness.value())

    def set_opacity(self):
        self.spinner.setMinimumTrailOpacity(self.sb_opacity.value())

    def set_fadeperc(self):
        self.spinner.setTrailFadePercentage(self.sb_fadeperc.value())

    def set_lines(self):
        self.spinner.setNumberOfLines(self.sb_lines.value())

    def set_line_length(self):
        self.spinner.setLineLength(self.sb_line_length.value())

    def set_line_width(self):
        self.spinner.setLineWidth(self.sb_line_width.value())

    def set_inner_radius(self):
        self.spinner.setInnerRadius(self.sb_inner_radius.value())

    def set_rev_s(self):
        self.spinner.setRevolutionsPerSecond(self.sb_rev_s.value())

    def spinner_start(self):
        self.spinner.start()

    def spinner_stop(self):
        self.spinner.stop()

    def show_color_picker(self):
        self.spinner.setColor(QColorDialog.getColor())

    def show_init_args(self):
        text = ('WaitingSpinner(\n'
                '    parent,\n'
                '    roundness={}, opacity={},\n'
                '    fade={}, radius={}, lines={},\n'
                '    line_length={}, line_width={},\n'
                '    speed={}, color={}\n'
                ')\n').format(self.sb_roundness.value(),
                              self.sb_opacity.value(),
                              self.sb_fadeperc.value(),
                              self.sb_inner_radius.value(),
                              self.sb_lines.value(),
                              self.sb_line_length.value(),
                              self.sb_line_width.value(),
                              self.sb_rev_s.value(),
                              self.spinner.color.getRgb()[:3])

        msg_box = QMessageBox(text=text)
        msg_box.setWindowTitle('Text was copied to clipboard')
        cb = QApplication.clipboard()
        cb.clear(mode=cb.Clipboard)
        cb.setText(text, mode=cb.Clipboard)
        print(text)
        msg_box.exec_()
class SplashScreen(QtWidgets.QSplashScreen):
    """
    Generic splashcreen. Must always be spawned in a new thread, while the original thread
    executes qt_app.processEvents() in a while loop, until it should be stopped.
    """

    def __init__(self, background=True):
        """
        background: set the image as the background.
        The layout changes if background ist set.
        Without: the spinner plays in the middle. A screenshot is taken when the splashcreen
        initializes and set as background, so changing elements in the gui are not seen by the user.
        With: background image is scaled and spinner plays in the bottom middle.
        """
        self._is_background_set = background
        self._label = None
        self._spinner = None

        if background:
            pixmap = QtGui.QPixmap(str(get_asset_file("gui_base", "loading")))
            pixmap = pixmap.scaled(800, 480, transformMode=Qt.SmoothTransformation)
        else:
            if not config.qt_app:
                return # can not really happen...
            screen = config.qt_app.primaryScreen()
            pixmap = screen.grabWindow(voidptr(0))

        QtWidgets.QSplashScreen.__init__(self, pixmap)
        if config.DEBUG_LEVEL > 0: # unlock gui when debugging
            self.setWindowFlags(Qt.FramelessWindowHint)

    def mousePressEvent(self, event):  # pylint: disable=unused-argument, invalid-name, no-self-use
        """ Do nothing on mouse click. Otherwise it disappears. """
        return

    def showEvent(self, event):  # pylint: disable=unused-argument, invalid-name
        """ Start movie, when it is shown. """

        # show version label
        if self._is_background_set:
            self._label = QtWidgets.QLabel(self)
            self._label.setText(WAQD_VERSION + "   ")
            self._label.setAlignment(Qt.AlignmentFlag(Qt.AlignBottom | Qt.AlignRight))
            self._label.setGeometry(0, 0, 800, 480)
            self._label.show()
        self._spinner = WaitingSpinner(self, centerOnParent=False, radius=30, roundness=60,
                                      line_length=20, line_width=6, speed=0.5, color=(15, 67, 116))
        if self._is_background_set:
            self._spinner.setGeometry(int(self.width()/2 - self._spinner.width()/2),
                                     int(self.height() - self._spinner.height() - 20),
                                     self._spinner.width(),
                                     self._spinner.height())
        else:
            self._spinner.setColor("white")
            self._spinner.setInnerRadius(40)
            self._spinner.setLineLength(40)
            self._spinner.setLineWidth(8)
            self._spinner.setTrailFadePercentage(90)
            self._spinner.setGeometry(int(self.width()/2 - self._spinner.width()/2),
                                      int(self.height()/2 - self._spinner.height()/2),
                                     self._spinner.width(),
                                     self._spinner.height())
        self._spinner.start()

    def hideEvent(self, event):  # pylint: disable=unused-argument, invalid-name
        """ Stop movie, when it is hidden. """
        if self._spinner:
            self._spinner.stop()
Example #14
0
    def __init__(self, *args, **kwargs):
        super(MainWindow, self).__init__(*args, **kwargs)

        self.setWindowTitle('TD')
        self.setWindowOpacity(0.9)  #-- Why? IDK, I think it's cool.

        self.bg_color = self.palette()
        self.bg_color.setColor(self.backgroundRole(), QColor(0, 48, 64))
        self.bg_color_drag = self.palette()
        self.bg_color_drag.setColor(self.backgroundRole(), QColor(4, 14, 18))
        self.setPalette(self.bg_color)

        self.statusBar_label = QLabel(' Image Detected')
        self.statusBar_label.setStyleSheet('color: #5dbcd2')
        self.statusBar().addWidget(self.statusBar_label)
        self.statusBar().hide()

        self.setAcceptDrops(True)

        widget = QWidget()

        #-----Objects in Layouts-------
        self.spinner = WaitingSpinner(self,
                                      True,
                                      True,
                                      roundness=70.0,
                                      opacity=15.0,
                                      fade=70.0,
                                      radius=14.0,
                                      lines=12,
                                      line_length=16.0,
                                      line_width=4.0,
                                      speed=1.5,
                                      color=(255, 255, 255))

        self.top_label = QLabel()
        self.top_label.setFont(QFont("Arial", 14))
        self.top_label.setStyleSheet('color: white')
        self.top_label.setTextInteractionFlags(Qt.TextSelectableByMouse)
        self.top_label.setCursor(Qt.IBeamCursor)

        hLine = QFrame()
        hLine.setFrameShape(QFrame.HLine)
        hLine.setStyleSheet('color: white')

        self.bottom_label = QLabel()
        self.bottom_label.setFont(QFont("Arial", 14))
        self.bottom_label.setStyleSheet('color: white')
        self.bottom_label.setTextInteractionFlags(Qt.TextSelectableByMouse)
        self.bottom_label.setCursor(Qt.IBeamCursor)

        info_button_image_path = resource_path('./images/info_black.png')

        self.infoButton = QPushButton('', self)
        self.infoButton.setIcon(QIcon(info_button_image_path))
        self.infoButton.setCursor(Qt.PointingHandCursor)
        self.infoButton.clicked.connect(self.show_infoButton_message)
        self.infoButton.setMaximumWidth(30)
        self.infoButton.setToolTip("Info")
        self.infoButton.setFlat(True)

        #-------Layout Containers---------
        topHBox = QHBoxLayout()
        topHBox.addWidget(self.top_label)
        topHBox.addWidget(self.infoButton, 0, Qt.AlignRight | Qt.AlignTop)

        _layout = QVBoxLayout()
        _layout.addLayout(topHBox)
        _layout.addWidget(hLine, 0, Qt.AlignVCenter)
        _layout.addWidget(self.bottom_label)

        widget.setLayout(_layout)
        self.setCentralWidget(widget)

        self.start_here()
Example #15
0
    def __init__(self):
        super(Ui, self).__init__()
        MainUiFile = pathlib.Path(__file__).parent.absolute() / 'MainWindow.ui'
        uic.loadUi(MainUiFile, self)
        self.setWindowFlags(QtCore.Qt.FramelessWindowHint)

        self.findBoard = WaitingSpinner(self.Spinner,
                                        centerOnParent=True,
                                        roundness=100.0,
                                        opacity=100.0,
                                        fade=70.0,
                                        radius=4.0,
                                        lines=50,
                                        line_length=5.0,
                                        line_width=1.0,
                                        speed=1.5,
                                        color=(235, 167, 99))
        self.refreshbtn.clicked.connect(self.animsearch)
        self.searchlbl.setVisible(False)

        self.listWidget.itemDoubleClicked.connect(self.change_to_analysis_ui)
        self.stackedWidget.currentChanged.connect(self.change_btn_ui)
        self.dataignore = 0
        #:::Connecting Slots
        self.exitbtn.clicked.connect(lambda x: app.exit())
        self.maximizebtn.clicked.connect(self.maximize)
        self.minibtn.clicked.connect(self.minimize)
        self.stontopbtn.clicked.connect(self.StayonTop)
        self.stopbtn.clicked.connect(self.Close_ard)
        self.board_btn.clicked.connect(
            lambda x: self.stackedWidget.setCurrentIndex(0))
        self.data_btn.clicked.connect(
            lambda x: self.stackedWidget.setCurrentIndex(1))
        self.vib_btn.clicked.connect(
            lambda x: self.stackedWidget.setCurrentIndex(2))
        self.pi_btn.clicked.connect(
            lambda x: self.stackedWidget.setCurrentIndex(3))
        self.sld_smooth.valueChanged.connect(
            lambda x: self.lbl_smooth.setText(str(x)))

        self.dataPlot_1 = PlotArea('Data Plot - Sensor 1')
        self.dataPlot_1.ApplySignal(self.Cleared)
        self.verticalLayout_14.addWidget(self.dataPlot_1.innerWidget)
        self.dataPlot_2 = PlotArea('Data Plot - Sensor 2')
        self.dataPlot_2.ApplySignal(self.Cleared)
        self.verticalLayout_14.addWidget(self.dataPlot_2.innerWidget)
        self.dataPlot_3 = PlotArea('Data Plot - Sensor 3')
        self.dataPlot_3.ApplySignal(self.Cleared)
        self.verticalLayout_14.addWidget(self.dataPlot_3.innerWidget)
        self.dataPlot_4 = PlotArea('Data Plot - Sensor 4')
        self.dataPlot_4.ApplySignal(self.Cleared)
        self.verticalLayout_14.addWidget(self.dataPlot_4.innerWidget)

        self.response_plot_1 = PlotArea('System Response - Sensor 1')
        self.verticalLayout_23.addWidget(self.response_plot_1.innerWidget)
        self.response_plot_2 = PlotArea('System Response - Sensor 2')
        self.verticalLayout_23.addWidget(self.response_plot_2.innerWidget)
        self.response_plot_3 = PlotArea('System Response - Sensor 3')
        self.verticalLayout_23.addWidget(self.response_plot_3.innerWidget)
        self.response_plot_4 = PlotArea('System Response - Sensor 4')
        self.verticalLayout_23.addWidget(self.response_plot_4.innerWidget)

        self.pitchbtn.clicked.connect(self.ChangeCarModel)
        self.rollbtn.clicked.connect(self.ChangeCarModel)
        self.fullbtn.clicked.connect(self.ChangeCarModel)

        self.startbtn.clicked.connect(self.Connect)
        #::: -> Sliders values
        self.kfl_sld.valueChanged.connect(
            lambda x: self.kfl_lbl.setText(str(x) + ' N/m'))
        self.kfr_sld.valueChanged.connect(
            lambda x: self.kfr_lbl.setText(str(x) + ' N/m'))
        self.krr_sld.valueChanged.connect(
            lambda x: self.krr_lbl.setText(str(x) + ' N/m'))
        self.krl_sld.valueChanged.connect(
            lambda x: self.krl_lbl.setText(str(x) + ' N/m'))

        self.dfl_sld.valueChanged.connect(
            lambda x: self.dfl_lbl.setText(str(x) + ' N.s/m'))
        self.dfr_sld.valueChanged.connect(
            lambda x: self.dfr_lbl.setText(str(x) + ' N.s/m'))
        self.drr_sld.valueChanged.connect(
            lambda x: self.drr_lbl.setText(str(x) + ' N.s/m'))
        self.drl_sld.valueChanged.connect(
            lambda x: self.drl_lbl.setText(str(x) + ' N.s/m'))

        self.time = []
        self.dislocation = []
        #::: Filtering and Events
        self.pushButton_16.installEventFilter(self)

        self.scrollArea.viewport().installEventFilter(self)
        self.scrollArea_2.viewport().installEventFilter(self)
        self.oldPos = self.pos()

        self.show()
Example #16
0
class TransactionsWidget(QStackedWidget):

    sendButtonEnableConditions = [False, False]
    spinner = None

    def __init__(self, controller, refreshSignal):
        super().__init__()
        self.controller = controller
        self.refreshSignal = refreshSignal

        # Balance label
        balaceLabel = QLabel()
        balaceLabel.setText('Balance')
        balaceLabel.setAlignment(Qt.AlignCenter)

        # Balance amount label
        self.balaceAmountLabel = QLabel()
        self.balaceAmountLabel.setText(f'{self.controller.getBalance()} XRP')
        self.balaceAmountLabel.setAlignment(Qt.AlignCenter)
        font = QFont()
        font.setPointSize(20)
        self.balaceAmountLabel.setFont(font)

        # Balance layout
        balanceLayout = QVBoxLayout()
        balanceLayout.addWidget(balaceLabel)
        balanceLayout.addWidget(self.balaceAmountLabel)
        balanceLayout.setContentsMargins(0, 10, 0, 10)

        # Transactions label
        transactionsLabel = QLabel('Transactions')
        transactionsLabel.setAlignment(Qt.AlignCenter)
        transactionsLabel.setContentsMargins(0, 0, 0, 10)

        # Transactions table
        self.tableWidget = QTableWidget()
        self.tableWidget.setColumnCount(1)
        self.tableWidget.verticalHeader().setVisible(False)
        self.tableWidget.horizontalHeader().setVisible(False)
        self.tableWidget.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.tableWidget.horizontalHeader().setSectionResizeMode(0, QHeaderView.Stretch)
        self.populateTable()
        monofont = QFont()
        monofont.setFamily("Courier New")
        monofont.setPointSize(10)
        self.tableWidget.setFont(monofont)

        # Transactions layout
        transactionsLayout = QVBoxLayout()
        transactionsLayout.addWidget(transactionsLabel)
        transactionsLayout.addWidget(self.tableWidget)
        transactionsLayout.setContentsMargins(0, 0, 0, 0)

        # Send label A
        sendLabelA = QLabel('Send')
        sendLabelA.setAlignment(Qt.AlignCenter)

        # Send amount
        self.sendAmount = QLineEdit()
        self.sendAmount.setAlignment(Qt.AlignCenter)
        self.sendAmount.setFont(monofont)
        self.sendAmount.setPlaceholderText('Amount')
        validator = QRegExpValidator(QRegExp(r'^[0-9]+\.?[0-9]{0,6}$'))
        self.sendAmount.setValidator(validator)
        self.sendAmount.textChanged.connect(self.check_state)
        self.sendAmount.textChanged.emit(self.sendAmount.text())
        self.sendAmount.textChanged.connect(lambda: self.on_text_changed(0))

        # Send label B
        sendLabelB = QLabel('XRP to')
        sendLabelB.setAlignment(Qt.AlignCenter)

        # Send address
        self.sendAddress = QLineEdit()
        self.sendAddress.setAlignment(Qt.AlignCenter)
        self.sendAddress.setFont(monofont)
        self.sendAddress.setPlaceholderText('Address')
        validator = QRegExpValidator(QRegExp('^r[A-HJ-NP-Za-km-z1-9]{24,34}$'))
        self.sendAddress.setValidator(validator)
        self.sendAddress.textChanged.connect(self.check_state)
        self.sendAddress.textChanged.emit(self.sendAmount.text())
        self.sendAddress.textChanged.connect(lambda: self.on_text_changed(1))

        # Send tag
        self.sendTag = QLineEdit()
        self.sendTag.setAlignment(Qt.AlignCenter)
        self.sendTag.setFont(monofont)
        self.sendTag.setPlaceholderText('Tag')
        validator = QRegExpValidator(QRegExp(r'^\d*$'))
        self.sendTag.setValidator(validator)
        self.sendTag.textChanged.connect(self.check_state)

        # Send button
        self.sendButton = QPushButton()
        self.sendButton.setMaximumSize(40, 40)
        sendIcon = QIcon.fromTheme("mail-send")
        self.sendButton.setIcon(sendIcon)
        self.sendButton.setIconSize(QSize(24,24))
        self.sendButton.clicked.connect(self.on_send_clicked)
        self.sendButton.setEnabled(False)

        # Send layout
        sendLayout = QHBoxLayout()
        sendLayout.addWidget(sendLabelA)
        sendLayout.addWidget(self.sendAmount, 2)
        sendLayout.addWidget(sendLabelB)
        sendLayout.addWidget(self.sendAddress, 4)
        sendLayout.addWidget(self.sendTag, 1)
        sendLayout.addWidget(self.sendButton)
        sendLayout.setContentsMargins(0, 0, 0, 0)

        # Info layout
        balanceWidget = QWidget()
        balanceWidget.setLayout(balanceLayout)
        transactionsWidget = QWidget()
        transactionsWidget.setLayout(transactionsLayout)
        sendWidget = QWidget()
        sendWidget.setLayout(sendLayout)

        self.infoLayout = QVBoxLayout()
        self.infoLayout.setContentsMargins(0, 0, 0, 0)
        self.infoLayout.addWidget(balanceWidget)
        self.infoLayout.addWidget(transactionsWidget)
        self.infoLayout.addWidget(sendWidget)

        # Waiting spinner
        self.spinner = WaitingSpinner(self)
        self.spinnerLayout = QVBoxLayout()
        self.spinnerLayout.addWidget(self.spinner)
        self.spinner.start()

        # Stacked widget
        infoWidget = QWidget()
        infoWidget.setLayout(self.infoLayout)

        spinnerWidget = QWidget()
        spinnerWidget.setLayout(self.spinnerLayout)

        self.setContentsMargins(0, 0, 0, 0)
        self.addWidget(infoWidget)
        self.addWidget(spinnerWidget)
        self.setCurrentIndex(0)

    def switchWidget(self):
        if self.currentIndex() == 0:
            self.setCurrentIndex(1)
        else:
            self.setCurrentIndex(0)

    def on_send_clicked(self):
        confirmAlert = QMessageBox()
        confirmAlert.setWindowTitle('Send payment')
        confirmAlert.setText(f'You are about to send {self.sendAmount.text()} XRP to:\n'
                             f'Address: {self.sendAddress.text()}\n'
                             f'Destination tag: {self.sendTag.text() if self.sendTag.text() else "None"}\n'
                              'Continue?')
        confirmAlert.setIcon(QMessageBox.Warning)
        confirmAlert.setStandardButtons(QMessageBox.Cancel | QMessageBox.Ok)
        result = confirmAlert.exec_()

        if result == QMessageBox.Ok:
            payment = self.controller.sendPayment(self.sendAmount.text(),
                                                  self.sendAddress.text(),
                                                  self.sendTag.text())
            alert = QMessageBox()
            alert.setWindowTitle('Send payment')
            if payment['status'] == 'ok':
                alert.setText('Payment sent!')
                alert.setIcon(QMessageBox.Information)
                self.sendAmount.setText('')
                self.sendAddress.setText('')
                self.sendTag.setText('')
                self.refreshSignal.emit()
            else:
                alert.setWindowTitle('Something went wrong')
                alert.setText(payment['message'])
                alert.setIcon(QMessageBox.Critical)
            alert.exec_()

    def populateTable(self):
        txs = self.controller.getFormattedTransactions()
        self.tableWidget.setRowCount(len(txs))

        for i in range(len(txs)):
            item = QTableWidgetItem(txs[i])
            if '+' in txs[i]:
                item.setForeground(QBrush(QColor(hex_colors['green'])))
            elif '-' in txs[i]:
                item.setForeground(QBrush(QColor(hex_colors['red'])))
            else:
                item.setForeground(QBrush(QColor(hex_colors['white'])))
            item.setTextAlignment(Qt.AlignVCenter | Qt.AlignHCenter)
            self.tableWidget.setItem(i, 0, item)

    def contextMenuEvent(self, event):
        menu = QMenu(self)
        openAction = menu.addAction('Open transaction in browser')
        copyAddressAction = menu.addAction('Copy destination address')
        copyIDAction = menu.addAction('Copy transaction ID')
        gp = event.globalPos()
        action = menu.exec_(gp)
        vp_pos = self.tableWidget.viewport().mapFromGlobal(gp)
        row = self.tableWidget.rowAt(vp_pos.y())

        if action == openAction:
            self.controller.openTransactionInBrowser(row)
        elif action == copyAddressAction:
            txAddress = self.controller.getTxAddressByIndex(row)
            QApplication.clipboard().setText(txAddress)
        elif action == copyIDAction:
            txID = self.controller.getTxIDByIndex(row)
            QApplication.clipboard().setText(txID)

    def check_state(self, *args, **kwargs):
        sender = self.sender()
        validator = sender.validator()
        state = validator.validate(sender.text(), 0)[0]
        if not sender.text():
            color = hex_colors['white95']
        else:
            if state == QValidator.Acceptable:
                color = hex_colors['green']
            else:
                color = hex_colors['red']
        sender.setStyleSheet('QLineEdit { color: %s }' % color)

    def on_text_changed(self, i: int):
        sender = self.sender()
        validator = sender.validator()
        state = validator.validate(sender.text(), 0)[0]
        if state == QValidator.Acceptable:
            self.sendButtonEnableConditions[i] = True
        else:
            self.sendButtonEnableConditions[i] = False

        if False not in self.sendButtonEnableConditions:
            self.sendButton.setEnabled(True)
            self.sendButton.setStyleSheet(f"background-color: {hex_colors['blue']}")
        else:
            self.sendButton.setEnabled(False)
            self.sendButton.setStyleSheet(f"background-color: {hex_colors['grey']}")

    def on_new_data(self):
        result = {'status': 'ok'}
        for data in [self.controller.account_info, self.controller.transactions]:
            if data['status'] == 'error':
                result['status'] = 'error'
                result['message'] = self.api.get_error_message(data)
                break

        if result['status'] == 'ok':
            self.balaceAmountLabel.setText(f'{self.controller.getBalance()} XRP')
            self.populateTable()
        else:
            confirmAlert = QMessageBox()
            confirmAlert.setWindowTitle('Something went wrong')
            confirmAlert.setText(result['message'])
            confirmAlert.setIcon(QMessageBox.Critical)
            confirmAlert.setStandardButtons(QMessageBox.Ok)
            confirmAlert.exec_()
Example #17
0
class MyMenu(QtWidgets.QWidget):
    """
    Abstract Class for Menu
    """
    def __init__(self, width, height, parent, *args, **kwargs):
        super(MyMenu, self).__init__(*args, **kwargs)
        self.setStyleSheet("""background: #b4b4b4; color: black;""")

        self.parent = parent

        self.resize(width, height)

        self.main_layout = QtWidgets.QGridLayout()

        self.threadpool = QtCore.QThreadPool()
        self.wait = WaitingSpinner(self,
                                   True,
                                   True,
                                   QtCore.Qt.ApplicationModal,
                                   roundness=70.0,
                                   opacity=100.0,
                                   fade=70.0,
                                   radius=10.0,
                                   lines=12,
                                   line_length=10.0,
                                   line_width=5.0,
                                   speed=1.0,
                                   color=(0, 0, 0))

        self.setLayout(self.main_layout)

    def paintEvent(self, event):
        o = Qt.QStyleOption()
        o.initFrom(self)
        p = Qt.QPainter(self)
        self.style().drawPrimitive(Qt.QStyle.PE_Widget, o, p, self)

    def start_waiting(self):
        """
        """
        self.wait = WaitingSpinner(self,
                                   True,
                                   True,
                                   QtCore.Qt.ApplicationModal,
                                   roundness=70.0,
                                   opacity=100.0,
                                   fade=70.0,
                                   radius=10.0,
                                   lines=12,
                                   line_length=10.0,
                                   line_width=5.0,
                                   speed=1.0,
                                   color=(0, 0, 0))
        self.parent.btn_next.setEnabled(False)
        self.parent.btn_back.setEnabled(False)
        self.wait.start()

    def stop_waiting(self):
        """
        """
        self.parent.btn_next.setEnabled(True)
        self.parent.btn_back.setEnabled(True)
        self.wait.stop()

    def stop_waiting_next(self):
        """
        """
        self.stop_waiting()

        if self.parent.front_wid == 1:
            self.parent.wids[self.parent.front_wid + 1].set_maximum_spinbox()

        self.parent.next_wid_logic()

    def error_no_music(self, value):
        """
        Receive signal if no music to create statistics
        """
        msg = QtWidgets.QMessageBox()
        msg.setStyleSheet("""background: #b4b4b4;""")
        msg.setContentsMargins(5, 5, 5, 5)
        msg.setIcon(QtWidgets.QMessageBox.Warning)
        msg.setText("No Music! Go Back and select some!")
        msg.setWindowTitle('No Music Warning')
        msg.exec_()

    def stop_waiting_final(self):
        self.stop_waiting()

        msg = QtWidgets.QMessageBox()
        msg.setStyleSheet("""background: #b4b4b4;""")
        msg.setContentsMargins(5, 5, 5, 5)
        msg.setIcon(QtWidgets.QMessageBox.Information)

        splitted_db = self.parent.application.database_path.split(os.sep)
        if len(splitted_db) == 1:
            splitted_db = splitted_db[0].split('/')

        db_path = os.sep.join(splitted_db[:-1] + ['generations'])
        if os.path.exists(db_path):
            all_subdirs = [
                os.sep.join([db_path, d]) for d in os.listdir(db_path + os.sep)
                if os.path.isdir(os.sep.join([db_path, d]))
            ]
            if len(all_subdirs) > 0:
                latest_subdir = max(all_subdirs, key=os.path.getmtime)
                db_path = latest_subdir

        msg.setText(
            wrap_text(
                "Generation of Sequences Finished!!!\n Sequences in folder: " +
                db_path, 40))
        msg.setWindowTitle('Creator Finished')
        msg.buttonClicked.connect(lambda: QtGui.QDesktopServices.openUrl(
            QtCore.QUrl.fromLocalFile(db_path)))
        msg.exec_()

    def next(self):
        """
        To Override
        """
        pass

    def back(self):
        """
        To Override
        """
        self.parent.last_wid_logic()
Example #18
0
    def __init__(self, controller, refreshSignal):
        super().__init__()
        self.controller = controller
        self.refreshSignal = refreshSignal

        # Balance label
        balaceLabel = QLabel()
        balaceLabel.setText('Balance')
        balaceLabel.setAlignment(Qt.AlignCenter)

        # Balance amount label
        self.balaceAmountLabel = QLabel()
        self.balaceAmountLabel.setText(f'{self.controller.getBalance()} XRP')
        self.balaceAmountLabel.setAlignment(Qt.AlignCenter)
        font = QFont()
        font.setPointSize(20)
        self.balaceAmountLabel.setFont(font)

        # Balance layout
        balanceLayout = QVBoxLayout()
        balanceLayout.addWidget(balaceLabel)
        balanceLayout.addWidget(self.balaceAmountLabel)
        balanceLayout.setContentsMargins(0, 10, 0, 10)

        # Transactions label
        transactionsLabel = QLabel('Transactions')
        transactionsLabel.setAlignment(Qt.AlignCenter)
        transactionsLabel.setContentsMargins(0, 0, 0, 10)

        # Transactions table
        self.tableWidget = QTableWidget()
        self.tableWidget.setColumnCount(1)
        self.tableWidget.verticalHeader().setVisible(False)
        self.tableWidget.horizontalHeader().setVisible(False)
        self.tableWidget.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.tableWidget.horizontalHeader().setSectionResizeMode(0, QHeaderView.Stretch)
        self.populateTable()
        monofont = QFont()
        monofont.setFamily("Courier New")
        monofont.setPointSize(10)
        self.tableWidget.setFont(monofont)

        # Transactions layout
        transactionsLayout = QVBoxLayout()
        transactionsLayout.addWidget(transactionsLabel)
        transactionsLayout.addWidget(self.tableWidget)
        transactionsLayout.setContentsMargins(0, 0, 0, 0)

        # Send label A
        sendLabelA = QLabel('Send')
        sendLabelA.setAlignment(Qt.AlignCenter)

        # Send amount
        self.sendAmount = QLineEdit()
        self.sendAmount.setAlignment(Qt.AlignCenter)
        self.sendAmount.setFont(monofont)
        self.sendAmount.setPlaceholderText('Amount')
        validator = QRegExpValidator(QRegExp(r'^[0-9]+\.?[0-9]{0,6}$'))
        self.sendAmount.setValidator(validator)
        self.sendAmount.textChanged.connect(self.check_state)
        self.sendAmount.textChanged.emit(self.sendAmount.text())
        self.sendAmount.textChanged.connect(lambda: self.on_text_changed(0))

        # Send label B
        sendLabelB = QLabel('XRP to')
        sendLabelB.setAlignment(Qt.AlignCenter)

        # Send address
        self.sendAddress = QLineEdit()
        self.sendAddress.setAlignment(Qt.AlignCenter)
        self.sendAddress.setFont(monofont)
        self.sendAddress.setPlaceholderText('Address')
        validator = QRegExpValidator(QRegExp('^r[A-HJ-NP-Za-km-z1-9]{24,34}$'))
        self.sendAddress.setValidator(validator)
        self.sendAddress.textChanged.connect(self.check_state)
        self.sendAddress.textChanged.emit(self.sendAmount.text())
        self.sendAddress.textChanged.connect(lambda: self.on_text_changed(1))

        # Send tag
        self.sendTag = QLineEdit()
        self.sendTag.setAlignment(Qt.AlignCenter)
        self.sendTag.setFont(monofont)
        self.sendTag.setPlaceholderText('Tag')
        validator = QRegExpValidator(QRegExp(r'^\d*$'))
        self.sendTag.setValidator(validator)
        self.sendTag.textChanged.connect(self.check_state)

        # Send button
        self.sendButton = QPushButton()
        self.sendButton.setMaximumSize(40, 40)
        sendIcon = QIcon.fromTheme("mail-send")
        self.sendButton.setIcon(sendIcon)
        self.sendButton.setIconSize(QSize(24,24))
        self.sendButton.clicked.connect(self.on_send_clicked)
        self.sendButton.setEnabled(False)

        # Send layout
        sendLayout = QHBoxLayout()
        sendLayout.addWidget(sendLabelA)
        sendLayout.addWidget(self.sendAmount, 2)
        sendLayout.addWidget(sendLabelB)
        sendLayout.addWidget(self.sendAddress, 4)
        sendLayout.addWidget(self.sendTag, 1)
        sendLayout.addWidget(self.sendButton)
        sendLayout.setContentsMargins(0, 0, 0, 0)

        # Info layout
        balanceWidget = QWidget()
        balanceWidget.setLayout(balanceLayout)
        transactionsWidget = QWidget()
        transactionsWidget.setLayout(transactionsLayout)
        sendWidget = QWidget()
        sendWidget.setLayout(sendLayout)

        self.infoLayout = QVBoxLayout()
        self.infoLayout.setContentsMargins(0, 0, 0, 0)
        self.infoLayout.addWidget(balanceWidget)
        self.infoLayout.addWidget(transactionsWidget)
        self.infoLayout.addWidget(sendWidget)

        # Waiting spinner
        self.spinner = WaitingSpinner(self)
        self.spinnerLayout = QVBoxLayout()
        self.spinnerLayout.addWidget(self.spinner)
        self.spinner.start()

        # Stacked widget
        infoWidget = QWidget()
        infoWidget.setLayout(self.infoLayout)

        spinnerWidget = QWidget()
        spinnerWidget.setLayout(self.spinnerLayout)

        self.setContentsMargins(0, 0, 0, 0)
        self.addWidget(infoWidget)
        self.addWidget(spinnerWidget)
        self.setCurrentIndex(0)
Example #19
0
 def set_loading_indicator(self):
     self.indicator = WaitingSpinner(self.view, True, True,
                                     Qt.ApplicationModal)
Example #20
0
class JobList(QWidget):
    def __init__(self, connection):
        super(JobList, self).__init__()
        self.connection = connection
        self.jobTableModel = JobTableModel()
        self.jobTableView = JobTableView(self.jobTableModel)
        #self.dbTable = config.DB.table("jobs")
        self.log = Logger(jobList=self)
        self.listJobs()
        self.tunnels = {}
        self.threadpool = QThreadPool()

        # Waiting spinner
        self.spinner = WaitingSpinner(self.jobTableView)
        self.spinner.setNumberOfLines(18)
        self.spinner.setInnerRadius(12)
        self.spinner.setLineLength(20)
        self.spinner.setLineWidth(5)

        # Init, but do not start timers before
        # a connection with the server is established
        self.timer = QTimer(self)
        self.timer.setInterval(1000)
        self.timer.timeout.connect(self.smartSync)

        self.elapsedTimer = QElapsedTimer()
        self.loaded = False
        self.jobsPending = True

    def isConnected(self):
        self.timer.start()
        self.elapsedTimer.restart()
        self.labelJobs.setText("Connecting with %s" %
                               self.connection.connectionName)
        self.labelJobs.setStyleSheet("QLabel { color : black; }")

    def isDisconnected(self):
        self.timer.stop()
        self.labelJobs.setText("Not connected with  %s" %
                               self.connection.connectionName)
        self.labelJobs.setStyleSheet("QLabel { color : red; }")

    def updateConnection(self, connection):
        self.connection = connection

    def smartSync(self):

        if self.loaded:
            minutes = floor(self.elapsedTimer.elapsed() / (60 * 1000))
            seconds = self.elapsedTimer.elapsed() % (60 * 1000) / 1000

            self.labelJobs.setText(
                "Jobs (%d). Last update: %d min and %d sec ago" %
                (len(self.jobTableModel.jobs), minutes, seconds))

            if self.jobsPending and self.elapsedTimer.hasExpired(
                    config.SYNC_JOBS_WITH_SERVER_INTERVAL_SECONDS_SHORT *
                    1000):
                self.syncJobs()
            elif self.elapsedTimer.hasExpired(
                    config.SYNC_JOBS_WITH_SERVER_INTERVAL_SECONDS_LONG * 1000):
                self.syncJobs()

    def updateJobsPending(self):
        self.jobsPending = False
        for jobID, job in self.jobTableModel.jobs.items():
            if job.status == 0:
                self.jobsPending = True
                return

    def listJobs(self):

        basedir = "icons"
        if hasattr(sys, 'frozen') and hasattr(sys, '_MEIPASS'):
            basedir = os.path.join(sys._MEIPASS, "icons")

        self.vLayout = QVBoxLayout()

        ### Add label
        font = QFont()
        font.setBold(True)
        font.setWeight(75)

        if self.connection.isConnected():
            self.labelJobs = QLabel("Jobs (%d)" % len(self.jobTableModel.jobs))
            self.labelJobs.setStyleSheet("QLabel { color : black; }")
        else:
            self.labelJobs = QLabel("Not connected with %s" %
                                    self.connection.connectionName)
            self.labelJobs.setStyleSheet("QLabel { color : red; }")
        self.labelJobs.setFont(font)
        self.vLayout.addWidget(self.labelJobs)

        ### Add jobView
        self.jobTableView.setView()
        self.vLayout.addWidget(self.jobTableView)

        ### Buttons
        hLayoutWidget = QWidget()
        hLayoutWidget.setGeometry(QRect(0, 0, 200, 200))
        hLayout = QHBoxLayout(hLayoutWidget)

        # Add job
        icon = QIcon()
        icon.addPixmap(QPixmap(os.path.join(basedir, "add_job_normal.png")),
                       QIcon.Normal)
        icon.addPixmap(QPixmap(os.path.join(basedir, "add_job_hot.png")),
                       QIcon.Active)
        icon.addPixmap(QPixmap(os.path.join(basedir, "add_job_disabled.png")),
                       QIcon.Disabled)

        self.addButton = QPushButton("Add Job")
        self.addButton.setObjectName("add_job")
        self.addButton.setIcon(icon)
        self.addButton.setIconSize(QSize(24, 24))
        self.addButton.installEventFilter(self)
        self.addButton.setEnabled(False)
        hLayout.addWidget(self.addButton)

        # Delete job
        icon1 = QIcon()
        icon1.addPixmap(
            QPixmap(os.path.join(basedir, "delete_jobs_normal.png")),
            QIcon.Normal)
        icon1.addPixmap(QPixmap(os.path.join(basedir, "delete_jobs_hot.png")),
                        QIcon.Active)
        icon1.addPixmap(
            QPixmap(os.path.join(basedir, "delete_jobs_disabled.png")),
            QIcon.Disabled)

        self.deleteAllButton = QPushButton("Delete all jobs")
        self.deleteAllButton.setObjectName("delete_jobs")
        self.deleteAllButton.setIcon(icon1)
        self.deleteAllButton.setIconSize(QSize(24, 24))
        self.deleteAllButton.installEventFilter(self)
        self.deleteAllButton.setEnabled(False)
        hLayout.addWidget(self.deleteAllButton)

        # syncButton
        icon2 = QIcon()
        icon2.addPixmap(QPixmap(os.path.join(basedir, "sync_jobs_normal.png")),
                        QIcon.Normal)
        icon2.addPixmap(QPixmap(os.path.join(basedir, "sync_job_hot.png")),
                        QIcon.Active)
        icon2.addPixmap(
            QPixmap(os.path.join(basedir, "sync_jobs_disabled.png")),
            QIcon.Disabled)

        self.syncButton = QPushButton("Sync jobs")
        self.syncButton.setObjectName("sync_jobs")
        self.syncButton.setIcon(icon2)
        self.syncButton.setIconSize(QSize(24, 24))
        self.syncButton.installEventFilter(self)
        self.syncButton.setEnabled(False)
        hLayout.addWidget(self.syncButton)

        # clearLogButton
        icon3 = QIcon()
        icon3.addPixmap(QPixmap(os.path.join(basedir, "clear_log_normal.png")),
                        QIcon.Normal)
        icon3.addPixmap(QPixmap(os.path.join(basedir, "clear_log_hot.png")),
                        QIcon.Active)
        icon3.addPixmap(
            QPixmap(os.path.join(basedir, "clear_log_disabled.png")),
            QIcon.Disabled)

        self.clearLogButton = QPushButton("Clear log")
        self.clearLogButton.setObjectName("clear_log")
        self.clearLogButton.setIcon(icon3)
        self.clearLogButton.setIconSize(QSize(24, 24))
        self.clearLogButton.installEventFilter(self)
        self.clearLogButton.setEnabled(False)
        hLayout.addWidget(self.clearLogButton)

        self.vLayout.addWidget(hLayoutWidget)

        # Log
        labelLogOutput = QLabel("Log output:")
        labelLogOutput.setFont(font)
        self.vLayout.addWidget(labelLogOutput)

        # Log edit box
        self.logEdit = QTextEdit()
        self.logEdit.setGeometry(QRect(0, 0, 800, 400))
        self.logEdit.setReadOnly(True)
        self.vLayout.addWidget(self.logEdit)

        # Button handling
        self.addButton.clicked.connect(self.addJob)
        self.deleteAllButton.pressed.connect(self.confirmDeleteAllJobs)
        self.syncButton.pressed.connect(self.syncJobs)
        self.clearLogButton.pressed.connect(self.clearLog)

        self.setLayout(self.vLayout)

    def clearLog(self):
        self.logEdit.clear()

    def syncJobs(self):
        # Start a worker that calls the __connect function and
        # synchronizes the jobs running on the server

        Q = JobQueue.getQueueObject(self.connection)

        # connect to host
        worker = Worker(Q.syncJobs, task="sync")
        worker.signals.updateStarted.connect(self.updateStarted)
        worker.signals.progress.connect(self.writeLog)
        worker.signals.jobsSynced.connect(self.jobTableModel.setJobs)
        worker.signals.updateFinished.connect(self.updateFinished)

        self.threadpool.start(worker)
        self.updateJobsPending()

    def addJob(self):
        frm = JobForm(Job(connection=self.connection))
        frm.setModal(True)
        if frm.exec():

            port = randint(8787, 10000)

            # Submit
            job = Job(
                connection=self.connection,
                jobID=0,
                jobName=frm.edtJobName.text(),
                projectFolder=frm.cmbProjectFolder.currentText().strip(),
                startTime=datetime.now().strftime("%m/%d/%Y %H:%M:%S"),
                runTime=frm.spinRuntime.value(),
                nCPU=frm.spinNrOfCPU.value(),
                nGPU=frm.spinNrOfGPU.value(),
                memory=frm.spinMemory.value(),
                singularityImg=frm.cmbSingularityImg.currentText().strip(),
                workerNode=None,
                status=0,
                editor=frm.cmbEditor.currentText().strip(),
                port=port)

            self.submitJob(job)

    def viewJob(self, jobID):
        frm = JobForm(self.jobTableModel.jobs[jobID], edit=False)
        frm.setModal(True)
        frm.exec()

    def submitJob(self, job):
        Q = JobQueue.getQueueObject(self.connection)

        worker = Worker(Q.submitJob, job=job, task="submit")

        # make
        # worker = Worker(self.__submit, job)
        worker.signals.updateStarted.connect(self.updateStarted)
        worker.signals.progress.connect(self.writeLog)
        worker.signals.jobSubmitted.connect(self.jobTableModel.addJob)
        worker.signals.updateFinished.connect(self.updateFinished)

        self.jobsPending = True
        self.threadpool.start(worker)

    def confirmDeleteJob(self, index):
        jobIDs = list(self.connection.jobs.keys())
        job = self.connection.jobs[jobIDs[index.row()]]

        msg = QMessageBox(self)
        msg.setIcon(QMessageBox.Information)

        msg.setText("Delete job %s (%d)?" % (job.jobName, job.jobID))
        msg.setInformativeText("Unsaved work will be lost!")
        msg.setWindowTitle("Delete Job")
        msg.setStandardButtons(QMessageBox.Ok | QMessageBox.Cancel)
        msg.setStandardButtons(QMessageBox.Ok | QMessageBox.Cancel)

        if msg.exec() == QMessageBox.Ok:
            job.closeSSHTunnel(self)
            self.connection.deleteJob(job.jobID)

    def confirmDeleteAllJobs(self):
        msg = QMessageBox(self)
        msg.setIcon(QMessageBox.Information)

        msg.setText("Delete all jobs?")
        msg.setInformativeText("Unsaved work will be lost!")
        msg.setWindowTitle("Delete jobs")
        msg.setStandardButtons(QMessageBox.Ok | QMessageBox.Cancel)
        if msg.exec() == QMessageBox.Ok:
            self.deleteAllJobs()

    def deleteAllJobs(self):
        for jobID in self.jobTableModel.jobs:
            self.deleteJob(jobID)

    def deleteJob(self, jobID):
        try:
            #print("joblist -> DELETE JOB")

            # part of the queue => this should use Factory design
            Q = JobQueue.getQueueObject(self.connection)

            worker = Worker(Q.deleteJob, jobID=jobID, task="delete")
            worker.signals.updateStarted.connect(self.updateStarted)
            worker.signals.progress.connect(self.writeLog)
            worker.signals.jobDeleted.connect(self.jobTableModel.deleteJob)
            worker.signals.updateFinished.connect(self.updateFinished)

            # Execute job
            self.threadpool.start(worker)
        except:
            self.msgSignal.emit({
                'connectionID': self.connectionID,
                'jobID': jobID,
                'message': str(sys.exc_info()[1]),
                'messageType': 'ERROR'
            })

    def updateStarted(self):
        self.addButton.setEnabled(False)
        self.deleteAllButton.setEnabled(False)
        self.syncButton.setEnabled(False)
        self.clearLogButton.setEnabled(False)

        self.spinner.start()

    def updateFinished(self):
        self.spinner.stop()

        # emit layout changed to reload all jobs
        self.jobTableModel.layoutChanged.emit()

        # enable buttons
        self.addButton.setEnabled(True)
        self.deleteAllButton.setEnabled(True)
        self.syncButton.setEnabled(True)
        self.clearLogButton.setEnabled(True)

        # restart timer
        self.loaded = True
        self.elapsedTimer.restart()

    def writeLog(self, msg):
        self.log.writeLine(connectionID=msg['connectionID'],
                           jobID=msg['jobID'],
                           message=msg['message'],
                           messageType=msg['messageType'],
                           show=True)

    def browse(self, jobID):
        job = self.jobTableModel.jobs[jobID]
        res = job.openSSHTunnel(self)

        if res is True:
            webbrowser.open_new_tab("http://localhost:%d" % int(job.port))
        else:
            self.log.writeLine(connectionID=self.connection.connectionID,
                               jobID=jobID,
                               message=res,
                               messageType="ERROR",
                               show=True)

    # Change the image from "normal" to "hot" on mouseover
    def eventFilter(self, object, event):

        basedir = "icons"
        if hasattr(sys, 'frozen') and hasattr(sys, '_MEIPASS'):
            basedir = os.path.join(sys._MEIPASS, "icons")

        if event.type() == QEvent.HoverEnter:
            object.setIcon(
                QIcon(os.path.join(basedir,
                                   object.objectName() + "_hot.png")))
        elif event.type() == QEvent.HoverLeave:
            object.setIcon(
                QIcon(
                    os.path.join(basedir,
                                 object.objectName() + "_normal.png")))

        return False
Example #21
0
    def __init__(self, *args, **kwargs):
        super(AppWindow, self).__init__(*args, **kwargs)
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)

        # translations..?!
        self._translate = QCoreApplication.translate

        self.check_config()

        # initialize attributes
        self.invoice_to_check = None
        self.invoice_to_check_flag = None

        self.uptime = 0

        self.status_lnd_due = 0
        self.status_lnd_interval = STATUS_INTERVAL_LND
        self.status_lnd_pid_ok = False
        self.status_lnd_listen_ok = False
        self.status_lnd_unlocked = False
        self.status_lnd_synced_to_chain = False
        self.status_lnd_synced_to_graph = False

        self.status_lnd_channel_due = 0
        self.status_lnd_channel_interval = STATUS_INTERVAL_LND_CHANNELS
        self.status_lnd_channel_total_active = 0
        self.status_lnd_channel_total_remote_balance = 0

        # initial updates
        self.update_uptime()
        if self.cfg_valid:
            self.update_status_lnd()
            self.update_status_lnd_channels()

        # initial update of Main Window Title Bar
        self.update_title_bar()

        # Align Main Window Top Left
        self.move(0, 0)

        # set as maximized (unless on Windows dev host)
        if IS_WIN32_ENV:
            log.info("not maximizing window on win32")
        else:
            self.setWindowState(Qt.WindowMaximized)

        # Bindings: buttons
        self.ui.pushButton_1.clicked.connect(self.on_button_1_clicked)
        self.ui.pushButton_2.clicked.connect(self.on_button_2_clicked)
        self.ui.pushButton_3.clicked.connect(self.on_button_3_clicked)
        self.ui.pushButton_4.clicked.connect(self.on_button_4_clicked)

        # disable button 1 for now
        self.ui.pushButton_1.setEnabled(False)

        # connect error dismiss button and hide for start
        self.ui.buttonBox_close.button(QDialogButtonBox.Close).setText("Ok")
        self.ui.buttonBox_close.button(QDialogButtonBox.Close).clicked.connect(
            self.hide_error)
        self.hide_error()

        # Show QR Code Dialog Windows
        self.w_qr_code = QDialog(flags=(Qt.Dialog | Qt.FramelessWindowHint))
        self.ui_qr_code = Ui_DialogShowQrCode()
        self.ui_qr_code.setupUi(self.w_qr_code)
        self.w_qr_code.move(0, 0)

        # SPINNER for CR Code Dialog Window
        self.ui_qr_code.spinner = WaitingSpinner(self.w_qr_code)

        self.beat_thread = BeatThread()
        self.beat_thread.signal.connect(self.process_beat)
        self.beat_thread.start()

        self.generate_qr_code_thread = GenerateQrCodeThread()
        self.generate_qr_code_thread.signal.connect(
            self.generate_qr_code_finished)

        self.file_watcher = FileWatcherThread(
            dir_names=[
                os.path.dirname(LND_CONF),
                os.path.dirname(RB_CONF),
                os.path.dirname(RB_INFO)
            ],
            file_names=[
                os.path.basename(LND_CONF),
                os.path.basename(RB_CONF),
                os.path.basename(RB_INFO)
            ],
        )
        self.file_watcher.signal.connect(self.update_watched_attr)
        self.file_watcher.start()

        # finally start 00infoBlitz.sh in dedicated xterm frame
        self.start_info_lcd()

        self.show()
Example #22
0
class MainWindow(QMainWindow):
    def __init__(self, *args, **kwargs):
        super(MainWindow, self).__init__(*args, **kwargs)

        self.setWindowTitle('TD')
        self.setWindowOpacity(0.9)  #-- Why? IDK, I think it's cool.

        self.bg_color = self.palette()
        self.bg_color.setColor(self.backgroundRole(), QColor(0, 48, 64))
        self.bg_color_drag = self.palette()
        self.bg_color_drag.setColor(self.backgroundRole(), QColor(4, 14, 18))
        self.setPalette(self.bg_color)

        self.statusBar_label = QLabel(' Image Detected')
        self.statusBar_label.setStyleSheet('color: #5dbcd2')
        self.statusBar().addWidget(self.statusBar_label)
        self.statusBar().hide()

        self.setAcceptDrops(True)

        widget = QWidget()

        #-----Objects in Layouts-------
        self.spinner = WaitingSpinner(self,
                                      True,
                                      True,
                                      roundness=70.0,
                                      opacity=15.0,
                                      fade=70.0,
                                      radius=14.0,
                                      lines=12,
                                      line_length=16.0,
                                      line_width=4.0,
                                      speed=1.5,
                                      color=(255, 255, 255))

        self.top_label = QLabel()
        self.top_label.setFont(QFont("Arial", 14))
        self.top_label.setStyleSheet('color: white')
        self.top_label.setTextInteractionFlags(Qt.TextSelectableByMouse)
        self.top_label.setCursor(Qt.IBeamCursor)

        hLine = QFrame()
        hLine.setFrameShape(QFrame.HLine)
        hLine.setStyleSheet('color: white')

        self.bottom_label = QLabel()
        self.bottom_label.setFont(QFont("Arial", 14))
        self.bottom_label.setStyleSheet('color: white')
        self.bottom_label.setTextInteractionFlags(Qt.TextSelectableByMouse)
        self.bottom_label.setCursor(Qt.IBeamCursor)

        info_button_image_path = resource_path('./images/info_black.png')

        self.infoButton = QPushButton('', self)
        self.infoButton.setIcon(QIcon(info_button_image_path))
        self.infoButton.setCursor(Qt.PointingHandCursor)
        self.infoButton.clicked.connect(self.show_infoButton_message)
        self.infoButton.setMaximumWidth(30)
        self.infoButton.setToolTip("Info")
        self.infoButton.setFlat(True)

        #-------Layout Containers---------
        topHBox = QHBoxLayout()
        topHBox.addWidget(self.top_label)
        topHBox.addWidget(self.infoButton, 0, Qt.AlignRight | Qt.AlignTop)

        _layout = QVBoxLayout()
        _layout.addLayout(topHBox)
        _layout.addWidget(hLine, 0, Qt.AlignVCenter)
        _layout.addWidget(self.bottom_label)

        widget.setLayout(_layout)
        self.setCentralWidget(widget)

        self.start_here()

    ###########
    ## START ##
    ###########
    def start_here(self):
        '''
        Checks to see if triggered by drag-and-dropped files OR by Mac OS Service.

            -If run by service, list of files paths is appeneded to sys.argv
        '''

        if len(sys.argv) > 1:
            sys.argv.pop(0)
            self.consolodate_files(sys.argv)
        else:
            self.show_OR_update_MainWindow()

    def consolodate_files(self, fileList):
        '''
        Makes it recursive through folders
        '''

        file_path_list = []
        for x in fileList:
            if x[0] != '.' and not os.path.isdir(
                    x):  #1) Add all NON-hidden files to file_path_list (l)
                file_path_list.append(x)
            elif os.path.isdir(
                    x
            ):  #2) If folder -> walk through and add all NON-hidden files to file_path_list
                for dirpath, subdirs, files in os.walk(x):
                    for y in files:
                        if not y.startswith('.'):
                            file_path_list.append(os.path.join(dirpath, y))

        self.start_ffprobe_thread(file_path_list)

    def start_ffprobe_thread(self, file_path_list):
        self.start_ffprobe_loop_thread = Start_ffprobe_Loop_Thread(
            file_path_list)
        self.start_ffprobe_loop_thread.threadPool_done.connect(
            lambda: self.show_OR_update_MainWindow())
        self.start_ffprobe_loop_thread.start()
        self.spinner.start()

    def show_OR_update_MainWindow(self):
        duration, size, frameRate, resolution = self.clean_up_label_numbers()
        self.update_labels(duration, size, frameRate, resolution)
        self.trigger_image_status_bar()
        self.spinner.stop()
        self.process_UI_events()
        self.test_if_error_message()

    def clean_up_label_numbers(self):
        try:
            duration = (str(
                datetime.timedelta(seconds=round(duration_GLOBAL))))
        except:
            duration = "Duration Invalid"
        size = self.format_bytes(size_GLOBAL)
        frameRate = ', '.join(self.remove_dupe(frameRate_GLOBAL))
        resolution = ', '.join(self.remove_dupe(resolution_GLOBAL))

        self.determine_wordwrap(resolution, frameRate)
        return duration, size, frameRate, resolution

    def update_labels(self, duration, size, frameRate, resolution):
        self.top_label.setText(
            dedent(f'''\
            Files:   {count_GLOBAL}

            Size:   {size}

            Duration:   {duration}'''))
        self.bottom_label.setText(
            dedent(f'''\
            Resolution(s):  {resolution}

            Frame Rate(s):  {frameRate}'''))
        self.determine_wordwrap(resolution, frameRate)

    def determine_wordwrap(self, resolution, frameRate):
        if len(resolution) > 100 or len(frameRate) > 100:
            self.bottom_label.setWordWrap(True)
        else:
            self.bottom_label.setWordWrap(False)

    def trigger_image_status_bar(self):
        if show_IMAGE_DETECTED_status_bar == True:
            self.statusBar().show()
        else:
            self.statusBar().hide()

    def process_UI_events(self):
        QApplication.processEvents(
        )  #Helps with resizing of the window (if necessary)
        self.setFixedSize(self.sizeHint())
        self.show()

    def test_if_error_message(self):
        if len(errorFiles_GlOBAL) > 0:
            ErrorFiles_Message()

    def remove_dupe(self, a_list):
        final_list = list(dict.fromkeys(a_list))
        return final_list

    def format_bytes(self, size):
        power = 2**10
        n = 0
        power_labels = {
            0: 'B',
            1: 'KB',
            2: 'MB',
            3: 'GB',
            4: 'TB',
            5: 'PB',
            6: 'EB'
        }
        while size > power:
            size /= power
            n += 1
        return f'{round(size, 2)} {power_labels[n]}'

    def show_infoButton_message(self):
        message = f'''
        <h3>Drag and Drop:</h3> 
        <p>Drag and drop media files onto app to caclulate total duration.</p>
        <h3><strong>Keyboard Shortcuts:</h3>
        <p style="text-indent: 15px;"><strong>c</strong> - Copy duration, close app</p>
        <p style="text-indent: 15px;"><strong>q</strong> - Close app</p>
        <br>
        <p>* This app is recursive; will dig through folders.<p>
        <br>
        v {version}
        '''
        Information_Message(message)

    def reset_vars(self):
        global count_GLOBAL, size_GLOBAL, duration_GLOBAL, frameRate_GLOBAL, errorFiles_GlOBAL, show_IMAGE_DETECTED_status_bar

        count_GLOBAL = 0
        size_GLOBAL = 0
        duration_GLOBAL = 0
        resolution_GLOBAL.clear()
        frameRate_GLOBAL.clear()
        errorFiles_GlOBAL.clear()
        show_IMAGE_DETECTED_status_bar = False

    #------DRAG AND DROP EVENT---------------------------------
    def dragEnterEvent(self, event):
        urls = event.mimeData().urls()
        if urls and urls[0].scheme() == 'file':
            self.setPalette(self.bg_color_drag)
            event.acceptProposedAction()

    def dragLeaveEvent(self, event):
        self.setPalette(self.bg_color)

    def dropEvent(self, event):
        data_obj = event.mimeData()
        urls = data_obj.urls()
        self.setPalette(self.bg_color)
        file_path_list = []
        if sys.platform == 'win32':
            for x in range(len(urls)):
                file_path_list.append(urls[x].path()[1:])
        else:
            for x in range(len(urls)):
                file_path_list.append(urls[x].path())
        self.reset_vars()
        self.consolodate_files(file_path_list)

    #------KEYPRESS EVENTS-------------------------------------
    def keyPressEvent(self, event):
        super(MainWindow, self).keyPressEvent(event)
        if event.key() == Qt.Key_Q:
            self.q_keyPress()
        if event.key() == Qt.Key_C:
            self.c_keypress()

    def q_keyPress(self):
        sys.exit(0)

    def c_keypress(self):
        pyperclip.copy(str(datetime.timedelta(seconds=round(duration_GLOBAL))))
        sys.exit(0)