def resizePixmap(self, parent: QLabel): size = parent.width( ) if parent.width() < parent.height() else parent.height() parent.setPixmap( parent.org_pix.scaled( size, size, Qt.KeepAspectRatio, Qt.SmoothTransformation, ))
def __init__( self, rank, suit, ): super().__init__() font = QFont() font.setPixelSize(20) layout = QVBoxLayout(self) rank_label = QLabel(self) rank_label.setText(rank) rank_label.setFont(font) rank_label.setAlignment(Qt.AlignHCenter | Qt.AlignVCenter) layout.addWidget(rank_label) suit_pixmap = QPixmap(f'./images/{suit}.svg') suit_label = QLabel() suit_label.setPixmap(suit_pixmap) h = suit_label.height() suit_label.setPixmap( suit_pixmap.scaled(h * 1.5, h / 5, Qt.KeepAspectRatio)) suit_label.setAlignment(Qt.AlignHCenter | Qt.AlignVCenter) layout.addWidget(suit_label)
def loading_message(self) -> QDialog: """Returns the message box to be displayed while the user waits for the input data to load.""" message = QDialog(self) message.setWindowTitle('Loading') message.resize(300, 50) label = QLabel('loading DataFrame into memory...', message) label.setStyleSheet(self.style['label']) label.adjustSize() label.setAlignment(Qt.AlignCenter) label.move(int((message.width() - label.width()) / 2), int((message.height() - label.height()) / 2)) return message
def quit_message(self) -> QDialog: """Displays a window while SCOUTS is exiting""" message = QDialog(self) message.setWindowTitle('Exiting SCOUTS') message.resize(300, 50) label = QLabel('SCOUTS is exiting, please wait...', message) label.setStyleSheet(self.style['label']) label.adjustSize() label.setAlignment(Qt.AlignCenter) label.move(int((message.width() - label.width()) / 2), int((message.height() - label.height()) / 2)) return message
class MainWindow(QMainWindow): pass def __init__(self): super().__init__() self.player = None self.setWindowTitle("FFPyPlayer Test") def showEvent(self, e): self.timer_id = self.startTimer(1) self.lbl = QLabel(self) self.lbl.setAlignment(Qt.AlignHCenter | Qt.AlignVCenter) self.setCentralWidget(self.lbl) def timerEvent(self, event) -> None: self.killTimer(self.timer_id) ff_opts = {'paused': False, 'autoexit': True} self.player = MediaPlayer('../example_data/sample.mp4', ff_opts=ff_opts, lib_opts={}) # self.player = MediaPlayer('http://localhost:1441/sample_stream.mp4', ff_opts=ff_opts, lib_opts={}) self.running = True while self.running: time.sleep(0.01) frame, val = self.player.get_frame() if val == 'eof': break if frame is None: time.sleep(0.01) else: img, t = frame data = img.to_bytearray()[0] width, height = img.get_size() # the technical name for the 'rgb24' default pixel format is RGB888, # which is QImage.Format_RGB888 in the QImage format enum qimage = QImage(data, width, height, QImage.Format_RGB888) pixmap = QPixmap.fromImage(qimage) pixmap = pixmap.scaled(self.lbl.width(), self.lbl.height(), Qt.KeepAspectRatio, Qt.SmoothTransformation) self.lbl.setPixmap(pixmap) time.sleep(val) QApplication.processEvents() def closeEvent(self, event) -> None: self.running = False if self.player is not None: self.player.set_pause(True) self.player.close_player()
class ItemWidget(QWidget): def __init__(self, _id, title, index, info, param, *args, **kwargs): super(ItemWidget, self).__init__(*args, **kwargs) self.id = _id self.param = param self.setMaximumSize(220, 400) self.setMaximumSize(220, 400) layout = QVBoxLayout(self) layout.setContentsMargins(10, 20, 10, 0) # 图片label self.picIcon = QLabel(self) # self.picIcon.setCursor(Qt.PointingHandCursor) # self.picIcon.setScaledContents(True) self.picIcon.setMinimumSize(220, 320) self.picIcon.setMaximumSize(220, 320) self.picIcon.setToolTip(title) pic = QPixmap() self.picIcon.setPixmap(pic) layout.addWidget(self.picIcon) layout2 = QHBoxLayout(self) self.indexLabel = QLabel(index, self, styleSheet="color: #999999;") self.indexLabel.setMinimumSize(40, 20) self.indexLabel.setMaximumSize(40, 40) self.indexLabel.setAlignment(Qt.AlignLeft) layout2.addWidget(self.indexLabel) self.infoLabel = QLabel(info, self, styleSheet="color: #999999;") self.infoLabel.setMinimumSize(160, 20) self.infoLabel.setMaximumSize(160, 40) self.infoLabel.setAlignment(Qt.AlignRight) layout2.addWidget(self.infoLabel) layout.addLayout(layout2) self.label = QLabel(title, self, styleSheet="color: #999999;") self.label.setMinimumSize(220, 20) self.label.setMaximumSize(220, 40) self.label.setAlignment(Qt.AlignCenter) self.label.setFont(QFont("Microsoft YaHei", 12, 87)) layout.addWidget(self.label) # if self.info: # self.PaintInfo() # def PaintInfo(self): # painter = QPainter(self.picIcon) # rect = self.picIcon.rect() # painter.save() # fheight = self.picIcon.fontMetrics().height() # # 底部矩形框背景渐变颜色 # bottomRectColor = QLinearGradient( # rect.width() / 2, rect.height() - 24 - fheight, # rect.width() / 2, rect.height()) # # bottomRectColor.setSpread(QGradient.PadSpread) # bottomRectColor.setColorAt(0, QColor(255, 255, 255, 70)) # bottomRectColor.setColorAt(1, QColor(0, 0, 0, 50)) # # # 画半透明渐变矩形框 # painter.setPen(Qt.NoPen) # painter.setBrush(QBrush(bottomRectColor)) # painter.drawRect(rect.x(), rect.height() - 24 - # fheight, rect.width(), 24 + fheight) # painter.restore() # # 距离底部一定高度画文字 # font = self.picIcon.font() or QFont() # font.setPointSize(8) # painter.setFont(font) # painter.setPen(Qt.white) # rect.setHeight(rect.height() - 12) # 底部减去一定高度 # painter.drawText(rect, Qt.AlignHCenter | # Qt.AlignBottom, self.info) def SetPicture(self, data): if not data: return pic = QPixmap() pic.loadFromData(data) # maxW = self.picIcon.width() # maxH = self.picIcon.height() # picW = pic.width() # picH = pic.height() # if maxW / picW < maxH / picH: # toW = maxW # toH = (picH/(picW/maxW)) # else: # toH = maxH # toW = (picW / (picH / maxH)) newPic = pic.scaled(self.picIcon.width(), self.picIcon.height(), Qt.KeepAspectRatio, Qt.SmoothTransformation) self.picIcon.setPixmap(newPic) def GetTitle(self): return self.label.text() def GetId(self): return self.id
def init_ui(self): file_name = 'ini_balance' with open(file_name) as f: lines = f.readlines() try: self.interval_e.setText(lines[0]) except: self.error_label.setText( ' Возможно в первой строке файла ini_balance нет времени таймера!' ) try: self.bars = lines[1] except: self.error_label.setText( ' Возможно во второй строке файла ini_balance нет запроса!' ) try: self.table_query = lines[2] except: self.error_label.setText( ' Возможно в третьей строке файла ini_balance нет запроса!' ) label = QLabel(self) label.setAlignment(Qt.AlignRight) label.resize(30, 30) image = QPixmap("b.jfif", format="JPG").scaled(label.width(), label.height()) #image = QPixmap("mon.png", format="PNG") label.setPixmap(image) self.group = QGroupBox("Таймер остатка") self.group.setStyleSheet("font: corbel; font-size: 14px;") v_group = QVBoxLayout() # Контейнер для группы v_group.addWidget(self.start_button1) v_group.addWidget(self.stop_button1) v_group.addWidget(self.interval_l) v_group.addWidget(self.interval_e) self.group.setLayout(v_group) form = QFormLayout() form.addRow("", label) form.addRow("По&льзователь", self.user_entry) form.addRow("&Пароль", self.pass_entry) form.addRow("&МФО области", self.ru_entry) form.addRow("&Валюта", self.cur_entry) form.addRow("&Необходимый остаток", self.balance_entry) form.addRow("", self.ok_button) form.addRow("", self.group) form.addRow("&Результат", self.table) form.addRow("&Ошибки", self.error_label) self.setLayout(form) # k10 - work with password # is_right in - hash, return - T/F; set_p in - pass return - hash hash_pass = hashlib.md5(self.pass_entry.text().encode('utf-8')) # print("hash", hash_pass) # keyring.set_password(getpass.getuser(), self.user_entry.text(), self.pass_entry.text()) self.pass_entry.editingFinished.connect( lambda: k10.keyring_pass(getpass.getuser(), self.user_entry.text( ), self.pass_entry, hash_pass, self.ru_entry)) self.ok_button.clicked.connect(lambda: self.run()) self.start_button1.clicked.connect(self.on_start) self.stop_button1.clicked.connect(self.on_stop) self.setGeometry(300, 100, 650, 550) self.setWindowTitle('Ждем деньги') self.show()
class Randomizer(QWidget): """A game randomizer for selecting a random game to play from the user's collection. User can select which platforms to choose from. gamesData: Raw table data in list of dictionaries""" def __init__(self, gamesData: list, platformsData: list, genresData: list): super(Randomizer, self).__init__() self._consoleItems = platformsData self._genreItems = genresData self._gamesData = gamesData self._games = [] # For holding the games to randomize self._gameCount = 0 self._coverdir = path.join("data", "images", "covers") self.consoleLabel = QLabel("Platforms") self.consoleList = QListWidget() self.consoleList.addItems(self._consoleItems) self.consoleList.setSelectionMode(QAbstractItemView.MultiSelection) self.consoleList.setMaximumWidth(350) self.consoleList.itemClicked.connect(self._updateGameCount) self.genreLabel = QLabel("Genres") self.genreMatchExclusiveCB = QCheckBox("Match exclusive") self.genreMatchExclusiveCB.setToolTip( "Only match games which exclusively contain the selected genres.") self.genreMatchExclusiveCB.setChecked(False) self.genreMatchExclusiveCB.stateChanged.connect(self._updateGameCount) self.genreList = QListWidget() self.genreList.addItems(self._genreItems) self.genreList.setSelectionMode(QAbstractItemView.MultiSelection) self.genreList.setMaximumWidth(350) self.genreList.itemClicked.connect(self._updateGameCount) self.btnAll = QPushButton("Select All") self.btnAll.setMaximumSize(self.btnAll.sizeHint()) self.btnAll.clicked.connect(self.consoleList.selectAll) self.btnAll.clicked.connect(self.genreList.selectAll) self.btnAll.clicked.connect(self._updateGameCount) self.btnNone = QPushButton("Select None") self.btnNone.setMaximumSize(self.btnNone.sizeHint()) self.btnNone.clicked.connect(self.consoleList.clearSelection) self.btnNone.clicked.connect(self.genreList.clearSelection) self.btnNone.clicked.connect(self._updateGameCount) self._btnRnd = QPushButton("Randomize") self._btnRnd.setMaximumSize(self._btnRnd.sizeHint()) self._btnRnd.clicked.connect(self._randomize) self._lblFont = QFont() self._lblFont.setPointSize(14) self._lblFont.setBold(True) self._lblPlay = QLabel() self._lblPlay.setAlignment(Qt.AlignCenter) self._lblPlay.setFont(self._lblFont) self._lblTitle = QLabel() self._lblTitle.setAlignment(Qt.AlignCenter) self._lblTitle.setFont(self._lblFont) self._lblTitle.setWordWrap(True) # Cover image self._cover = QLabel() self._cover.setVisible(False) self._cover.setAlignment(Qt.AlignCenter) p = QPixmap(path.join(self._coverdir, "none.png")) w = self._cover.width() h = self._cover.height() self._cover.setPixmap( p.scaled(w, h, Qt.KeepAspectRatio, Qt.SmoothTransformation)) self._hboxButtons = QHBoxLayout() self._vboxLists = QVBoxLayout() self._vboxConsoles = QVBoxLayout() self._hboxGenres = QHBoxLayout() self._vboxGenres = QVBoxLayout() self._vboxResult = QVBoxLayout() self._grid = QGridLayout() self._hboxButtons.addWidget(self.btnAll, 0) self._hboxButtons.addWidget(self.btnNone, 0) self._hboxButtons.addWidget(self._btnRnd, 0) self._vboxConsoles.addWidget(self.consoleLabel, 0) self._vboxConsoles.addWidget(self.consoleList, 1) self._hboxGenres.addWidget(self.genreLabel, 0) self._hboxGenres.addWidget(self.genreMatchExclusiveCB, 0) self._vboxGenres.addWidget(self.genreList, 1) self._vboxLists.addSpacing(10) self._vboxLists.addLayout(self._vboxConsoles, 1) self._vboxLists.addSpacing(10) self._vboxLists.addLayout(self._hboxGenres, 0) self._vboxLists.addLayout(self._vboxGenres, 1) self._vboxResult.addStretch(3) self._vboxResult.addWidget(self._lblPlay, 0) self._vboxResult.addWidget(self._lblTitle, 0) self._vboxResult.addSpacing(50) self._vboxResult.addWidget(self._cover, 0) self._vboxResult.addStretch(3) self._grid.setMargin(0) self._grid.setSpacing(0) self._grid.addLayout(self._vboxLists, 0, 0) self._grid.addLayout(self._hboxButtons, 1, 0) self._grid.addLayout(self._vboxResult, 0, 1, 1, -1) self.widget = QWidget() self.widget.setLayout(self._grid) def _getSelectedItems(self) -> tuple: return [x.text() for x in self.consoleList.selectedItems() ], [x.text() for x in self.genreList.selectedItems()] def _randomize(self): platforms, genres = self._getSelectedItems() if len(self._games) > 0 and (len(platforms) > 0 or len(genres) > 0): choice = randint(0, len(self._games) - 1) self._lblPlay.setText("You will play:") self._lblTitle.setText( f"{self._games[choice]['name']}" if len(platforms) == 1 else f"{self._games[choice]['name']} [{self._games[choice]['platform']}]" ) # Cover image cover = str(self._games[choice]['id']) + ".jpg" if path.exists(path.join(self._coverdir, cover)): # Update cover image if the game has one pixmap = path.join(self._coverdir, cover) self._cover.setVisible(True) else: pixmap = path.join(self._coverdir, "none.png") self._cover.setVisible(False) p = QPixmap(pixmap) w = self._cover.width() h = self._cover.height() self._cover.setPixmap( p.scaled(w, h, Qt.KeepAspectRatio, Qt.SmoothTransformation)) elif len(self._games) == 0 and (len(platforms) > 0 or len(genres) > 0): self._lblPlay.setText("") self._lblTitle.setText("No games found with those criteria.") self._cover.setVisible(False) else: self._lblPlay.setText("") self._lblTitle.setText("Select at least one console or genre...") self._cover.setVisible(False) def _updateGameCount(self): platforms, genres = self._getSelectedItems() self._gameCount = 0 self._games = [] if len(platforms) > 0 or len(genres) > 0: for row in self._gamesData: if len(platforms) > 0 and len(genres) > 0: if row["platform"] in platforms: if self.genreMatchExclusiveCB.isChecked(): count = 0 for genre in row["genre"].split(", "): if genre in genres: count += 1 else: # Not exclusive count = 0 break if count == len(genres): self._gameCount += 1 self._games.append(row) else: for genre in row["genre"].split(", "): if genre in genres: self._gameCount += 1 self._games.append(row) break # We only need to match with one genre elif len(platforms) > 0 and len(genres) == 0: if row["platform"] in platforms: self._gameCount += 1 self._games.append(row) elif len(platforms) == 0 and len(genres) > 0: if self.genreMatchExclusiveCB.isChecked(): count = 0 for genre in row["genre"].split(", "): if genre in genres: count += 1 else: # Not exclusive count = 0 break if count == len(genres): self._gameCount += 1 self._games.append(row) else: for genre in row["genre"].split(", "): if genre in genres: self._gameCount += 1 self._games.append(row) break # We only need to match with one genre def gameCount(self) -> int: return self._gameCount def updateLists(self, gamesData: list, platformsData: list, genresData: list): self._gamesData = gamesData self._consoleItems = platformsData self._genreItems = genresData self.consoleList.clear() self.genreList.clear() self.consoleList.addItems(self._consoleItems) self.genreList.addItems(self._genreItems)
class DLPPrinterGUI(QWidget): closing_window_event = Signal() spinboxValueChanged = Signal(float) def __init__(self, dlp_controller=None, parent=None, printer_setup='BOTTOM-UP'): QWidget.__init__(self, parent) if dlp_controller: self.dlp_controller = dlp_controller else: self.dlp_controller = DLPMainController(printer_setup) self.dlp_controller.block_parameters_signal.connect( self.block_parameters_signals) self.dlp_controller.reactivate_parameters_signal.connect( self.reactivate_parameters_signals) self.dlp_controller.motor_changed_signal.connect( self.update_motor_parameters) self.closing_window_event.connect(self.dlp_controller.close_projector) self.parent = parent self.main_layout = QHBoxLayout() self.__init_widget__() self.setLayout(self.main_layout) def __init_widget__(self): self.__left_widget = QWidget() self.__left_widget.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.MinimumExpanding) self.__right_widget = QWidget() self.__right_widget.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.MinimumExpanding) self.__init_printer_options_widget__(self.__left_widget) self.__init_projector_widget__(self.__left_widget) self.__init_support_widget__(self.__left_widget) self.__init_features_widget__(self.__left_widget) self.__init_advanced_features_widget__(self.__left_widget) # self.__init_expected_time_widget__(self.__left_widget) self.__left_layout = QGridLayout() self.__left_layout.addWidget(self.__printer_options_widget, 0, 0, 1, 2) self.__left_layout.addWidget(self.__projector_widget, 1, 0, 1, 2) self.__left_layout.addWidget(self.__support_widget, 2, 0, 1, 1) self.__left_layout.addWidget(self.__features_widget, 2, 1, 1, 1) self.__left_layout.addWidget(self.__advanced_widget, 3, 0, 1, 2) # self.__left_layout.addWidget(self.__expected_time_widget, 4,0) self.__left_widget.setLayout(self.__left_layout) self.__left_widget.show() self.__init_start_stop_widget__(self.__right_widget) self.__init_preview_widget__(self.__right_widget) self.__init_console_widget__(self.__right_widget) self.__init_username_jobname_widget__() self.__right_layout = QVBoxLayout() self.__right_layout.addWidget(self.__start_stop_widget) self.__right_layout.addWidget(self.__username_jobname_widget) self.__right_layout.addWidget(self.__preview_widget) self.__right_layout.addWidget(self.__console_widget) self.__right_widget.setLayout(self.__right_layout) # print(self.__left_layout.sizeHint(), self.__right_layout.sizeHint()) self.main_layout.addWidget(self.__left_widget) self.main_layout.addWidget(self.__right_widget) def __init_printer_options_widget__(self, parent=None): self.__printer_options_widget = QGroupBox("Printer Options", parent) # self.__printer_options_widget.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Maximum) port_label = QLabel("Port:", self.__printer_options_widget) self.port_list = MyQComboBox(self.__printer_options_widget) self.port_list.addItems(self.dlp_controller.available_ports()) self.port_list.currentIndexChanged.connect( self.dlp_controller.select_port) self.port_list.combo_box_clicked.connect(self.update_port_list) connect_button = QPushButton("Connect", self.__printer_options_widget) connect_button.clicked.connect(self.dlp_controller.connect_printer) disconnect_button = QPushButton("Disconnect", self.__printer_options_widget) disconnect_button.clicked.connect( self.dlp_controller.disconnect_printer) reset_button = QPushButton("Reset", self.__printer_options_widget) reset_button.clicked.connect(self.dlp_controller.reset_printer) move_button = QPushButton("Move Building Plate", self.__printer_options_widget) self.move_edit = MyDiscreteStepsSpinBox( self.dlp_controller.get_step_length_microns() / 1000.0, self.__printer_options_widget) self.move_edit.setSuffix("mm") self.move_edit.setMaximum(1000) self.move_edit.setMinimum(-1000) self.move_edit.setDecimals(6) self.move_edit.my_value_changed_signal.connect( self.dlp_controller.update_building_plate_distance) move_button.clicked.connect(self.dlp_controller.move_building_plate) set_origin_button = QPushButton("Set Building Plate Origin", self.__printer_options_widget) set_origin_button.clicked.connect( self.dlp_controller.set_building_plate_origin) home_button = QPushButton("Home Building Plate", self.__printer_options_widget) home_button.clicked.connect(self.dlp_controller.home_building_plate) origin_button = QPushButton("Send Building Plate to Origin", self.__printer_options_widget) origin_button.clicked.connect( self.dlp_controller.move_building_plate_to_origin) options_layout = QGridLayout(self.__printer_options_widget) # options_layout.addWidget(options_label, 0, 0, 1, 5) options_layout.addWidget(port_label, 0, 0) options_layout.addWidget(self.port_list, 0, 1) options_layout.addWidget(connect_button, 0, 2) options_layout.addWidget(disconnect_button, 0, 3) options_layout.addWidget(reset_button, 0, 4) options_layout.addWidget(move_button, 1, 0, 1, 2) options_layout.addWidget(self.move_edit, 1, 2) options_layout.addWidget(set_origin_button, 1, 3, 1, 2) options_layout.addWidget(home_button, 2, 0, 1, 2) options_layout.addWidget(origin_button, 2, 2, 1, 2) self.__printer_options_widget.setLayout(options_layout) def __init_projector_widget__(self, parent=None): self.__projector_widget = QGroupBox("Projector Options", parent) # self.__projector_widget.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Maximum) mirror_x = QCheckBox("Mirror X") mirror_x.setChecked(self.dlp_controller.is_horizontal_mirrored()) mirror_x.toggled.connect(self.dlp_controller.set_horizontal_mirroring) mirror_y = QCheckBox("Mirror Y") mirror_y.setChecked(self.dlp_controller.is_vertical_mirrored()) mirror_y.toggled.connect(self.dlp_controller.set_vertical_mirroring) start_projector_button = QPushButton("Start Projector", self.__projector_widget) start_projector_button.clicked.connect( self.dlp_controller.start_projector) project_pattern_button = QPushButton("Project Pattern", self.__projector_widget) project_pattern_button.clicked.connect( self.dlp_controller.project_calibration_pattern) print_position_button = QPushButton("Print Position", self.__projector_widget) print_position_button.clicked.connect( self.dlp_controller.print_motor_position) home_projector_button = QPushButton("Home Projector", self.__projector_widget) home_projector_button.clicked.connect( self.dlp_controller.home_projector) move_projector_button = QPushButton("Move Projector", self.__projector_widget) move_projector_button.clicked.connect( self.dlp_controller.move_projector) move_projector_edit = QDoubleSpinBox(self.__projector_widget) move_projector_edit.setSuffix("mm") move_projector_edit.setMaximum(10000) move_projector_edit.setMinimum(-10000) move_projector_edit.setDecimals(3) move_projector_edit.setSingleStep(0.001) move_projector_edit.valueChanged.connect( self.dlp_controller.update_projector_distance) set_amplitude_button = QPushButton("Set Projector Amplitude", self.__projector_widget) set_amplitude_button.clicked.connect( self.dlp_controller.set_projector_amplitude) set_amplitude_edit = QSpinBox(self.__projector_widget) set_amplitude_edit.setMaximum(1000) set_amplitude_edit.setMinimum(0) set_amplitude_edit.setValue(self.dlp_controller.projector_amplitude) set_amplitude_edit.valueChanged.connect( self.dlp_controller.update_projector_amplitude) lock_unlock_projector_button = QPushButton("Lock/Unlock Projector", self.__projector_widget) lock_unlock_projector_button.clicked.connect( self.dlp_controller.lock_unlock_projector) projector_layout = QGridLayout(self.__projector_widget) # projector_layout.addWidget(projector_label, 0, 0) projector_layout.addWidget(mirror_x, 0, 1) projector_layout.addWidget(mirror_y, 0, 2) projector_layout.addWidget(start_projector_button, 1, 0, 1, 1) projector_layout.addWidget(project_pattern_button, 1, 1, 1, 1) projector_layout.addWidget(print_position_button, 1, 2, 1, 1) projector_layout.addWidget(home_projector_button, 2, 0, 1, 1) projector_layout.addWidget(move_projector_button, 2, 1, 1, 1) projector_layout.addWidget(move_projector_edit, 2, 2) projector_layout.addWidget(set_amplitude_button, 3, 0, 1, 1) projector_layout.addWidget(set_amplitude_edit, 3, 1) projector_layout.addWidget(lock_unlock_projector_button, 3, 2, 1, 1) self.__projector_widget.setLayout(projector_layout) def __init_support_widget__(self, parent=None): self.__support_widget = QGroupBox("Support Layers Parameters", parent) # self.__support_widget.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Maximum) thickness_label = QLabel("Layer Thickness", self.__support_widget) self.support_thickness_edit = MyDiscreteStepsSpinBox( self.dlp_controller.get_step_length_microns(), self.__support_widget) self.support_thickness_edit.setSuffix(str('\u03BCm')) self.support_thickness_edit.setMaximum(1000000) self.support_thickness_edit.setMinimum(0) self.support_thickness_edit.setDecimals(3) self.support_thickness_edit.my_value_changed_signal.connect( self.dlp_controller.set_support_thickness) self.support_thickness_edit.setValue( self.dlp_controller.support_thickness * 1000) exposure_label = QLabel("Exposure Time", self.__support_widget) exposure_edit = QDoubleSpinBox(self.__support_widget) exposure_edit.setSuffix(str('ms')) exposure_edit.setMaximum(10000000) exposure_edit.setMinimum(0) exposure_edit.setDecimals(1) exposure_edit.setSingleStep(0.1) exposure_edit.setValue(self.dlp_controller.support_exposure) exposure_edit.valueChanged.connect( self.dlp_controller.set_support_exposure_time) amplitude_label = QLabel("Light Amplitude", self.__support_widget) amplitude_edit = QSpinBox(self.__support_widget) amplitude_edit.setMaximum(1600) amplitude_edit.setMinimum(0) amplitude_edit.setSingleStep(1) amplitude_edit.setValue(self.dlp_controller.support_amplitude) amplitude_edit.valueChanged.connect( self.dlp_controller.set_support_amplitude) burn_layers_label = QLabel("Burn Layers", self.__support_widget) burn_layers_edit = QSpinBox(self.__support_widget) burn_layers_edit.setMaximum(1000) burn_layers_edit.setMinimum(0) burn_layers_edit.setSingleStep(1) burn_layers_edit.setValue(self.dlp_controller.support_burn_layers) burn_layers_edit.valueChanged.connect( self.dlp_controller.set_support_burning_layers) burn_exposure_label = QLabel("Burn Exposure", self.__support_widget) burn_exposure_edit = QDoubleSpinBox(self.__support_widget) burn_exposure_edit.setSuffix(str('ms')) burn_exposure_edit.setMaximum(100000) burn_exposure_edit.setMinimum(0) burn_exposure_edit.setDecimals(1) burn_exposure_edit.setSingleStep(0.1) burn_exposure_edit.setValue(self.dlp_controller.support_burn_exposure) burn_exposure_edit.valueChanged.connect( self.dlp_controller.set_support_burning_exposure_time) burn_amplitude_label = QLabel("Burn Amplitude", self.__support_widget) burn_amplitude_edit = QSpinBox(self.__support_widget) burn_amplitude_edit.setMaximum(1600) burn_amplitude_edit.setMinimum(0) burn_amplitude_edit.setSingleStep(1) burn_amplitude_edit.setValue( self.dlp_controller.support_burn_amplitude) burn_amplitude_edit.valueChanged.connect( self.dlp_controller.set_support_burning_amplitude) select_layers_button = QPushButton("Select Support Images") select_layers_button.clicked.connect(self.load_support_images) support_layout = QGridLayout(self.__support_widget) support_layout.addWidget(thickness_label, 1, 0) support_layout.addWidget(self.support_thickness_edit, 1, 1) support_layout.addWidget(exposure_label, 2, 0) support_layout.addWidget(exposure_edit, 2, 1) support_layout.addWidget(amplitude_label, 3, 0) support_layout.addWidget(amplitude_edit, 3, 1) support_layout.addWidget(burn_layers_label, 4, 0) support_layout.addWidget(burn_layers_edit, 4, 1) support_layout.addWidget(burn_exposure_label, 5, 0) support_layout.addWidget(burn_exposure_edit, 5, 1) support_layout.addWidget(burn_amplitude_label, 6, 0) support_layout.addWidget(burn_amplitude_edit, 6, 1) support_layout.addWidget(select_layers_button, 7, 0, 1, 2) self.__support_widget.setLayout(support_layout) def __init_features_widget__(self, parent=None): self.__features_widget = QGroupBox("Features Layers Parameters", parent) # self.__features_widget.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Maximum) thickness_label = QLabel("Layer Thickness", self.__features_widget) self.features_thickness_edit = MyDiscreteStepsSpinBox( self.dlp_controller.get_step_length_microns(), self.__features_widget) self.features_thickness_edit.setSuffix(str('\u03BCm')) self.features_thickness_edit.setMaximum(1000000) self.features_thickness_edit.setMinimum(0) self.features_thickness_edit.setDecimals(3) self.features_thickness_edit.my_value_changed_signal.connect( self.dlp_controller.set_features_thickness) self.features_thickness_edit.setValue( self.dlp_controller.features_thickness * 1000) exposure_label = QLabel("Exposure Time", self.__features_widget) exposure_edit = QDoubleSpinBox(self.__features_widget) exposure_edit.setSuffix(str('ms')) exposure_edit.setMaximum(10000000) exposure_edit.setMinimum(0) exposure_edit.setDecimals(1) exposure_edit.setSingleStep(0.1) exposure_edit.setValue(self.dlp_controller.features_exposure) exposure_edit.valueChanged.connect( self.dlp_controller.set_features_exposure_time) amplitude_label = QLabel("Light Amplitude", self.__features_widget) amplitude_edit = QSpinBox(self.__features_widget) amplitude_edit.setMaximum(1600) amplitude_edit.setMinimum(0) amplitude_edit.setSingleStep(1) amplitude_edit.setValue(self.dlp_controller.features_amplitude) amplitude_edit.valueChanged.connect( self.dlp_controller.set_features_amplitude) burn_layers_label = QLabel("Burn Layers", self.__features_widget) burn_layers_edit = QSpinBox(self.__features_widget) burn_layers_edit.setMaximum(1000) burn_layers_edit.setMinimum(0) burn_layers_edit.setSingleStep(1) burn_layers_edit.setValue(self.dlp_controller.features_burn_layers) burn_layers_edit.valueChanged.connect( self.dlp_controller.set_features_burning_layers) burn_exposure_label = QLabel("Burn Exposure", self.__features_widget) burn_exposure_edit = QDoubleSpinBox(self.__features_widget) burn_exposure_edit.setSuffix(str('ms')) burn_exposure_edit.setMaximum(100000) burn_exposure_edit.setMinimum(0) burn_exposure_edit.setDecimals(1) burn_exposure_edit.setSingleStep(0.1) burn_exposure_edit.setValue(self.dlp_controller.features_burn_exposure) burn_exposure_edit.valueChanged.connect( self.dlp_controller.set_features_burning_exposure_time) burn_amplitude_label = QLabel("Burn Amplitude", self.__features_widget) burn_amplitude_edit = QSpinBox(self.__features_widget) burn_amplitude_edit.setMaximum(1600) burn_amplitude_edit.setMinimum(0) burn_amplitude_edit.setSingleStep(1) burn_amplitude_edit.setValue( self.dlp_controller.features_burn_amplitude) burn_amplitude_edit.valueChanged.connect( self.dlp_controller.set_features_burning_amplitude) select_layers_button = QPushButton("Select Features Images") select_layers_button.clicked.connect(self.load_features_images) features_layout = QGridLayout(self.__features_widget) features_layout.addWidget(thickness_label, 1, 0) features_layout.addWidget(self.features_thickness_edit, 1, 1) features_layout.addWidget(exposure_label, 2, 0) features_layout.addWidget(exposure_edit, 2, 1) features_layout.addWidget(amplitude_label, 3, 0) features_layout.addWidget(amplitude_edit, 3, 1) features_layout.addWidget(burn_layers_label, 4, 0) features_layout.addWidget(burn_layers_edit, 4, 1) features_layout.addWidget(burn_exposure_label, 5, 0) features_layout.addWidget(burn_exposure_edit, 5, 1) features_layout.addWidget(burn_amplitude_label, 6, 0) features_layout.addWidget(burn_amplitude_edit, 6, 1) features_layout.addWidget(select_layers_button, 7, 0, 1, 2) self.__features_widget.setLayout(features_layout) def __init_advanced_features_widget__(self, parent=None): self.__advanced_widget = QGroupBox("Advanced Features Options", parent) fixed_layer_check = QCheckBox("Fixed Layer", self.__advanced_widget) fixed_layer_check.setChecked(self.dlp_controller.fixed_layer) fixed_layer_check.toggled.connect(self.dlp_controller.set_fixed_layer) incremental_amplitude_check = QCheckBox("Incremental Amplitude", self.__advanced_widget) incremental_amplitude_check.setChecked( self.dlp_controller.incremental_amplitude) incremental_amplitude_check.toggled.connect( self.dlp_controller.set_incremental_amplitude) starting_amplitude_label = QLabel("Starting Amplitude", self.__advanced_widget) starting_amplitude_edit = QSpinBox(self.__advanced_widget) starting_amplitude_edit.setMaximum(1000) starting_amplitude_edit.setMinimum(0) starting_amplitude_edit.setSingleStep(1) starting_amplitude_edit.setValue( self.dlp_controller.starting_incremental_amplitude) starting_amplitude_edit.valueChanged.connect( self.dlp_controller.set_starting_incremental_amplitude) amplitude_step_label = QLabel("Step Size", self.__advanced_widget) amplitude_step_edit = QSpinBox(self.__advanced_widget) amplitude_step_edit.setMaximum(1000) amplitude_step_edit.setMinimum(0) amplitude_step_edit.setSingleStep(1) amplitude_step_edit.setValue( self.dlp_controller.incremental_step_amplitude) amplitude_step_edit.valueChanged.connect( self.dlp_controller.set_incremental_step_amplitude) incremental_exposure_check = QCheckBox("Incremental Exposure", self.__advanced_widget) incremental_exposure_check.setChecked( self.dlp_controller.incremental_exposure) incremental_exposure_check.toggled.connect( self.dlp_controller.set_incremental_exposure) starting_exposure_label = QLabel("Starting Exposure", self.__advanced_widget) starting_exposure_edit = QDoubleSpinBox(self.__advanced_widget) starting_exposure_edit.setSuffix(str('ms')) starting_exposure_edit.setMaximum(100000) starting_exposure_edit.setMinimum(0) starting_exposure_edit.setDecimals(1) starting_exposure_edit.setSingleStep(0.1) starting_exposure_edit.valueChanged.connect( self.dlp_controller.set_starting_incremental_exposure) starting_exposure_edit.setValue( self.dlp_controller.starting_incremental_exposure) exposure_step_label = QLabel("Step Size", self.__advanced_widget) exposure_step_edit = QDoubleSpinBox(self.__advanced_widget) exposure_step_edit.setSuffix(str('ms')) exposure_step_edit.setMaximum(100000) exposure_step_edit.setMinimum(0) exposure_step_edit.setDecimals(1) exposure_step_edit.setSingleStep(0.1) exposure_step_edit.valueChanged.connect( self.dlp_controller.set_incremental_step_exposure) exposure_step_edit.setValue( self.dlp_controller.incremental_step_exposure) incremental_thickness_check = QCheckBox("Incremental Thickness", self.__advanced_widget) incremental_thickness_check.setChecked( self.dlp_controller.incremental_thickness) incremental_thickness_check.toggled.connect( self.dlp_controller.set_incremental_thickness) thickness_label = QLabel("Starting Thickness", self.__features_widget) self.starting_thickness_edit = MyDiscreteStepsSpinBox( self.dlp_controller.get_step_length_microns(), self.__features_widget) self.starting_thickness_edit.setSuffix(str('\u03BCm')) self.starting_thickness_edit.setMaximum(1000000) self.starting_thickness_edit.setMinimum(0) self.starting_thickness_edit.setDecimals(3) self.starting_thickness_edit.my_value_changed_signal.connect( self.dlp_controller.set_starting_incremental_thickness) self.starting_thickness_edit.setValue( self.dlp_controller.starting_incremental_thickness * 1000) thickness_step_label = QLabel("Step Size", self.__features_widget) self.thickness_step_edit = MyDiscreteStepsSpinBox( self.dlp_controller.get_step_length_microns(), self.__features_widget) self.thickness_step_edit.setSuffix(str('\u03BCm')) self.thickness_step_edit.setMaximum(1000000) self.thickness_step_edit.setMinimum(0) self.thickness_step_edit.setDecimals(3) self.thickness_step_edit.my_value_changed_signal.connect( self.dlp_controller.set_incremental_step_thickness) self.thickness_step_edit.setValue( self.dlp_controller.incremental_step_thickness * 1000) apply_grayscale_correction_check = QCheckBox("Grayscale Correction", self.__advanced_widget) apply_grayscale_correction_check.setChecked( self.dlp_controller.grayscale_correction) apply_grayscale_correction_check.toggled.connect( self.dlp_controller.set_grayscale_correction) grayscale_parameters_widget = QWidget(self.__features_widget) a_parameter_label = QLabel("\u03B1", grayscale_parameters_widget) alpha_parameter_edit = QDoubleSpinBox(grayscale_parameters_widget) alpha_parameter_edit.setMaximum(1000) alpha_parameter_edit.setMinimum(0) alpha_parameter_edit.setDecimals(3) alpha_parameter_edit.setSingleStep(0.001) alpha_parameter_edit.valueChanged.connect( self.dlp_controller.set_grayscale_alpha) alpha_parameter_edit.setValue(self.dlp_controller.grayscale_alpha) beta_parameter_label = QLabel("\u03B2", grayscale_parameters_widget) beta_parameter_edit = QDoubleSpinBox(grayscale_parameters_widget) beta_parameter_edit.setMaximum(1000) beta_parameter_edit.setMinimum(0) beta_parameter_edit.setDecimals(3) beta_parameter_edit.setSingleStep(0.001) beta_parameter_edit.valueChanged.connect( self.dlp_controller.set_grayscale_beta) beta_parameter_edit.setValue(self.dlp_controller.grayscale_beta) gamma_parameter_label = QLabel("\u03B3", grayscale_parameters_widget) gamma_parameter_edit = QDoubleSpinBox(grayscale_parameters_widget) gamma_parameter_edit.setMaximum(1000) gamma_parameter_edit.setMinimum(0) gamma_parameter_edit.setDecimals(3) gamma_parameter_edit.setSingleStep(0.001) gamma_parameter_edit.valueChanged.connect( self.dlp_controller.set_grayscale_gamma) gamma_parameter_edit.setValue(self.dlp_controller.grayscale_gamma) grayscale_parameters_layout = QHBoxLayout(grayscale_parameters_widget) grayscale_parameters_layout.addWidget(a_parameter_label) grayscale_parameters_layout.addWidget(alpha_parameter_edit) grayscale_parameters_layout.addWidget(beta_parameter_label) grayscale_parameters_layout.addWidget(beta_parameter_edit) grayscale_parameters_layout.addWidget(gamma_parameter_label) grayscale_parameters_layout.addWidget(gamma_parameter_edit) grayscale_parameters_widget.setLayout(grayscale_parameters_layout) advanced_features_layout = QGridLayout(self.__advanced_widget) advanced_features_layout.addWidget(incremental_amplitude_check, 1, 0, 1, 2) advanced_features_layout.addWidget(fixed_layer_check, 1, 3) advanced_features_layout.addWidget(starting_amplitude_label, 2, 0) advanced_features_layout.addWidget(starting_amplitude_edit, 2, 1) advanced_features_layout.addWidget(amplitude_step_label, 2, 2) advanced_features_layout.addWidget(amplitude_step_edit, 2, 3) advanced_features_layout.addWidget(incremental_exposure_check, 3, 0, 1, 2) advanced_features_layout.addWidget(starting_exposure_label, 4, 0) advanced_features_layout.addWidget(starting_exposure_edit, 4, 1) advanced_features_layout.addWidget(exposure_step_label, 4, 2) advanced_features_layout.addWidget(exposure_step_edit, 4, 3) advanced_features_layout.addWidget(incremental_thickness_check, 5, 0, 1, 2) advanced_features_layout.addWidget(thickness_label, 6, 0) advanced_features_layout.addWidget(self.starting_thickness_edit, 6, 1) advanced_features_layout.addWidget(thickness_step_label, 6, 2) advanced_features_layout.addWidget(self.thickness_step_edit, 6, 3) advanced_features_layout.addWidget(apply_grayscale_correction_check, 7, 0, 1, 2) advanced_features_layout.addWidget(grayscale_parameters_widget, 8, 0, 1, 4) self.__advanced_widget.setLayout(advanced_features_layout) def __init_start_stop_widget__(self, parent=None): self.__start_stop_widget = QFrame(parent) size = self.__left_layout.sizeHint() start_button = QPushButton("START", self.__start_stop_widget) start_button.setFixedSize(size.width() / 2, size.height() / 7) start_button.clicked.connect( self.dlp_controller.starting_printing_process) stop_button = QPushButton("STOP", self.__start_stop_widget) stop_button.setFixedSize(size.width() / 3, size.height() / 8) stop_button.setStyleSheet( "QPushButton {background-color: red; border-style: outset; border-width: 2px; " "border-radius: 10px; border-color: beige; font: bold 20px; padding: 10px;}" ) stop_button.clicked.connect(self.dlp_controller.stop_printing_process) self.__start_stop_widget.setMinimumSize(size.width(), size.height() / 6) start_stop_layout = QGridLayout(self.__start_stop_widget) start_stop_layout.addWidget(start_button, 0, 0) start_stop_layout.addWidget(stop_button, 0, 1) self.__start_stop_widget.setLayout(start_stop_layout) def __init_preview_widget__(self, parent=None): self.__preview_widget = QLabel(parent) size = self.__left_layout.sizeHint() self.dlp_controller.display_image_signal.connect(self.preview_image) self.__preview_widget.setMinimumSize(size.width(), size.height() / 2.3) # self.__preview_widget.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum) self.__preview_widget.setScaledContents(True) self.__preview_widget.setStyleSheet( "QLabel { background-color : black}") def __init_console_widget__(self, parent=None): self.__console_widget = QPlainTextEdit(parent) self.__console_widget.setReadOnly(True) size = self.__left_layout.sizeHint() # self.__console_widget.setFixedSize(size.width(), size.height()/3) self.__console_widget.setStyleSheet( "QPlainTextEdit { background-color : gray}") palette = self.__console_widget.palette() palette.setColor(QPalette.Text, QColor(255, 255, 255)) self.__console_widget.setPalette(palette) self.dlp_controller.print_text_signal.connect(self.print_to_console) def __init_username_jobname_widget__(self, parent=None): self.__username_jobname_widget = QFrame(parent) self.__username_jobname_widget.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Maximum) username_label = QLabel("Username", parent=self.__username_jobname_widget) username_edit = QLineEdit(parent=self.__username_jobname_widget) username_edit.setText(self.dlp_controller.username) username_edit.textChanged.connect(self.dlp_controller.set_username) jobname_label = QLabel("Print Job Name", parent=self.__username_jobname_widget) jobname_edit = QLineEdit(parent=self.__username_jobname_widget) jobname_edit.setText(self.dlp_controller.print_job_name) jobname_edit.textChanged.connect(self.dlp_controller.set_printjob_name) etc = self.dlp_controller.evaluate_time_estimate() self.etc_label = QLabel( "ETC: " + QDateTime.fromTime_t(etc / 1000.0).toUTC().toString('hh:mm:ss'), self.__username_jobname_widget) self.dlp_controller.etc_updated_signal.connect( self.update_time_estimate) username_jobname_layout = QHBoxLayout(self.__username_jobname_widget) username_jobname_layout.addWidget(self.etc_label) username_jobname_layout.addWidget(username_label) username_jobname_layout.addWidget(username_edit) username_jobname_layout.addWidget(jobname_label) username_jobname_layout.addWidget(jobname_edit) self.__username_jobname_widget.setLayout(username_jobname_layout) @Slot(QPixmap) def preview_image(self, image): image = image.scaled(self.__preview_widget.width(), self.__preview_widget.height(), Qt.IgnoreAspectRatio) self.__preview_widget.setPixmap(image) @Slot(str) def print_to_console(self, txt): self.__console_widget.appendPlainText(txt) @Slot() def closeEvent(self, event: QCloseEvent): self.closing_window_event.emit() event.accept() @Slot() def load_support_images(self): file_names = QFileDialog.getOpenFileNames( caption='Select images', dir='../', filter="Image Files (*.png *.jpg *.bmp)") self.dlp_controller.set_support_images(file_names[0]) @Slot() def load_features_images(self): file_names = QFileDialog.getOpenFileNames( caption='Select images', dir='../', filter="Image Files (*.png *.jpg *.bmp)") self.dlp_controller.set_features_images(file_names[0]) @Slot() def block_parameters_signals(self): for widget in self.__left_widget.findChildren(QWidget): widget.blockSignals(True) @Slot() def reactivate_parameters_signals(self): for widget in self.__left_widget.findChildren(QWidget): widget.blockSignals(False) @Slot() def update_time_estimate(self, etc_ms): self.etc_label.setText( "ETC: " + QDateTime.fromTime_t(etc_ms / 1000.0).toUTC().toString('hh:mm:ss')) @Slot() def update_port_list(self): self.dlp_controller.update_port_list() self.port_list.clear() self.port_list.addItems(self.dlp_controller.available_ports()) @Slot(bool) def update_motor_parameters(self, is_changed): self.move_edit.set_step_size( self.dlp_controller.get_step_length_microns() / 1000.0) self.support_thickness_edit.set_step_size( self.dlp_controller.get_step_length_microns()) self.support_thickness_edit.spinbox_is_value_valid( self.dlp_controller.support_thickness * 1000) self.features_thickness_edit.set_step_size( self.dlp_controller.get_step_length_microns()) self.features_thickness_edit.spinbox_is_value_valid( self.dlp_controller.features_thickness * 1000) self.starting_thickness_edit.set_step_size( self.dlp_controller.get_step_length_microns()) self.starting_thickness_edit.spinbox_is_value_valid( self.dlp_controller.starting_incremental_thickness * 1000) self.thickness_step_edit.set_step_size( self.dlp_controller.get_step_length_microns()) self.thickness_step_edit.spinbox_is_value_valid( self.dlp_controller.incremental_step_thickness * 1000)
class TreeWidget(QTreeWidget): def __init__(self, parent=None, emptyText="Hint"): super().__init__(parent=parent) self.backgroundLabel = QLabel(self) self.backgroundLabel.setAttribute( QtCore.Qt.WA_TransparentForMouseEvents) self.backgroundLabel.setWordWrap(True) self.backgroundLabel.show() self.openFileAction = self.doNothing self.backgroundLabel.setAlignment(QtCore.Qt.AlignCenter) self.backgroundLabel.setText(emptyText) self.backgroundLabel.resize(400, 200) self.opacity = QtWidgets.QGraphicsOpacityEffect(self) self.opacity.setOpacity(0.5) self.backgroundLabel.setGraphicsEffect(self.opacity) self.backgroundLabel.setStyleSheet( "background-color: transparent; font-size: 15pt; font-weight: light;" ) self.setColumnCount(5) self.setIconSize(QtCore.QSize(32, 32)) self.setAutoScroll(True) self.setVerticalScrollMode(QtWidgets.QTreeWidget.ScrollPerPixel) self.setHorizontalScrollMode(QtWidgets.QTreeWidget.ScrollPerPixel) self.setColumnWidth(0, 300) self.setSelectionMode( QtWidgets.QTreeView.SelectionMode.ContiguousSelection) self.setColumnWidth(3, 200) self.setHeaderLabels( ["File name", "Size", "Status", "File location", "Relative path"]) self.setDropIndicatorShown(True) self.setAcceptDrops(True) self.setSupportedDropActions = QtCore.Qt.CopyAction | QtCore.Qt.MoveAction def dragEnterEvent(self, e): e.accept() def dragMoveEvent(self, e): e.accept() def dropEvent(self, e): self.openFileAction(str(e.mimeData().text().replace("file://", ""))) def resizeEvent(self, event) -> None: eventResult = super().resizeEvent(event) w, h = self.width(), self.height() diffW = w - self.backgroundLabel.width() diffH = h - self.backgroundLabel.height() self.backgroundLabel.move(diffW // 2, diffH // 2) return eventResult def setEmptyText(self, text: str) -> None: self.backgroundLabel.setText(text) def connectFileDragEvent(self, func) -> None: self.openFileAction = func def doNothing(self, f: str) -> None: log("[ WARN ] File {f} dragged, but no actoin was defined for this event" ) def showHideLabel(self) -> None: if (self.topLevelItemCount() > 0): self.backgroundLabel.hide() else: self.backgroundLabel.show() def addTopLevelItem(self, item: QtWidgets.QTreeWidgetItem) -> None: super().addTopLevelItem(item) self.showHideLabel() def addTopLevelItems(self, items: typing.Sequence) -> None: super().addTopLevelItems(items) self.showHideLabel() def clear(self) -> None: super().clear() self.showHideLabel() def takeTopLevelItem(self, index: int) -> QtWidgets.QTreeWidgetItem: w = super().takeTopLevelItem(index) self.showHideLabel() return w def insertTopLevelItem(self, index: int, item: QtWidgets.QTreeWidgetItem) -> None: super().insertTopLevelItem(index, item) self.showHideLabel() def insertTopLevelItems(self, index: int, items: typing.Sequence) -> None: super().insertTopLevelItems(index, items) self.showHideLabel()
class ViewWidget(QScrollArea): """Widget providing an interactive viewport.""" def __init__(self, app): QScrollArea.__init__(self) self.app = app self.image = QLabel() self.image.setScaledContents(True) self.image.setMouseTracking(True) self.image.mouseMoveEvent = self.mouseMoveEvent_over_image self.image.mousePressEvent = self.mousePressEvent_over_image self.image.mouseReleaseEvent = self.mouseReleaseEvent_over_image self.zoom_factor = 1 """The current zoom factor of the image.""" self.mouse_action = 0 """The current action on mouse move. Can be *ROI*, *WINDOW* or *PAN*.""" self.last_position = None """The last position, from which mouse events were processed.""" self.setMouseTracking(True) self.setAlignment(Qt.AlignHCenter | Qt.AlignVCenter) self.setWidget(self.image) # Hide scrollbars self.horizontalScrollBar().setStyleSheet("QScrollBar { height: 0 }") self.verticalScrollBar().setStyleSheet("QScrollBar { width: 0 }") def set(self, pixmap): """Display the image in *pixmap*.""" self.image.setPixmap(pixmap) def zoom(self, factor, relative=True): """Set the zoom level for the displayed image. By default, the new zoom factor will be relative to the current zoom factor. If *relative* is set to False, *factor* will be used as the new zoom factor.""" if self.app.dataset is None \ or (relative and (0.1 >= self.zoom_factor * factor >= 100)): return self.zoom_factor = self.zoom_factor * factor if relative else factor self.image.resize(self.zoom_factor * self.image.pixmap().size()) v_scroll = int(factor * self.verticalScrollBar().value() + ( (factor - 1) * self.verticalScrollBar().pageStep() / 2)) self.verticalScrollBar().setValue(v_scroll) h_scroll = int(factor * self.horizontalScrollBar().value() + ( (factor - 1) * self.horizontalScrollBar().pageStep() / 2)) self.horizontalScrollBar().setValue(h_scroll) def zoom_fit(self): """Zoom the displayed image to fit the available viewport.""" image = self.image.pixmap().size() viewport = self.size() if image.height() == 0 or image.width() == 0: return v_zoom = viewport.height() / image.height() h_zoom = viewport.width() / image.width() self.zoom(min(v_zoom, h_zoom) * 0.99, False) def mousePressEvent(self, event): # pylint: disable=C0103 """Handle pan and window functionality on mouse button down.""" if event.buttons() == Qt.LeftButton \ and event.modifiers() == Qt.NoModifier: self.mouse_action = "PAN" elif event.buttons() == Qt.MiddleButton: self.mouse_action = "WINDOW" self.last_position = event.screenPos() def mouseReleaseEvent(self, event): # pylint: disable=C0103,W0613 """Handle RoI functionality on mouse button up.""" if self.mouse_action == "ROI": self.app.recalculate() self.last_position = None self.mouse_action = 0 def mouseMoveEvent(self, event): # pylint: disable=C0103 """Handle pan, window and RoI functionality on mouse move.""" self.app.window.show_status("") if self.mouse_action == "PAN": vertical = self.verticalScrollBar().value() \ + self.last_position.y() - event.screenPos().y() horizontal = self.horizontalScrollBar().value() \ + self.last_position.x() - event.screenPos().x() self.verticalScrollBar().setValue(vertical) self.horizontalScrollBar().setValue(horizontal) self.last_position = event.screenPos() elif self.mouse_action == "WINDOW": move = self.last_position.x() - event.screenPos().x() scale = self.last_position.y() - event.screenPos().y() self.last_position = event.screenPos() self.app.mode.adjust_window(move, scale) self.app.refresh() elif self.mouse_action == "ROI": x_pos = event.pos().x() if event.pos().x() <= self.image.width() \ else self.image.width() y_pos = event.pos().y() if event.pos().y() <= self.image.height() \ else self.image.height() if self.app.tool is not None: self.app.tool.end_roi(int(x_pos / self.zoom_factor), int(y_pos / self.zoom_factor)) self.app.refresh() def mousePressEvent_over_image(self, event): # pylint: disable=C0103 """Handle RoI functionality on mouse button down over the image. Hands off contorl to *mousePressEvent* when appropriate.""" if event.buttons() == Qt.LeftButton \ and event.modifiers() == Qt.ControlModifier: self.mouse_action = "ROI" self.last_position = event.pos() if self.app.tool is not None: x_pos = event.pos().x() y_pos = event.pos().y() self.app.tool.start_roi(int(x_pos / self.zoom_factor), int(y_pos / self.zoom_factor)) else: self.mousePressEvent(event) def mouseMoveEvent_over_image(self, event): # pylint: disable=C0103 """Handle value display functionality on mouse move over the image. Call *mouseMoveEvent* for pan, window and RoI functionality.""" self.mouseMoveEvent(event) x_coord = int((self.horizontalScrollBar().value() + event.pos().x()) // self.zoom_factor) y_coord = int((self.verticalScrollBar().value() + event.pos().y()) // self.zoom_factor) slice_ = self.app.dataset.get_pixeldata(self.app.slice) shape = slice_.shape if (x_coord < shape[0] and y_coord < shape[1]): value = slice_[x_coord, y_coord] self.app.window.show_status("{} x {} - {:.4g}".format( x_coord, y_coord, value)) def mouseReleaseEvent_over_image(self, event): # pylint: disable=C0103 """Call *mouseReleaseEvent* on mouse button up for RoI functionality.""" self.mouseReleaseEvent(event) def wheelEvent(self, event): # pylint: disable=C0103 """Handle scroll wheel events in the viewport. Scroll - Change current slice up or down. Alt+Scroll - Change current scan up or down. Strg+Scroll - Zoom the current image in or out.""" if event.modifiers() == Qt.NoModifier: slice_ = int(numpy.sign(event.delta())) self.app.select_slice(slice_, True) elif event.modifiers() == Qt.ControlModifier: self.zoom(0.8 if event.delta() < 0 else 1.25) elif event.modifiers() == Qt.AltModifier: scan = int(numpy.sign(event.delta())) self.app.select_scan(scan, True)
def __init__(self, game: Game, unit_type: UnitType) -> None: super().__init__() self.setModal(True) self.game = game self.unit_type = unit_type self.name = unit_type.name self.setWindowTitle(f"Unit Info: {self.name}") self.setWindowIcon(QIcon("./resources/icon.png")) self.setMinimumHeight(570) self.setMaximumWidth(640) self.setWindowFlags(Qt.WindowStaysOnTopHint) self.layout = QGridLayout() header = QLabel(self) header.setGeometry(0, 0, 720, 360) pixmap = None if isinstance(self.unit_type, AircraftType): pixmap = AIRCRAFT_BANNERS.get(self.unit_type.dcs_id) elif isinstance(self.unit_type, GroundUnitType): pixmap = VEHICLE_BANNERS.get(self.unit_type.dcs_id) if pixmap is None: pixmap = AIRCRAFT_BANNERS.get("Missing") header.setPixmap(pixmap.scaled(header.width(), header.height())) self.layout.addWidget(header, 0, 0) self.gridLayout = QGridLayout() # Build the topmost details grid. self.details_grid = QFrame() self.details_grid_layout = QGridLayout() self.details_grid_layout.setMargin(0) self.name_box = QLabel( f"<b>Name:</b> {unit_type.manufacturer} {unit_type.name}") self.name_box.setProperty("style", "info-element") self.country_box = QLabel( f"<b>Country of Origin:</b> {unit_type.country_of_origin}") self.country_box.setProperty("style", "info-element") self.role_box = QLabel(f"<b>Role:</b> {unit_type.role}") self.role_box.setProperty("style", "info-element") self.year_box = QLabel( f"<b>Variant Introduction:</b> {unit_type.year_introduced}") self.year_box.setProperty("style", "info-element") self.details_grid_layout.addWidget(self.name_box, 0, 0) self.details_grid_layout.addWidget(self.country_box, 0, 1) self.details_grid_layout.addWidget(self.role_box, 1, 0) self.details_grid_layout.addWidget(self.year_box, 1, 1) self.details_grid.setLayout(self.details_grid_layout) self.gridLayout.addWidget(self.details_grid, 1, 0) # If it's an aircraft, include the task list. if isinstance(unit_type, AircraftType): self.tasks_box = QLabel( f"<b>In-Game Tasks:</b> {self.generateAircraftTasks()}") self.tasks_box.setProperty("style", "info-element") self.gridLayout.addWidget(self.tasks_box, 2, 0) # Finally, add the description box. self.details_text = QTextBrowser() self.details_text.setProperty("style", "info-desc") self.details_text.setText(unit_type.description) self.details_text.setOpenExternalLinks( True ) # in aircrafttype.py and groundunittype.py, for the descriptions, if No Data. including a google search link self.gridLayout.addWidget(self.details_text, 3, 0) self.layout.addLayout(self.gridLayout, 1, 0) self.setLayout(self.layout)
def initUi(self): self.layout = QGridLayout() header = QLabel(self) header.setGeometry(0, 0, 720, 360) if ( dcs.planes.plane_map.get(self.unit_type.id) is not None or dcs.helicopters.helicopter_map.get(self.unit_type.id) is not None ): pixmap = AIRCRAFT_BANNERS.get(self.unit_type.id) elif dcs.vehicles.vehicle_map.get(self.unit_type.id) is not None: pixmap = VEHICLE_BANNERS.get(self.unit_type.id) if pixmap is None: pixmap = AIRCRAFT_BANNERS.get("Missing") header.setPixmap(pixmap.scaled(header.width(), header.height())) self.layout.addWidget(header, 0, 0) self.gridLayout = QGridLayout() # Build the topmost details grid. self.details_grid = QFrame() self.details_grid_layout = QGridLayout() self.details_grid_layout.setMargin(0) self.name_box = QLabel( f"<b>Name:</b> {db.unit_get_expanded_info(self.game.player_country, self.unit_type, 'manufacturer')} {db.unit_get_expanded_info(self.game.player_country, self.unit_type, 'name')}" ) self.name_box.setProperty("style", "info-element") self.country_box = QLabel( f"<b>Country of Origin:</b> {db.unit_get_expanded_info(self.game.player_country, self.unit_type, 'country-of-origin')}" ) self.country_box.setProperty("style", "info-element") self.role_box = QLabel( f"<b>Role:</b> {db.unit_get_expanded_info(self.game.player_country, self.unit_type, 'role')}" ) self.role_box.setProperty("style", "info-element") self.year_box = QLabel( f"<b>Variant Introduction:</b> {db.unit_get_expanded_info(self.game.player_country, self.unit_type, 'year-of-variant-introduction')}" ) self.year_box.setProperty("style", "info-element") self.details_grid_layout.addWidget(self.name_box, 0, 0) self.details_grid_layout.addWidget(self.country_box, 0, 1) self.details_grid_layout.addWidget(self.role_box, 1, 0) self.details_grid_layout.addWidget(self.year_box, 1, 1) self.details_grid.setLayout(self.details_grid_layout) self.gridLayout.addWidget(self.details_grid, 1, 0) # If it's an aircraft, include the task list. if ( dcs.planes.plane_map.get(self.unit_type.id) is not None or dcs.helicopters.helicopter_map.get(self.unit_type.id) is not None ): self.tasks_box = QLabel( f"<b>In-Game Tasks:</b> {self.generateAircraftTasks()}" ) self.tasks_box.setProperty("style", "info-element") self.gridLayout.addWidget(self.tasks_box, 2, 0) # Finally, add the description box. self.details_text = QTextBrowser() self.details_text.setProperty("style", "info-desc") self.details_text.setText( db.unit_get_expanded_info(self.game.player_country, self.unit_type, "text") ) self.gridLayout.addWidget(self.details_text, 3, 0) self.layout.addLayout(self.gridLayout, 1, 0) self.setLayout(self.layout)
def playDiaporama(diaporamaGenerator, parent=None): """ Open a new window and play a slide show. @param diaporamaGenerator: generator for file names @type diaporamaGenerator: iterator object @param parent: @type parent: """ global isSuspended isSuspended = False # init diaporama window newWin = QMainWindow(parent) newWin.setAttribute(Qt.WA_DeleteOnClose) newWin.setContextMenuPolicy(Qt.CustomContextMenu) newWin.setWindowTitle(parent.tr('Slide show')) label = QLabel() label.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) label.img = None newWin.setCentralWidget(label) newWin.showFullScreen() from bLUe import set_event_handlers set_event_handlers(label) # Pause key shortcut actionEsc = QAction('Pause', None) actionEsc.setShortcut(QKeySequence(Qt.Key_Escape)) newWin.addAction(actionEsc) # context menu event handler def contextMenuHandler(action): global isSuspended if action.text() == 'Pause': isSuspended = True # quit full screen mode newWin.showMaximized() elif action.text() == 'Full Screen': if action.isChecked(): newWin.showFullScreen() else: newWin.showMaximized() elif action.text() == 'Resume': newWin.close() isSuspended = False playDiaporama(diaporamaGenerator, parent=window) # rating : the tag is written into the .mie file; the file is # created if needed. elif action.text() in ['0', '1', '2', '3', '4', '5']: with exiftool.ExifTool() as e: e.writeXMPTag(name, 'XMP:rating', int(action.text())) # connect shortkey action actionEsc.triggered.connect( lambda checked=False, name=actionEsc: contextMenuHandler(name)) # named arg checked is sent # context menu def contextMenu(position): menu = QMenu() actionEsc.setEnabled(not isSuspended) action2 = QAction('Full Screen', None) action2.setCheckable(True) action2.setChecked(newWin.windowState() & Qt.WindowFullScreen) action3 = QAction('Resume', None) action3.setEnabled(isSuspended) for action in [actionEsc, action2, action3]: menu.addAction(action) action.triggered.connect( lambda checked=False, name=action: contextMenuHandler(name)) # named arg checked is sent subMenuRating = menu.addMenu('Rating') for i in range(6): action = QAction(str(i), None) subMenuRating.addAction(action) action.triggered.connect( lambda checked=False, name=action: contextMenuHandler(name)) # named arg checked is sent menu.exec_(position) # connect contextMenuRequested newWin.customContextMenuRequested.connect(contextMenu) newWin.setToolTip("Esc to exit full screen mode") newWin.setWhatsThis( """ <b>Slide Show</b><br> The slide show cycles through the starting directory and its subfolders to display images. Photos rated 0 or 1 star are not shown (by default, all photos are rated 5 stars).<br> Hit the Esc key to <b>exit full screen mode and pause.</b><br> Use the Context Menu for <b>rating and resuming.</b> The rating is saved in the .mie sidecar and the image file is not modified. """ ) # end of setWhatsThis # play diaporama from bLUe import loadImageFromFile window.modeDiaporama = True while True: if isSuspended: newWin.setWindowTitle(newWin.windowTitle() + ' Paused') break try: if not newWin.isVisible(): break name = next(diaporamaGenerator) # search rating in metadata rating = 5 # default with exiftool.ExifTool() as e: try: rt = e.readXMPTag(name, 'XMP:rating') # raise ValueError if sidecar not found r = search("\d", rt) if r is not None: rating = int(r.group(0)) except ValueError: rating = 5 # don't display image with low rating if rating < 2: app.processEvents() imImg = loadImageFromFile(name, createsidecar=False) # zoom might be modified by the mouse wheel : remember if label.img is not None: imImg.Zoom_coeff = label.img.Zoom_coeff coeff = imImg.resize_coeff(label) imImg.yOffset -= (imImg.height() * coeff - label.height()) / 2.0 imImg.xOffset -= (imImg.width() * coeff - label.width()) / 2.0 app.processEvents() if isSuspended: newWin.setWindowTitle(newWin.windowTitle() + ' Paused') break newWin.setWindowTitle(parent.tr('Slide show') + ' ' + name + ' ' + ' '.join(['*'] * imImg.meta.rating)) gc.collect() label.img = imImg label.repaint() app.processEvents() gc.collect() sleep(2) app.processEvents() except StopIteration: newWin.close() window.diaporamaGenerator = None break except ValueError: continue except RuntimeError: window.diaporamaGenerator = None break except: window.diaporamaGenerator = None window.modeDiaporama = False raise app.processEvents() window.modeDiaporama = False
class Dicom_Browser(QWidget): draw_state: bool = False erase_state: bool = False point_pick: bool = False nj_points = [] nj_points_ready = Signal() series_id: str mask: np.array def __init__(self): super().__init__() self.initUI() self.rubberBand: QRubberBand = QRubberBand(QRubberBand.Line, self.image_label) def initUI(self): self.image = DicomImage() self.pixmap = QPixmap() self.image_label = QLabel() self.image_label.setAlignment(Qt.AlignHCenter | Qt.AlignVCenter) self.image_label.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred) self.image_label.setPixmap(self.pixmap) self.tags_view = Dicom_Tags_Widget(['']) self.tools = Dicom_ImageToolsWidget() self.tabs_widget = self.__inti_tab_widget__( [self.tags_view, self.tools]) self.tabs_widget.setMaximumWidth(600) image_layout = QVBoxLayout() image_layout.setContentsMargins(0, 0, 0, 0) image_layout.addWidget(self.image_label) image_group = QGroupBox() image_group.setStyleSheet("margin:0; padding: 0; border: 0;") image_group.setContentsMargins(0, 0, 0, 0) image_group.setLayout(image_layout) splitter = QSplitter() splitter.addWidget(image_group) splitter.addWidget(self.tabs_widget) layout = QHBoxLayout(self) layout.setContentsMargins(0, 0, 0, 0) layout.addWidget(splitter) self.tools.pen_selected.connect(self.pen_select) self.tools.erase_btn.clicked.connect(self.erase_btn_click) self.tools.slider.valueChanged.connect(self.slider_changed) self.tools.processing_btn.clicked.connect(self.send_nn_segmentation) self.tools.load_mask_btn.clicked.connect(self.load_nifti_mask_click) self.tools.save_mask_btn.clicked.connect(self.save_nifti_mask_click) self.tools.nj_segment_btn.clicked.connect(self.nj_segment_click) self.nj_points_ready.connect(self.nj_segment) def set_image(self): self.pixmap = QPixmap.fromImage(self.image.get_slice_as_QImage()) self.image_label.setPixmap(self.pixmap) self.set_tags() def update_mask(self): self.mask = np.zeros([ self.image.get_shape()[0], self.image.get_shape()[1], self.image.get_slice_amount() ], np.int) self.draw_mask() def load_series(self, path): if isinstance(path, list): if len(path) == 1: path = path[0] else: path = os.path.dirname(path[0]) + '/' self.image.load_dicom(path) self.set_image() if self.image.is_series(): self.set_slider_maximum() self.tools.slider.setDisabled(False) else: self.tools.slider.setDisabled(True) self.set_tags() self.update_tags() self.update_mask() def set_tags(self): result = [] for elem in self.image.slice().iterall(): result.append([str(elem.tag), elem.name, str(elem.value)]) return result def update_tags(self): self.tags_view.model.update(self.set_tags()) self.tags_view.model.layoutChanged.emit() # MOUSE EVENTS def wheelEvent(self, event): if self.image_label.underMouse(): delta = event.delta() if delta > 0: self.image.next_slice() elif delta < 0: self.image.pre_slice() self.set_image() self.tools.slider.setSliderPosition(self.image.get_slice_index()) self.update_tags() self.draw_mask() self.update() def mousePressEvent(self, e): if self.image_label.underMouse(): if self.draw_state: self.pos = self.point_on_image(e) self.set_mask_pixels(self.pos) self.draw_mask_point(self.pos) self.update() elif self.erase_state: self.pos = self.point_on_image(e) self.set_mask_pixels(self.pos, 0) self.set_image() self.draw_mask() self.update() elif self.point_pick: point = [ self.point_on_image(e).x(), self.point_on_image(e).x(), self.image.get_slice_index() ] self.nj_points.append(point) if len(self.nj_points) == 2: self.point_pick = False QApplication.restoreOverrideCursor() self.nj_points_ready.emit() else: self.origin = e.pos() if not self.rubberBand: self.rubberBand = QRubberBand(QRubberBand.Rectangle, self) self.rubberBand.setGeometry(QRect(self.origin, QSize())) self.rubberBand.show() def mouseMoveEvent(self, e): if self.image_label.underMouse(): if self.draw_state: self.pos = self.point_on_image(e) self.set_mask_pixels(self.pos) # self.mask[int(self.pos.y())][int(self.pos.x())][self.image.get_slice_index()] = 255 self.draw_mask_point(self.pos) self.update() elif self.erase_state: self.pos = self.point_on_image(e) self.set_mask_pixels(self.pos, 0) # self.mask[int(self.pos.y())][int(self.pos.x())][self.image.get_slice_index()] = 0 self.set_image() self.draw_mask() self.update() else: self.rubberBand.setGeometry( QRect(self.origin, e.pos()).normalized()) def mouseReleaseEvent(self, event): if self.image_label.underMouse(): if self.draw_state: return self.rubberBand.hide() def keyPressEvent(self, event): # Re-direct ESC key to closeEvent if event.key() == Qt.Key_Escape: if self.point_pick: self.point_pick = not self.point_pick QApplication.restoreOverrideCursor() # IMAGE SLIDER def set_slider_maximum(self): self.tools.set_slider_maximum(self.image.get_slice_amount() - 1) def slider_changed(self): self.image.set_slice_index(self.tools.slider.value()) self.set_image() self.update_tags() self.draw_mask() self.update() def pen_select(self): self.draw_state = self.tools.pen_btn.isChecked() def __init_slider(self) -> QSlider: slider = QSlider() slider.setOrientation(Qt.Horizontal) slider.setMaximumWidth(self.image_label.width()) slider.setMinimum(0) slider.setMaximum(self.image.get_slice_amount()) slider.setTickInterval(1) slider.setSliderPosition(1) slider.valueChanged.connect(self.slider_changed) if not self.image.is_series(): slider.setHidden(True) return slider def __inti_tab_widget__(self, widgets: list) -> object: tabs_widget = QTabWidget() tabs_widget.setTabPosition(QTabWidget.South) tabs_widget.setMinimumWidth(50) for wdg in widgets: tabs_widget.addTab(wdg, wdg.tab_name) return tabs_widget # MASKING def send_nn_segmentation(self): # Dicom_BrowserCtrl.save_mask(self, self.mask, 'res/H-DenseUNet-master_v1/livermask/0.nii') ctrl = Dicom_BrowserCtrl() head, tail = os.path.split(os.path.split(self.image.dicom_dir)[0]) ctrl.image_to_nn(tail, self.mask, self.image.get_shape()[0], self.image.get_shape()[1]) def set_mask(self): img = self.__arr_to_QImage(self.mask[:, :, self.image.get_slice_index()].T()) self.mask_pixmap = QPixmap.fromImage(img) self.mask_label.setPixmap(self.mask_pixmap) def draw_mask(self): try: if not np.array_equal( self.mask[:, :, self.image.get_slice_index()], np.zeros( [self.image.get_shape()[0], self.image.get_shape()[1]])): it = np.nditer(self.mask[:, :, self.image.get_slice_index()], flags=['multi_index']) for pixel in it: if pixel != 0: point = QPoint(it.multi_index[1], it.multi_index[0]) self.draw_mask_point(point, 1) except Exception: self.update_mask() def set_mask_pixels(self, center_point: QPoint, value=255): it = np.nditer(self.mask[:, :, self.image.get_slice_index()], flags=['multi_index']) size = int(self.tools.get_size() / 2) - 1 x = center_point.x() y = center_point.y() for pixel in it: if x - size <= it.multi_index[ 1] <= x + size and y + size >= it.multi_index[ 0] >= y - size: self.mask[it.multi_index[0]][it.multi_index[1]][ self.image.get_slice_index()] = value def draw_mask_point(self, point, pen_size: int = None): if pen_size is None: pen_size = self.tools.get_size() painter = QPainter(self.image_label.pixmap()) painter.setPen( QPen(self.tools.mask_color, pen_size, Qt.SolidLine, Qt.SquareCap, Qt.RoundJoin)) painter.drawPoint(point) def erase_btn_click(self): self.erase_state = not self.erase_state self.tools.erase_btn.setChecked(self.erase_state) if self.draw_state: self.draw_state = not self.draw_state self.tools.pen_btn.setChecked(self.draw_state) def load_nifti_mask_click(self): ctrl = Dicom_BrowserCtrl() self.mask = ctrl.load_nitfit_mask() self.draw_mask() self.update() def save_nifti_mask_click(self): Dicom_BrowserCtrl.save_mask(self, self.mask) def nj_segment_click(self): QApplication.setOverrideCursor(QCursor(Qt.CrossCursor)) self.point_pick = True def nj_segment(self): ctrl = Dicom_BrowserCtrl() ctrl.nj_segment(self.image.dicom_dir, self.nj_points) self.nj_points = [] self.mask = ctrl.load_nitfit_mask('data/.tmp.nii') self.draw_mask() self.update() def point_on_image(self, e): x_offset, y_offset = self.__image_offset() pos = QPoint(e.x() - x_offset, e.y() - y_offset) return pos def __image_offset(self): x_offset = (self.image_label.width() - self.pixmap.width()) / 2 y_offset = (self.image_label.height() - self.pixmap.height()) / 2 return x_offset, y_offset def __arr_to_QImage(self, arr_img): img = PIL.Image.fromarray(arr_img) img = img.convert("L") result = ImageQt(img) return result
class ShowValHist_NodeInstance_MainWidget(QWidget): def __init__(self, parent_node_instance): super(ShowValHist_NodeInstance_MainWidget, self).__init__() # leave these lines ------------------------------ self.parent_node_instance = parent_node_instance # ------------------------------------------------ self.setStyleSheet(''' background-color: #333333; ''') self.setLayout(QVBoxLayout()) # settings widget settings_widget = QWidget() settings_widget.setLayout(QHBoxLayout()) self.connect_lines_check_box = QCheckBox('connect lines linear') settings_widget.layout().addWidget(self.connect_lines_check_box) self.layout().addWidget(settings_widget) # points area self.label = QLabel() pix = QPixmap(300, 200) self.label.setPixmap(pix) self.layout().addWidget(self.label) self.resize(300, 200) self.values = [] def update(self, new_vals): self.values = new_vals painter = QPainter(self.label.pixmap()) painter.setRenderHint(QPainter.Antialiasing) painter.setPen(QPen('#333333')) painter.setBrush(QColor('#333333')) painter.drawRect(self.label.rect()) pen = QPen(QColor(255, 255, 255)) pen.setWidth(1) painter.setPen(pen) painter.setBrush(QBrush(Qt.white)) x_old = -1 y_old = -1 for i in range(len(self.values)): v = self.values[i] x = i * (self.label.width() / len(self.values)) y = self.label.height() - self.label.height() * v if self.connect_lines_check_box.isChecked() and i > 0: painter.drawLine(x_old, y_old, x, y) else: painter.drawEllipse(x - 1, y - 1, 2, 2) x_old = x y_old = y self.repaint() def get_data(self): return { 'connect lines linear': self.connect_lines_check_box.isChecked() } def set_data(self, data): self.connect_lines_check_box.setChecked(data['connect lines linear']) # optional - important for threading - stop everything here def removing(self): pass
class QAnimatedStatusBar(QStatusBar): def __init__(self): super().__init__() self.dbg = False self.height_ = 0 self.anim = QPropertyAnimation(self, b"geometry") self.hide() self.timer = QTimer() self.timer.setSingleShot(True) self.btn_close = QPushButton("X") self.insertPermanentWidget(0, self.btn_close) self.btn_close.clicked.connect(self._hide_message) self.btn_close.setAutoDefault(False) self.btn_close.setDefault(False) self.animationInterval = 1000 self.label = QLabel("") self.label.setWordWrap(True) self.label.setStyleSheet( "background-color:transparent;margin:0px;border:0px;text-decoration:none" ) self.addWidget(self.label) self.showInterval = 3000 self.msg = '' self.css = {} self.css[ 'default'] = "background-color:qlineargradient(x1:0 y1:0,x2:0 y2:1,stop:0 rgba(25,25,25,1), stop:1 rgba(25,25,25,0.6));color:white;\ text-decoration:underline;font-weight:bold;border:1px;border-color:black;border-style:solid;" #def __init__ def _debug(self, msg): print("QAnimatedStatusBar: %s" % msg) #def _debug def setText(self, msg): #self.msg="%s"%msg.replace("\n","<br>") self.label.setText("%s" % msg.replace("\n", "<br>")) #def setText def setAnimation(self, animation): try: self.anim = QPropertyAnimation(self, b"%s" % animation) except Exception as e: self._debug(e) #def setAnimation def setAnimationInterval(self, miliseconds): self.animationInterval = miliseconds #def setAnimationInterval def setShowInterval(self, miliseconds): self.showInterval = miliseconds #def setShowInterval def setStateCss(self, state, css): self.css[ state] = "QStatusBar{text-decoration:underline;font-weight:bold;border:1px;border-color:black;border-style:solid;%s}" % css #def setStateCss def setCss(self, css): self.css[ 'default'] = "QStatusBar{text-decoration:underline;font-weight:bold;border:1px;border-color:black;border-style:solid;%s}" % css #def setCss def show(self, state=None): self._debug("Show state %s" % state) if state: if state in self.css.keys(): self.setStyleSheet("""%s""" % self.css[state]) else: self._debug("No css found for %s" % state) self.setStyleSheet("""%s""" % self.css['default']) else: self.setStyleSheet("""%s""" % self.css['default']) self.raise_() #self.showMessage("%s"%self.msg) self.showMessage("") self.anim.setDuration(self.animationInterval) self.anim.setLoopCount(1) self.btn_close.height = 16 super(QAnimatedStatusBar, self).show() width_ = self.parentWidget().width() #360px should be good enough.... width = 360 self.anim.setDuration(1) self.anim.setStartValue(QRect(width_ - width, 0, width, 0)) self.anim.setEndValue( QRect(width_ - width, 0, width, self.label.height() + 6)) self.anim.start() if state == None or state == '': self._debug("Hide state %s" % state) height = (self.height() / 10) - 10 self.height_ = height self.timer.singleShot(self.showInterval, lambda: self._hide_message()) #def show(self,state=None): def _hide_message(self): self._debug("Hiding statusbar") width_ = self.parentWidget().width() width = 360 self.anim.setDuration(self.animationInterval) self.anim.setStartValue(QRect(width_ - width, 0, width, self.height_)) self.anim.setEndValue(QRect(width_ - width, 0, width, 0)) self.anim.start() self.timer.singleShot(self.animationInterval, lambda: self.hide())
class %CLASS%(QWidget, MWB): def __init__(self, params): MWB.__init__(self, params) QWidget.__init__(self) self.setStyleSheet(''' background-color: #333333; ''') self.setLayout(QVBoxLayout()) # settings widget settings_widget = QWidget() settings_widget.setLayout(QHBoxLayout()) self.connect_lines_check_box = QCheckBox('connect lines linear') settings_widget.layout().addWidget(self.connect_lines_check_box) self.layout().addWidget(settings_widget) # points area self.label = QLabel() pix = QPixmap(300,200) self.label.setPixmap(pix) self.layout().addWidget(self.label) self.resize(300, 200) self.values = [] def update(self, new_vals): self.values = new_vals if len(self.values) == 0: return painter = QPainter(self.label.pixmap()) painter.setRenderHint(QPainter.Antialiasing) painter.setPen(QPen('#333333')) painter.setBrush(QColor('#333333')) painter.drawRect(self.label.rect()) pen = QPen(QColor(255, 255, 255)) pen.setWidth(1) painter.setPen(pen) painter.setBrush(QBrush(Qt.white)) x_old = -1 y_old = -1 div = max(self.values) for i in range(len(self.values)): v = self.values[i] x = i * (self.label.width()/len(self.values)) y = self.label.height()-self.label.height()*v/div if self.connect_lines_check_box.isChecked() and i>0: painter.drawLine(x_old, y_old, x, y) else: painter.drawEllipse(x-1, y-1, 2, 2) x_old = x y_old = y self.repaint() def get_data(self): return {'connect lines linear': self.connect_lines_check_box.isChecked()} def set_data(self, data): self.connect_lines_check_box.setChecked(data['connect lines linear']) def remove_event(self): pass
class Ui_MainWindow(object): def __init__(self): self.file_name = "" self.threadpool = QThreadPool() self.num_of_co = 1000 self.alpha = 0.1 self.watermarker = None def setupUi(self, MainWindow): if not MainWindow.objectName(): MainWindow.setObjectName(u"MainWindow") MainWindow.resize(1024, 768) self.centralwidget = QWidget(MainWindow) self.centralwidget.setObjectName(u"centralwidget") self.verticalLayoutWidget_2 = QWidget(self.centralwidget) self.verticalLayoutWidget_2.setObjectName(u"verticalLayoutWidget_2") self.verticalLayoutWidget_2.setGeometry(QRect(0, 0, 1021, 511)) self.pictureLayout = QVBoxLayout(self.verticalLayoutWidget_2) self.pictureLayout.setObjectName(u"pictureLayout") self.pictureLayout.setContentsMargins(0, 0, 0, 0) self.picture_label = QLabel(self.verticalLayoutWidget_2) self.picture_label.setObjectName(u"picture_label") self.pictureLayout.addWidget(self.picture_label) self.picture_button = QPushButton(self.verticalLayoutWidget_2) self.picture_button.setObjectName(u"picture_button") self.pictureLayout.addWidget(self.picture_button) self.horizontalLayoutWidget = QWidget(self.centralwidget) self.horizontalLayoutWidget.setObjectName(u"horizontalLayoutWidget") self.horizontalLayoutWidget.setGeometry(QRect(10, 520, 1011, 120)) self.horizontalLayout_2 = QHBoxLayout(self.horizontalLayoutWidget) self.horizontalLayout_2.setObjectName(u"horizontalLayout_2") self.horizontalLayout_2.setContentsMargins(0, 0, 0, 0) self.verticalLayout_3 = QVBoxLayout() self.verticalLayout_3.setObjectName(u"verticalLayout_3") self.label_2 = QLabel(self.horizontalLayoutWidget) self.label_2.setObjectName(u"label_2") self.verticalLayout_3.addWidget(self.label_2) self.DCT_encode = QPushButton(self.horizontalLayoutWidget) self.DCT_encode.setObjectName(u"DCT_encode") self.verticalLayout_3.addWidget(self.DCT_encode) self.DCT_decode = QPushButton(self.horizontalLayoutWidget) self.DCT_decode.setObjectName(u"DCT_decode") self.verticalLayout_3.addWidget(self.DCT_decode) self.label_4 = QLabel(self.horizontalLayoutWidget) self.label_4.setObjectName(u"label_4") self.verticalLayout_3.addWidget(self.label_4) self.DCT_masg = QLineEdit(self.horizontalLayoutWidget) self.DCT_masg.setObjectName(u"DCT_masg") self.verticalLayout_3.addWidget(self.DCT_masg) self.horizontalLayout_2.addLayout(self.verticalLayout_3) self.verticalLayout = QVBoxLayout() self.verticalLayout.setObjectName(u"verticalLayout") self.label_3 = QLabel(self.horizontalLayoutWidget) self.label_3.setObjectName(u"label_3") self.verticalLayout.addWidget(self.label_3) self.LSB_encode = QPushButton(self.horizontalLayoutWidget) self.LSB_encode.setObjectName(u"LSB_encode") self.verticalLayout.addWidget(self.LSB_encode) self.LSB_decode = QPushButton(self.horizontalLayoutWidget) self.LSB_decode.setObjectName(u"LSB_decode") self.verticalLayout.addWidget(self.LSB_decode) self.lsb_encode_msg = QLabel(self.horizontalLayoutWidget) self.lsb_encode_msg.setObjectName(u"lsb_encode_msg") self.verticalLayout.addWidget(self.lsb_encode_msg) self.LSB_msg = QLineEdit(self.horizontalLayoutWidget) self.LSB_msg.setObjectName(u"LSB_msg") self.verticalLayout.addWidget(self.LSB_msg) self.horizontalLayout_2.addLayout(self.verticalLayout) self.verticalLayoutWidget_3 = QWidget(self.centralwidget) self.verticalLayoutWidget_3.setObjectName(u"verticalLayoutWidget_3") self.verticalLayoutWidget_3.setGeometry(QRect(20, 650, 981, 51)) self.verticalLayout_2 = QVBoxLayout(self.verticalLayoutWidget_3) self.verticalLayout_2.setObjectName(u"verticalLayout_2") self.verticalLayout_2.setContentsMargins(0, 0, 0, 0) self.label_6 = QLabel(self.verticalLayoutWidget_3) self.label_6.setObjectName(u"label_6") self.verticalLayout_2.addWidget(self.label_6) self.progressBar = QProgressBar(self.verticalLayoutWidget_3) self.progressBar.setObjectName(u"progressBar") self.progressBar.setValue(0) self.verticalLayout_2.addWidget(self.progressBar) MainWindow.setCentralWidget(self.centralwidget) self.menubar = QMenuBar(MainWindow) self.menubar.setObjectName(u"menubar") self.menubar.setGeometry(QRect(0, 0, 1024, 21)) MainWindow.setMenuBar(self.menubar) self.statusbar = QStatusBar(MainWindow) self.statusbar.setObjectName(u"statusbar") MainWindow.setStatusBar(self.statusbar) self.retranslateUi(MainWindow) # bind functions self.picture_button.clicked.connect(self.open_file) self.LSB_encode.clicked.connect(self.call_lsb_encode) self.LSB_decode.clicked.connect(self.call_lsb_decode) self.DCT_encode.clicked.connect(self.call_dct_encode) self.DCT_decode.clicked.connect(self.call_dct_decode) # end bind functions() self.hide_progress_bar() self.disable_Methods(True) QMetaObject.connectSlotsByName(MainWindow) # setupUi def retranslateUi(self, MainWindow): MainWindow.setWindowTitle( QCoreApplication.translate("MainWindow", u"Watermarking tool", None)) # self.picture_label.setText(QCoreApplication.translate("MainWindow", u"TextLabel", None)) self.picture_button.setText( QCoreApplication.translate("MainWindow", u"Select picture", None)) self.label_2.setText( QCoreApplication.translate("MainWindow", u"DCT", None)) self.DCT_encode.setText( QCoreApplication.translate("MainWindow", u"encode", None)) self.DCT_decode.setText( QCoreApplication.translate("MainWindow", u"decode", None)) self.label_4.setText( QCoreApplication.translate("MainWindow", u"coeficient:", None)) self.DCT_masg.setText( QCoreApplication.translate("MainWindow", u"1000, 0.1", None)) self.label_3.setText( QCoreApplication.translate("MainWindow", u"LSB", None)) self.LSB_encode.setText( QCoreApplication.translate("MainWindow", u"encode", None)) self.LSB_decode.setText( QCoreApplication.translate("MainWindow", u"decode", None)) self.lsb_encode_msg.setText( QCoreApplication.translate("MainWindow", u"LSB msg:", None)) self.LSB_msg.setText( QCoreApplication.translate("MainWindow", u"secret", None)) self.label_6.setText( QCoreApplication.translate("MainWindow", u"Work in progress:", None)) # retranslateUi # def bindFunctions(self): def load_picture(self): pixmap = QPixmap(self.file_name[0]) if pixmap.width() > pixmap.height(): self.picture_label.setPixmap( pixmap.scaledToWidth(self.picture_label.width())) else: self.picture_label.setPixmap( pixmap.scaledToHeight(self.picture_label.height())) def open_file(self): self.hide_progress_bar() self.file_name = QFileDialog.getOpenFileName( None, "Open Image", "", "Image Files (*.png *.jpg *.bmp)") self.load_picture() self.disable_Methods(False) def method_LSB_encode(self, progress_callback): self.disable_Methods(True) progress_callback.emit(10) msg = self.LSB_msg.text() image = cv2.imread(self.file_name[0]) watermarker = LSBWatermarker(image=image, mode='encode-message', message=msg, filename='result.png') progress_callback.emit(50) self.file_name = ["result.png", ""] watermarker.run() progress_callback.emit(90) self.load_picture() self.disable_Methods(False) progress_callback.emit(100) def method_LSB_decode(self, progress_callback): self.disable_Methods(True) self.LSB_msg.setText("") progress_callback.emit(10) image = cv2.imread(self.file_name[0]) watermarker = LSBWatermarker(image=image, mode='decode-message') progress_callback.emit(50) watermarker.run() self.disable_Methods(False) progress_callback.emit(90) # self.show_decoded_msg(watermarker.decoded_msg) if watermarker.decoded_msg == "Provided file has no message encoded!": self.LSB_msg.setText(watermarker.decoded_msg) else: self.LSB_msg.setText("Decoded: " + watermarker.decoded_msg) progress_callback.emit(100) def method_DCT_encode(self, progress_callback): self.disable_Methods(True) progress_callback.emit(10) msg = self.DCT_masg.text().split(",") try: self.num_of_co = int(msg[0]) self.alpha = float(msg[1]) self.watermarker = WatermarkDCT(self.file_name[0], num_of_co=self.num_of_co, alpha=self.alpha) progress_callback.emit(50) self.watermarker.encode_watermark() self.file_name = ["result_DCT.png", ""] self.DCT_masg.setText("Picture is watermarked?:" + str(self.watermarker.detect_watermark())) except Exception as e: print(e) self.DCT_masg.setText("Error: wrong parameters: example 1000, 0.1") finally: progress_callback.emit(90) self.load_picture() self.disable_Methods(False) progress_callback.emit(100) def method_DCT_decode(self, progress_callback): self.disable_Methods(True) progress_callback.emit(10) try: if self.watermarker is None: self.watermarker = WatermarkDCT(self.file_name[0], num_of_co=self.num_of_co, alpha=self.alpha) progress_callback.emit(50) self.DCT_masg.setText( "Picture is watermarked?:" + str(self.watermarker.detect_watermark(self.file_name[0]))) except Exception as e: print(e) self.DCT_masg.setText("Error: Unable to check the picture.") finally: progress_callback.emit(90) self.load_picture() self.disable_Methods(False) progress_callback.emit(100) def show_decoded_msg(self, msg): msgBox = QMessageBox() msgBox.setWindowTitle("Decoded message:") msgBox.setText(msg) msgBox.exec_() def thread_complete(self): print("THREAD COMPLETE!") def progress_fn(self, n): self.progressBar.setValue(n) def print_output(self, s): print(s) def call_lsb_encode(self): self.show_progress_bar() self.call_function(self.method_LSB_encode) def call_lsb_decode(self): self.show_progress_bar() self.call_function(self.method_LSB_decode) def call_dct_encode(self): self.show_progress_bar() self.call_function(self.method_DCT_encode) def call_dct_decode(self): self.show_progress_bar() self.call_function(self.method_DCT_decode) def call_function(self, fn): worker = Worker( fn) # Any other args, kwargs are passed to the run function worker.signals.result.connect(self.print_output) worker.signals.finished.connect(self.thread_complete) worker.signals.progress.connect(self.progress_fn) # Execute self.threadpool.start(worker) def hide_progress_bar(self): self.progressBar.setValue(0) self.progressBar.setVisible(False) self.label_6.setVisible(False) def show_progress_bar(self): self.progressBar.setValue(0) self.progressBar.setVisible(True) self.label_6.setVisible(True) def disable_Methods(self, disable): self.LSB_encode.setDisabled(disable) self.LSB_decode.setDisabled(disable) self.DCT_decode.setDisabled(disable) self.DCT_encode.setDisabled(disable)
class SidePanel(QDockWidget): saved = Signal(dict) def __init__(self): super(SidePanel, self).__init__() # Internal variables self._coverdir = path.join("data", "images", "covers") self._id = 0 self._imagedata = "" size = [220, 16] # Width, Height (for QLineEdits/QTextEdits) # QDockWidget settings self.setAllowedAreas(Qt.RightDockWidgetArea) self.setFeatures(QDockWidget.DockWidgetClosable) self.setFixedWidth(350) self.setVisible(False) # Fonts bold = QFont() bold.setBold(True) boldUnderline = QFont() boldUnderline.setBold(True) boldUnderline.setUnderline(True) # Horizontal line hline = QFrame() hline.setFrameShape(QFrame.HLine) hline.setFrameShadow(QFrame.Sunken) """Widgets""" # Cover self.cover = QLabel() self.cover.setAlignment(Qt.AlignCenter) self.cover.setMinimumHeight(200) self.cover.setMaximumSize(self.width(), 250) # Buttons self.fetchInfoButton = QPushButton("Fetch missing info") self.fetchInfoButton.setToolTip("Try to fetch info from MobyGames") self.fetchInfoButton.clicked.connect(self._fetchInfo) self.editDetailsButton = QPushButton("Edit") self.editDetailsButton.setCheckable(True) self.editDetailsButton.clicked.connect(self._editDetails) self.saveDetailsButton = QPushButton("Save") self.saveDetailsButton.clicked.connect(self._saveInfo) self.fetchPriceButton = QPushButton("Update price data") self.fetchPriceButton.setToolTip("Try to update price data from Pricecharting") self.fetchPriceButton.clicked.connect(self._fetchPriceData) self.savePriceButton = QPushButton("Save") self.savePriceButton.clicked.connect(self._saveInfo) # Info layout widgets self.nameInfoLabel = QLabel("Name:") self.nameInfoLabel.setFont(bold) self.nameDataLabel = QLabel() self.nameDataLabel.setWordWrap(True) self.platformInfoLabel = QLabel("Platform:") self.platformInfoLabel.setFont(bold) self.platformDataLabel = QLabel() self.publisherInfoLabel = QLabel("Publisher:") self.publisherInfoLabel.setFont(bold) self.publisherDataLabel = QLabel() self.developerInfoLabel = QLabel("Developer:") self.developerInfoLabel.setFont(bold) self.developerDataLabel = QLabel() self.regionInfoLabel = QLabel("Region:") self.regionInfoLabel.setFont(bold) self.regionDataLabel = QLabel() self.codeInfoLabel = QLabel("Code:") self.codeInfoLabel.setFont(bold) self.codeDataLabel = QLabel() self.codeDataLabel.setWordWrap(True) self.itemInfoLabel = QLabel("Game:") self.itemInfoLabel.setFont(bold) self.itemDataLabel = QLabel() self.boxInfoLabel = QLabel("Box:") self.boxInfoLabel.setFont(bold) self.boxDataLabel = QLabel() self.manualInfoLabel = QLabel("Manual:") self.manualInfoLabel.setFont(bold) self.manualDataLabel = QLabel() self.genreInfoLabel = QLabel("Genre:") self.genreInfoLabel.setFont(bold) self.genreDataLabel = QLabel() self.yearInfoLabel = QLabel("Year:") self.yearInfoLabel.setFont(bold) self.yearDataLabel = QLabel() self.commentInfoLabel = QLabel("Comment:") self.commentInfoLabel.setFont(bold) self.commentDataLabel = QLabel() self.commentDataLabel.setWordWrap(True) self.platformsInfoLabel = QLabel("Available for:") self.platformsInfoLabel.setFont(bold) self.platformsDataLabel = QLabel() self.platformsDataLabel.setWordWrap(True) self.platformsDataLabel.setMaximumHeight(50) # Can get quite large otherwise # Edit layout widgets self.nameEditLabel = QLabel("Name:") self.nameEditLabel.setFont(bold) self.nameDataTE = QTextEdit() self.nameDataTE.setMaximumSize(size[0], size[1] * 2) self.platformEditLabel = QLabel("Platform:") self.platformEditLabel.setFont(bold) self.platformDataLE = QLineEdit() self.platformDataLE.setMaximumSize(size[0], size[1]) self.publisherEditLabel = QLabel("Publisher:") self.publisherEditLabel.setFont(bold) self.publisherDataLE = QLineEdit() self.publisherDataLE.setMaximumSize(size[0], size[1]) self.developerEditLabel = QLabel("Developer:") self.developerEditLabel.setFont(bold) self.developerDataLE = QLineEdit() self.developerDataLE.setMaximumSize(size[0], size[1]) self.regionEditLabel = QLabel("Region:") self.regionEditLabel.setFont(bold) self.regionDataCoB = QComboBox() self.regionDataCoB.addItems(("NTSC (JP)", "NTSC (NA)", "PAL")) self.regionDataCoB.setMinimumWidth(size[0]) # If not set it will be too small self.regionDataCoB.setMaximumSize(size[0], size[1]) self.codeEditLabel = QLabel("Code:") self.codeEditLabel.setFont(bold) self.codeDataLE = QLineEdit() self.codeDataLE.setMaximumSize(size[0], size[1]) self.itemEditLabel = QLabel("Game:") self.itemEditLabel.setFont(bold) self.itemDataCB = QCheckBox() self.itemDataCB.setChecked(False) self.boxEditLabel = QLabel("Box:") self.boxEditLabel.setFont(bold) self.boxDataCB = QCheckBox() self.boxDataCB.setChecked(False) self.manualEditLabel = QLabel("Manual:") self.manualEditLabel.setFont(bold) self.manualDataCB = QCheckBox() self.manualDataCB.setChecked(False) self.genreEditLabel = QLabel("Genre:") self.genreEditLabel.setFont(bold) self.genreDataLE = QLineEdit() self.genreDataLE.setMaximumSize(size[0], size[1]) self.yearEditLabel = QLabel("Year:") self.yearEditLabel.setFont(bold) self.yearDataLE = QLineEdit() self.yearDataLE.setMaximumSize(size[0], size[1]) self.commentEditLabel = QLabel("Comment:") self.commentEditLabel.setFont(bold) self.commentDataTE = QTextEdit() self.commentDataTE.setMaximumSize(size[0], size[1] * 2) self.platformsEditLabel = QLabel("Available for:") self.platformsEditLabel.setFont(bold) self.platformsDataTE = QTextEdit() self.platformsDataTE.setMaximumSize(size[0], size[1] * 2) # Price widgets self.paidPriceLabel = QLabel("Paid:") self.paidPriceLabel.setFont(bold) self.paidPriceDataLE = QLineEdit() self.paidPriceDataLE.setMaximumSize(60, size[1]) self.paidPriceDataLE.setAlignment(Qt.AlignRight) self.loosePriceLabel = QLabel("Loose:") self.loosePriceLabel.setFont(bold) self.loosePriceDataLabel = QLabel() self.loosePriceDataLabel.setAlignment(Qt.AlignRight) self.cibPriceLabel = QLabel("CIB:") self.cibPriceLabel.setFont(bold) self.cibPriceDataLabel = QLabel() self.cibPriceDataLabel.setAlignment(Qt.AlignRight) self.newPriceLabel = QLabel("New:") self.newPriceLabel.setFont(bold) self.newPriceDataLabel = QLabel() self.newPriceDataLabel.setAlignment(Qt.AlignRight) """Layouts""" # Cover self.coverVbox = QVBoxLayout() self.coverVbox.addWidget(self.cover, 1) self.coverVbox.addWidget(hline, 0) # Buttons self.detailsButtonHbox = QHBoxLayout() self.detailsButtonHbox.addWidget(self.fetchInfoButton, 0) self.detailsButtonHbox.addWidget(self.editDetailsButton, 0) self.detailsButtonHbox.addWidget(self.saveDetailsButton, 0) self.priceButtonHbox = QHBoxLayout() self.priceButtonHbox.addWidget(self.fetchPriceButton, 0) self.priceButtonHbox.addWidget(self.savePriceButton, 0) # Info layouts self.nameInfoHbox = QHBoxLayout() self.nameInfoHbox.addWidget(self.nameInfoLabel, 0) self.nameInfoHbox.addWidget(self.nameDataLabel, 0) self.platformInfoHbox = QHBoxLayout() self.platformInfoHbox.addWidget(self.platformInfoLabel, 0) self.platformInfoHbox.addWidget(self.platformDataLabel, 0) self.publisherInfoHbox = QHBoxLayout() self.publisherInfoHbox.addWidget(self.publisherInfoLabel, 0) self.publisherInfoHbox.addWidget(self.publisherDataLabel, 0) self.developerInfoHbox = QHBoxLayout() self.developerInfoHbox.addWidget(self.developerInfoLabel, 0) self.developerInfoHbox.addWidget(self.developerDataLabel, 0) self.regionInfoHbox = QHBoxLayout() self.regionInfoHbox.addWidget(self.regionInfoLabel, 0) self.regionInfoHbox.addWidget(self.regionDataLabel, 0) self.codeInfoHbox = QHBoxLayout() self.codeInfoHbox.addWidget(self.codeInfoLabel, 0) self.codeInfoHbox.addWidget(self.codeDataLabel, 0) self.itemInfoHbox = QHBoxLayout() self.itemInfoHbox.addWidget(self.itemInfoLabel, 0) self.itemInfoHbox.addWidget(self.itemDataLabel, 0) self.boxInfoHbox = QHBoxLayout() self.boxInfoHbox.addWidget(self.boxInfoLabel, 0) self.boxInfoHbox.addWidget(self.boxDataLabel, 0) self.manualInfoHbox = QHBoxLayout() self.manualInfoHbox.addWidget(self.manualInfoLabel, 0) self.manualInfoHbox.addWidget(self.manualDataLabel, 0) self.genreInfoHbox = QHBoxLayout() self.genreInfoHbox.addWidget(self.genreInfoLabel, 0) self.genreInfoHbox.addWidget(self.genreDataLabel, 0) self.yearInfoHbox = QHBoxLayout() self.yearInfoHbox.addWidget(self.yearInfoLabel, 0) self.yearInfoHbox.addWidget(self.yearDataLabel, 0) self.commentInfoHbox = QHBoxLayout() self.commentInfoHbox.addWidget(self.commentInfoLabel, 0) self.commentInfoHbox.addWidget(self.commentDataLabel, 0) self.platformsInfoHbox = QHBoxLayout() self.platformsInfoHbox.addWidget(self.platformsInfoLabel, 0) self.platformsInfoHbox.addWidget(self.platformsDataLabel, 0) # Edit layouts self.nameEditHbox = QHBoxLayout() self.nameEditHbox.addWidget(self.nameEditLabel, 0) self.nameEditHbox.addWidget(self.nameDataTE, 0) self.platformEditHbox = QHBoxLayout() self.platformEditHbox.addWidget(self.platformEditLabel, 0) self.platformEditHbox.addWidget(self.platformDataLE, 0) self.publisherEditHbox = QHBoxLayout() self.publisherEditHbox.addWidget(self.publisherEditLabel, 0) self.publisherEditHbox.addWidget(self.publisherDataLE, 0) self.developerEditHbox = QHBoxLayout() self.developerEditHbox.addWidget(self.developerEditLabel, 0) self.developerEditHbox.addWidget(self.developerDataLE, 0) self.regionEditHbox = QHBoxLayout() self.regionEditHbox.addWidget(self.regionEditLabel, 0) self.regionEditHbox.addWidget(self.regionDataCoB, 0) self.codeEditHbox = QHBoxLayout() self.codeEditHbox.addWidget(self.codeEditLabel, 0) self.codeEditHbox.addWidget(self.codeDataLE, 0) self.itemEditHbox = QHBoxLayout() self.itemEditHbox.addWidget(self.itemEditLabel, 0) self.itemEditHbox.addWidget(self.itemDataCB, 0) self.itemEditHbox.addSpacing(135) self.boxEditHbox = QHBoxLayout() self.boxEditHbox.addWidget(self.boxEditLabel, 0) self.boxEditHbox.addWidget(self.boxDataCB, 0) self.boxEditHbox.addSpacing(135) self.manualEditHbox = QHBoxLayout() self.manualEditHbox.addWidget(self.manualEditLabel, 0) self.manualEditHbox.addWidget(self.manualDataCB, 0) self.manualEditHbox.addSpacing(135) self.genreEditHbox = QHBoxLayout() self.genreEditHbox.addWidget(self.genreEditLabel, 0) self.genreEditHbox.addWidget(self.genreDataLE, 0) self.yearEditHbox = QHBoxLayout() self.yearEditHbox.addWidget(self.yearEditLabel, 0) self.yearEditHbox.addWidget(self.yearDataLE, 0) self.commentEditHbox = QHBoxLayout() self.commentEditHbox.addWidget(self.commentEditLabel, 0) self.commentEditHbox.addWidget(self.commentDataTE, 0) self.platformsEditHbox = QHBoxLayout() self.platformsEditHbox.addWidget(self.platformsEditLabel, 0) self.platformsEditHbox.addWidget(self.platformsDataTE, 0) # Price layouts self.paidPriceHbox = QHBoxLayout() self.paidPriceHbox.addWidget(self.paidPriceLabel, 0) self.paidPriceHbox.addWidget(self.paidPriceDataLE, 0) self.loosePriceHbox = QHBoxLayout() self.loosePriceHbox.addWidget(self.loosePriceLabel, 0) self.loosePriceHbox.addWidget(self.loosePriceDataLabel, 0) self.cibPriceHbox = QHBoxLayout() self.cibPriceHbox.addWidget(self.cibPriceLabel, 0) self.cibPriceHbox.addWidget(self.cibPriceDataLabel, 0) self.newPriceHbox = QHBoxLayout() self.newPriceHbox.addWidget(self.newPriceLabel, 0) self.newPriceHbox.addWidget(self.newPriceDataLabel, 0) # Info layout self.infoLayout = QVBoxLayout() self.infoLayout.addLayout(self.nameInfoHbox, 0) self.infoLayout.addLayout(self.platformInfoHbox, 0) self.infoLayout.addLayout(self.publisherInfoHbox, 0) self.infoLayout.addLayout(self.developerInfoHbox, 0) self.infoLayout.addLayout(self.genreInfoHbox, 0) self.infoLayout.addLayout(self.regionInfoHbox, 0) self.infoLayout.addLayout(self.yearInfoHbox, 0) self.infoLayout.addLayout(self.codeInfoHbox, 0) self.infoLayout.addLayout(self.itemInfoHbox, 0) self.infoLayout.addLayout(self.boxInfoHbox, 0) self.infoLayout.addLayout(self.manualInfoHbox, 0) self.infoLayout.addLayout(self.commentInfoHbox, 0) self.infoLayout.addLayout(self.platformsInfoHbox, 0) # Edit layout self.editLayout = QVBoxLayout() self.editLayout.addLayout(self.nameEditHbox, 0) self.editLayout.addLayout(self.platformEditHbox, 0) self.editLayout.addLayout(self.publisherEditHbox, 0) self.editLayout.addLayout(self.developerEditHbox, 0) self.editLayout.addLayout(self.genreEditHbox, 0) self.editLayout.addLayout(self.regionEditHbox, 0) self.editLayout.addLayout(self.yearEditHbox, 0) self.editLayout.addLayout(self.codeEditHbox, 0) self.editLayout.addLayout(self.itemEditHbox, 0) self.editLayout.addLayout(self.boxEditHbox, 0) self.editLayout.addLayout(self.manualEditHbox, 0) self.editLayout.addLayout(self.commentEditHbox, 0) self.editLayout.addLayout(self.platformsEditHbox, 0) # Price layout self.priceLayout = QVBoxLayout() self.priceLayout.addLayout(self.paidPriceHbox, 0) self.priceLayout.addLayout(self.loosePriceHbox, 0) self.priceLayout.addLayout(self.cibPriceHbox, 0) self.priceLayout.addLayout(self.newPriceHbox, 0) self.priceLayout.addStretch(1) self.priceLayout.addLayout(self.priceButtonHbox, 0) """Main layout""" self.infoWidget = QWidget() self.infoWidget.setLayout(self.infoLayout) self.editWidget = QWidget() self.editWidget.setLayout(self.editLayout) # Add info and edit widgets to a stacked layout so we can switch layouts when editing self.stackedLayout = QStackedLayout() self.stackedLayout.addWidget(self.infoWidget) self.stackedLayout.addWidget(self.editWidget) self.stackedLayout.setCurrentIndex(0) # Default to info layout self.detailsLayout = QVBoxLayout() self.detailsLayout.addLayout(self.coverVbox, 1) self.detailsLayout.addLayout(self.stackedLayout, 0) self.detailsLayout.addLayout(self.detailsButtonHbox, 0) self.detailsWidget = QWidget() self.detailsWidget.setLayout(self.detailsLayout) self.priceWidget = QWidget() self.priceWidget.setLayout(self.priceLayout) self.tab = QTabWidget() self.tab.addTab(self.detailsWidget, "Details") self.tab.addTab(self.priceWidget, "Price info") self.setWidget(self.tab) def _editDetails(self): if self.editDetailsButton.isChecked(): self._updateWidgetData(1) self.stackedLayout.setCurrentIndex(1) else: self._updateWidgetData(0) self.stackedLayout.setCurrentIndex(0) def _fetchInfo(self): name = self.nameDataLabel.text() platform = self.platformDataLabel.text() region = self.regionDataLabel.text() info = getMobyRelease(name, platform, region) if "image" in info.keys() and info["image"] != "": self._imagedata = requests.get(info["image"]).content pixmap = QPixmap() pixmap.loadFromData(self._imagedata) w = self.cover.width() h = self.cover.height() self.cover.setPixmap(pixmap.scaled(w, h, Qt.KeepAspectRatio, Qt.SmoothTransformation)) if self.publisherDataLabel.text() == "": self.publisherDataLabel.setText(info["publisher"]) if self.developerDataLabel.text() == "": self.developerDataLabel.setText(info["developer"]) if self.genreDataLabel.text() == "": self.genreDataLabel.setText(info["genre"]) if self.yearDataLabel.text() == "": self.yearDataLabel.setText(info["year"]) if self.codeDataLabel.text() == "": self.codeDataLabel.setText(info["code"]) if self.platformsDataLabel.text() == "": self.platformsDataLabel.setText(info["platforms"]) # Update edit widgets if we're editing: if self.editDetailsButton.isChecked(): self._updateWidgetData(1) def _fetchPriceData(self): name = self.nameDataLabel.text() platform = self.platformDataLabel.text() region = self.regionDataLabel.text() prices = getPriceData(name, platform, region) self.loosePriceDataLabel.setText(prices["loose"]) self.cibPriceDataLabel.setText(prices["cib"]) self.newPriceDataLabel.setText(prices["new"]) def _saveInfo(self): if self.editDetailsButton.isChecked(): self._updateWidgetData(0) paidPrice = str(self.paidPriceDataLE.text()).replace(",", ".") # Better use '.' as decimal denominator info = {"id": self._id, "name": self.nameDataLabel.text(), "platform": self.platformDataLabel.text(), "publisher": self.publisherDataLabel.text(), "developer": self.developerDataLabel.text(), "genre": self.genreDataLabel.text(), "region": self.regionDataLabel.text(), "year": self.yearDataLabel.text(), "code": self.codeDataLabel.text(), "item": self.itemDataLabel.text(), "box": self.boxDataLabel.text(), "manual": self.manualDataLabel.text(), "comment": self.commentDataLabel.text(), "platforms": self.platformsDataLabel.text(), "price": ",".join((paidPrice, self.loosePriceDataLabel.text(), self.cibPriceDataLabel.text(), self.newPriceDataLabel.text()))} # Save imagedata to file if self._imagedata != "" and not path.exists(path.join(self._coverdir, str(self._id) + ".jpg")): with open(path.join(self._coverdir, str(self._id) + ".jpg"), "wb") as f: f.write(self._imagedata) self.saved.emit(info) def _updateWidgetData(self, layoutIndex: int): if layoutIndex == 0: self.nameDataLabel.setText(self.nameDataTE.toPlainText()) self.platformDataLabel.setText(self.platformDataLE.text()) self.publisherDataLabel.setText(self.publisherDataLE.text()) self.developerDataLabel.setText(self.developerDataLE.text()) self.genreDataLabel.setText(self.genreDataLE.text()) self.regionDataLabel.setText(self.regionDataCoB.currentText()) self.yearDataLabel.setText(self.yearDataLE.text()) self.codeDataLabel.setText(self.codeDataLE.text()) self.itemDataLabel.setText("Yes") if self.itemDataCB.isChecked() else self.itemDataLabel.setText("No") self.boxDataLabel.setText("Yes") if self.boxDataCB.isChecked() else self.boxDataLabel.setText("No") self.manualDataLabel.setText("Yes") if self.manualDataCB.isChecked() else self.manualDataLabel.setText("No") self.commentDataLabel.setText(self.commentDataTE.toPlainText()) self.platformsDataLabel.setText(self.platformsDataTE.toPlainText()) else: self.nameDataTE.setText(self.nameDataLabel.text()) self.platformDataLE.setText(self.platformDataLabel.text()) self.publisherDataLE.setText(self.publisherDataLabel.text()) self.developerDataLE.setText(self.developerDataLabel.text()) self.genreDataLE.setText(self.genreDataLabel.text()) self.regionDataCoB.setCurrentIndex(0) if self.regionDataLabel.text == "NTSC (JP)"\ else self.regionDataCoB.setCurrentIndex(1) if self.regionDataLabel.text == "NTSC (NA)"\ else self.regionDataCoB.setCurrentIndex(2) self.yearDataLE.setText(self.yearDataLabel.text()) self.codeDataLE.setText(self.codeDataLabel.text()) self.itemDataCB.setChecked(True) if self.itemDataLabel.text() == "Yes" \ else self.itemDataCB.setChecked("False") self.boxDataCB.setChecked(True) if self.boxDataLabel.text() == "Yes" \ else self.boxDataCB.setChecked(False) self.manualDataCB.setChecked(True) if self.manualDataLabel.text() == "Yes" \ else self.manualDataCB.setChecked(False) self.commentDataTE.setText(self.commentDataLabel.text()) self.platformsDataTE.setText(self.platformsDataLabel.text()) def showDetails(self, info: dict): if not self.isVisible(): self.setVisible(True) self.tab.setCurrentIndex(0) # Show details tab initially if self.editDetailsButton.isChecked(): self.editDetailsButton.setChecked(False) self.stackedLayout.setCurrentIndex(0) # Show info layout initially self._id = info["id"] self._imagedata = "" pixmap = path.join(self._coverdir, "none.png") if path.exists(path.join(self._coverdir, str(self._id) + ".jpg")) and info["table"] == "games": pixmap = path.join(self._coverdir, str(self._id) + ".jpg") p = QPixmap(pixmap) w = self.cover.width() h = self.cover.height() self.cover.setPixmap(p.scaled(w, h, Qt.KeepAspectRatio, Qt.SmoothTransformation)) # Price data is stored in form $x,$x,$x,$x [paid, loose, cib, new] paidPrice, loosePrice, cibPrice, newPrice = info["price"].split(",") self.nameDataLabel.setText(info["name"]) self.platformDataLabel.setText(info["platform"]) self.regionDataLabel.setText(info["region"]) self.boxDataLabel.setText(info["box"]) self.manualDataLabel.setText(info["manual"]) self.yearDataLabel.setText(str(info["year"])) self.commentDataLabel.setText(info["comment"]) self.paidPriceDataLE.setText(paidPrice) self.loosePriceDataLabel.setText(loosePrice) self.cibPriceDataLabel.setText(cibPrice) self.newPriceDataLabel.setText(newPrice) if info["table"] == "games": self.publisherDataLabel.setText(info["publisher"]) self.developerDataLabel.setText(info["developer"]) self.genreInfoLabel.setText("Genre:") self.genreEditLabel.setText("Genre:") self.genreDataLabel.setText(info["genre"]) self.codeInfoLabel.setText("Code:") self.codeInfoLabel.setVisible(True) self.codeEditLabel.setText("Code") self.codeEditLabel.setVisible(True) self.codeDataLabel.setText(info["code"]) self.codeDataLabel.setVisible(True) self.codeDataLE.setVisible(True) self.itemInfoLabel.setText("Game:") self.itemEditLabel.setText("Game:") self.itemDataLabel.setText(info["game"]) self.platformsDataLabel.setText(info["platforms"]) self.platformsDataLabel.setVisible(True) self.platformsInfoLabel.setVisible(True) self.fetchInfoButton.setEnabled(True) self.fetchInfoButton.setVisible(True) self.fetchInfoButton.setToolTip("Try to fetch info from MobyGames") self.saveDetailsButton.setEnabled(True) self.saveDetailsButton.setVisible(True) elif info["table"] == "consoles": self.genreInfoLabel.setText("Country:") self.genreEditLabel.setText("Country:") self.genreDataLabel.setText(info["country"]) self.codeInfoLabel.setText("Serial Number:") self.codeInfoLabel.setVisible(True) self.codeEditLabel.setText("Serial Number:") self.codeEditLabel.setVisible(True) self.codeDataLabel.setText(info["serial number"]) self.codeDataLabel.setVisible(True) self.codeDataLE.setVisible(True) self.itemInfoLabel.setText("Console:") self.itemEditLabel.setText("Console:") self.itemDataLabel.setText(info["console"]) self.platformsInfoLabel.setVisible(False) self.platformsDataLabel.setVisible(False) self.fetchInfoButton.setEnabled(False) self.fetchInfoButton.setToolTip("Not available for Consoles tab") elif info["table"] == "accessories": self.genreInfoLabel.setText("Country:") self.genreEditLabel.setText("Country:") self.genreDataLabel.setText(info["country"]) self.itemInfoLabel.setText("Accessory:") self.itemEditLabel.setText("Accessory:") self.itemDataLabel.setText(info["accessory"]) self.codeInfoLabel.setVisible(False) self.codeEditLabel.setVisible(False) self.codeDataLabel.setVisible(False) self.codeDataLE.setVisible(False) self.platformsInfoLabel.setVisible(False) self.platformsDataLabel.setVisible(False) self.fetchInfoButton.setEnabled(False) self.fetchInfoButton.setToolTip("Not avaiable for Accessories tab") def hideDetails(self): self.setVisible(False)
class NewWidget(QWidget): def __init__(self): super().__init__() self.setParent(None) self.label = QLabel(text="1111") self.font = QFont() self.font.setBold(True) self.font.setPointSize(15) self.label.setFont(self.font) self.label.setStyleSheet("color: #EBE75C") self.label.setWordWrap(True) self.label.setAlignment(Qt.AlignCenter) self.label.setFixedWidth(1000) self.h = 0 self.w = 0 self.chars = 250 self.quotes = [] # self.page = randint(1, 10) # print(self.page) # self.url = "http://quotes.toscrape.com/page/{}/".format(self.page) # self.response = requests.get(self.url) # self.soup = BeautifulSoup(self.response.text, "html.parser") self.subreddit = self.connectReddit() self.quotes = [quote.title for quote in self.subreddit.hot(limit=25)] self.i = 1 self.layout = QVBoxLayout() self.layout.addWidget(self.label) self.setAttribute(Qt.WA_NoSystemBackground, True) self.setAttribute(Qt.WA_TranslucentBackground, True) self.flags = QtWidgets self.setWindowFlags(Qt.FramelessWindowHint | Qt.WindowStaysOnBottomHint | Qt.WindowCloseButtonHint | Qt.Tool) self.setLayout(self.layout) self.m_nMouseClick_X_Coordinate = None self.m_nMouseClick_Y_Coordinate = None self.oldPos = self.pos() self.uus = self.quotes[0] self.label.setText(self.uus) self.startTimer(1000 * 60 * 60) #self.startTimer(5000) # def choose(self): # for quote in self.soup.find_all("span", {"class": "text"}): # if quote.text in self.quotes: # pass # else: # if len(quote.text) > self.chars: # self.quotes.append(quote.text) # return self.choose() # self.quotes.append(quote.text) # author = quote.parent.findChild("small", {"class": "author"}) # self.author = author.text # return quote.text # # print(10000) # if self.page == 10: # self.page = 1 # else: # self.page += 1 # self.url = "http://quotes.toscrape.com/page/{}/".format(str(self.page)) # self.response = requests.get(self.url) # self.soup = BeautifulSoup(self.response.text, "html.parser") # return self.choose() def timerEvent(self, event): #self.uus = self.choose() #self.label.setText(self.uus + "\n - " + self.author) quote = self.quotes[self.i] self.label.setText(quote) self.i += 1 if self.i == 25: self.i = 0 self.label.ensurePolished() self.setFixedSize(self.sizeHint()) self.change_size() return def mousePressEvent(self, event): self.oldPos = event.globalPos() def mouseMoveEvent(self, event): delta = QPoint(event.globalPos() - self.oldPos) self.move(self.x() + delta.x(), self.y() + delta.y()) self.oldPos = event.globalPos() def connectReddit(self): with open("secrets.data", "r") as file: lines = file.readlines() self.reddit = praw.Reddit(client_id=lines[0].strip(), client_secret=lines[1].strip(), password=lines[2].strip(), user_agent=lines[3].strip(), username=lines[4].strip()) return self.reddit.subreddit("quotes") def change_size(self): self.move( QPoint(self.w / 2 - self.width() / 2, self.h - self.height() - 10)) print(self.label.height()) print(self.y())
class VideoPlayer(QWidget): """ Main widget for displaying video, heatmaps, peaks, tracks and other information. """ def __init__(self, main_window): super().__init__() self.disply_width = 1000 self.display_height = 800 self.main_window = main_window btn_size = QSize(16, 16) # Open button for opening video files self.open_button = QPushButton("Open Video") self.open_button.setToolTip("Open Video File") self.open_button.setStatusTip("Open Video File") self.open_button.setFixedHeight(24) self.open_button.setIconSize(btn_size) self.open_button.setFont(QFont("Helvetica", 8)) self.open_button.setIcon(QIcon.fromTheme("edit-undo")) self.open_button.clicked.connect(self.open_video_file) # Label for drawing scenes self.image_label = QLabel(self) self.image_label.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.image_label.setAlignment(Qt.AlignCenter) # Play button self.play_button = QPushButton() self.play_button.setEnabled(False) self.play_button.setFixedHeight(24) self.play_button.setIconSize(btn_size) self.play_button.setIcon(self.style().standardIcon( QStyle.SP_MediaPlay)) self.play_button.clicked.connect(self.play) # Pause button self.pause_button = QPushButton() self.pause_button.setEnabled(True) self.pause_button.setFixedHeight(24) self.pause_button.setIconSize(btn_size) self.pause_button.setIcon(self.style().standardIcon( QStyle.SP_MediaPause)) self.pause_button.clicked.connect(self.pause) # Next button self.next_button = QPushButton() self.next_button.setEnabled(False) self.next_button.setFixedHeight(24) self.next_button.setIconSize(btn_size) self.next_button.setIcon(self.style().standardIcon( QStyle.SP_MediaSkipForward)) self.next_button.clicked.connect(self.next) # Back button self.back_button = QPushButton() self.back_button.setEnabled(False) self.back_button.setFixedHeight(24) self.back_button.setIconSize(btn_size) self.back_button.setIcon(self.style().standardIcon( QStyle.SP_MediaSkipBackward)) self.back_button.clicked.connect(self.back) # Seeker self.seeker = QSlider(Qt.Horizontal) self.seeker.setRange(0, 5000) self.seeker.valueChanged.connect(self.seeker_value_changed) self.seeker.sliderMoved.connect(self.seeker_slider_moved) # Layout for media player controls control_layout = QHBoxLayout() control_layout.addWidget(self.open_button) control_layout.addWidget(self.play_button) control_layout.addWidget(self.pause_button) control_layout.addWidget(self.next_button) control_layout.addWidget(self.back_button) control_layout.addWidget(self.seeker) # Vertical layout for scene (image_label) and player controls layout = QVBoxLayout() layout.addWidget(self.image_label) layout.addLayout(control_layout) self.setLayout(layout) def open_video_file(self): """Shows dialog for opening a video file""" file_name, _ = QFileDialog.getOpenFileName( self, "Select the media.", ".", "Video Files (*.mp4 *.flv *.ts *.mts *.avi)") if file_name != '': # If video already loaded restart worker if hasattr(self, "_video_controller"): self._video_controller.stop() self._video_controller.wait() self._video_controller = VideoController(file_name) # Connect video controller signals to functions self._video_controller.scene_changed.connect(self.update_scene) self._video_controller.tracks_updated.connect( self.main_window.update_track_viewer) self._video_controller.player_paused.connect(self.pause) self._video_controller.seeker_range_updated.connect( self.seeker_range_update) self._video_controller.seeker_value_updated.connect( self.seeker_value_update) self._video_controller.server_stats_updated.connect( self.main_window.update_server_stats) # Start the thread self._video_controller.start() # Reset track viewer self.main_window.reset_tracks_table() # Set controllers state as play self.play_mode(play=True) def closeEvent(self, event) -> None: # If has _video_controller close it. if hasattr(self, "_video_controller"): self._video_controller.stop() event.accept() def seeker_value_changed(self) -> None: pass def seeker_range_update(self, max_range) -> None: """ Updates slider range according to the input video. Seeker range updated whenever a new video file opened. Args: max_range: Maximum value of slider. (0-max) """ self.seeker.setRange(0, max_range) def seeker_value_update(self, value): """ Sets slider value. Updates for each frame Args: value: New value of the slider """ self.seeker.setValue(value) def seeker_slider_moved(self, p): """ Changes controller active frame number if slider moved Args: p: Slider active point """ self._video_controller.set_frame(p) def play(self): """Play button action""" if hasattr(self, "_video_controller"): self._video_controller._paused = False self.play_mode(play=True) def pause(self): """Pause button action""" if hasattr(self, "_video_controller"): self._video_controller._paused = True self.play_mode(play=False) def next(self): """Next button action""" if hasattr(self, "_video_controller"): self._video_controller.set_frame(self.seeker.value() + 1) def back(self): """Next button action""" if hasattr(self, "_video_controller"): self._video_controller.set_frame(self.seeker.value() - 1) # Changes video player controls according to the video player status def play_mode(self, play=True): """ Changes video player controls according to the video player status Args: play: Status of the media player """ self.play_button.setEnabled(not play) self.pause_button.setEnabled(play) self.next_button.setEnabled(not play) self.back_button.setEnabled(not play) def update_scene(self, meta_frame): """ Updates the image_label with a new opencv image. Args: meta_frame: MetaFrame Object """ # Get frame and other data from meta_frame frame = meta_frame.frame peaks = meta_frame.peaks tracks = meta_frame.tracks # Get display_options from main_window display_options = self.main_window.display_options # Get display dimensions self.display_height = self.image_label.height() self.display_width = self.image_label.width() # Adjust the scale factor scale_factor = self.display_height / 256 # Convert frame to qt image pm_img = convert_cv_qt(frame, self.display_width, self.display_height) # Start painter painter = QPainter() painter.begin(pm_img) # Create pen pen = QtGui.QPen() pen.setWidth(2) pen.setColor(QtGui.QColor(204, 0, 0)) # r, g, b painter.setPen(pen) if display_options["show_tracks"] == True: # Plot peaks with centered for point in peaks: painter.drawEllipse((point[0] * scale_factor) - 4, (point[1] * scale_factor) - 4, 8, 8) pen.setWidth(2) pen.setColor(QtGui.QColor(0, 0, 255)) if display_options["show_labels"] == True: # Draw tracked objects labels for label, trace in tracks.items(): if len(trace) > 1: # Assign random color for different tracks. color = get_random_color(int(label)) qcolor = QColor() qcolor.setNamedColor(color) pen.setColor(qcolor) painter.setPen(pen) label = label label_pos_x = trace[-1][0][0] * scale_factor + 10 label_pos_y = trace[-1][0][1] * scale_factor + 10 painter.drawText(label_pos_x, label_pos_y, label) if display_options["show_traces"] == True: # For identified object tracks draw tracking line # Use various colors to indicate different track_id for label, trace in tracks.items(): if len(trace) > 1: # Assign random color for different tracks. color = get_random_color(int(label)) qcolor = QColor() qcolor.setNamedColor(color) pen.setColor(qcolor) painter.setPen(pen) limit = 0 if len(trace) > 200: limit = len(trace) - 200 for j in range(limit, len(trace) - 1): # Draw trace line x1 = trace[j][0][0] * scale_factor y1 = trace[j][0][1] * scale_factor x2 = trace[j + 1][0][0] * scale_factor y2 = trace[j + 1][0][1] * scale_factor painter.drawLine(int(x1), int(y1), int(x2), int(y2)) painter.setCompositionMode(QPainter.CompositionMode_SourceOver) # painter.drawImage(0, 0, pix_map) painter.end() # label = QLabel() self.image_label.setPixmap(QPixmap.fromImage(pm_img))
class FormMidContextWidget(QtWidgets.QWidget): #定义成员变量 #定义信号 def __init__(self): super().__init__() self.__initForm() self.__loadMusicLibraryListWidgetData() self.__loadSongsNameListWidgetData() self.__loadCollectionMusicListWidgetData() def __initForm(self): self.mainLayout = QHBoxLayout() self.mainLayout.setContentsMargins(1, 1, 1, 1) self.contextFrame = QtWidgets.QFrame() self.contextFrame.setObjectName("contextFrame") self.midContextLayout = QHBoxLayout() self.midContextLayout.setSpacing(1) self.midContextLayout.setContentsMargins(0, 1, 0, 1) self.midLeftFrame = QtWidgets.QFrame() self.midLeftFrame.setObjectName("midLeftFrame") self.midLeftLayout = QVBoxLayout() self.midLeftFrame.setLayout(self.midLeftLayout) self.midLeftLayout.setSpacing(0) self.midLeftLayout.setContentsMargins(2, 2, 2, 2) self.musicLibraryTitleLabel = QLabel("音乐库") self.textFont = QFont("微软雅黑", 11) self.textFont.setBold(True) self.musicLibraryTitleLabel.setFont(self.textFont) self.musicLibraryListView = QListView() self.musicLibraryListView.setFixedHeight(140) self.musicLibraryListView.setObjectName('musicLibraryListView') self.musicLibraryListView.setFixedWidth(190) self.localCollectionTitleLabel = QLabel("本地收藏") self.localCollectionTitleLabel.setFont(self.textFont) self.localCollectionListView = QListView() self.localCollectionListView.setObjectName('localCollectionListView') self.localCollectionListView.setFixedWidth(190) self.songsNameListTitleLabel = QLabel("歌单列表") self.songsNameListTitleLabel.setFont(self.textFont) self.songsNameListView = QListView() self.songsNameListView.setObjectName('songsNameListView') self.songsNameListView.setFixedWidth(190) self.songsNameListView.setFixedHeight(300) self.midLeftLayout.addWidget(self.musicLibraryTitleLabel) self.midLeftLayout.addWidget(self.musicLibraryListView) self.midLeftLayout.addWidget(self.songsNameListTitleLabel) self.midLeftLayout.addWidget(self.songsNameListView) self.midLeftLayout.addWidget(self.localCollectionTitleLabel) self.midLeftLayout.addWidget(self.localCollectionListView) self.rightContextStackWidget = QStackedWidget() self.testLabel = QLabel() self.testLabel.setScaledContents(True) self.testLabel.setPixmap( QPixmap(":/icon/Resources/icon/icon-meinv.jpg").scaled( self.testLabel.width(), self.testLabel.height(), Qt.KeepAspectRatio, Qt.SmoothTransformation)) self.rightContextStackWidget.addWidget(self.testLabel) self.midContextLayout.addWidget(self.midLeftFrame) self.midContextLayout.addWidget(self.rightContextStackWidget) self.midContextLayout.setStretch(0, 0) self.midContextLayout.setStretch(1, 1) self.contextFrame.setLayout(self.midContextLayout) self.mainLayout.addWidget(self.contextFrame) self.setLayout(self.mainLayout) def __loadMusicLibraryListWidgetData(self): self.textFont = QFont("微软雅黑", 11) self.localMusicItemData = QStandardItem("本地音乐") self.localMusicItemData.setFont(self.textFont) self.localMusicItemData.setEditable(False) self.localMusicItemData.setData( QIcon(":/icon/Resources/icon/icon-localmusic.svg"), Qt.DecorationRole) self.wangyiYunItemData = QStandardItem("网易云音乐") self.wangyiYunItemData.setFont(self.textFont) self.wangyiYunItemData.setEditable(False) self.wangyiYunItemData.setData( QIcon(":/icon/Resources/icon/icon-wangyiyunmusic.svg"), Qt.DecorationRole) self.qqMusicItemData = QStandardItem("QQ音乐") self.qqMusicItemData.setFont(self.textFont) self.qqMusicItemData.setEditable(False) self.qqMusicItemData.setData( QIcon(":/icon/Resources/icon/icon-qqmusic.svg"), Qt.DecorationRole) self.xiaMiItemData = QStandardItem("虾米音乐") self.xiaMiItemData.setFont(self.textFont) self.xiaMiItemData.setEditable(False) self.xiaMiItemData.setData( QIcon(":/icon/Resources/icon/icon-xiamimusic.svg"), Qt.DecorationRole) self.musicLibraryModel = QStandardItemModel() self.musicLibraryModel.appendRow(self.localMusicItemData) self.musicLibraryModel.appendRow(self.wangyiYunItemData) self.musicLibraryModel.appendRow(self.qqMusicItemData) self.musicLibraryModel.appendRow(self.xiaMiItemData) self.musicLibraryListView.setSpacing(2) self.musicLibraryListView.setModel(self.musicLibraryModel) def __loadSongsNameListWidgetData(self): self.wubaiItemData = QStandardItem("伍佰&China blue") self.textFont = QFont("微软雅黑", 11) self.wubaiItemData.setFont(self.textFont) self.wubaiItemData.setEditable(False) self.wubaiItemData.setData( QIcon(":/icon/Resources/icon/icon-gedanlist.svg"), Qt.DecorationRole) self.zongguanxianItemData = QStandardItem("纵贯线") self.zongguanxianItemData.setFont(self.textFont) self.zongguanxianItemData.setEditable(False) self.zongguanxianItemData.setData( QIcon(":/icon/Resources/icon/icon-gedanlist.svg"), Qt.DecorationRole) self.zhaoleiItemData = QStandardItem("赵雷专辑") self.zhaoleiItemData.setFont(self.textFont) self.zhaoleiItemData.setEditable(False) self.zhaoleiItemData.setData( QIcon(":/icon/Resources/icon/icon-gedanlist.svg"), Qt.DecorationRole) self.xuweiItemData = QStandardItem("许巍专辑") self.xuweiItemData.setFont(self.textFont) self.xuweiItemData.setEditable(False) self.xuweiItemData.setData( QIcon(":/icon/Resources/icon/icon-gedanlist.svg"), Qt.DecorationRole) self.zhouhuajianItemData = QStandardItem("周华健专辑") self.zhouhuajianItemData.setFont(self.textFont) self.zhouhuajianItemData.setEditable(False) self.zhouhuajianItemData.setData( QIcon(":/icon/Resources/icon/icon-gedanlist.svg"), Qt.DecorationRole) self.banderuiItemData = QStandardItem("班得瑞专辑") self.banderuiItemData.setFont(self.textFont) self.banderuiItemData.setEditable(False) self.banderuiItemData.setData( QIcon(":/icon/Resources/icon/icon-gedanlist.svg"), Qt.DecorationRole) self.yaogunItemData = QStandardItem("摇滚专辑") self.yaogunItemData.setFont(self.textFont) self.yaogunItemData.setEditable(False) self.yaogunItemData.setData( QIcon(":/icon/Resources/icon/icon-gedanlist.svg"), Qt.DecorationRole) self.yinshiyuanshenItemData = QStandardItem("影视原声") self.yinshiyuanshenItemData.setFont(self.textFont) self.yinshiyuanshenItemData.setEditable(False) self.yinshiyuanshenItemData.setData( QIcon(":/icon/Resources/icon/icon-gedanlist.svg"), Qt.DecorationRole) self.minyaoItemData = QStandardItem("民谣专辑") self.minyaoItemData.setFont(self.textFont) self.minyaoItemData.setEditable(False) self.minyaoItemData.setData( QIcon(":/icon/Resources/icon/icon-gedanlist.svg"), Qt.DecorationRole) self.tianlaizhiyinItemData = QStandardItem("天籁之音") self.tianlaizhiyinItemData.setFont(self.textFont) self.tianlaizhiyinItemData.setEditable(False) self.tianlaizhiyinItemData.setData( QIcon(":/icon/Resources/icon/icon-gedanlist.svg"), Qt.DecorationRole) self.songsNameListModel = QStandardItemModel() self.songsNameListModel.appendRow(self.wubaiItemData) self.songsNameListModel.appendRow(self.zongguanxianItemData) self.songsNameListModel.appendRow(self.zhaoleiItemData) self.songsNameListModel.appendRow(self.xuweiItemData) self.songsNameListModel.appendRow(self.zhouhuajianItemData) self.songsNameListModel.appendRow(self.banderuiItemData) self.songsNameListModel.appendRow(self.yaogunItemData) self.songsNameListModel.appendRow(self.yinshiyuanshenItemData) self.songsNameListModel.appendRow(self.minyaoItemData) self.songsNameListModel.appendRow(self.tianlaizhiyinItemData) self.songsNameListView.setSpacing(2) self.songsNameListView.setModel(self.songsNameListModel) def __loadCollectionMusicListWidgetData(self): self.jingdianItemData = QStandardItem("经典老歌") self.textFont = QFont("微软雅黑", 11) self.jingdianItemData.setFont(self.textFont) self.jingdianItemData.setEditable(False) self.jingdianItemData.setData( QIcon(":/icon/Resources/icon/icon-collectionmusic.svg"), Qt.DecorationRole) self.qinyinyueItemData = QStandardItem("轻音乐系") self.qinyinyueItemData.setFont(self.textFont) self.qinyinyueItemData.setEditable(False) self.qinyinyueItemData.setData( QIcon(":/icon/Resources/icon/icon-collectionmusic.svg"), Qt.DecorationRole) self.jitaxilieItemData = QStandardItem("吉他系列") self.jitaxilieItemData.setFont(self.textFont) self.jitaxilieItemData.setEditable(False) self.jitaxilieItemData.setData( QIcon(":/icon/Resources/icon/icon-collectionmusic.svg"), Qt.DecorationRole) self.remengequItemData = QStandardItem("热门歌曲") self.remengequItemData.setFont(self.textFont) self.remengequItemData.setEditable(False) self.remengequItemData.setData( QIcon(":/icon/Resources/icon/icon-collectionmusic.svg"), Qt.DecorationRole) self.songsNameModel = QStandardItemModel() self.songsNameModel.appendRow(self.jingdianItemData) self.songsNameModel.appendRow(self.qinyinyueItemData) self.songsNameModel.appendRow(self.jitaxilieItemData) self.songsNameModel.appendRow(self.remengequItemData) self.localCollectionListView.setSpacing(2) self.localCollectionListView.setModel(self.songsNameModel)