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)
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()
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 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 __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 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)
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()
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()
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()
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()
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()
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()
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_()
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()
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 set_loading_indicator(self): self.indicator = WaitingSpinner(self.view, True, True, Qt.ApplicationModal)
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
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()
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)