def setup_starting_area_elements(self): game_description = default_prime2_game_description() world_to_group = {} self._starting_location_for_area = {} for row, world in enumerate(game_description.world_list.worlds): for column, is_dark_world in enumerate([False, True]): group_box = QGroupBox(self.starting_locations_contents) group_box.setTitle(world.correct_name(is_dark_world)) vertical_layout = QVBoxLayout(group_box) vertical_layout.setContentsMargins(8, 4, 8, 4) vertical_layout.setSpacing(2) vertical_layout.setAlignment(QtCore.Qt.AlignTop) group_box.vertical_layout = vertical_layout world_to_group[world.correct_name(is_dark_world)] = group_box self.starting_locations_layout.addWidget(group_box, row, column) for world in game_description.world_list.worlds: for area in sorted(world.areas, key=lambda a: a.name): group_box = world_to_group[world.correct_name(area.in_dark_aether)] check = QtWidgets.QCheckBox(group_box) check.setText(area.name) check.area_location = AreaLocation(world.world_asset_id, area.area_asset_id) check.stateChanged.connect(functools.partial(self._on_check_starting_area, check)) group_box.vertical_layout.addWidget(check) self._starting_location_for_area[area.area_asset_id] = check self.starting_area_quick_fill_ship.clicked.connect(self._starting_location_on_select_ship) self.starting_area_quick_fill_save_station.clicked.connect(self._starting_location_on_select_save_station)
def setup_location_pool_elements(self): self.randomization_mode_combo.setItemData(0, RandomizationMode.FULL) self.randomization_mode_combo.setItemData( 1, RandomizationMode.MAJOR_MINOR_SPLIT) self.randomization_mode_combo.currentIndexChanged.connect( self._on_update_randomization_mode) game_description = default_prime2_game_description() world_to_group = {} self._location_pool_for_node = {} for world in game_description.world_list.worlds: for is_dark_world in [False, True]: group_box = QGroupBox(self.excluded_locations_area_contents) group_box.setTitle(world.correct_name(is_dark_world)) vertical_layout = QVBoxLayout(group_box) vertical_layout.setContentsMargins(8, 4, 8, 4) vertical_layout.setSpacing(2) group_box.vertical_layout = vertical_layout world_to_group[world.correct_name(is_dark_world)] = group_box self.excluded_locations_area_layout.addWidget(group_box) for world, area, node in game_description.world_list.all_worlds_areas_nodes: if not isinstance(node, PickupNode): continue group_box = world_to_group[world.correct_name(area.in_dark_aether)] check = QtWidgets.QCheckBox(group_box) check.setText(game_description.world_list.node_name(node)) check.node = node check.stateChanged.connect( functools.partial(self._on_check_location, check)) group_box.vertical_layout.addWidget(check) self._location_pool_for_node[node] = check
def setup_location_pool_elements(self): self.randomization_mode_combo.setItemData(0, RandomizationMode.FULL) self.randomization_mode_combo.setItemData( 1, RandomizationMode.MAJOR_MINOR_SPLIT) self.randomization_mode_combo.currentIndexChanged.connect( self._on_update_randomization_mode) vertical_layouts = [ QtWidgets.QVBoxLayout(self.excluded_locations_area_contents), QtWidgets.QVBoxLayout(self.excluded_locations_area_contents), ] for layout in vertical_layouts: self.excluded_locations_area_layout.addLayout(layout) world_list = self.game_description.world_list self._location_pool_for_node = {} nodes_by_world = collections.defaultdict(list) node_names = {} pickup_match = re.compile(r"Pickup \(([^\)]+)\)") for world in world_list.worlds: for is_dark_world in dark_world_flags(world): for area in world.areas: if area.in_dark_aether != is_dark_world: continue for node in area.nodes: if isinstance(node, PickupNode): nodes_by_world[world.correct_name( is_dark_world)].append(node) match = pickup_match.match(node.name) if match is not None: node_name = match.group(1) else: node_name = node.name node_names[ node] = f"{world_list.nodes_to_area(node).name} ({node_name})" for i, world_name in enumerate(sorted(nodes_by_world.keys())): group_box = QGroupBox(self.excluded_locations_area_contents) group_box.setTitle(world_name) vertical_layout = QVBoxLayout(group_box) vertical_layout.setContentsMargins(8, 4, 8, 4) vertical_layout.setSpacing(2) group_box.vertical_layout = vertical_layout vertical_layouts[i % len(vertical_layouts)].addWidget(group_box) for node in sorted(nodes_by_world[world_name], key=node_names.get): check = QtWidgets.QCheckBox(group_box) check.setText(node_names[node]) check.node = node check.stateChanged.connect( functools.partial(self._on_check_location, check)) group_box.vertical_layout.addWidget(check) self._location_pool_for_node[node] = check for layout in vertical_layouts: layout.addSpacerItem( QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding))
def _add_widget_for_requirement_array(self, requirement: Requirement): parents = [(self.parent, self.grid_layout)] self.grid_layout.setAlignment(Qt.AlignTop) next_title = "" current_depth = 0 for depth, text in data_writer.pretty_print_requirement(requirement): if depth > current_depth: group_box = QGroupBox(parents[current_depth][0]) group_box.setTitle(next_title) self._elements.append(group_box) vertical_layout = QVBoxLayout(group_box) vertical_layout.setAlignment(Qt.AlignTop) parents[current_depth][1].addWidget(group_box) parents.append((group_box, vertical_layout)) elif depth < current_depth: parents.pop() current_depth = depth if "of the following" in text: next_title = text else: label = QLabel(parents[current_depth][0]) label.setText(text) self._elements.append(label) parents[current_depth][1].addWidget(label)
def __init__(self, parent, level_ref: LevelRef): title = f"Palette Groups for Object Set {level_ref.level.object_set_number}" super(PaletteViewer, self).__init__(parent, title=title) self.level_ref = level_ref layout = QGridLayout(self) for palette_group in range(PALETTE_GROUPS_PER_OBJECT_SET): group_box = QGroupBox() group_box.setTitle(f"Palette Group {palette_group}") group_box_layout = QVBoxLayout(group_box) group_box_layout.setSpacing(0) palette = load_palette_group( self.level_ref.level.object_set_number, palette_group) for palette_no in range(PALETTES_PER_PALETTES_GROUP): group_box_layout.addWidget(PaletteWidget(palette, palette_no)) row = palette_group // self.palettes_per_row col = palette_group % self.palettes_per_row layout.addWidget(group_box, row, col)
def _create_pickup_spoilers(self, game_description: GameDescription): if game_description == self._pickup_spoiler_current_game: return for groups in self._pickup_spoiler_world_to_group.values(): groups.deleteLater() self._pickup_spoiler_current_game = game_description self.pickup_spoiler_show_all_button.currently_show_all = True self.pickup_spoiler_buttons.clear() self._pickup_spoiler_world_to_group = {} nodes_in_world = collections.defaultdict(list) for world, area, node in game_description.world_list.all_worlds_areas_nodes: if isinstance(node, PickupNode): world_name = world.correct_name(area.in_dark_aether) nodes_in_world[world_name].append( (f"{area.name} - {node.name}", node.pickup_index)) continue for world_name in sorted(nodes_in_world.keys()): group_box = QGroupBox(self.pickup_spoiler_scroll_contents) group_box.setTitle(world_name) vertical_layout = QVBoxLayout(group_box) vertical_layout.setContentsMargins(8, 4, 8, 4) vertical_layout.setSpacing(2) group_box.vertical_layout = vertical_layout vertical_layout.horizontal_layouts = [] self._pickup_spoiler_world_to_group[world_name] = group_box self.pickup_spoiler_scroll_content_layout.addWidget(group_box) for area_name, pickup_index in sorted(nodes_in_world[world_name], key=lambda it: it[0]): horizontal_layout = QHBoxLayout() horizontal_layout.setSpacing(2) label = QLabel(group_box) label.setText(area_name) horizontal_layout.addWidget(label) horizontal_layout.label = label push_button = QPushButton(group_box) push_button.setFlat(True) push_button.setText("Hidden") push_button.item_is_hidden = True push_button.pickup_index = pickup_index push_button.clicked.connect( partial(self._toggle_pickup_spoiler, push_button)) push_button.item_name = "Nothing was Set, ohno" push_button.row = horizontal_layout horizontal_layout.addWidget(push_button) horizontal_layout.button = push_button self.pickup_spoiler_buttons.append(push_button) group_box.vertical_layout.addLayout(horizontal_layout) group_box.vertical_layout.horizontal_layouts.append( horizontal_layout)
class Ui_dlgAddUser(QDialog): def __init__(self): super().__init__() self.setupUi() def setupUi(self): self.setObjectName("dlgAddUser") self.resize(335, 154) self.setWindowFlags(Qt.MSWindowsFixedSizeDialogHint) self.gridLayout = QGridLayout(self) self.gridLayout.setObjectName("gridLayout") self.groupBox = QGroupBox(self) self.groupBox.setObjectName("groupBox") self.verticalLayout = QVBoxLayout(self.groupBox) self.verticalLayout.setObjectName("verticalLayout") self.leFullName = QLineEdit(self.groupBox) self.leFullName.setObjectName("leFullName") self.verticalLayout.addWidget(self.leFullName) self.leUsuario = QLineEdit(self.groupBox) self.leUsuario.setObjectName("leUsuario") self.verticalLayout.addWidget(self.leUsuario) self.lePassword = QLineEdit(self.groupBox) self.lePassword.setObjectName("lePassword") self.lePassword.setEchoMode(QLineEdit.Password) self.verticalLayout.addWidget(self.lePassword) self.gridLayout.addWidget(self.groupBox, 0, 0, 1, 1) self.horizontalLayout = QHBoxLayout() self.horizontalLayout.setObjectName("horizontalLayout") spacerItem = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) self.horizontalLayout.addItem(spacerItem) self.pbAddUser = QPushButton(self) self.pbAddUser.setObjectName("pbAddUser") self.horizontalLayout.addWidget(self.pbAddUser) self.pbCancel = QPushButton(self) self.pbCancel.setObjectName("pbCancel") self.horizontalLayout.addWidget(self.pbCancel) self.gridLayout.addLayout(self.horizontalLayout, 1, 0, 1, 1) self.retranslateUi() QMetaObject.connectSlotsByName(self) def retranslateUi(self): self.setWindowTitle( QApplication.translate("dlgAddUser", "Dialog", None, -1)) self.groupBox.setTitle( QApplication.translate("dlgAddUser", "GroupBox", None, -1)) self.leFullName.setPlaceholderText( QApplication.translate("dlgAddUser", "Ingresar nombre completo", None, -1)) self.leUsuario.setPlaceholderText( QApplication.translate("dlgAddUser", "Ingrese nombre de usuario", None, -1)) self.lePassword.setPlaceholderText( QApplication.translate("dlgAddUser", "Ingrese su clave", None, -1)) self.pbAddUser.setText( QApplication.translate("dlgAddUser", "Add user", None, -1)) self.pbCancel.setText( QApplication.translate("dlgAddUser", "Cancel", None, -1))
def _create_pickup_spoilers(self): self.pickup_spoiler_show_all_button.clicked.connect( self._toggle_show_all_pickup_spoiler) self.pickup_spoiler_show_all_button.currently_show_all = True self._create_pickup_spoiler_combobox() game_description = default_prime2_game_description() world_to_group = {} for world in game_description.world_list.worlds: for is_dark_world in [False, True]: group_box = QGroupBox(self.pickup_spoiler_scroll_contents) group_box.setTitle(world.correct_name(is_dark_world)) vertical_layout = QVBoxLayout(group_box) vertical_layout.setContentsMargins(8, 4, 8, 4) vertical_layout.setSpacing(2) group_box.vertical_layout = vertical_layout vertical_layout.horizontal_layouts = [] world_to_group[world.correct_name(is_dark_world)] = group_box self.pickup_spoiler_scroll_content_layout.addWidget(group_box) for world, area, node in game_description.world_list.all_worlds_areas_nodes: if not isinstance(node, PickupNode): continue group_box = world_to_group[world.correct_name(area.in_dark_aether)] horizontal_layout = QHBoxLayout() horizontal_layout.setSpacing(2) label = QLabel(group_box) label.setText(game_description.world_list.node_name(node)) horizontal_layout.addWidget(label) horizontal_layout.label = label push_button = QPushButton(group_box) push_button.setFlat(True) push_button.setText("Hidden") push_button.item_is_hidden = True push_button.pickup_index = node.pickup_index push_button.clicked.connect( partial(self._toggle_pickup_spoiler, push_button)) push_button.item_name = "Nothing was Set, ohno" push_button.row = horizontal_layout horizontal_layout.addWidget(push_button) horizontal_layout.button = push_button self.pickup_spoiler_buttons.append(push_button) group_box.vertical_layout.addLayout(horizontal_layout) group_box.vertical_layout.horizontal_layouts.append( horizontal_layout)
class MainWindow(QMainWindow): def __init__(self): super().__init__() self.init_ui() self.thread_pool = QThreadPool() self.thread_pool.setMaxThreadCount(1) self.active_thread_count = 0 def init_ui(self): self.setWindowTitle('Thread Example 2') self.setFixedSize(800, 400) self.group_box_1 = QGroupBox(self) self.group_box_1.setTitle('GroupBox Test Thread') self.group_box_1.resize(350, 275) self.button_start = QPushButton('Start', self.group_box_1) self.button_stop = QPushButton('Stop', self.group_box_1) self.button_start.move(0, 30) self.button_stop.move(90, 30) self.show() self.button_start.clicked.connect(self.on_button_start_click) self.button_stop.clicked.connect(self.on_button_stop_click) def on_button_start_click(self): self.button_start.setEnabled(False) self.active_thread_count = 0 links = [ 'google.com', 'youtube.com', 'instagram.com', 'twitter.com', 'netflix.com' ] self.threads = [] for link in links: self.thread = MyThread(link) self.thread.signals.finished.connect(self.on_finish) self.threads.append(self.thread) for thread in self.threads: self.thread_pool.start(thread) self.active_thread_count += 1 def on_button_stop_click(self): print('Threads stopping...') self.button_start.setEnabled(False) self.thread_pool.clear() self.active_thread_count = self.thread_pool.activeThreadCount() def on_finish(self): self.active_thread_count -= 1 if self.active_thread_count == 0: print('Finished All Jobs') self.button_start.setEnabled(True)
def load(parent): global plugin_widget, main_window, ui main_window = parent plugin_widget = QGroupBox() plugin_widget.setTitle('') ui = Ui_GroupBox() ui.setupUi(plugin_widget) ui.checkBox_asp_asn.clicked.connect(show_motifs) ui.checkBox_glu_his.clicked.connect(show_motifs) ui.checkBox_his_his.clicked.connect(show_motifs) ui.checkBox_ser_backbone.clicked.connect(show_motifs) ui.checkBox_asp_backbone.clicked.connect(show_motifs) ui.checkBox_his_ser.clicked.connect(show_motifs) ui.checkBox_asp_ser.clicked.connect(show_motifs)
def load(parent): global plugin_widget, main_window, ui main_window = parent plugin_widget = QGroupBox() plugin_widget.setTitle('') ui = Ui_GroupBox() ui.setupUi(plugin_widget) ui.pushButton_plot_occupancy.clicked.connect(plot_occupancy) ui.pushButton_save_occupancy.clicked.connect(save_occupancy) ui.pushButton_plot_jo.clicked.connect(plot_jo) ui.pushButton_save_jo.clicked.connect(save_jo) ui.pushButton_plot_timeseries.clicked.connect(plot_timeseries) ui.pushButton_save_timeseries.clicked.connect(save_timeseries) ui.checkBox_color_segments_occupancy.clicked.connect(toggle_stacked)
def load(parent): global plugin_widget, main_window, ui main_window = parent plugin_widget = QGroupBox() plugin_widget.setTitle('') ui = Ui_GroupBox() ui.setupUi(plugin_widget) ui.pushButton_degree_plot.clicked.connect(plot_centrality) ui.pushButton_degree_save.clicked.connect(save_centrality) ui.groupBox_per_residue.toggled.connect(toggle_histogram) ui.groupBox_histogram.toggled.connect(toggle_per_residue) ui.checkBox_normalized.toggled.connect(update_min_max) ui.checkBox_averaged_frames.toggled.connect(update_min_max) ui.radioButton_degree.toggled.connect(update_min_max) ui.radioButton_betweenness.toggled.connect(update_min_max)
class UiMainWindow: def __init__(self, window: QMainWindow, vscreen: VScreen): self.window = window self.vscreen = vscreen window.setWindowFlags(Qt.Window | Qt.MSWindowsFixedSizeDialogHint | Qt.WindowMinimizeButtonHint | Qt.WindowCloseButtonHint | Qt.CustomizeWindowHint) self.centralWidget = QWidget() self.centralWidget.setLayout(QVBoxLayout()) self.centralWidget.layout().setContentsMargins(0, 0, 0, 0) window.setCentralWidget(self.centralWidget) self.monitor_overview_widget = VScreenOverview(vscreen, window) self.centralWidget.layout().addWidget(self.monitor_overview_widget) self.sub_widget = QWidget() self.sub_layout = QVBoxLayout() self.sub_widget.setLayout(self.sub_layout) self.centralWidget.layout().addWidget(self.sub_widget) self.monitor_info_group = QGroupBox() self.monitor_info_group.setLayout(QHBoxLayout()) for monitor in self.vscreen.monitor_order: info_box = QGroupBox("Monitor Information") info_box.ui = UiMonitorInfoBox(info_box, monitor) self.monitor_info_group.layout().addWidget(info_box) self.sub_layout.addWidget(self.monitor_info_group) self.button_group = QDialogButtonBox(Qt.Horizontal) self.button_group.setStyleSheet('* { button-layout: 2 }') self.close_button = self.button_group.addButton("Close", QDialogButtonBox.RejectRole) self.adjust_button = self.button_group.addButton("Adjust", QDialogButtonBox.ActionRole) self.about_button = self.button_group.addButton("About", QDialogButtonBox.HelpRole) self.sub_layout.addWidget(self.button_group) self.translate_ui() def translate_ui(self): self.window.setWindowTitle("HwMonitorAlignment") self.monitor_info_group.setTitle("Monitor Setup Information") self.close_button.setText("Close") self.adjust_button.setText("Adjust")
def _create_categories_boxes(self, item_database: ItemDatabase, size_policy): self._boxes_for_category = {} categories = set() for major_item in item_database.major_items.values(): if not major_item.required: categories.add(major_item.item_category) all_categories = list(iterate_enum(ItemCategory)) for major_item_category in sorted(categories, key=lambda it: all_categories.index(it)): category_box = QGroupBox(self.scroll_area_contents) category_box.setTitle(major_item_category.long_name) category_box.setSizePolicy(size_policy) category_box.setObjectName(f"category_box {major_item_category}") category_layout = QGridLayout(category_box) category_layout.setObjectName(f"category_layout {major_item_category}") self.item_pool_layout.addWidget(category_box) self._boxes_for_category[major_item_category] = category_box, category_layout, {}
def _init_widgets(self): # status status_box = QGroupBox(self) status_box.setTitle("Status") self._status_table = QStatusTable(self._controller) self._status_table.status = "ready" status_layout = QVBoxLayout() status_layout.addWidget(self._status_table) status_box.setLayout(status_layout) # table self._team_table = QTeamTable(self._controller) team_box = QGroupBox(self) team_box.setTitle("Team") # operations # pull function button pullfunc_btn = QPushButton(self) pullfunc_btn.setText("Pull func") pullfunc_btn.setToolTip("Pull current function from the selected user") pullfunc_btn.clicked.connect(self._on_pullfunc_clicked) # push function button pushfunc_btn = QPushButton() pushfunc_btn.setText('Push func') pushfunc_btn.setToolTip("Push current function to the repo") pushfunc_btn.clicked.connect(self._on_pushfunc_clicked) # pull patches button pullpatches_btn = QPushButton(self) pullpatches_btn.setText("Pull patches") pullpatches_btn.setToolTip("Pull all patches from the selected user") pullpatches_btn.clicked.connect(self._on_pullpatches_clicked) actions_box = QGroupBox(self) actions_box.setTitle("Actions") actions_layout = QHBoxLayout() actions_layout.addWidget(pullfunc_btn) actions_layout.addWidget(pushfunc_btn) actions_layout.addWidget(pullpatches_btn) actions_box.setLayout(actions_layout) team_layout = QVBoxLayout() team_layout.addWidget(self._team_table) team_layout.addWidget(actions_box) team_box.setLayout(team_layout) main_layout = QVBoxLayout() main_layout.addWidget(status_box) main_layout.addWidget(team_box) self.setLayout(main_layout)
def _add_widget_for_requirement_array(self, requirement: Requirement): self.grid_layout.setAlignment(Qt.AlignTop) parents: List[Tuple[QGroupBox, QVBoxLayout]] = [(self.parent, self.grid_layout)] for depth, text in randovania.game_description.pretty_print.pretty_print_requirement(requirement): if "of the following" in text: parent = parents[depth] group_box = QGroupBox(parent[0]) group_box.setContentsMargins(8, 0, 2, 6) group_box.setTitle(text) self._elements.append(group_box) vertical_layout = QVBoxLayout(group_box) vertical_layout.setAlignment(Qt.AlignTop) parent[1].addWidget(group_box) if len(parents) <= depth + 1: parents.append(None) parents[depth + 1] = (group_box, vertical_layout) else: label = QLabel(parents[depth][0]) label.setText(text) self._elements.append(label) parents[depth][1].addWidget(label)
class SaveDialog(QDialog): def __init__(self, main_window, nodes_dict: dict, last_export_dir: str): super(SaveDialog, self).__init__(parent=main_window) self.create_UI() self.main_window = main_window self.nodes = nodes_dict self.export_nodes = [] self.nodes_check_box_list = [] self.export_dir = last_export_dir self.package_name = '' self.set_package_name(self.export_dir) # add node-checkboxes node_keys = list(self.nodes.keys()) nodes_list_widget = self.nodes_scroll_area.takeWidget() for i in range(len(node_keys)): n = node_keys[i] node_check_box = QCheckBox(n.title) node_check_box.setObjectName('node_check_box_' + str(i)) node_check_box.setChecked(self.nodes[n]) nodes_list_widget.layout().addWidget(node_check_box) self.nodes_check_box_list.append(node_check_box) nodes_list_widget.adjustSize() self.nodes_scroll_area.setWidget(nodes_list_widget) def create_UI(self): # main layouts and widgets self.main_vertical_layout = QVBoxLayout(self) self.horizontal_layout = QHBoxLayout(self) self.nodes_vertical_layout = QVBoxLayout(self) self.nodes_vertical_layout.setAlignment(Qt.AlignTop) self.export_widget = QWidget(self) self.export_widget.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.export_layout = QVBoxLayout(self) self.export_layout.setAlignment(Qt.AlignTop) self.export_widget.setLayout(self.export_layout) # nodes selection section self.nodes_group_box = QGroupBox(self) self.nodes_group_box.setLayout(QVBoxLayout(self)) self.nodes_group_box.setTitle('Select nodes to export') self.nodes_scroll_area = QScrollArea(self) self.nodes_list_widget = QWidget() self.nodes_list_widget.setLayout(self.nodes_vertical_layout) select_all_button = QPushButton('select all') select_all_button.clicked.connect(self.select_all) deselect_all_button = QPushButton('deselect all') deselect_all_button.clicked.connect(self.deselect_all) self.nodes_vertical_layout.addWidget(select_all_button) self.nodes_vertical_layout.addWidget(deselect_all_button) self.nodes_scroll_area.setWidget(self.nodes_list_widget) self.nodes_group_box.layout().addWidget(self.nodes_scroll_area) # export settings section self.select_package_dir_button = QPushButton('Select package dir', self) self.select_package_dir_button.clicked.connect(self.select_package_dir) self.package_dir_label = QLabel() self.export_button = QPushButton('export', self) self.export_button.clicked.connect(self.export) self.export_layout.addWidget(self.select_package_dir_button) self.export_layout.addWidget(self.package_dir_label) self.export_layout.addWidget(self.export_button) # button box self.button_box = QDialogButtonBox(self) self.button_box.setStandardButtons(QDialogButtonBox.Ok) self.button_box.button(QDialogButtonBox.Ok).clicked.connect( self.close_) # merge layouts self.horizontal_layout.addWidget(self.nodes_group_box) self.horizontal_layout.addWidget(self.export_widget) self.main_vertical_layout.addLayout(self.horizontal_layout) self.main_vertical_layout.addWidget(self.button_box) self.setWindowTitle('Export Nodes') self.resize(500, 300) def select_all(self): for cb in self.nodes_check_box_list: cb.setChecked(True) def deselect_all(self): for cb in self.nodes_check_box_list: cb.setChecked(False) def select_package_dir(self): self.export_dir = QFileDialog.getExistingDirectory( self, 'Select the package folder where your nodes shall be exported at', '../packages') self.set_package_name(self.export_dir) def set_package_name(self, path: str): self.package_name = os.path.basename(path) self.package_dir_label.setText('package dir: ' + path) def get_selected_nodes(self): nodes = [] node_keys = list(self.nodes.keys()) for i in range(len(self.nodes_check_box_list)): check_box: QCheckBox = self.nodes_check_box_list[i] if check_box.isChecked(): nodes.append(node_keys[int(check_box.objectName()[15:])]) return nodes def export(self): self.export_nodes = self.get_selected_nodes() nodes_dict = {} module_name_separator = '___' nodes_list = [] node_titles_count = {} # title (str) : number (int) for i in range(len(self.export_nodes)): n: Node = self.export_nodes[i] c_w: NodeContentWidget = n.content_widget node_number = 0 title = c_w.get_node_title() if title in node_titles_count.values(): node_number = node_titles_count[title] # index node_titles_count[title] += 1 else: node_titles_count[title] = 1 node_data = c_w.get_json_data( package_name=self.package_name, module_name_separator=module_name_separator, number=node_number) nodes_list.append(node_data) nodes_dict['nodes'] = nodes_list info_dict = {'type': 'Ryven nodes package'} whole_dict = { **info_dict, **nodes_dict } # merges single two dictionaries to one json_data = json.dumps(whole_dict) print(json_data) # create dirs and save files if not os.path.isdir(self.export_dir + '/nodes'): os.mkdir(self.export_dir + '/nodes') save_file(self.export_dir + '/' + self.package_name + '.rpc', json_data) for i in range(len(self.export_nodes)): n = self.export_nodes[i] module_name = nodes_list[i]['module name'] # create node folder node_dir = self.export_dir + '/nodes/' + module_name if not os.path.isdir(node_dir): os.mkdir(node_dir) # create widgets folder widgets_dir = node_dir + '/widgets' if not os.path.isdir(widgets_dir): os.mkdir(widgets_dir) n.content_widget.save_metacode_files( node_dir=node_dir, widgets_dir=widgets_dir, module_name_separator=module_name_separator, module_name=module_name) def close_(self): self.main_window.last_exported_nodes = self.get_selected_nodes() self.main_window.last_export_path = self.export_dir self.close()
class Ui_GroupBox(object): def setupUi(self, GroupBox): if not GroupBox.objectName(): GroupBox.setObjectName(u"GroupBox") GroupBox.resize(528, 576) sizePolicy = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Minimum) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(GroupBox.sizePolicy().hasHeightForWidth()) GroupBox.setSizePolicy(sizePolicy) self.verticalLayout_2 = QVBoxLayout(GroupBox) self.verticalLayout_2.setObjectName(u"verticalLayout_2") self.groupBox = QGroupBox(GroupBox) self.groupBox.setObjectName(u"groupBox") self.verticalLayout_4 = QVBoxLayout(self.groupBox) self.verticalLayout_4.setObjectName(u"verticalLayout_4") self.horizontalLayout_7 = QHBoxLayout() self.horizontalLayout_7.setObjectName(u"horizontalLayout_7") self.horizontalSpacer_7 = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) self.horizontalLayout_7.addItem(self.horizontalSpacer_7) self.pushButton_degree_save = QPushButton(self.groupBox) self.pushButton_degree_save.setObjectName(u"pushButton_degree_save") self.horizontalLayout_7.addWidget(self.pushButton_degree_save) self.verticalLayout_4.addLayout(self.horizontalLayout_7) self.verticalLayout_2.addWidget(self.groupBox) self.verticalSpacer_2 = QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding) self.verticalLayout_2.addItem(self.verticalSpacer_2) self.groupBox_degree = QGroupBox(GroupBox) self.groupBox_degree.setObjectName(u"groupBox_degree") self.verticalLayout_3 = QVBoxLayout(self.groupBox_degree) self.verticalLayout_3.setObjectName(u"verticalLayout_3") self.horizontalLayout_2 = QHBoxLayout() self.horizontalLayout_2.setObjectName(u"horizontalLayout_2") self.radioButton_betweenness = QRadioButton(self.groupBox_degree) self.radioButton_betweenness.setObjectName(u"radioButton_betweenness") self.horizontalLayout_2.addWidget(self.radioButton_betweenness) self.radioButton_degree = QRadioButton(self.groupBox_degree) self.radioButton_degree.setObjectName(u"radioButton_degree") self.radioButton_degree.setChecked(True) self.horizontalLayout_2.addWidget(self.radioButton_degree) self.horizontalSpacer_5 = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) self.horizontalLayout_2.addItem(self.horizontalSpacer_5) self.verticalLayout_3.addLayout(self.horizontalLayout_2) self.checkBox_averaged_frames = QCheckBox(self.groupBox_degree) self.checkBox_averaged_frames.setObjectName( u"checkBox_averaged_frames") self.checkBox_averaged_frames.setChecked(True) self.verticalLayout_3.addWidget(self.checkBox_averaged_frames) self.checkBox_normalized = QCheckBox(self.groupBox_degree) self.checkBox_normalized.setObjectName(u"checkBox_normalized") self.verticalLayout_3.addWidget(self.checkBox_normalized) self.groupBox_per_residue = QGroupBox(self.groupBox_degree) self.groupBox_per_residue.setObjectName(u"groupBox_per_residue") self.groupBox_per_residue.setCheckable(True) self.verticalLayout = QVBoxLayout(self.groupBox_per_residue) self.verticalLayout.setObjectName(u"verticalLayout") self.horizontalLayout_6 = QHBoxLayout() self.horizontalLayout_6.setObjectName(u"horizontalLayout_6") self.label_2 = QLabel(self.groupBox_per_residue) self.label_2.setObjectName(u"label_2") self.horizontalLayout_6.addWidget(self.label_2) self.comboBox = QComboBox(self.groupBox_per_residue) self.comboBox.setObjectName(u"comboBox") self.horizontalLayout_6.addWidget(self.comboBox) self.horizontalSpacer_2 = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) self.horizontalLayout_6.addItem(self.horizontalSpacer_2) self.verticalLayout.addLayout(self.horizontalLayout_6) self.horizontalLayout = QHBoxLayout() self.horizontalLayout.setObjectName(u"horizontalLayout") self.label_10 = QLabel(self.groupBox_per_residue) self.label_10.setObjectName(u"label_10") self.label_10.setAlignment(Qt.AlignRight | Qt.AlignTrailing | Qt.AlignVCenter) self.horizontalLayout.addWidget(self.label_10) self.lineEdit_degree_residue_ids = QLineEdit(self.groupBox_per_residue) self.lineEdit_degree_residue_ids.setObjectName( u"lineEdit_degree_residue_ids") self.horizontalLayout.addWidget(self.lineEdit_degree_residue_ids) self.horizontalSpacer_6 = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) self.horizontalLayout.addItem(self.horizontalSpacer_6) self.verticalLayout.addLayout(self.horizontalLayout) self.verticalLayout_3.addWidget(self.groupBox_per_residue) self.groupBox_histogram = QGroupBox(self.groupBox_degree) self.groupBox_histogram.setObjectName(u"groupBox_histogram") self.groupBox_histogram.setCheckable(True) self.groupBox_histogram.setChecked(False) self.verticalLayout_5 = QVBoxLayout(self.groupBox_histogram) self.verticalLayout_5.setObjectName(u"verticalLayout_5") self.horizontalLayout_3 = QHBoxLayout() self.horizontalLayout_3.setObjectName(u"horizontalLayout_3") self.label_56 = QLabel(self.groupBox_histogram) self.label_56.setObjectName(u"label_56") self.label_56.setMaximumSize(QSize(16777215, 16777215)) self.label_56.setAlignment(Qt.AlignRight | Qt.AlignTrailing | Qt.AlignVCenter) self.horizontalLayout_3.addWidget(self.label_56) self.lineEdit_bins = QLineEdit(self.groupBox_histogram) self.lineEdit_bins.setObjectName(u"lineEdit_bins") self.lineEdit_bins.setMinimumSize(QSize(50, 0)) self.lineEdit_bins.setMaximumSize(QSize(50, 16777215)) self.horizontalLayout_3.addWidget(self.lineEdit_bins) self.label_55 = QLabel(self.groupBox_histogram) self.label_55.setObjectName(u"label_55") self.label_55.setMaximumSize(QSize(16777215, 16777215)) self.label_55.setAlignment(Qt.AlignRight | Qt.AlignTrailing | Qt.AlignVCenter) self.horizontalLayout_3.addWidget(self.label_55) self.lineEdit_minimum = QLineEdit(self.groupBox_histogram) self.lineEdit_minimum.setObjectName(u"lineEdit_minimum") self.lineEdit_minimum.setMinimumSize(QSize(50, 0)) self.lineEdit_minimum.setMaximumSize(QSize(50, 16777215)) self.horizontalLayout_3.addWidget(self.lineEdit_minimum) self.label_17 = QLabel(self.groupBox_histogram) self.label_17.setObjectName(u"label_17") self.label_17.setAlignment(Qt.AlignRight | Qt.AlignTrailing | Qt.AlignVCenter) self.horizontalLayout_3.addWidget(self.label_17) self.lineEdit_maximum = QLineEdit(self.groupBox_histogram) self.lineEdit_maximum.setObjectName(u"lineEdit_maximum") self.lineEdit_maximum.setMinimumSize(QSize(50, 0)) self.lineEdit_maximum.setMaximumSize(QSize(50, 16777215)) self.horizontalLayout_3.addWidget(self.lineEdit_maximum) self.horizontalSpacer_3 = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) self.horizontalLayout_3.addItem(self.horizontalSpacer_3) self.verticalLayout_5.addLayout(self.horizontalLayout_3) self.horizontalLayout_8 = QHBoxLayout() self.horizontalLayout_8.setObjectName(u"horizontalLayout_8") self.checkBox_cumulative_histogram = QCheckBox(self.groupBox_histogram) self.checkBox_cumulative_histogram.setObjectName( u"checkBox_cumulative_histogram") self.horizontalLayout_8.addWidget(self.checkBox_cumulative_histogram) self.horizontalSpacer_12 = QSpacerItem(40, 20, QSizePolicy.Fixed, QSizePolicy.Minimum) self.horizontalLayout_8.addItem(self.horizontalSpacer_12) self.checkBox_stacked_histogram = QCheckBox(self.groupBox_histogram) self.checkBox_stacked_histogram.setObjectName( u"checkBox_stacked_histogram") self.horizontalLayout_8.addWidget(self.checkBox_stacked_histogram) self.horizontalSpacer_11 = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) self.horizontalLayout_8.addItem(self.horizontalSpacer_11) self.verticalLayout_5.addLayout(self.horizontalLayout_8) self.horizontalLayout_9 = QHBoxLayout() self.horizontalLayout_9.setObjectName(u"horizontalLayout_9") self.checkBox_color_segments_occupancy = QCheckBox( self.groupBox_histogram) self.checkBox_color_segments_occupancy.setObjectName( u"checkBox_color_segments_occupancy") self.checkBox_color_segments_occupancy.setChecked(True) self.horizontalLayout_9.addWidget( self.checkBox_color_segments_occupancy) self.horizontalSpacer_9 = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) self.horizontalLayout_9.addItem(self.horizontalSpacer_9) self.verticalLayout_5.addLayout(self.horizontalLayout_9) self.verticalLayout_3.addWidget(self.groupBox_histogram) self.horizontalLayout_5 = QHBoxLayout() self.horizontalLayout_5.setObjectName(u"horizontalLayout_5") self.horizontalSpacer = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) self.horizontalLayout_5.addItem(self.horizontalSpacer) self.pushButton_degree_plot = QPushButton(self.groupBox_degree) self.pushButton_degree_plot.setObjectName(u"pushButton_degree_plot") self.pushButton_degree_plot.setAutoDefault(False) self.horizontalLayout_5.addWidget(self.pushButton_degree_plot) self.verticalLayout_3.addLayout(self.horizontalLayout_5) self.verticalLayout_2.addWidget(self.groupBox_degree) self.retranslateUi(GroupBox) QMetaObject.connectSlotsByName(GroupBox) # setupUi def retranslateUi(self, GroupBox): GroupBox.setWindowTitle( QCoreApplication.translate("GroupBox", u"GroupBox", None)) self.groupBox.setTitle( QCoreApplication.translate("GroupBox", u"All centrality measures", None)) self.pushButton_degree_save.setText( QCoreApplication.translate("GroupBox", u"Data", None)) self.groupBox_degree.setTitle( QCoreApplication.translate("GroupBox", u"Plots", None)) self.radioButton_betweenness.setText( QCoreApplication.translate("GroupBox", u"betweenness centrality", None)) self.radioButton_degree.setText( QCoreApplication.translate("GroupBox", u"degree centrality", None)) #if QT_CONFIG(tooltip) self.checkBox_averaged_frames.setToolTip( QCoreApplication.translate( "GroupBox", u"<html><head/><body><p align=\"justify\">Toggle, if absolute number of connections or time averaged number of connections are used.</p></body></html>", None)) #endif // QT_CONFIG(tooltip) self.checkBox_averaged_frames.setText( QCoreApplication.translate("GroupBox", u"average across frames", None)) self.checkBox_normalized.setText( QCoreApplication.translate("GroupBox", u"normalized", None)) self.groupBox_per_residue.setTitle( QCoreApplication.translate("GroupBox", u"Per Residue", None)) self.label_2.setText( QCoreApplication.translate("GroupBox", u"segment: ", None)) self.label_10.setText( QCoreApplication.translate("GroupBox", u"residue ids: ", None)) self.lineEdit_degree_residue_ids.setPlaceholderText( QCoreApplication.translate("GroupBox", u"e.g. 0-12, 20, 70-90", None)) self.groupBox_histogram.setTitle( QCoreApplication.translate("GroupBox", u"Histogram", None)) self.label_56.setText( QCoreApplication.translate("GroupBox", u"# of bins", None)) self.lineEdit_bins.setText( QCoreApplication.translate("GroupBox", u"10", None)) self.label_55.setText( QCoreApplication.translate("GroupBox", u"min. value", None)) self.lineEdit_minimum.setText( QCoreApplication.translate("GroupBox", u"0.0", None)) self.label_17.setText( QCoreApplication.translate("GroupBox", u"max. value", None)) self.lineEdit_maximum.setText( QCoreApplication.translate("GroupBox", u"1.0", None)) self.checkBox_cumulative_histogram.setText( QCoreApplication.translate("GroupBox", u"cumulative", None)) self.checkBox_stacked_histogram.setText( QCoreApplication.translate("GroupBox", u"stacked", None)) #if QT_CONFIG(tooltip) self.checkBox_color_segments_occupancy.setToolTip( QCoreApplication.translate( "GroupBox", u"<html><head/><body><p align=\"justify\">Toggle if histogram bars are colored by segment or molecule. With colors turned on, comparing to other analyses is not possible.</p></body></html>", None)) #endif // QT_CONFIG(tooltip) self.checkBox_color_segments_occupancy.setText( QCoreApplication.translate("GroupBox", u"color by segment", None)) #if QT_CONFIG(tooltip) self.pushButton_degree_plot.setToolTip( QCoreApplication.translate( "GroupBox", u"<html><head/><body><p align=\"justify\">Compute the number of H bonds per residue. Results are colored by segment.</p></body></html>", None)) #endif // QT_CONFIG(tooltip) self.pushButton_degree_plot.setText( QCoreApplication.translate("GroupBox", u"Plot", None))
class DatasheetView(QMainWindow): def __init__(self, pdfPath=None, pageNumber=1): super().__init__() # initialize data files # self.fileStore = path.join(path.curdir, "/files") # mkdir(self.fileStore) self.svgFiles = [] # window dimensions self.top = 300 self.left = 800 self.width = 860 self.height = 980 self.setGeometry(self.left, self.top, self.width, self.height) # window title self.setWindowTitle("Hello") # sets up main layout -- splitters self.initUILayout() self.initUIToolbar() self.populatePDF(pdfPath, pageNumber) self.show() def initUILayout(self): # set left-side, Dynamic View self.dynamicViewDisplay = QLabel() self.vBoxA = QVBoxLayout() self.vBoxA.addWidget(self.dynamicViewDisplay) self.groupA = QGroupBox() self.groupA.setTitle("Dynamic Veiw") self.groupA.setLayout(self.vBoxA) # set left-side, Static View self.staticViewDisplay = QLabel() self.vBoxB = QVBoxLayout() self.vBoxB.addWidget(self.staticViewDisplay) self.groupB = QGroupBox() self.groupB.setTitle("Static View") self.groupB.setLayout(self.vBoxB) # add Dynamic and Static Views to resizeable left-side Splitter self.altViewSplit = QSplitter(Qt.Vertical) self.altViewSplit.addWidget(self.groupA) self.altViewSplit.addWidget(self.groupB) # set up Tools View section self.toolsTabView = QTabWidget() self.toolsTabView.setTabsClosable(True) self.toolsTabView.setMovable(True) self.toolsTabView.setDocumentMode(True) # self.toolsTabView.setTabBarAutoHide(True) # add attribute for storing page notes self.notesDB = [] self.notesDisplay = QListWidget(self) self.notesDisplay.setMaximumHeight(200) # add ToC to Tools View self.ToCListView = QListWidget() self.toolsTabView.addTab(self.ToCListView, "Table of Contents") # add notes list to tools view self.toolsTabView.addTab(self.notesDisplay, "Notes") # add tools view to the left-side splitter self.altViewSplit.addWidget(self.toolsTabView) # set right-side view -- SVG Viewer self.mainDisplay = QSvgWidget() self.vBoxMain = QVBoxLayout() self.vBoxMain.addWidget(self.mainDisplay) self.notesArea = QLineEdit() self.notesArea.setPlaceholderText("Add a note about this page...") self.notesArea.returnPressed.connect(self.onAddNote) self.vBoxMain.addWidget(self.notesArea) self.mainViewGroup = QGroupBox() self.mainViewGroup.setTitle("Main View") self.mainViewGroup.setLayout(self.vBoxMain) # join both sides together self.leftRightSplit = QSplitter(Qt.Horizontal) self.leftRightSplit.addWidget(self.altViewSplit) self.leftRightSplit.addWidget(self.mainViewGroup) self.setCentralWidget(self.leftRightSplit) def initUIToolbar(self): mainMenu = self.menuBar() # get the menu bar already in use by this QMainWindow class fileMenu = mainMenu.addMenu("File") editMenu = mainMenu.addMenu("Edit") LayoutMenu = mainMenu.addMenu("Layout") AboutMenu = mainMenu.addMenu("About") saveAction = fileMenu.addAction("Save") quitAction = fileMenu.addAction("Exit Bettersheets") quitAction.triggered.connect(self.quitApp) copyAction = editMenu.addAction("Copy") resetAction = LayoutMenu.addAction("Reset Default Layout") # mainMenu.setNativeMenuBar(True) # mainMenu.show() self. toolBar = self.addToolBar("Tools") self.toolBar.addAction(saveAction) self.toolBar.addAction(copyAction) def contextMenuEvent(self, event): # return super().contextMenuEvent(event) contextMenu = QMenu() selectAction = contextMenu.addAction("Select Area") extractAction = contextMenu.addAction("Extract Content") openAction = contextMenu.addAction("Open PDF") closeAction = contextMenu.addAction("Close PDF") quitAction = contextMenu.addAction("Quit") triggered_action = contextMenu.exec_(self.mapToGlobal(event.pos())) if triggered_action == quitAction: self.quitApp() def quitApp(self): self.close() def onAddNote(self): print("note added") text = self.notesArea.text() if text: self.notesDB.append(text) self.notesDisplay.clear() self.notesDisplay.addItems(self.notesDB) self.notesArea.clear() def populatePDF(self, pdfPath, pageNumber): if pdfPath: self.document = PDFContext(pdfPath, pageNumber) ToC = self.document.getToC() ToC_headings_list = [x[1] for x in ToC] self.ToCListView.clear() self.ToCListView.addItems(ToC_headings_list) # display page in main view self.document.openPDF(pdfPath, pageNumber) self.SVGString = self.document.getRender(self.document.currentPageNumber) # set filename of current PDF self.pdfName = path.split(pdfPath)[1].split('.')[0] # write current page to .svg file file_loc = self._writeSVGToFile_(self.pdfName, pageNumber, self.SVGString) # open the file we just wrote to self.mainDisplay.load(file_loc) @staticmethod def _writeSVGToFile_(pdfName: str, pageNumber: int, svg_string: str) -> str: """ return the full file path we just wrote """ file_loc = f"./src/main/files/{pdfName}-page-{pageNumber}.svg" with open(file_loc , 'w') as f: f.write(svg_string) print("File_loc: ", file_loc) return file_loc
def _create_ammo_pickup_boxes(self, size_policy, item_database: ItemDatabase): """ Creates the GroupBox with SpinBoxes for selecting the pickup count of all the ammo :param item_database: :return: """ self._ammo_maximum_spinboxes = collections.defaultdict(list) self._ammo_pickup_widgets = {} resource_database = default_database.resource_database_for(self.game) broad_to_category = { ItemCategory.BEAM_RELATED: ItemCategory.BEAM, ItemCategory.MORPH_BALL_RELATED: ItemCategory.MORPH_BALL, ItemCategory.MISSILE_RELATED: ItemCategory.MISSILE, } for ammo in item_database.ammo.values(): category_box, category_layout, _ = self._boxes_for_category[ broad_to_category[ammo.broad_category]] pickup_box = QGroupBox(category_box) pickup_box.setSizePolicy(size_policy) pickup_box.setTitle(ammo.name + "s") layout = QGridLayout(pickup_box) layout.setObjectName(f"{ammo.name} Box Layout") current_row = 0 for ammo_item in ammo.items: item = resource_database.get_by_type_and_index( ResourceType.ITEM, ammo_item) target_count_label = QLabel(pickup_box) target_count_label.setText(f"{item.long_name} Target" if len( ammo.items) > 1 else "Target count") maximum_spinbox = QSpinBox(pickup_box) maximum_spinbox.setMaximum(ammo.maximum) maximum_spinbox.valueChanged.connect( partial(self._on_update_ammo_maximum_spinbox, ammo_item)) self._ammo_maximum_spinboxes[ammo_item].append(maximum_spinbox) layout.addWidget(target_count_label, current_row, 0) layout.addWidget(maximum_spinbox, current_row, 1) current_row += 1 count_label = QLabel(pickup_box) count_label.setText("Pickup Count") count_label.setToolTip( "How many instances of this expansion should be placed.") pickup_spinbox = QSpinBox(pickup_box) pickup_spinbox.setMaximum(AmmoState.maximum_pickup_count()) pickup_spinbox.valueChanged.connect( partial(self._on_update_ammo_pickup_spinbox, ammo)) layout.addWidget(count_label, current_row, 0) layout.addWidget(pickup_spinbox, current_row, 1) current_row += 1 if ammo.temporaries: require_major_item_check = QCheckBox(pickup_box) require_major_item_check.setText( "Requires the major item to work?") require_major_item_check.stateChanged.connect( partial(self._on_update_ammo_require_major_item, ammo)) layout.addWidget(require_major_item_check, current_row, 0, 1, 2) current_row += 1 else: require_major_item_check = None expected_count = QLabel(pickup_box) expected_count.setWordWrap(True) expected_count.setText(_EXPECTED_COUNT_TEXT_TEMPLATE) expected_count.setToolTip( "Some expansions may provide 1 extra, even with no variance, if the total count " "is not divisible by the pickup count.") layout.addWidget(expected_count, current_row, 0, 1, 2) current_row += 1 self._ammo_pickup_widgets[ammo] = AmmoPickupWidgets( pickup_spinbox, expected_count, pickup_box, require_major_item_check) category_layout.addWidget(pickup_box)
class NumberConversion(QWidget): def __init__(self): super(NumberConversion, self).__init__() # App attributes self.bin_format_base = None self.bin_format_base_byte = None # Use language settings self.ml = ManageLng() main_layout = QGridLayout() self.setLayout(main_layout) # Input self.inputbox = QGroupBox( self.ml.get_tr_text("tab_num_conv_inputbox_gbox_name")) self.inputbox.setMaximumWidth(400) main_layout.addWidget(self.inputbox, 0, 0) inputbox_layout = QGridLayout() inputbox_layout.setHorizontalSpacing(25) inputbox_layout.setVerticalSpacing(35) inputbox_layout.setAlignment(Qt.AlignCenter) self.inputbox.setLayout(inputbox_layout) self.input_number_label = QLabel( self.ml.get_tr_text("tab_num_conv_inputbox_in_number_lab")) self.input_number_textfield = QLineEdit() self.input_number_textfield.setPlaceholderText("192") self.input_number_textfield.setAlignment(Qt.AlignCenter) self.input_number_textfield.returnPressed.connect(self.convert_action) inputbox_layout.addWidget(self.input_number_label, 0, 0, alignment=Qt.AlignCenter) inputbox_layout.addWidget(self.input_number_textfield, 0, 1) button_layout = QVBoxLayout() self.bin_button = QRadioButton( self.ml.get_tr_text("tab_num_conv_inputbox_bin_chkbox")) self.bin_button.clicked.connect( lambda: self.input_number_textfield.setPlaceholderText("11100010")) self.dec_button = QRadioButton( self.ml.get_tr_text("tab_num_conv_inputbox_dec_chkbox")) self.dec_button.clicked.connect( lambda: self.input_number_textfield.setPlaceholderText("192")) self.hex_button = QRadioButton( self.ml.get_tr_text("tab_num_conv_inputbox_hex_chkbox")) self.hex_button.clicked.connect( lambda: self.input_number_textfield.setPlaceholderText("FF")) self.dec_button.setChecked(True) button_layout.addWidget(self.bin_button) button_layout.addWidget(self.dec_button) button_layout.addWidget(self.hex_button) inputbox_layout.addLayout(button_layout, 0, 3, 1, 2) self.convert_button = QPushButton( self.ml.get_tr_text("tab_num_conv_inputbox_conv_btn")) self.convert_button.clicked.connect(self.convert_action) self.convert_button.setIcon(QIcon("static/images/exchange.png")) inputbox_layout.addWidget(self.convert_button, 1, 1, alignment=Qt.AlignCenter) # Output self.outputbox = QGroupBox( self.ml.get_tr_text("tab_num_conv_outputbox_gbox_name")) main_layout.addWidget(self.outputbox, 0, 1) outputbox_layout = QGridLayout() outputbox_layout.setHorizontalSpacing(25) self.outputbox.setLayout(outputbox_layout) self.bin_label = QLabel( self.ml.get_tr_text("tab_num_conv_outputbox_bin_lab")) self.bin_label.setAlignment(Qt.AlignCenter) self.dec_label = QLabel( self.ml.get_tr_text("tab_num_conv_outputbox_dec_lab")) self.dec_label.setAlignment(Qt.AlignCenter) self.hex_label = QLabel( self.ml.get_tr_text("tab_num_conv_outputbox_hex_lab")) self.hex_label.setAlignment(Qt.AlignCenter) self.bin_output = QLineEdit() self.bin_output.setReadOnly(True) self.bin_output.setAlignment(Qt.AlignCenter) self.dec_output = QLineEdit() self.dec_output.setReadOnly(True) self.dec_output.setAlignment(Qt.AlignCenter) self.hex_output = QLineEdit() self.hex_output.setReadOnly(True) self.hex_output.setAlignment(Qt.AlignCenter) self.bin_output_copy_button = QPushButton( self.ml.get_tr_text("tab_num_conv_outputbox_copy_btn")) self.bin_output_copy_button.setIcon( QIcon("static/images/copy_clipboard.png")) self.bin_output_copy_button.clicked.connect( lambda: copy_action(self.bin_output.text())) self.dec_output_copy_button = QPushButton( self.ml.get_tr_text("tab_num_conv_outputbox_copy_btn")) self.dec_output_copy_button.setIcon( QIcon("static/images/copy_clipboard.png")) self.dec_output_copy_button.clicked.connect( lambda: copy_action(self.dec_output.text())) self.hex_output_copy_button = QPushButton( self.ml.get_tr_text("tab_num_conv_outputbox_copy_btn")) self.hex_output_copy_button.setIcon( QIcon("static/images/copy_clipboard.png")) self.hex_output_copy_button.clicked.connect( lambda: copy_action(self.hex_output.text())) outputbox_layout.addWidget(self.bin_label, 0, 0) outputbox_layout.addWidget(self.bin_output, 0, 1) outputbox_layout.addWidget(self.bin_output_copy_button, 0, 2) outputbox_layout.addWidget(self.dec_label, 1, 0) outputbox_layout.addWidget(self.dec_output, 1, 1) outputbox_layout.addWidget(self.dec_output_copy_button, 1, 2) outputbox_layout.addWidget(self.hex_label, 2, 0) outputbox_layout.addWidget(self.hex_output, 2, 1) outputbox_layout.addWidget(self.hex_output_copy_button, 2, 2) # IP address/mask number conversion self.ip_address_number_conversion_box = QGroupBox( self.ml.get_tr_text("tab_num_conv_ip_mask_conv_gbox_name")) main_layout.addWidget(self.ip_address_number_conversion_box, 1, 0, 1, 2) ip_address_number_conversion_layout = QGridLayout() ip_address_number_conversion_layout.setAlignment(Qt.AlignCenter) ip_address_number_conversion_layout.setHorizontalSpacing(25) ip_address_number_conversion_layout.setVerticalSpacing(24) self.ip_address_number_conversion_box.setLayout( ip_address_number_conversion_layout) self.input_label = QLabel( self.ml.get_tr_text("tab_num_conv_ip_mask_conv_in_lab")) self.input_label.setAlignment(Qt.AlignCenter) self.input_label.setMaximumWidth(150) self.input_textfield = QLineEdit() self.input_textfield.setPlaceholderText("192.168.1.1") self.input_textfield.setAlignment(Qt.AlignLeft) self.input_textfield.setMaximumWidth(300) self.input_textfield.setAlignment(Qt.AlignCenter) self.input_textfield.returnPressed.connect(self.convert_action_2) ip_address_number_conversion_layout.addWidget(self.input_label, 0, 0) ip_address_number_conversion_layout.addWidget(self.input_textfield, 0, 1) button_layout_2 = QVBoxLayout() self.dec_to_bin_button = QRadioButton( self.ml.get_tr_text("tab_num_conv_ip_mask_conv_dectobin")) self.dec_to_bin_button.clicked.connect( lambda: self.input_textfield.setPlaceholderText("192.168.1.1")) self.dec_to_bin_button.setMaximumWidth(150) self.bin_to_dec_button = QRadioButton( self.ml.get_tr_text("tab_num_conv_ip_mask_conv_bintodec")) self.bin_to_dec_button.clicked.connect( lambda: self.input_textfield.setPlaceholderText( "11000000.10101000.00000001.00000001")) self.bin_to_dec_button.setMaximumWidth(150) self.dec_to_bin_button.setChecked(True) button_layout_2.addWidget(self.dec_to_bin_button) button_layout_2.addWidget(self.bin_to_dec_button) ip_address_number_conversion_layout.addLayout(button_layout_2, 0, 2) self.output_label = QLabel( self.ml.get_tr_text("tab_num_conv_ip_mask_conv_out_lab")) self.output_label.setAlignment(Qt.AlignCenter) self.output_textfield = QLineEdit() self.output_textfield.setMaximumWidth(300) self.output_textfield.setReadOnly(True) self.output_textfield.setAlignment(Qt.AlignCenter) ip_address_number_conversion_layout.addWidget(self.output_label, 1, 0) ip_address_number_conversion_layout.addWidget(self.output_textfield, 1, 1) self.output_textfield_copy_button = QPushButton( self.ml.get_tr_text("tab_num_conv_ip_mask_conv_copy_btn")) self.output_textfield_copy_button.setIcon( QIcon("static/images/copy_clipboard.png")) self.output_textfield_copy_button.clicked.connect( lambda: copy_action(self.output_textfield.text())) ip_address_number_conversion_layout.addWidget( self.output_textfield_copy_button, 1, 2, alignment=Qt.AlignLeft) self.convert_button_2 = QPushButton( self.ml.get_tr_text("tab_num_conv_ip_mask_conv_convert_btn")) self.convert_button_2.clicked.connect(self.convert_action_2) self.convert_button_2.setIcon(QIcon("static/images/exchange.png")) ip_address_number_conversion_layout.addWidget( self.convert_button_2, 2, 0, 1, 3, alignment=Qt.AlignHCenter) def convert_action(self): if is_empty(self.input_number_textfield.text()): PopupWindow("warning", self.ml.get_tr_text("tab_num_conv_warning01"), self.input_number_textfield) else: if self.bin_button.isChecked(): self.source_bin(self.input_number_textfield.text()) elif self.dec_button.isChecked(): self.source_dec(self.input_number_textfield.text()) else: self.source_hex(self.input_number_textfield.text()) def source_bin(self, bin_number): bin_number_corrected = get_corrected_number(bin_number) bin_number_corrected_byte = bin_number_corrected.rjust(8, "0") if not is_correct_binary(bin_number_corrected): PopupWindow("warning", self.ml.get_tr_text("tab_num_conv_warning02"), self.input_number_textfield) else: if 0 <= int(bin_number_corrected, 2) <= 255: if bin_number_corrected != bin_number_corrected_byte: self.bin_format_base = bin_number_corrected self.bin_format_base_byte = bin_number_corrected_byte bin_format = get_bin_format( self.bin_format_base, self.ml.get_tr_text("byte_format_str"), self.bin_format_base_byte) else: bin_format = self.bin_format_base else: bin_format = bin_number_corrected dec_format = str(int(bin_number_corrected, 2)) hex_format = hex(int(bin_number_corrected, 2)).replace("0x", "").upper() self.bin_output.setText(bin_format) self.dec_output.setText(dec_format) self.hex_output.setText(hex_format) def source_dec(self, dec_number): dec_number_corrected = get_corrected_number(dec_number) if not is_correct_decimal(dec_number_corrected): PopupWindow("warning", self.ml.get_tr_text("tab_num_conv_warning03"), self.input_number_textfield) else: if 0 <= int(dec_number_corrected) <= 255: self.bin_format_base = bin(int(dec_number_corrected)).replace( "0b", "") self.bin_format_base_byte = self.bin_format_base.rjust(8, "0") if self.bin_format_base != self.bin_format_base_byte: bin_format = get_bin_format( self.bin_format_base, self.ml.get_tr_text("byte_format_str"), self.bin_format_base_byte) else: bin_format = self.bin_format_base else: bin_format = bin(int(dec_number_corrected)).replace("0b", "") dec_format = dec_number_corrected hex_format = hex(int(dec_number_corrected)).replace("0x", "").upper() self.bin_output.setText(bin_format) self.dec_output.setText(dec_format) self.hex_output.setText(hex_format) def source_hex(self, hex_number): hex_number_corrected = get_corrected_number(hex_number).upper() if not is_correct_hexadecimal(hex_number_corrected): PopupWindow("warning", self.ml.get_tr_text("tab_num_conv_warning04"), self.input_number_textfield) else: if 0 <= int(hex_number_corrected, 16) <= 255: self.bin_format_base = bin(int(hex_number_corrected, 16)).replace("0b", "") self.bin_format_base_byte = self.bin_format_base.rjust(8, "0") if self.bin_format_base != self.bin_format_base_byte: bin_format = get_bin_format( self.bin_format_base, self.ml.get_tr_text("byte_format_str"), self.bin_format_base_byte) else: bin_format = self.bin_format_base else: bin_format = bin(int(hex_number_corrected, 16)).replace("0b", "") dec_format = str(int(hex_number_corrected, 16)) hex_format = hex_number_corrected self.bin_output.setText(bin_format) self.dec_output.setText(dec_format) self.hex_output.setText(hex_format) def convert_action_2(self): if is_empty(self.input_textfield.text()): PopupWindow("warning", self.ml.get_tr_text("tab_num_conv_warning05"), self.input_textfield) elif self.dec_to_bin_button.isChecked(): if is_correct_any_ip_dec(self.input_textfield.text()): self.output_textfield.setText( dec_to_bin(self.input_textfield.text())) else: PopupWindow("warning", self.ml.get_tr_text("tab_num_conv_warning06"), self.input_textfield) else: if is_correct_any_ip_bin(self.input_textfield.text()): self.output_textfield.setText( bin_to_dec(self.input_textfield.text())) else: PopupWindow("warning", self.ml.get_tr_text("tab_num_conv_warning07"), self.input_textfield) def re_translate_ui(self, lang): self.ml = ManageLng(lang) self.inputbox.setTitle( self.ml.get_tr_text("tab_num_conv_inputbox_gbox_name")) self.input_number_label.setText( self.ml.get_tr_text("tab_num_conv_inputbox_in_number_lab")) self.bin_button.setText( self.ml.get_tr_text("tab_num_conv_inputbox_bin_chkbox")) self.dec_button.setText( self.ml.get_tr_text("tab_num_conv_inputbox_dec_chkbox")) self.hex_button.setText( self.ml.get_tr_text("tab_num_conv_inputbox_hex_chkbox")) self.convert_button.setText( self.ml.get_tr_text("tab_num_conv_inputbox_conv_btn")) self.outputbox.setTitle( self.ml.get_tr_text("tab_num_conv_outputbox_gbox_name")) self.bin_label.setText( self.ml.get_tr_text("tab_num_conv_outputbox_bin_lab")) self.dec_label.setText( self.ml.get_tr_text("tab_num_conv_outputbox_dec_lab")) self.hex_label.setText( self.ml.get_tr_text("tab_num_conv_outputbox_hex_lab")) self.bin_output_copy_button.setText( self.ml.get_tr_text("tab_num_conv_outputbox_copy_btn")) self.dec_output_copy_button.setText( self.ml.get_tr_text("tab_num_conv_outputbox_copy_btn")) self.hex_output_copy_button.setText( self.ml.get_tr_text("tab_num_conv_outputbox_copy_btn")) self.ip_address_number_conversion_box.setTitle( self.ml.get_tr_text("tab_num_conv_ip_mask_conv_gbox_name")) self.input_label.setText( self.ml.get_tr_text("tab_num_conv_ip_mask_conv_in_lab")) self.dec_to_bin_button.setText( self.ml.get_tr_text("tab_num_conv_ip_mask_conv_dectobin")) self.bin_to_dec_button.setText( self.ml.get_tr_text("tab_num_conv_ip_mask_conv_bintodec")) self.output_label.setText( self.ml.get_tr_text("tab_num_conv_ip_mask_conv_out_lab")) self.output_textfield_copy_button.setText( self.ml.get_tr_text("tab_num_conv_ip_mask_conv_copy_btn")) self.convert_button_2.setText( self.ml.get_tr_text("tab_num_conv_ip_mask_conv_convert_btn")) if self.bin_output.text(): self.bin_output.setText( get_bin_format(self.bin_format_base, self.ml.get_tr_text("byte_format_str"), self.bin_format_base_byte))
def __init__(self, targetImage=None, axeSize=500, layer=None, parent=None): super().__init__(layer=layer, targetImage=targetImage, parent=parent) ####################################### # Libraw correspondences: # rgb_xyz_matrix is libraw cam_xyz # camera_whitebalance is libraw cam_mul # daylight_whitebalance is libraw pre_mul # dng correspondences: # ASSHOTNEUTRAL tag value is (X,Y,Z) = 1 / rawpyObj.camera_whitebalance ########################################## rawpyObj = layer.parentImage.rawImage # constants and as shot values self.XYZ2CameraMatrix = rawpyObj.rgb_xyz_matrix[:3, :] self.XYZ2CameraInverseMatrix = np.linalg.inv(self.XYZ2CameraMatrix) # initial post processing multipliers (as shot) m1, m2, m3, m4 = rawpyObj.camera_whitebalance self.asShotMultipliers = ( m1 / m2, 1.0, m3 / m2, m4 / m2 ) # normalization is mandatory : for nef files white balance is around 256 self.asShotTemp, self.asShotTint = multipliers2TemperatureAndTint( *1 / np.array(self.asShotMultipliers[:3]), self.XYZ2CameraMatrix) self.rawMultipliers = self.asShotMultipliers # rawpyObj.camera_whitebalance # = 1/(dng ASSHOTNEUTRAL tag value) self.sampleMultipliers = False self.samples = [] ######################################## # XYZ-->Camera conversion matrix: # Last row is zero for RGB cameras (cf. rawpy and libraw docs). # type ndarray, shape (4,3) ######################################### # attributes initialized in setDefaults, declared here for the sake of correctness self.tempCorrection, self.tintCorrection, self.expCorrection, self.highCorrection,\ self.contCorrection, self.satCorrection, self.brCorrection = [None] * 7 # contrast spline vie (initialized by setContrastSpline) self.contrastForm = None # tone spline view (initialized by setToneSpline) self.toneForm = None # dock containers for contrast and tome forms self.dockC, self.dockT = None, None # options optionList0, optionNames0 = ['Auto Brightness', 'Preserve Highlights' ], ['Auto Expose', 'Preserve Highlights'] optionList1, optionNames1 = ['Auto WB', 'Camera WB', 'User WB' ], ['Auto', 'Camera (As Shot)', 'User'] optionList2, optionNames2 = [ 'cpLookTable', 'cpToneCurve', 'manualCurve' ], [ 'Use Camera Profile Look Table', 'Show Tone Curves', 'Show Contrast Curve' ] self.listWidget1 = optionsWidget( options=optionList0, optionNames=optionNames0, exclusive=False, changed=lambda: self.dataChanged.emit(1)) self.listWidget2 = optionsWidget( options=optionList1, optionNames=optionNames1, exclusive=True, changed=lambda: self.dataChanged.emit(1)) self.listWidget3 = optionsWidget( options=optionList2, optionNames=optionNames2, exclusive=False, changed=lambda: self.dataChanged.emit(2)) self.options = UDict( (self.listWidget1.options, self.listWidget2.options, self.listWidget3.options)) # display the 'as shot' temperature item = self.listWidget2.item(1) item.setText(item.text() + ' : %d' % self.asShotTemp) # temperature slider self.sliderTemp = QbLUeSlider(Qt.Horizontal) self.sliderTemp.setStyleSheet( QbLUeSlider.bLueSliderDefaultColorStylesheet) self.sliderTemp.setRange(0, 100) self.sliderTemp.setSingleStep(1) self.tempLabel = QLabel() self.tempLabel.setText("Temp") self.tempValue = QLabel() font = self.tempValue.font() metrics = QFontMetrics(font) w = metrics.width("10000") h = metrics.height() self.tempValue.setMinimumSize(w, h) self.tempValue.setMaximumSize(w, h) self.tempValue.setText( str("{:.0f}".format(self.slider2Temp(self.sliderTemp.value())))) self.sliderTemp.valueChanged.connect( self.tempUpdate) # signal send new value as parameter self.sliderTemp.sliderReleased.connect(lambda: self.tempUpdate( self.sliderTemp.value())) # signal pass no parameter # tint slider self.sliderTint = QbLUeSlider(Qt.Horizontal) self.sliderTint.setStyleSheet( QbLUeSlider.bLueSliderDefaultIMGColorStylesheet) self.sliderTint.setRange(0, 150) self.sliderTint.setSingleStep(1) self.tintLabel = QLabel() self.tintLabel.setText("Tint") self.tintValue = QLabel() font = self.tempValue.font() metrics = QFontMetrics(font) w = metrics.width("100") h = metrics.height() self.tintValue.setMinimumSize(w, h) self.tintValue.setMaximumSize(w, h) self.tintValue.setText( str("{:.0f}".format(self.sliderTint2User( self.sliderTint.value())))) self.sliderTint.valueChanged.connect(self.tintUpdate) self.sliderTint.sliderReleased.connect(lambda: self.tintUpdate( self.sliderTint.value())) # signal pass no parameter) ###################### # From libraw and dcraw sources: # Exposure and brightness are curve transformations. # Exposure curve is y = alpha*x, with cubic root ending; it is applied before demosaicing. # Brightness is (similar to) y = x**alpha and part of gamma transformation from linear sRGB to RGB. # Exposure and brightness both dilate the histogram towards highlights. # Exposure dilatation is uniform (homothety), brightness dilataion is # maximum for the midtones and the highlghts are preserved. # As a consequence, normal workflow begins with the adjustment of exposure, # to fill the entire range of the histogram and to adjust the highlights. Next, # one adjusts the brightness to put the midtones at the level we want them to be. # Cf. https://www.cambridgeincolour.com/forums/thread653.htm ##################### # profile combo self.dngDict = self.setCameraProfilesCombo() # cameraProfilesCombo index changed event handler def cameraProfileUpdate(value): self.dngDict = self.cameraProfilesCombo.itemData(value) if self.options['cpToneCurve']: toneCurve = dngProfileToneCurve( self.dngDict.get('ProfileToneCurve', [])) self.toneForm.baseCurve = [ QPointF(x * axeSize, -y * axeSize) for x, y in zip(toneCurve.dataX, toneCurve.dataY) ] self.toneForm.update() # recompute as shot temp and tint using new profile self.asShotTemp, self.asShotTint = multipliers2TemperatureAndTint( *1 / np.array(self.asShotMultipliers[:3]), self.XYZ2CameraMatrix, dngDict=self.dngDict ) # TODO 6/12/19 added keyword dngDict validate # display updated as shot temp item = self.listWidget2.item(1) item.setText(item.text().split(":")[0] + ': %d' % self.asShotTemp) # invalidate cache self.layer.bufCache_HSV_CV32 = None self.dataChanged.emit(2) # 2 = no postprocessing self.cameraProfilesCombo.currentIndexChanged.connect( cameraProfileUpdate) # denoising combo self.denoiseCombo = QComboBox() items = OrderedDict([('Off', 0), ('Medium', 1), ('Full', 2)]) for key in items: self.denoiseCombo.addItem(key, items[key]) # denoiseCombo index changed event handler def denoiseUpdate(value): self.denoiseValue = self.denoiseCombo.itemData(value) self.dataChanged.emit(1) self.denoiseCombo.currentIndexChanged.connect(denoiseUpdate) # overexposed area restoration self.overexpCombo = QComboBox() items = OrderedDict([('Clip', 0), ('Ignore', 1), ('Blend', 2), ('Reconstruct', 3)]) for key in items: self.overexpCombo.addItem(key, items[key]) # overexpCombo index changed event handler def overexpUpdate(value): self.overexpValue = self.overexpCombo.itemData(value) self.dataChanged.emit(1) self.overexpCombo.currentIndexChanged.connect(overexpUpdate) # exp slider self.sliderExp = QbLUeSlider(Qt.Horizontal) self.sliderExp.setStyleSheet(QbLUeSlider.bLueSliderDefaultBWStylesheet) self.sliderExp.setRange(0, 100) self.sliderExp.setSingleStep(1) self.expLabel = QLabel() self.expLabel.setText("Exp.") self.expValue = QLabel() font = self.expValue.font() metrics = QFontMetrics(font) w = metrics.width("+1.0") h = metrics.height() self.expValue.setMinimumSize(w, h) self.expValue.setMaximumSize(w, h) self.expValue.setText( str("{:.1f}".format(self.slider2Exp(self.sliderExp.value())))) # exp done event handler def expUpdate(value): self.expValue.setText( str("{:+.1f}".format( self.sliderExp2User(self.sliderExp.value())))) # move not yet terminated or value not modified if self.sliderExp.isSliderDown() or self.slider2Exp( value) == self.expCorrection: return try: self.sliderExp.valueChanged.disconnect() self.sliderExp.sliderReleased.disconnect() except RuntimeError: pass # rawpy: expCorrection range is -2.0...3.0, boiling down to exp_shift range 2**(-2)=0.25...2**3=8.0 self.expCorrection = self.slider2Exp(self.sliderExp.value()) self.dataChanged.emit(1) self.sliderExp.valueChanged.connect( expUpdate) # send new value as parameter self.sliderExp.sliderReleased.connect(lambda: expUpdate( self.sliderExp.value())) # signal pass no parameter self.sliderExp.valueChanged.connect( expUpdate) # send new value as parameter self.sliderExp.sliderReleased.connect(lambda: expUpdate( self.sliderExp.value())) # signal pass no parameter # brightness slider brSlider = QbLUeSlider(Qt.Horizontal) brSlider.setRange(1, 101) self.sliderExp.setSingleStep(1) brSlider.setStyleSheet(QbLUeSlider.bLueSliderDefaultBWStylesheet) self.sliderBrightness = brSlider brLabel = QLabel() brLabel.setText("Bright.") self.brValue = QLabel() font = self.expValue.font() metrics = QFontMetrics(font) w = metrics.width("+99") h = metrics.height() self.brValue.setMinimumSize(w, h) self.brValue.setMaximumSize(w, h) self.brValue.setText( str("{:+d}".format( int(self.brSlider2User(self.sliderBrightness.value()))))) # brightness done event handler def brUpdate(value): self.brValue.setText( str("{:+d}".format( int(self.brSlider2User(self.sliderBrightness.value()))))) # move not yet terminated or value not modified if self.sliderBrightness.isSliderDown() or self.slider2Br( value) == self.brCorrection: return try: self.sliderBrightness.valueChanged.disconnect() self.sliderBrightness.sliderReleased.disconnect() except RuntimeError: pass self.brCorrection = self.slider2Br(self.sliderBrightness.value()) self.dataChanged.emit(1) self.sliderBrightness.sliderReleased.connect( lambda: brUpdate(self.sliderBrightness.value())) self.sliderBrightness.valueChanged.connect( brUpdate) # send new value as parameter self.sliderBrightness.valueChanged.connect( brUpdate) # send new value as parameter self.sliderBrightness.sliderReleased.connect( lambda: brUpdate(self.sliderBrightness.value())) # contrast slider self.sliderCont = QbLUeSlider(Qt.Horizontal) self.sliderCont.setStyleSheet( QbLUeSlider.bLueSliderDefaultBWStylesheet) self.sliderCont.setRange(0, 20) self.sliderCont.setSingleStep(1) self.contLabel = QLabel() self.contLabel.setText("Cont.") self.contValue = QLabel() font = self.contValue.font() metrics = QFontMetrics(font) w = metrics.width("100") h = metrics.height() self.contValue.setMinimumSize(w, h) self.contValue.setMaximumSize(w, h) self.contValue.setText( str("{:.0f}".format(self.slider2Cont(self.sliderCont.value())))) # cont done event handler def contUpdate(value): self.contValue.setText( str("{:.0f}".format(self.slider2Cont( self.sliderCont.value())))) # move not yet terminated or value not modified if self.sliderCont.isSliderDown() or self.slider2Cont( value) == self.tempCorrection: return try: self.sliderCont.valueChanged.disconnect() self.sliderCont.sliderReleased.disconnect() except RuntimeError: pass self.contCorrection = self.slider2Cont(self.sliderCont.value()) self.contValue.setText(str("{:+d}".format(self.contCorrection))) # force to recalculate the spline self.layer.autoSpline = True self.dataChanged.emit( 3) # no postprocessing and no camera profile stuff self.sliderCont.valueChanged.connect( contUpdate) # send new value as parameter self.sliderCont.sliderReleased.connect(lambda: contUpdate( self.sliderCont.value())) # signal has no parameter self.sliderCont.valueChanged.connect( contUpdate) # send new value as parameter self.sliderCont.sliderReleased.connect(lambda: contUpdate( self.sliderCont.value())) # signal has no parameter # saturation slider self.sliderSat = QbLUeSlider(Qt.Horizontal) self.sliderSat.setStyleSheet( QbLUeSlider.bLueSliderDefaultColorStylesheet) self.sliderSat.setRange(0, 100) self.sliderSat.setSingleStep(1) satLabel = QLabel() satLabel.setText("Sat.") self.satValue = QLabel() font = self.satValue.font() metrics = QFontMetrics(font) w = metrics.width("+10") h = metrics.height() self.satValue.setMinimumSize(w, h) self.satValue.setMaximumSize(w, h) self.satValue.setText( str("{:+d}".format(self.slider2Sat(self.sliderSat.value())))) """sat done event handler""" def satUpdate(value): self.satValue.setText( str("{:+d}".format(self.slider2Sat(self.sliderSat.value())))) # move not yet terminated or value not modified if self.sliderSat.isSliderDown() or self.slider2Sat( value) == self.satCorrection: return try: self.sliderSat.valueChanged.disconnect() self.sliderSat.sliderReleased.disconnect() except RuntimeError: pass self.satCorrection = self.slider2Sat(self.sliderSat.value()) self.dataChanged.emit( 3) # no post processing and no camera profile stuff self.sliderSat.valueChanged.connect( satUpdate) # send new value as parameter self.sliderSat.sliderReleased.connect(lambda: satUpdate( self.sliderSat.value())) # signal has no parameter self.sliderSat.valueChanged.connect( satUpdate) # send new value as parameter self.sliderSat.sliderReleased.connect(lambda: satUpdate( self.sliderSat.value())) # signal has no parameter # layout l = QVBoxLayout() l.addWidget(self.listWidget3) hl01 = QHBoxLayout() hl01.addWidget(QLabel('Camera Profile')) hl01.addWidget(self.cameraProfilesCombo) l.addLayout(hl01) hl0 = QHBoxLayout() hl0.addWidget(QLabel('Denoising')) hl0.addWidget(self.denoiseCombo) l.addLayout(hl0) hl00 = QHBoxLayout() hl00.addWidget(QLabel('Overexp. Restoration')) hl00.addWidget(self.overexpCombo) l.addLayout(hl00) hl1 = QHBoxLayout() hl1.addWidget(self.expLabel) hl1.addWidget(self.expValue) hl1.addWidget(self.sliderExp) l.addLayout(hl1) hl8 = QHBoxLayout() hl8.addWidget(brLabel) hl8.addWidget(self.brValue) hl8.addWidget(self.sliderBrightness) l.addLayout(hl8) l.addWidget(self.listWidget1) vl1 = QVBoxLayout() vl1.addWidget(self.listWidget2) gb1 = QGroupBox() gb1.setTitle('White Balance') hl2 = QHBoxLayout() hl2.addWidget(self.tempLabel) hl2.addWidget(self.tempValue) hl2.addWidget(self.sliderTemp) hl3 = QHBoxLayout() hl3.addWidget(self.tintLabel) hl3.addWidget(self.tintValue) hl3.addWidget(self.sliderTint) vl1.addLayout(hl2) vl1.addLayout(hl3) gb1.setLayout(vl1) l.addWidget(gb1) hl4 = QHBoxLayout() hl4.addWidget(self.contLabel) hl4.addWidget(self.contValue) hl4.addWidget(self.sliderCont) hl7 = QHBoxLayout() hl7.addWidget(satLabel) hl7.addWidget(self.satValue) hl7.addWidget(self.sliderSat) # separator sep = QFrame() sep.setFrameShape(QFrame.HLine) sep.setFrameShadow(QFrame.Sunken) l.addWidget(sep) l.addLayout(hl4) l.addLayout(hl7) l.addStretch(1) self.setLayout(l) self.adjustSize() self.setDefaults() self.setWhatsThis("""<b>Development of raw files</b><br> <b>Default settings</b> are a good starting point.<br> A <b>Tone Curve</b> is applied to the raw image prior to postprocessing.<br> The cuvre can be edited by checking the option <b>Show Tone Curve</b>; this option works best with manual exposure.<br> <b>Contrast</b> correction is based on an automatic algorithm well suited to multi-mode histograms.<br> <b>Brightness, Contrast</b> and <b>Saturation</b> levels</b> are adjustable with the correponding sliders.<br> The <b>Contrast Curve</b> can be edited manually by checking the option <b>Show Contrast Curve</b>.<br> Uncheck <b>Auto Expose</b> to adjust the exposure manually.<br> The <b>OverExp. Rest.</b> slider controls the mode of restoration of overexposed areas. Valid values are 0 to 3 (0=clip;1=unclip;2=blend;3=rebuild); (with Auto Exposed checked the mode is clip).<br> """) # end of setWhatsThis
class Ui_GroupBox(object): def setupUi(self, GroupBox): if not GroupBox.objectName(): GroupBox.setObjectName(u"GroupBox") GroupBox.resize(535, 520) sizePolicy = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Minimum) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(GroupBox.sizePolicy().hasHeightForWidth()) GroupBox.setSizePolicy(sizePolicy) self.verticalLayout_2 = QVBoxLayout(GroupBox) self.verticalLayout_2.setObjectName(u"verticalLayout_2") self.groupBox_occupancy_histogram = QGroupBox(GroupBox) self.groupBox_occupancy_histogram.setObjectName( u"groupBox_occupancy_histogram") self.verticalLayout = QVBoxLayout(self.groupBox_occupancy_histogram) self.verticalLayout.setObjectName(u"verticalLayout") self.horizontalLayout = QHBoxLayout() self.horizontalLayout.setObjectName(u"horizontalLayout") self.label_56 = QLabel(self.groupBox_occupancy_histogram) self.label_56.setObjectName(u"label_56") self.label_56.setMaximumSize(QSize(16777215, 16777215)) self.label_56.setAlignment(Qt.AlignRight | Qt.AlignTrailing | Qt.AlignVCenter) self.horizontalLayout.addWidget(self.label_56) self.lineEdit_bins = QLineEdit(self.groupBox_occupancy_histogram) self.lineEdit_bins.setObjectName(u"lineEdit_bins") self.lineEdit_bins.setMinimumSize(QSize(50, 0)) self.lineEdit_bins.setMaximumSize(QSize(50, 16777215)) self.horizontalLayout.addWidget(self.lineEdit_bins) self.horizontalSpacer_3 = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) self.horizontalLayout.addItem(self.horizontalSpacer_3) self.label_55 = QLabel(self.groupBox_occupancy_histogram) self.label_55.setObjectName(u"label_55") self.label_55.setMaximumSize(QSize(16777215, 16777215)) self.label_55.setAlignment(Qt.AlignRight | Qt.AlignTrailing | Qt.AlignVCenter) self.horizontalLayout.addWidget(self.label_55) self.lineEdit_minimum = QLineEdit(self.groupBox_occupancy_histogram) self.lineEdit_minimum.setObjectName(u"lineEdit_minimum") self.lineEdit_minimum.setMinimumSize(QSize(50, 0)) self.lineEdit_minimum.setMaximumSize(QSize(50, 16777215)) self.horizontalLayout.addWidget(self.lineEdit_minimum) self.horizontalSpacer_2 = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) self.horizontalLayout.addItem(self.horizontalSpacer_2) self.label_17 = QLabel(self.groupBox_occupancy_histogram) self.label_17.setObjectName(u"label_17") self.label_17.setAlignment(Qt.AlignRight | Qt.AlignTrailing | Qt.AlignVCenter) self.horizontalLayout.addWidget(self.label_17) self.lineEdit_maximum = QLineEdit(self.groupBox_occupancy_histogram) self.lineEdit_maximum.setObjectName(u"lineEdit_maximum") self.lineEdit_maximum.setMinimumSize(QSize(50, 0)) self.lineEdit_maximum.setMaximumSize(QSize(50, 16777215)) self.horizontalLayout.addWidget(self.lineEdit_maximum) self.verticalLayout.addLayout(self.horizontalLayout) self.horizontalLayout_7 = QHBoxLayout() self.horizontalLayout_7.setObjectName(u"horizontalLayout_7") self.checkBox_cumulative_histogram = QCheckBox( self.groupBox_occupancy_histogram) self.checkBox_cumulative_histogram.setObjectName( u"checkBox_cumulative_histogram") self.horizontalLayout_7.addWidget(self.checkBox_cumulative_histogram) self.horizontalSpacer_12 = QSpacerItem(40, 20, QSizePolicy.Fixed, QSizePolicy.Minimum) self.horizontalLayout_7.addItem(self.horizontalSpacer_12) self.checkBox_stacked_histogram = QCheckBox( self.groupBox_occupancy_histogram) self.checkBox_stacked_histogram.setObjectName( u"checkBox_stacked_histogram") self.horizontalLayout_7.addWidget(self.checkBox_stacked_histogram) self.horizontalSpacer_11 = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) self.horizontalLayout_7.addItem(self.horizontalSpacer_11) self.verticalLayout.addLayout(self.horizontalLayout_7) self.horizontalLayout_6 = QHBoxLayout() self.horizontalLayout_6.setObjectName(u"horizontalLayout_6") self.checkBox_color_segments_occupancy = QCheckBox( self.groupBox_occupancy_histogram) self.checkBox_color_segments_occupancy.setObjectName( u"checkBox_color_segments_occupancy") self.checkBox_color_segments_occupancy.setChecked(True) self.horizontalLayout_6.addWidget( self.checkBox_color_segments_occupancy) self.horizontalSpacer_9 = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) self.horizontalLayout_6.addItem(self.horizontalSpacer_9) self.verticalLayout.addLayout(self.horizontalLayout_6) self.horizontalLayout_2 = QHBoxLayout() self.horizontalLayout_2.setObjectName(u"horizontalLayout_2") self.horizontalSpacer = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) self.horizontalLayout_2.addItem(self.horizontalSpacer) self.pushButton_save_occupancy = QPushButton( self.groupBox_occupancy_histogram) self.pushButton_save_occupancy.setObjectName( u"pushButton_save_occupancy") self.horizontalLayout_2.addWidget(self.pushButton_save_occupancy) self.pushButton_plot_occupancy = QPushButton( self.groupBox_occupancy_histogram) self.pushButton_plot_occupancy.setObjectName( u"pushButton_plot_occupancy") self.pushButton_plot_occupancy.setAutoDefault(False) self.horizontalLayout_2.addWidget(self.pushButton_plot_occupancy) self.verticalLayout.addLayout(self.horizontalLayout_2) self.verticalLayout_2.addWidget(self.groupBox_occupancy_histogram) self.verticalSpacer_2 = QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding) self.verticalLayout_2.addItem(self.verticalSpacer_2) self.groupBox_nb_connections = QGroupBox(GroupBox) self.groupBox_nb_connections.setObjectName(u"groupBox_nb_connections") self.verticalLayout_3 = QVBoxLayout(self.groupBox_nb_connections) self.verticalLayout_3.setObjectName(u"verticalLayout_3") self.horizontalLayout_5 = QHBoxLayout() self.horizontalLayout_5.setObjectName(u"horizontalLayout_5") self.checkBox_color_segments_timeseries = QCheckBox( self.groupBox_nb_connections) self.checkBox_color_segments_timeseries.setObjectName( u"checkBox_color_segments_timeseries") self.checkBox_color_segments_timeseries.setChecked(True) self.horizontalLayout_5.addWidget( self.checkBox_color_segments_timeseries) self.horizontalSpacer_7 = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) self.horizontalLayout_5.addItem(self.horizontalSpacer_7) self.verticalLayout_3.addLayout(self.horizontalLayout_5) self.horizontalLayout_4 = QHBoxLayout() self.horizontalLayout_4.setObjectName(u"horizontalLayout_4") self.horizontalSpacer_5 = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) self.horizontalLayout_4.addItem(self.horizontalSpacer_5) self.pushButton_save_timeseries = QPushButton( self.groupBox_nb_connections) self.pushButton_save_timeseries.setObjectName( u"pushButton_save_timeseries") self.horizontalLayout_4.addWidget(self.pushButton_save_timeseries) self.pushButton_plot_timeseries = QPushButton( self.groupBox_nb_connections) self.pushButton_plot_timeseries.setObjectName( u"pushButton_plot_timeseries") self.pushButton_plot_timeseries.setAutoDefault(False) self.horizontalLayout_4.addWidget(self.pushButton_plot_timeseries) self.verticalLayout_3.addLayout(self.horizontalLayout_4) self.verticalLayout_2.addWidget(self.groupBox_nb_connections) self.verticalSpacer = QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding) self.verticalLayout_2.addItem(self.verticalSpacer) self.groupBox_joint_occupancy = QGroupBox(GroupBox) self.groupBox_joint_occupancy.setObjectName( u"groupBox_joint_occupancy") self.verticalLayout_4 = QVBoxLayout(self.groupBox_joint_occupancy) self.verticalLayout_4.setObjectName(u"verticalLayout_4") self.horizontalLayout_10 = QHBoxLayout() self.horizontalLayout_10.setObjectName(u"horizontalLayout_10") self.radioButton_scatter = QRadioButton(self.groupBox_joint_occupancy) self.radioButton_scatter.setObjectName(u"radioButton_scatter") self.radioButton_scatter.setChecked(True) self.horizontalLayout_10.addWidget(self.radioButton_scatter) self.label_3 = QLabel(self.groupBox_joint_occupancy) self.label_3.setObjectName(u"label_3") self.horizontalLayout_10.addWidget(self.label_3) self.lineEdit_scatter_size = QLineEdit(self.groupBox_joint_occupancy) self.lineEdit_scatter_size.setObjectName(u"lineEdit_scatter_size") self.lineEdit_scatter_size.setMaximumSize(QSize(50, 16777215)) self.horizontalLayout_10.addWidget(self.lineEdit_scatter_size) self.horizontalSpacer_10 = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) self.horizontalLayout_10.addItem(self.horizontalSpacer_10) self.verticalLayout_4.addLayout(self.horizontalLayout_10) self.horizontalLayout_3 = QHBoxLayout() self.horizontalLayout_3.setObjectName(u"horizontalLayout_3") self.radioButton_heatmap = QRadioButton(self.groupBox_joint_occupancy) self.radioButton_heatmap.setObjectName(u"radioButton_heatmap") self.horizontalLayout_3.addWidget(self.radioButton_heatmap) self.horizontalSpacer_4 = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) self.horizontalLayout_3.addItem(self.horizontalSpacer_4) self.pushButton_save_jo = QPushButton(self.groupBox_joint_occupancy) self.pushButton_save_jo.setObjectName(u"pushButton_save_jo") self.horizontalLayout_3.addWidget(self.pushButton_save_jo) self.pushButton_plot_jo = QPushButton(self.groupBox_joint_occupancy) self.pushButton_plot_jo.setObjectName(u"pushButton_plot_jo") self.pushButton_plot_jo.setAutoDefault(False) self.horizontalLayout_3.addWidget(self.pushButton_plot_jo) self.verticalLayout_4.addLayout(self.horizontalLayout_3) self.verticalLayout_2.addWidget(self.groupBox_joint_occupancy) self.retranslateUi(GroupBox) QMetaObject.connectSlotsByName(GroupBox) # setupUi def retranslateUi(self, GroupBox): GroupBox.setWindowTitle( QCoreApplication.translate("GroupBox", u"GroupBox", None)) self.groupBox_occupancy_histogram.setTitle( QCoreApplication.translate("GroupBox", u"Occupancy histogram", None)) self.label_56.setText( QCoreApplication.translate("GroupBox", u"# of bins", None)) self.lineEdit_bins.setText( QCoreApplication.translate("GroupBox", u"10", None)) self.label_55.setText( QCoreApplication.translate("GroupBox", u"min. occupancy", None)) self.lineEdit_minimum.setText( QCoreApplication.translate("GroupBox", u"0.0", None)) self.label_17.setText( QCoreApplication.translate("GroupBox", u"max. occupancy", None)) self.lineEdit_maximum.setText( QCoreApplication.translate("GroupBox", u"1.0", None)) self.checkBox_cumulative_histogram.setText( QCoreApplication.translate("GroupBox", u"cumulative", None)) self.checkBox_stacked_histogram.setText( QCoreApplication.translate("GroupBox", u"stacked", None)) #if QT_CONFIG(tooltip) self.checkBox_color_segments_occupancy.setToolTip( QCoreApplication.translate( "GroupBox", u"<html><head/><body><p align=\"justify\">Toggle if histogram bars are colored by segment or molecule. With colors turned on, comparing to other analyses is not possible.</p></body></html>", None)) #endif // QT_CONFIG(tooltip) self.checkBox_color_segments_occupancy.setText( QCoreApplication.translate("GroupBox", u"color by segment", None)) self.pushButton_save_occupancy.setText( QCoreApplication.translate("GroupBox", u"Data", None)) #if QT_CONFIG(tooltip) self.pushButton_plot_occupancy.setToolTip( QCoreApplication.translate( "GroupBox", u"<html><head/><body><p>Compute histogram of H bond occupancies. Counts the number of H bonds with an occupancy equal or greater than the respective value.</p></body></html>", None)) #endif // QT_CONFIG(tooltip) self.pushButton_plot_occupancy.setText( QCoreApplication.translate("GroupBox", u"Plot", None)) self.groupBox_nb_connections.setTitle( QCoreApplication.translate("GroupBox", u"Number of connections time series", None)) #if QT_CONFIG(tooltip) self.checkBox_color_segments_timeseries.setToolTip( QCoreApplication.translate( "GroupBox", u"<html><head/><body><p align=\"justify\">Toggle if histogram bars are colored by segment or molecule. With colors turned on, comparing to other analyses is not possible.</p></body></html>", None)) #endif // QT_CONFIG(tooltip) self.checkBox_color_segments_timeseries.setText( QCoreApplication.translate("GroupBox", u"color by segment", None)) self.pushButton_save_timeseries.setText( QCoreApplication.translate("GroupBox", u"Data", None)) #if QT_CONFIG(tooltip) self.pushButton_plot_timeseries.setToolTip( QCoreApplication.translate( "GroupBox", u"<html><head/><body><p align=\"justify\">Compute the number of H bonds per frame.</p></body></html>", None)) #endif // QT_CONFIG(tooltip) self.pushButton_plot_timeseries.setText( QCoreApplication.translate("GroupBox", u"Plot", None)) self.groupBox_joint_occupancy.setTitle( QCoreApplication.translate("GroupBox", u"Joint Occupancy", None)) self.radioButton_scatter.setText( QCoreApplication.translate("GroupBox", u"scatter plot", None)) self.label_3.setText( QCoreApplication.translate("GroupBox", u"with dot size", None)) self.lineEdit_scatter_size.setText( QCoreApplication.translate("GroupBox", u"1", None)) self.lineEdit_scatter_size.setPlaceholderText( QCoreApplication.translate("GroupBox", u"0 - 100", None)) self.radioButton_heatmap.setText( QCoreApplication.translate("GroupBox", u"heatmap", None)) self.pushButton_save_jo.setText( QCoreApplication.translate("GroupBox", u"Data", None)) #if QT_CONFIG(tooltip) self.pushButton_plot_jo.setToolTip( QCoreApplication.translate( "GroupBox", u"<html><head/><body><p align=\"justify\">Compute the joint occupancy of the H bond network. The joint occupancy is true, if all H bonds of the network are present in a frame and false otherwise.</p></body></html>", None)) #endif // QT_CONFIG(tooltip) self.pushButton_plot_jo.setText( QCoreApplication.translate("GroupBox", u"Plot", None))
class App(QWidget): def __init__(self, bk, prefs): super().__init__() self.bk = bk self.prefs = prefs self.update = False # Install translator for the DOCXImport plugin dialog. # Use the Sigil language setting unless manually overridden. plugin_translator = QTranslator() if prefs['language_override'] is not None: print('Plugin preferences language override in effect') qmf = '{}_{}'.format(bk._w.plugin_name.lower(), prefs['language_override']) else: qmf = '{}_{}'.format(bk._w.plugin_name.lower(), bk.sigil_ui_lang) print( qmf, os.path.join(bk._w.plugin_dir, bk._w.plugin_name, 'translations')) plugin_translator.load( qmf, os.path.join(bk._w.plugin_dir, bk._w.plugin_name, 'translations')) print(QCoreApplication.instance().installTranslator(plugin_translator)) self._ok_to_close = False self.FTYPE_MAP = { 'smap': { 'title': _translate('App', 'Select custom style-map file'), 'defaultextension': '.txt', 'filetypes': 'Text Files (*.txt);;All files (*.*)', }, 'css': { 'title': _translate('App', 'Select custom CSS file'), 'defaultextension': '.css', 'filetypes': 'CSS Files (*.css)', }, 'docx': { 'title': _translate('App', 'Select DOCX file'), 'defaultextension': '.docx', 'filetypes': 'DOCX Files (*.docx)', }, } # Check online github files for newer version if self.prefs['check_for_updates']: self.update, self.newversion = self.check_for_update() self.initUI() def initUI(self): main_layout = QVBoxLayout(self) self.setWindowTitle('DOCXImport') self.upd_layout = QVBoxLayout() self.update_label = QLabel() self.update_label.setAlignment(Qt.AlignCenter) self.upd_layout.addWidget(self.update_label) self.get_update_button = QPushButton() self.get_update_button.clicked.connect(self.get_update) self.upd_layout.addWidget(self.get_update_button) main_layout.addLayout(self.upd_layout) if not self.update: self.update_label.hide() self.get_update_button.hide() self.details_grid = QGridLayout() self.epub2_select = QRadioButton() self.epub2_select.setText('EPUB2') self.epubType = QButtonGroup() self.epubType.addButton(self.epub2_select) self.details_grid.addWidget(self.epub2_select, 0, 0, 1, 1) self.checkbox_get_updates = QCheckBox() self.details_grid.addWidget(self.checkbox_get_updates, 0, 1, 1, 1) self.epub3_select = QRadioButton() self.epub3_select.setText('EPUB3') self.epubType.addButton(self.epub3_select) self.details_grid.addWidget(self.epub3_select, 1, 0, 1, 1) main_layout.addLayout(self.details_grid) self.checkbox_get_updates.setChecked(self.prefs['check_for_updates']) if self.prefs['epub_version'] == '2.0': self.epub2_select.setChecked(True) elif self.prefs['epub_version'] == '3.0': self.epub3_select.setChecked(True) else: self.epub2_select.setChecked(True) self.groupBox = QGroupBox() self.groupBox.setTitle('') self.verticalLayout_2 = QVBoxLayout(self.groupBox) self.docx_grid = QGridLayout() self.docx_label = QLabel() self.docx_grid.addWidget(self.docx_label, 0, 0, 1, 1) self.docx_path = QLineEdit() self.docx_grid.addWidget(self.docx_path, 1, 0, 1, 1) self.choose_docx_button = QPushButton() self.choose_docx_button.setText('...') self.docx_grid.addWidget(self.choose_docx_button, 1, 1, 1, 1) self.verticalLayout_2.addLayout(self.docx_grid) self.choose_docx_button.clicked.connect( lambda: self.fileChooser('docx', self.docx_path)) if len(self.prefs['lastDocxPath']): self.docx_path.setText(self.prefs['lastDocxPath']) self.docx_path.setEnabled(False) self.smap_grid = QGridLayout() self.checkbox_smap = QCheckBox(self.groupBox) self.smap_grid.addWidget(self.checkbox_smap, 0, 0, 1, 1) self.cust_smap_path = QLineEdit(self.groupBox) self.smap_grid.addWidget(self.cust_smap_path, 1, 0, 1, 1) self.choose_smap_button = QPushButton(self.groupBox) self.choose_smap_button.setText('...') self.smap_grid.addWidget(self.choose_smap_button, 1, 1, 1, 1) self.verticalLayout_2.addLayout(self.smap_grid) self.checkbox_smap.setChecked(self.prefs['useSmap']) self.checkbox_smap.stateChanged.connect(lambda: self.chkBoxActions( self.checkbox_smap, self.choose_smap_button)) self.choose_smap_button.clicked.connect( lambda: self.fileChooser('smap', self.cust_smap_path, self. checkbox_smap, self.choose_smap_button)) if len(self.prefs['useSmapPath']): self.cust_smap_path.setText(self.prefs['useSmapPath']) self.cust_smap_path.setEnabled(False) self.chkBoxActions(self.checkbox_smap, self.choose_smap_button) self.css_grid = QGridLayout() self.checkbox_css = QCheckBox(self.groupBox) self.css_grid.addWidget(self.checkbox_css, 0, 0, 1, 1) self.cust_css_path = QLineEdit(self.groupBox) self.css_grid.addWidget(self.cust_css_path, 1, 0, 1, 1) self.choose_css_button = QPushButton(self.groupBox) self.choose_css_button.setText('...') self.css_grid.addWidget(self.choose_css_button, 1, 1, 1, 1) self.verticalLayout_2.addLayout(self.css_grid) self.checkbox_css.setChecked(self.prefs['useCss']) self.checkbox_css.stateChanged.connect(lambda: self.chkBoxActions( self.checkbox_css, self.choose_css_button)) self.choose_css_button.clicked.connect( lambda: self.fileChooser('css', self.cust_css_path, self. checkbox_css, self.choose_css_button)) if len(self.prefs['useCssPath']): self.cust_css_path.setText(self.prefs['useCssPath']) self.cust_css_path.setEnabled(False) self.chkBoxActions(self.checkbox_css, self.choose_css_button) main_layout.addWidget(self.groupBox) self.checkbox_debug = QCheckBox() main_layout.addWidget(self.checkbox_debug) self.checkbox_debug.setChecked(self.prefs['debug']) spacerItem = QSpacerItem(20, 15, QSizePolicy.Minimum, QSizePolicy.Expanding) main_layout.addItem(spacerItem) button_box = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) button_box.accepted.connect(self._ok_clicked) button_box.rejected.connect(self._cancel_clicked) main_layout.addWidget(button_box) self.retranslateUi(self) if self.prefs['qt_geometry'] is not None: try: self.restoreGeometry( QByteArray.fromHex( self.prefs['qt_geometry'].encode('ascii'))) except: pass self.show() def retranslateUi(self, App): self.update_label.setText(_translate('App', 'Plugin Update Available')) self.get_update_button.setText(_translate('App', 'Go to download page')) self.checkbox_get_updates.setText( _translate('App', 'Check for plugin updates')) self.docx_label.setText(_translate('App', 'DOCX File to import')) self.checkbox_smap.setText(_translate('App', 'Use Custom Style Map')) self.checkbox_css.setText(_translate('App', 'Use Custom CSS')) self.checkbox_debug.setText( _translate('App', 'Debug Mode (change takes effect next plugin run)')) def fileChooser(self, ftype, qlineedit, qcheck=None, qbutton=None): options = QFileDialog.Options() options |= QFileDialog.DontUseNativeDialog title = self.FTYPE_MAP[ftype]['title'] startfolder = self.prefs['lastDir'][ftype] ffilter = self.FTYPE_MAP[ftype]['filetypes'] inpath, _ = QFileDialog.getOpenFileName(self, title, startfolder, ffilter, options=options) if len(inpath): qlineedit.setEnabled(True) qlineedit.setText(os.path.normpath(inpath)) self.prefs['lastDir'][ftype] = os.path.dirname(inpath) qlineedit.setEnabled(False) else: if qcheck is not None: qcheck.setChecked(False) if qbutton is not None: qbutton.setEnabled(False) def chkBoxActions(self, chk, btn): btn.setEnabled(chk.isChecked()) def cmdDo(self): global _DETAILS self.prefs['qt_geometry'] = self.saveGeometry().toHex().data().decode( 'ascii') self.prefs['check_for_updates'] = self.checkbox_get_updates.isChecked() self.prefs['epub_version'] = self.epubType.checkedButton().text( )[-1] + '.0' self.prefs['debug'] = self.checkbox_debug.isChecked() _DETAILS['vers'] = self.epubType.checkedButton().text()[-1] + '.0' self.prefs['useSmap'] = self.checkbox_smap.isChecked() if self.checkbox_smap.isChecked(): if len(self.cust_smap_path.text()): self.prefs['useSmapPath'] = self.cust_smap_path.text() _DETAILS['smap'] = (self.checkbox_smap.isChecked(), self.cust_smap_path.text()) else: # Message box that no file is selected return self.prefs['useCss'] = self.checkbox_css.isChecked() if self.checkbox_css.isChecked(): if len(self.cust_css_path.text()): self.prefs['useCssPath'] = self.cust_css_path.text() _DETAILS['css'] = (self.checkbox_css.isChecked(), self.cust_css_path.text()) else: # Message box that no file is selected return if len(self.docx_path.text()): self.prefs['lastDocxPath'] = self.docx_path.text() _DETAILS['docx'] = self.docx_path.text() else: # Message box that no file is selected return def check_for_update(self): '''Use updatecheck.py to check for newer versions of the plugin''' chk = UpdateChecker(self.prefs['last_time_checked'], self.bk._w) update_available, online_version, time = chk.update_info() # update preferences with latest date/time/version self.prefs['last_time_checked'] = time if online_version is not None: self.prefs['last_online_version'] = online_version if update_available: return (True, online_version) return (False, online_version) def get_update(self): url = DOWNLOAD_PAGE if self.update: latest = '/tag/v{}'.format(self.newversion) url = url + latest webbrowser.open_new_tab(url) def _ok_clicked(self): self._ok_to_close = True self.cmdDo() self.bk.savePrefs(self.prefs) QCoreApplication.instance().quit() def _cancel_clicked(self): self._ok_to_close = True '''Close aborting any changes''' self.prefs['qt_geometry'] = self.saveGeometry().toHex().data().decode( 'ascii') self.prefs['check_for_updates'] = self.checkbox_get_updates.isChecked() self.prefs['debug'] = self.checkbox_debug.isChecked() self.bk.savePrefs(self.prefs) QCoreApplication.instance().quit() def closeEvent(self, event): if self._ok_to_close: event.accept() # let the window close else: self._cancel_clicked()
class DataBrowserMain(QWidget): sliceUpdated = Signal(int, int, int, int) def __init__(self, parent): super(DataBrowserMain, self).__init__(parent) # data import self.brkraw_obj = self.parent().brkraw_obj self.selectedScan = None self.selectedScanTR = None self.set_viewer_frame() self.set_controller_frame() self.set_gridlayouts() self.set_font() # self.set_palette() # TODO self.set_size() self.set_objectnames() self.set_texts() self.ratio_container = [] self.init_connection() self.inactivate_widgets() # Inactivate during startup def init_connection(self): self.parent().dataSelected.connect( self.selectScanEvent) # run selectScanEvent when data selected self.event_timer = QTimer() self.event_timer.timeout.connect(self.sliceUpdateEvent) # self.sliceUpdated.connect(self.updateImage) self.xaxis_slider.valueChanged.connect(self.xaxis_spinbox.setValue) self.xaxis_spinbox.valueChanged.connect(self.xaxis_slider.setValue) self.yaxis_slider.valueChanged.connect(self.yaxis_spinbox.setValue) self.yaxis_spinbox.valueChanged.connect(self.yaxis_slider.setValue) self.zaxis_slider.valueChanged.connect(self.zaxis_spinbox.setValue) self.zaxis_spinbox.valueChanged.connect(self.zaxis_slider.setValue) self.frame_slider.valueChanged.connect(self.frame_spinbox.setValue) self.frame_spinbox.valueChanged.connect(self.frame_slider.setValue) self.axial_view.pointed.connect(self.axialview_pointing_event) self.sagittal_view.pointed.connect(self.sagittalview_pointing_event) self.coronal_view.pointed.connect(self.coronalview_pointing_event) self.connect_sliders_to_update() def sagittalview_pointing_event(self, pos_x, pos_y, meta): max_x = self.yaxis_slider.maximum() max_y = self.zaxis_slider.maximum() # print(pos_x, pos_y, max_x, max_y) self.yaxis_slider.setValue(int(max_x * pos_x)) self.zaxis_slider.setValue(max_y - int(max_y * pos_y)) # print(int(max_x * pos_x), int(max_y * pos_y)) def axialview_pointing_event(self, pos_x, pos_y, meta): max_x = self.yaxis_slider.maximum() max_y = self.xaxis_slider.maximum() # print(pos_x, pos_y, max_x, max_y) self.yaxis_slider.setValue(int(max_x * pos_x)) self.xaxis_slider.setValue(int(max_y * pos_y)) # print(int(max_x * pos_x), int(max_y * pos_y)) def coronalview_pointing_event(self, pos_x, pos_y, meta): max_x = self.xaxis_slider.maximum() max_y = self.zaxis_slider.maximum() # print(pos_x, pos_y, max_x, max_y) self.xaxis_slider.setValue(int(max_x * pos_x)) self.zaxis_slider.setValue(max_y - int(max_y * pos_y)) # print(int(max_x * pos_x), int(max_y * pos_y)) def sliderChangeEvent(self): self.event_timer.start(10) def sliceUpdateEvent(self): # This will executed only when timer timeout x = self.xaxis_slider.value() y = self.yaxis_slider.value() z = self.zaxis_slider.value() t = self.frame_slider.value() self.sliceUpdated.emit(x, y, z, t) self.event_timer.stop() @staticmethod def slice_data(dataobj, slice_orient, slice_num): if slice_orient == 'axial': sliced_data = dataobj[:, :, slice_num] elif slice_orient == 'sagittal': sliced_data = dataobj[:, slice_num, ::-1] elif slice_orient == 'coronal': sliced_data = dataobj[slice_num, :, ::-1] else: popup_error_dialog(UnexpectedError.message) return None return sliced_data def updateImage(self, x, y, z, frame): if len(self.selectedScan.shape) == 4: dataobj = self.selectedScan[:, :, :, frame] else: dataobj = self.selectedScan[...] data_xy = self.slice_data(dataobj, 'axial', z) data_yz = self.slice_data(dataobj, 'sagittal', x) data_xz = self.slice_data(dataobj, 'coronal', y) ratio_xy, ratio_yz, ratio_xz = self.ratio_container # ratio_xy, ratio_yz, ratio_xz = 1, 1, 1 qm_xy = convert_arr2qpixmap(data_xy, ratio_xy) qm_yz = convert_arr2qpixmap(data_yz, ratio_yz) qm_xz = convert_arr2qpixmap(data_xz, ratio_xz) self.axial_view.setPixmap(qm_xy) self.sagittal_view.setPixmap(qm_yz) self.coronal_view.setPixmap(qm_xz) def selectScanEvent(self, delivery_package: list): """ this event is occurring when a scan selected on scanlist """ self.axial_view.setEnabled(True) self.sagittal_view.setEnabled(True) self.coronal_view.setEnabled(True) self.selectedScan, affine, resol, self.selectedScanTR, is_localizer = delivery_package self.selectedScanTR /= 1000 from slfmri.imgman import reorient_to_ras, determine_slice_plane slice_plane_ref = dict(sagittal=0, coronal=1, axial=2) if is_localizer: img_container = dict() for i, aff in enumerate(affine): size = config.get('ImageViewer', 'size') data = self.selectedScan[..., i] slice_plane = determine_slice_plane(2, aff, resol) ras_data, ras_resol = reorient_to_ras(data[:, :, np.newaxis], aff, resol) slice_axis = slice_plane_ref[slice_plane] ras_data = ras_data.mean(slice_axis) ras_resol = np.delete(ras_resol, slice_axis) qpixmap = convert_arr2qpixmap(ras_data, ras_resol, size) img_container[slice_plane] = qpixmap self.update_axisview(img_container) else: # other than localizer self.init_data(self.selectedScan) matrix_size = np.asarray(self.selectedScan.shape) resol = np.asarray(resol) fov = matrix_size[:3] * resol self.ratio_container = [ fov[0] / fov[1], fov[1] / fov[2], fov[0] / fov[2] ] # reset value init_x, init_y, init_z = (np.asarray(self.selectedScan.shape[:3]) / 2.0).astype(int) init_f = 0 self.disconnect_sliders_to_update() self.xaxis_slider.setValue(init_x) self.yaxis_slider.setValue(init_y) self.zaxis_slider.setValue(init_z) self.frame_slider.setValue(init_f) self.connect_sliders_to_update() self.updateImage(init_x, init_y, init_z, init_f) def connect_sliders_to_update(self): # connect to check slice update self.xaxis_slider.valueChanged.connect(self.sliderChangeEvent) self.yaxis_slider.valueChanged.connect(self.sliderChangeEvent) self.zaxis_slider.valueChanged.connect(self.sliderChangeEvent) self.frame_slider.valueChanged.connect(self.sliderChangeEvent) def disconnect_sliders_to_update(self): # disconnect to check slice update self.xaxis_slider.valueChanged.disconnect(self.sliderChangeEvent) self.yaxis_slider.valueChanged.disconnect(self.sliderChangeEvent) self.zaxis_slider.valueChanged.disconnect(self.sliderChangeEvent) self.frame_slider.valueChanged.disconnect(self.sliderChangeEvent) def init_data(self, dataobj): self.slicecontrol_pane.setEnabled(True) dim = len(dataobj.shape) if dim == 3: size_x, size_y, size_z = dataobj.shape size_frame = None elif dim == 4: size_x, size_y, size_z, size_frame = dataobj.shape else: popup_error_dialog(UnexpectedError.message) return None # init sliders and spinboxes self.xaxis_slider.setRange(0, size_x - 1) self.yaxis_slider.setRange(0, size_y - 1) self.zaxis_slider.setRange(0, size_z - 1) self.xaxis_spinbox.setRange(0, size_x - 1) self.yaxis_spinbox.setRange(0, size_y - 1) self.zaxis_spinbox.setRange(0, size_z - 1) if dim == 3: self.frame_label.setDisabled(True) self.frame_slider.setDisabled(True) self.frame_spinbox.setDisabled(True) else: self.frame_label.setEnabled(True) self.frame_slider.setEnabled(True) self.frame_spinbox.setEnabled(True) self.frame_slider.setRange(0, size_frame - 1) self.frame_spinbox.setRange(0, size_frame - 1) def update_axisview(self, img_container: dict): for view_plane, pixmap in img_container.items(): if view_plane == 'axial': self.axial_view.setPixmap(pixmap) elif view_plane == 'sagittal': self.sagittal_view.setPixmap(pixmap) else: self.coronal_view.setPixmap(pixmap) def inactivate_widgets(self): self.slicecontrol_pane.setDisabled(True) self.graph_frame.setDisabled(True) def set_navigationmode(self): # mouse click will navigate slice. pass def set_drawingmode(self): # roi drawing function pass def mask_data_handler(self): # mask later handler pass def slider_event_related(self): # slider for slicing. pass def set_viewer_frame(self): self.imageframe = QFrame(self) self.axial_view = SliceViewer(self.imageframe) self.axial_view.setDisabled(True) self.sagittal_view = SliceViewer(self.imageframe) self.sagittal_view.setDisabled(True) self.coronal_view = SliceViewer(self.imageframe) self.coronal_view.setDisabled(True) # TODO: Will reactivate these on later version # self.axial_title = QLabel(self.imageframe) # self.coronal_title = QLabel(self.imageframe) # self.sagittal_title = QLabel(self.imageframe) # # self.axialL_label = QLabel(self.imageframe) # self.axialA_label = QLabel(self.imageframe) # self.axialR_label = QLabel(self.imageframe) # self.axialP_label = QLabel(self.imageframe) # # self.sagittalS_label = QLabel(self.imageframe) # self.sagittalA_label = QLabel(self.imageframe) # self.sagittalI_label = QLabel(self.imageframe) # self.sagittalP_label = QLabel(self.imageframe) # # self.coronalL_label = QLabel(self.imageframe) # self.coronalS_label = QLabel(self.imageframe) # self.coronalR_label = QLabel(self.imageframe) # self.coronalI_label = QLabel(self.imageframe) # # self.axial_title.setTextFormat(Qt.MarkdownText) # self.axialL_label.setTextFormat(Qt.MarkdownText) # self.axialA_label.setTextFormat(Qt.MarkdownText) # self.axialR_label.setTextFormat(Qt.MarkdownText) # self.axialP_label.setTextFormat(Qt.MarkdownText) # # self.sagittal_title.setTextFormat(Qt.MarkdownText) # self.sagittalS_label.setTextFormat(Qt.MarkdownText) # self.sagittalA_label.setTextFormat(Qt.MarkdownText) # self.sagittalI_label.setTextFormat(Qt.MarkdownText) # self.sagittalP_label.setTextFormat(Qt.MarkdownText) # # self.coronal_title.setTextFormat(Qt.MarkdownText) # self.coronalL_label.setTextFormat(Qt.MarkdownText) # self.coronalS_label.setTextFormat(Qt.MarkdownText) # self.coronalR_label.setTextFormat(Qt.MarkdownText) # self.coronalI_label.setTextFormat(Qt.MarkdownText) # # self.axial_title.setAlignment(Qt.AlignCenter) # self.axialL_label.setAlignment(Qt.AlignRight | Qt.AlignTrailing | Qt.AlignVCenter) # self.axialA_label.setAlignment(Qt.AlignBottom | Qt.AlignHCenter) # self.axialR_label.setAlignment(Qt.AlignLeading | Qt.AlignLeft | Qt.AlignVCenter) # self.axialP_label.setAlignment(Qt.AlignHCenter | Qt.AlignTop) # # self.sagittal_title.setAlignment(Qt.AlignCenter) # self.sagittalS_label.setAlignment(Qt.AlignRight | Qt.AlignTrailing | Qt.AlignVCenter) # self.sagittalA_label.setAlignment(Qt.AlignBottom | Qt.AlignHCenter) # self.sagittalI_label.setAlignment(Qt.AlignLeading | Qt.AlignLeft | Qt.AlignVCenter) # self.sagittalP_label.setAlignment(Qt.AlignHCenter | Qt.AlignTop) # # self.coronal_title.setAlignment(Qt.AlignCenter) # self.coronalL_label.setAlignment(Qt.AlignRight | Qt.AlignTrailing | Qt.AlignVCenter) # self.coronalS_label.setAlignment(Qt.AlignBottom | Qt.AlignHCenter) # self.coronalR_label.setAlignment(Qt.AlignLeading | Qt.AlignLeft | Qt.AlignVCenter) # self.coronalI_label.setAlignment(Qt.AlignHCenter | Qt.AlignTop) def set_controller_frame(self): self.controller_frame = QFrame(self) self.slicecontrol_pane = QGroupBox(self.controller_frame) self.frame_spinbox = QSpinBox(self.slicecontrol_pane) self.xaxis_label = QLabel(self.slicecontrol_pane) self.yaxis_label = QLabel(self.slicecontrol_pane) self.zaxis_label = QLabel(self.slicecontrol_pane) self.frame_label = QLabel(self.slicecontrol_pane) self.xaxis_slider = QSlider(self.slicecontrol_pane) self.yaxis_slider = QSlider(self.slicecontrol_pane) self.zaxis_slider = QSlider(self.slicecontrol_pane) self.frame_slider = QSlider(self.slicecontrol_pane) self.xaxis_spinbox = QSpinBox(self.slicecontrol_pane) self.yaxis_spinbox = QSpinBox(self.slicecontrol_pane) self.zaxis_spinbox = QSpinBox(self.slicecontrol_pane) self.graph_frame = QFrame(self) self.graph_view = pg.PlotWidget(self.graph_frame) self.graph_view.setBackground('w') # TODO: Will reactivate these on later version # self.graph_view = QGraphicsView(self.graph_frame) # self.graphcontrol_pane = QGroupBox(self.graph_frame) # self.addmask_button = QPushButton(self.graphcontrol_pane) # self.removemask_button = QPushButton(self.graphcontrol_pane) # self.mask_listview = QListView(self.graphcontrol_pane) # self.savepng_button = QPushButton(self.graphcontrol_pane) # self.savecsv_button = QPushButton(self.graphcontrol_pane) self.axial_view.setAlignment(Qt.AlignHCenter | Qt.AlignVCenter) self.sagittal_view.setAlignment(Qt.AlignHCenter | Qt.AlignVCenter) self.coronal_view.setAlignment(Qt.AlignHCenter | Qt.AlignVCenter) self.xaxis_slider.setOrientation(Qt.Horizontal) self.yaxis_slider.setOrientation(Qt.Horizontal) self.zaxis_slider.setOrientation(Qt.Horizontal) self.frame_slider.setOrientation(Qt.Horizontal) self.slicecontrol_pane.setAlignment(Qt.AlignCenter) self.xaxis_label.setAlignment(Qt.AlignCenter) self.yaxis_label.setAlignment(Qt.AlignCenter) self.zaxis_label.setAlignment(Qt.AlignCenter) self.frame_label.setAlignment(Qt.AlignCenter) # TODO: Will reactivate these on later version # self.graphcontrol_pane.setAlignment(Qt.AlignCenter) def set_size(self): size = int(config.get('ImageViewer', 'size')) self.imageframe.setLineWidth(0) self.axial_view.setMinimumSize(QSize(size, size)) self.axial_view.setMaximumSize(QSize(size, size)) self.axial_view.setLineWidth(0) self.sagittal_view.setMinimumSize(QSize(size, size)) self.sagittal_view.setMaximumSize(QSize(size, size)) self.sagittal_view.setLineWidth(0) self.coronal_view.setMinimumSize(QSize(size, size)) self.coronal_view.setMaximumSize(QSize(size, size)) self.coronal_view.setLineWidth(0) # TODO: Will reactivate these on later version # self.axialL_label.setMinimumSize(QSize(20, 0)) # self.axialA_label.setMinimumSize(QSize(0, 20)) # self.axialR_label.setMinimumSize(QSize(20, 0)) # self.axialP_label.setMinimumSize(QSize(0, 20)) # self.sagittalS_label.setMinimumSize(QSize(20, 0)) # self.sagittalA_label.setMinimumSize(QSize(0, 20)) # self.sagittalI_label.setMinimumSize(QSize(20, 0)) # self.sagittalP_label.setMinimumSize(QSize(0, 20)) # self.coronalL_label.setMinimumSize(QSize(20, 0)) # self.coronalS_label.setMinimumSize(QSize(0, 20)) # self.coronalR_label.setMinimumSize(QSize(20, 0)) # self.coronalI_label.setMinimumSize(QSize(0, 20)) self.controller_frame.setMinimumSize(QSize(300, 300)) self.controller_frame.setMaximumSize(QSize(400, 300)) self.graph_frame.setMinimumSize(QSize(0, 300)) self.graph_frame.setMaximumSize(QSize(4000, 4000)) self.graph_view.setMaximumSize(QSize(4000, 600)) # TODO: Will reactivate these on later version # self.graphcontrol_pane.setMinimumSize(QSize(300, 0)) # self.graphcontrol_pane.setMaximumSize(QSize(300, 4000)) # self.addmask_button.setMinimumSize(QSize(30, 0)) # self.addmask_button.setMaximumSize(QSize(30, 4000)) # self.removemask_button.setMinimumSize(QSize(30, 0)) # self.removemask_button.setMaximumSize(QSize(30, 4000)) def set_font(self): self.arial_8 = QFont() self.arial_8.setFamily(u"Arial") self.arial_8.setPointSize(8) self.setFont(self.arial_8) # TODO: Will reactivate these on later version # self.axial_title.setFont(self.arial_8) # self.coronal_title.setFont(self.arial_8) # self.sagittal_title.setFont(self.arial_8) # self.axialL_label.setFont(self.arial_8) # self.axialA_label.setFont(self.arial_8) # self.axialR_label.setFont(self.arial_8) # self.axialP_label.setFont(self.arial_8) # self.sagittalS_label.setFont(self.arial_8) # self.sagittalA_label.setFont(self.arial_8) # self.sagittalI_label.setFont(self.arial_8) # self.sagittalP_label.setFont(self.arial_8) # self.coronalL_label.setFont(self.arial_8) # self.coronalS_label.setFont(self.arial_8) # self.coronalR_label.setFont(self.arial_8) # self.coronalI_label.setFont(self.arial_8) self.slicecontrol_pane.setFont(self.arial_8) # TODO: Will reactivate these on later version # self.xaxis_label.setFont(self.arial_8) # self.yaxis_label.setFont(self.arial_8) # self.zaxis_label.setFont(self.arial_8) # self.frame_label.setFont(self.arial_8) # self.graphcontrol_pane.setFont(self.arial_8) # self.addmask_button.setFont(self.arial_8) # self.removemask_button.setFont(self.arial_8) # self.savepng_button.setFont(self.arial_8) # self.savecsv_button.setFont(self.arial_8) def set_palette(self): # Brush gray_text = QBrush(QColor(171, 171, 171, 255)) gray_text.setStyle(Qt.SolidPattern) black_background = QBrush(QColor(0, 0, 0, 255)) black_background.setStyle(Qt.SolidPattern) self.orientation_label_palette = QPalette() self.orientation_label_palette.setBrush(QPalette.Active, QPalette.WindowText, gray_text) self.orientation_label_palette.setBrush(QPalette.Inactive, QPalette.WindowText, gray_text) self.orientation_label_palette.setBrush(QPalette.Disabled, QPalette.WindowText, gray_text) self.ortho_viewer_palette = QPalette() self.ortho_viewer_palette.setBrush(QPalette.Active, QPalette.Base, black_background) self.ortho_viewer_palette.setBrush(QPalette.Inactive, QPalette.Base, black_background) self.ortho_viewer_palette.setBrush(QPalette.Disabled, QPalette.Base, black_background) self.axialA_label.setPalette(self.orientation_label_palette) self.axialL_label.setPalette(self.orientation_label_palette) self.axialR_label.setPalette(self.orientation_label_palette) self.axialP_label.setPalette(self.orientation_label_palette) self.axial_view.setPalette(self.ortho_viewer_palette) self.sagittalS_label.setPalette(self.orientation_label_palette) self.sagittalA_label.setPalette(self.orientation_label_palette) self.sagittalI_label.setPalette(self.orientation_label_palette) self.sagittalP_label.setPalette(self.orientation_label_palette) self.sagittal_view.setPalette(self.ortho_viewer_palette) self.coronalL_label.setPalette(self.orientation_label_palette) self.coronalS_label.setPalette(self.orientation_label_palette) self.coronalR_label.setPalette(self.orientation_label_palette) self.coronalI_label.setPalette(self.orientation_label_palette) self.coronal_view.setPalette(self.ortho_viewer_palette) def set_gridlayouts(self): self.axial_gridLayout = QGridLayout() self.coronal_gridLayout = QGridLayout() self.sagittal_gridLayout = QGridLayout() self.imagecont_gridLayout = QGridLayout(self.slicecontrol_pane) self.imageframe_gridLayout = QGridLayout(self.imageframe) # self.graphcontrol_gridLayout = QGridLayout(self.graphcontrol_pane) self.verticalLayout = QVBoxLayout(self.controller_frame) self.horizontalLayout = QHBoxLayout(self.graph_frame) self.main_gridLayout = QGridLayout(self) # TODO: Will reactivate these on later version # self.imageframe_gridLayout.addWidget(self.axial_title, 0, 1, 1, 1) # self.imageframe_gridLayout.addWidget(self.coronal_title, 0, 2, 1, 1) # self.imageframe_gridLayout.addWidget(self.sagittal_title, 0, 0, 1, 1) # self.axial_gridLayout.addWidget(self.axialL_label, 1, 0, 1, 1) # self.axial_gridLayout.addWidget(self.axialA_label, 0, 1, 1, 1) # self.axial_gridLayout.addWidget(self.axialR_label, 1, 2, 1, 1) # self.axial_gridLayout.addWidget(self.axialP_label, 2, 1, 1, 1) self.axial_gridLayout.addWidget(self.axial_view, 1, 1, 1, 1) # self.sagittal_gridLayout.addWidget(self.sagittalS_label, 1, 0, 1, 1) # self.sagittal_gridLayout.addWidget(self.sagittalA_label, 0, 1, 1, 1) # self.sagittal_gridLayout.addWidget(self.sagittalI_label, 1, 2, 1, 1) # self.sagittal_gridLayout.addWidget(self.sagittalP_label, 2, 1, 1, 1) self.sagittal_gridLayout.addWidget(self.sagittal_view, 1, 1, 1, 1) # self.coronal_gridLayout.addWidget(self.coronalL_label, 1, 0, 1, 1) # self.coronal_gridLayout.addWidget(self.coronalS_label, 0, 1, 1, 1) # self.coronal_gridLayout.addWidget(self.coronalR_label, 1, 2, 1, 1) # self.coronal_gridLayout.addWidget(self.coronalI_label, 2, 1, 1, 1) self.coronal_gridLayout.addWidget(self.coronal_view, 1, 1, 1, 1) self.imagecont_gridLayout.addWidget(self.xaxis_label, 0, 0, 1, 1) self.imagecont_gridLayout.addWidget(self.xaxis_slider, 0, 1, 1, 1) self.imagecont_gridLayout.addWidget(self.xaxis_spinbox, 0, 2, 1, 1) self.imagecont_gridLayout.addWidget(self.yaxis_label, 1, 0, 1, 1) self.imagecont_gridLayout.addWidget(self.yaxis_slider, 1, 1, 1, 1) self.imagecont_gridLayout.addWidget(self.yaxis_spinbox, 1, 2, 1, 1) self.imagecont_gridLayout.addWidget(self.zaxis_label, 2, 0, 1, 1) self.imagecont_gridLayout.addWidget(self.zaxis_slider, 2, 1, 1, 1) self.imagecont_gridLayout.addWidget(self.zaxis_spinbox, 2, 2, 1, 1) self.imagecont_gridLayout.addWidget(self.frame_label, 3, 0, 1, 1) self.imagecont_gridLayout.addWidget(self.frame_slider, 3, 1, 1, 1) self.imagecont_gridLayout.addWidget(self.frame_spinbox, 3, 2, 1, 1) self.imageframe_gridLayout.addLayout(self.axial_gridLayout, 1, 1, 1, 1) self.imageframe_gridLayout.addLayout(self.coronal_gridLayout, 1, 2, 1, 1) self.imageframe_gridLayout.addLayout(self.sagittal_gridLayout, 1, 0, 1, 1) # self.graphcontrol_gridLayout.addWidget(self.addmask_button, 3, 0, 1, 1) # self.graphcontrol_gridLayout.addWidget(self.removemask_button, 3, 1, 1, 1) # self.graphcontrol_gridLayout.addWidget(self.mask_listview, 0, 0, 1, 5) # self.graphcontrol_gridLayout.addWidget(self.savepng_button, 3, 4, 1, 1) # self.graphcontrol_gridLayout.addWidget(self.savecsv_button, 3, 3, 1, 1) self.verticalLayout.addWidget(self.slicecontrol_pane) self.horizontalLayout.addWidget(self.graph_view) # self.horizontalLayout.addWidget(self.graphcontrol_pane) self.main_gridLayout.addWidget(self.imageframe, 0, 0, 1, 2) self.main_gridLayout.addWidget(self.controller_frame, 1, 0, 1, 1) self.main_gridLayout.addWidget(self.graph_frame, 1, 1, 1, 1) def set_objectnames(self): self.setObjectName(u"data_browser") self.imageframe.setObjectName(u"image_frame") self.axial_gridLayout.setObjectName(u"axial_gridLayout") self.coronal_gridLayout.setObjectName(u"coronal_gridLayout") self.sagittal_gridLayout.setObjectName(u"sagittal_gridLayout") # TODO: Will reactivate these on later version # self.axial_title.setObjectName(u"axial_label") # self.coronal_title.setObjectName(u"coronal_label") # self.sagittal_title.setObjectName(u"sagittal_label") self.axial_view.setObjectName(u"axial_view") self.sagittal_view.setObjectName(u"sagittal_view") self.coronal_view.setObjectName(u"coronal_view") # self.axialL_label.setObjectName(u"axialL_label") # self.axialR_label.setObjectName(u"axialR_label") # self.axialA_label.setObjectName(u"axialA_label") # self.axialP_label.setObjectName(u"axialP_label") # self.sagittalS_label.setObjectName(u"sagittalS_label") # self.sagittalA_label.setObjectName(u"sagittalA_label") # self.sagittalI_label.setObjectName(u"sagittalI_label") # self.sagittalP_label.setObjectName(u"sagittalP_label") # self.coronalL_label.setObjectName(u"coronalL_label") # self.coronalS_label.setObjectName(u"coronalS_label") # self.coronalR_label.setObjectName(u"coronalR_label") # self.coronalI_label.setObjectName(u"coronalI_label") self.controller_frame.setObjectName(u"controller_frame") self.slicecontrol_pane.setObjectName(u"slicecontrol_pane") self.xaxis_label.setObjectName(u"xaxis_label") self.xaxis_slider.setObjectName(u"xaxis_slider") self.xaxis_spinbox.setObjectName(u"xaxis_spinbox") self.yaxis_label.setObjectName(u"yaxis_label") self.yaxis_slider.setObjectName(u"yaxis_slider") self.yaxis_spinbox.setObjectName(u"yaxis_spinbox") self.zaxis_label.setObjectName(u"zaxis_label") self.zaxis_slider.setObjectName(u"zaxis_slider") self.zaxis_spinbox.setObjectName(u"zaxis_spinbox") self.frame_label.setObjectName(u"frame_label") self.frame_slider.setObjectName(u"frame_slider") self.frame_spinbox.setObjectName(u"frame_spinbox") self.graph_frame.setObjectName(u"graph_frame") self.graph_view.setObjectName(u"graph_view") # TODO: Will reactivate these on later version # self.graphcontrol_pane.setObjectName(u"graphcontrol_pane") # self.addmask_button.setObjectName(u"addmask_button") # self.removemask_button.setObjectName(u"removemask_button") # self.mask_listview.setObjectName(u"mask_listview") # self.savepng_button.setObjectName(u"savepng_button") # self.savecsv_button.setObjectName(u"savecsv_button") self.imagecont_gridLayout.setObjectName(u"imagecont_gridLayout") self.imageframe_gridLayout.setObjectName(u"imageframe_gridLayout") # self.graphcontrol_gridLayout.setObjectName(u"graphcontrol_gridLayout") self.verticalLayout.setObjectName(u"verticalLayout") self.horizontalLayout.setObjectName(u"horizontalLayout") self.main_gridLayout.setObjectName(u"main_gridLayout") QMetaObject.connectSlotsByName(self) def set_texts(self): self.setWindowTitle(u"Data Browser") # TODO: Will reactivate these on later version # self.axial_title.setText(u"**Axial**") # self.coronal_title.setText(u"**Coronal**") # self.sagittal_title.setText(u"**Sagittal**") # self.sagittalS_label.setText(u"**S**") # self.sagittalA_label.setText(u"**A**") # self.sagittalI_label.setText(u"**I**") # self.sagittalP_label.setText(u"**P**") # self.axialL_label.setText(u"**L**") # self.axialA_label.setText(u"**A**") # self.axialR_label.setText(u"**R**") # self.axialP_label.setText( u"**P**") # self.coronalL_label.setText(u"**L**") # self.coronalS_label.setText(u"**S**") # self.coronalR_label.setText(u"**R**") # self.coronalI_label.setText(u"**I**") self.slicecontrol_pane.setTitle(u"Slice Control Pane") self.xaxis_label.setText(u"x") self.yaxis_label.setText(u"y") self.zaxis_label.setText(u"z") self.frame_label.setText(u"Frame") # TODO: Will reactivate these on later version # self.graphcontrol_pane.setTitle(u"Graph Control Pane") # self.addmask_button.setText(u"+") # self.removemask_button.setText(u"-") # self.savepng_button.setText(u"toPNG") # self.savecsv_button.setText(u"toCSV") def plot_timecourse(self, x, y): self.graph_frame.setEnabled(True) self.graph_view.clear() pen = pg.mkPen(color=(255, 0, 0)) if x is None: x = [0] y = [y] self.graph_view.plot(x, y, pen=pen, symbol='o') else: self.graph_view.plot(x, y, pen=pen) def get_coord(self): x = self.xaxis_slider.value() y = self.yaxis_slider.value() z = self.zaxis_slider.value() return (x, y, z)
class ChapterSelectionSetting(GlobalSetting): tab_clicked_signal = Signal() activation_signal = Signal(bool) def __init__(self): super().__init__() self.create_properties() self.create_widgets() self.setup_widgets() self.connect_signals() def create_widgets(self): self.chapter_source_label = QLabel("Chapter Source Folder:") self.chapter_extension_label = QLabel("Chapter Extension:") self.chapter_source_lineEdit = ChapterSourceLineEdit() self.chapter_source_button = ChapterSourceButton() self.chapter_extensions_comboBox = ChapterExtensionsCheckableComboBox() self.chapter_match_layout = MatchChapterLayout(parent=self) self.chapter_options_layout = QHBoxLayout() self.MainLayout = QVBoxLayout() self.main_layout = QGridLayout() self.chapter_main_groupBox = QGroupBox() self.chapter_match_groupBox = QGroupBox("Chapter Matching") self.chapter_match_groupBox.setLayout(self.chapter_match_layout) def setup_widgets(self): self.setup_chapter_main_groupBox() self.setup_layouts() # noinspection PyUnresolvedReferences def connect_signals(self): self.chapter_main_groupBox.toggled.connect(self.activate_tab) self.chapter_source_button.clicked_signal.connect( self.update_folder_path) self.chapter_source_lineEdit.edit_finished_signal.connect( self.update_folder_path) self.chapter_extensions_comboBox.close_list.connect( self.check_extension_changes) self.chapter_match_layout.sync_chapter_files_with_global_files_after_swap_signal.connect( self.sync_chapter_files_with_global_files) self.tab_clicked_signal.connect(self.tab_clicked) def create_properties(self): self.folder_path = "" self.files_names_list = [] self.files_names_absolute_list = [] self.current_chapter_extensions = [Default_Chapter_Extension] def setup_layouts(self): self.setup_chapter_options_layout() self.setup_main_layout() self.setLayout(self.MainLayout) self.MainLayout.addWidget(self.chapter_main_groupBox) def setup_chapter_options_layout(self): self.chapter_options_layout.addWidget(self.chapter_extensions_comboBox) self.chapter_options_layout.addStretch() def setup_main_layout(self): self.main_layout.addWidget(self.chapter_source_label, 0, 0) self.main_layout.addWidget(self.chapter_source_lineEdit, 0, 1, 1, 1) self.main_layout.addWidget(self.chapter_source_button, 0, 2) self.main_layout.addWidget(self.chapter_extension_label, 1, 0) self.main_layout.addLayout(self.chapter_options_layout, 1, 1, 1, 2) self.main_layout.addWidget(self.chapter_match_groupBox, 2, 0, 1, -1) def setup_chapter_main_groupBox(self): self.chapter_main_groupBox.setParent(self) self.chapter_main_groupBox.setLayout(self.main_layout) self.chapter_main_groupBox.setTitle("Chapters") self.chapter_main_groupBox.setCheckable(True) self.chapter_main_groupBox.setChecked(True) def update_folder_path(self, new_path: str): if new_path != "": self.chapter_source_lineEdit.setText(new_path) self.update_files_lists(new_path) self.show_chapter_files_list() def update_files_lists(self, folder_path): if folder_path == "" or folder_path.isspace(): self.folder_path = "" self.chapter_source_lineEdit.setText("") return try: self.folder_path = folder_path self.files_names_list = self.get_files_list(self.folder_path) self.files_names_absolute_list = get_files_names_absolute_list( self.files_names_list, self.folder_path) except Exception as e: invalid_path_dialog = InvalidPathDialog() invalid_path_dialog.execute() def check_extension_changes(self, new_extensions): if self.current_chapter_extensions != new_extensions: self.current_chapter_extensions = new_extensions self.update_files_lists(self.folder_path) self.show_chapter_files_list() def get_files_list(self, folder_path): temp_files_names = sort_names_like_windows( names_list=os.listdir(folder_path)) temp_files_names_absolute = get_files_names_absolute_list( temp_files_names, folder_path) current_extensions = self.chapter_extensions_comboBox.currentData() result = [] for i in range(len(temp_files_names)): if os.path.isdir(temp_files_names_absolute[i]): continue if os.path.getsize(temp_files_names_absolute[i]) == 0: continue for j in range(len(current_extensions)): temp_file_extension_start_index = temp_files_names[i].rfind( ".") if temp_file_extension_start_index == -1: continue temp_file_extension = temp_files_names[i][ temp_file_extension_start_index + 1:] if temp_file_extension.lower() == current_extensions[j].lower( ): result.append(temp_files_names[i]) break return result def show_chapter_files_list(self): self.update_other_classes_variables() self.chapter_match_layout.show_chapter_files() def update_other_classes_variables(self): self.change_global_last_path_directory() self.change_global_chapter_list() self.chapter_source_button.set_is_there_old_file( len(self.files_names_list) > 0) self.chapter_source_lineEdit.set_is_there_old_file( len(self.files_names_list) > 0) self.chapter_extensions_comboBox.set_is_there_old_file( len(self.files_names_list) > 0) self.chapter_source_lineEdit.set_current_folder_path(self.folder_path) self.chapter_extensions_comboBox.set_current_folder_path( self.folder_path) self.chapter_extensions_comboBox.set_current_files_list( self.files_names_list) def change_global_chapter_list(self): GlobalSetting.CHAPTER_FILES_LIST = self.files_names_list GlobalSetting.CHAPTER_FILES_ABSOLUTE_PATH_LIST = self.files_names_absolute_list def show_video_files_list(self): if self.chapter_main_groupBox.isChecked(): self.chapter_match_layout.show_video_files() def activate_tab(self, on): if on: self.show_video_files_list() else: self.chapter_source_lineEdit.setText("") self.chapter_match_layout.clear_tables() self.folder_path = "" self.files_names_list = [] self.files_names_absolute_list = [] self.current_chapter_extensions = [Default_Chapter_Extension] self.chapter_extensions_comboBox.setData( self.current_chapter_extensions) GlobalSetting.CHAPTER_FILES_LIST = [] GlobalSetting.CHAPTER_FILES_ABSOLUTE_PATH_LIST = [] GlobalSetting.CHAPTER_TRACK_NAME = "" GlobalSetting.CHAPTER_DELAY = 0.0 GlobalSetting.CHAPTER_SET_DEFAULT = False GlobalSetting.CHAPTER_SET_FORCED = False GlobalSetting.CHAPTER_LANGUAGE = "" self.activation_signal.emit(on) GlobalSetting.CHAPTER_ENABLED = on def mousePressEvent(self, QMouseEvent): if QMouseEvent.buttons() == Qt.RightButton: self.chapter_match_layout.clear_chapter_selection() if (QMouseEvent.buttons() == Qt.RightButton or QMouseEvent.buttons() == Qt.LeftButton) and (self.chapter_source_lineEdit.text() == ""): self.chapter_source_lineEdit.setText(self.folder_path) return QWidget.mousePressEvent(self, QMouseEvent) def showEvent(self, a0: QtGui.QShowEvent) -> None: super().showEvent(a0) if self.chapter_main_groupBox.isChecked(): self.show_video_files_list() def change_global_last_path_directory(self): if self.folder_path != "" and not self.folder_path.isspace(): GlobalSetting.LAST_DIRECTORY_PATH = self.folder_path def tab_clicked(self): if self.chapter_main_groupBox.isChecked(): self.show_chapter_files_list() self.show_video_files_list() if not GlobalSetting.JOB_QUEUE_EMPTY: self.disable_editable_widgets() else: self.enable_editable_widgets() def disable_editable_widgets(self): self.chapter_source_lineEdit.setEnabled(False) self.chapter_source_button.setEnabled(False) self.chapter_extensions_comboBox.setEnabled(False) self.chapter_main_groupBox.setCheckable(False) self.chapter_match_layout.disable_editable_widgets() def enable_editable_widgets(self): self.chapter_source_lineEdit.setEnabled(True) self.chapter_source_button.setEnabled(True) self.chapter_extensions_comboBox.setEnabled(True) if GlobalSetting.CHAPTER_ENABLED: self.chapter_main_groupBox.setCheckable(True) else: self.chapter_main_groupBox.setCheckable(True) GlobalSetting.CHAPTER_ENABLED = False self.chapter_main_groupBox.setChecked( GlobalSetting.CHAPTER_ENABLED) self.chapter_match_layout.enable_editable_widgets() def sync_chapter_files_with_global_files(self): self.files_names_list = GlobalSetting.CHAPTER_FILES_LIST GlobalSetting.CHAPTER_FILES_ABSOLUTE_PATH_LIST = get_files_names_absolute_list( self.files_names_list, self.folder_path) self.files_names_absolute_list = GlobalSetting.CHAPTER_FILES_ABSOLUTE_PATH_LIST self.update_other_classes_variables()
class MuxSettingTab(QWidget): tab_clicked_signal = Signal() start_muxing_signal = Signal() update_task_bar_progress_signal = Signal(int) update_task_bar_paused_signal = Signal() update_task_bar_clear_signal = Signal() def __init__(self): super().__init__() self.create_widgets() self.setup_widgets() self.connect_signals() def connect_signals(self): self.tab_clicked_signal.connect(self.tab_clicked) self.destination_path_button.clicked.connect(self.open_select_destination_folder_dialog) self.only_keep_those_audios_checkBox.stateChanged.connect( self.only_keep_those_audios_multi_choose_comboBox.check_box_state_changed) self.only_keep_those_subtitles_checkBox.stateChanged.connect( self.only_keep_those_subtitles_multi_choose_comboBox.check_box_state_changed) self.make_this_audio_default_checkBox.disable_combo_box.connect(self.disable_make_this_audio_default_comboBox) self.make_this_subtitle_default_checkBox.disable_combo_box.connect( self.disable_make_this_subtitle_default_comboBox) self.control_queue_button.add_to_queue_clicked_signal.connect(self.add_to_queue_button_clicked) self.control_queue_button.start_multiplexing_clicked_signal.connect(self.start_multiplexing_button_clicked) self.control_queue_button.pause_multiplexing_clicked_signal.connect(self.pause_multiplexing_button_clicked) self.clear_job_queue_button.clicked.connect(self.clear_job_queue_button_clicked) self.only_keep_those_audios_multi_choose_comboBox.closeList.connect(self.only_keep_those_audios_close_list) self.only_keep_those_subtitles_multi_choose_comboBox.closeList.connect( self.only_keep_those_subtitles_close_list) self.make_this_audio_default_comboBox.currentTextChanged.connect( self.make_this_audio_default_comboBox_text_changed) self.make_this_subtitle_default_comboBox.currentTextChanged.connect( self.make_this_subtitle_default_comboBox_text_changed) self.abort_on_errors_checkBox.stateChanged.connect(self.abort_on_errors_state_changed) self.keep_log_file_checkBox.stateChanged.connect(self.keep_log_file_state_changed) self.job_queue_layout.update_task_bar_progress_signal.connect(self.update_task_bar_progress) self.job_queue_layout.paused_done_signal.connect(self.paused_done) self.job_queue_layout.cancel_done_signal.connect(self.cancel_done) self.job_queue_layout.finished_all_jobs_signal.connect(self.finished_all_jobs) self.job_queue_layout.pause_from_error_occurred_signal.connect(self.pause_multiplexing_button_clicked) def setup_widgets(self): self.setup_mux_setting_groupBox() self.setup_job_queue_groupBox() self.setup_destination_path_label() self.setup_destination_path_lineEdit() self.setup_destination_path_button() self.setup_abort_on_errors_checkBox() self.setup_discard_old_attachments_checkBox() self.setup_keep_log_file_checkBox() self.setup_clear_job_queue_button() self.setup_tool_tip_hint() self.setup_layouts() def setup_layouts(self): self.setup_MainLayout() self.mux_setting_groupBox.setLayout(self.mux_setting_layout) self.job_queue_groupBox.setLayout(self.job_queue_layout) self.setup_mux_tools_layout_first_row() self.setup_mux_tools_layout_second_row() self.setup_mux_setting_layout() self.setLayout(self.MainLayout) # noinspection PyAttributeOutsideInit def create_widgets(self): self.MainLayout = QVBoxLayout() self.mux_setting_groupBox = QGroupBox(self) self.job_queue_groupBox = QGroupBox(self) self.mux_setting_layout = QGridLayout() self.job_queue_layout = JobQueueLayout() self.destination_path_label = QLabel() self.destination_path_lineEdit = QLineEdit() self.destination_path_button = QPushButton() self.only_keep_those_audios_checkBox = OnlyKeepThoseAudiosCheckBox() self.only_keep_those_subtitles_checkBox = OnlyKeepThoseSubtitlesCheckBox() self.only_keep_those_audios_multi_choose_comboBox = AudioTracksCheckableComboBox() self.only_keep_those_subtitles_multi_choose_comboBox = SubtitleTracksCheckableComboBox() self.make_this_audio_default_checkBox = MakeThisAudioDefaultCheckBox() self.make_this_subtitle_default_checkBox = MakeThisSubtitleDefaultCheckBox() self.make_this_audio_default_comboBox = MakeThisTrackDefaultComboBox() self.make_this_subtitle_default_comboBox = MakeThisTrackDefaultComboBox() self.abort_on_errors_checkBox = QCheckBox() self.discard_old_attachments_checkBox = QCheckBox() self.keep_log_file_checkBox = QCheckBox() self.control_queue_button = ControlQueueButton() self.clear_job_queue_button = QPushButton() self.mux_tools_layout_first_row = QHBoxLayout() self.mux_tools_layout_second_row = QHBoxLayout() self.job_queue_tools_layout = QHBoxLayout() def setup_mux_setting_layout(self): self.mux_setting_layout.addWidget(self.destination_path_label, 0, 0) self.mux_setting_layout.addWidget(self.destination_path_lineEdit, 0, 1) self.mux_setting_layout.addWidget(self.destination_path_button, 0, 2) self.mux_setting_layout.addWidget(self.only_keep_those_audios_checkBox, 1, 0) self.mux_setting_layout.addWidget(self.only_keep_those_subtitles_checkBox, 2, 0) self.mux_setting_layout.addLayout(self.mux_tools_layout_first_row, 1, 1) self.mux_setting_layout.addLayout(self.mux_tools_layout_second_row, 2, 1) def setup_mux_tools_layout_first_row(self): self.mux_tools_layout_first_row.addWidget(self.only_keep_those_audios_multi_choose_comboBox, 2) self.mux_tools_layout_first_row.addWidget(self.make_this_audio_default_checkBox, 1) self.mux_tools_layout_first_row.addWidget(self.make_this_audio_default_comboBox, 2) self.mux_tools_layout_first_row.addWidget(self.abort_on_errors_checkBox, 1) self.mux_tools_layout_first_row.addWidget(self.keep_log_file_checkBox) def setup_mux_tools_layout_second_row(self): self.mux_tools_layout_second_row.addWidget(self.only_keep_those_subtitles_multi_choose_comboBox, 2) self.mux_tools_layout_second_row.addWidget(self.make_this_subtitle_default_checkBox, 1) self.mux_tools_layout_second_row.addWidget(self.make_this_subtitle_default_comboBox, 2) self.mux_tools_layout_second_row.addWidget(self.control_queue_button, 1) self.mux_tools_layout_second_row.addWidget(self.clear_job_queue_button, 1) def setup_clear_job_queue_button(self): self.clear_job_queue_button.setText("Clear All") self.clear_job_queue_button.setIcon(GlobalFiles.CleanIcon) self.clear_job_queue_button.setDisabled(True) def setup_keep_log_file_checkBox(self): self.keep_log_file_checkBox.setText("Keep Log File") self.keep_log_file_checkBox.setToolTip("log file will located in the source folder after finished muxing") def setup_discard_old_attachments_checkBox(self): self.discard_old_attachments_checkBox.setText("Discard Old Attachments ") def setup_abort_on_errors_checkBox(self): self.abort_on_errors_checkBox.setText("Abort On Errors") self.abort_on_errors_checkBox.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Preferred) def setup_destination_path_button(self): self.destination_path_button.setIcon(GlobalFiles.SelectFolderIcon) def setup_destination_path_lineEdit(self): self.destination_path_lineEdit.setPlaceholderText("Enter Destination Folder Path") self.destination_path_lineEdit.setClearButtonEnabled(True) def setup_destination_path_label(self): self.destination_path_label.setText("Videos Destination Folder :") def setup_MainLayout(self): self.MainLayout.addWidget(self.mux_setting_groupBox) self.MainLayout.addWidget(self.job_queue_groupBox) def setup_job_queue_groupBox(self): self.job_queue_groupBox.setTitle("Job Queue") def setup_mux_setting_groupBox(self): self.mux_setting_groupBox.setTitle("Mux Setting") def paintEvent(self, event: QPaintEvent): self.update_widgets_size() super().paintEvent(event) def resizeEvent(self, event: QResizeEvent): self.job_queue_layout.update_layout() super().resizeEvent(event) def update_widgets_size(self): self.only_keep_those_subtitles_multi_choose_comboBox.resize( self.only_keep_those_audios_multi_choose_comboBox.width(), self.only_keep_those_audios_multi_choose_comboBox.height(), ) self.make_this_subtitle_default_checkBox.resize( self.make_this_audio_default_checkBox.width(), self.make_this_audio_default_checkBox.height(), ) self.make_this_subtitle_default_checkBox.move( self.make_this_audio_default_checkBox.x(), self.make_this_subtitle_default_checkBox.y(), ) self.make_this_subtitle_default_comboBox.resize( self.make_this_audio_default_comboBox.width(), self.make_this_audio_default_comboBox.height(), ) self.make_this_subtitle_default_comboBox.move( self.make_this_audio_default_comboBox.x(), self.make_this_subtitle_default_comboBox.y(), ) self.control_queue_button.move( self.abort_on_errors_checkBox.x(), self.control_queue_button.y(), ) self.clear_job_queue_button.move( self.control_queue_button.x() + self.control_queue_button.width() + 5, self.clear_job_queue_button.y(), ) def open_select_destination_folder_dialog(self): temp_folder_path = QFileDialog.getExistingDirectory(self, caption="Choose Destination Folder", dir=GlobalSetting.LAST_DIRECTORY_PATH, ) if temp_folder_path == "" or temp_folder_path.isspace(): return elif Path(temp_folder_path) == Path(GlobalSetting.VIDEO_SOURCE_PATH): invalid_dialog = InvalidPathDialog( error_message="Source and destination videos can't be in the same folder") invalid_dialog.execute() return else: self.destination_path_lineEdit.setText(str(Path(temp_folder_path))) GlobalSetting.LAST_DIRECTORY_PATH = self.destination_path_lineEdit.text() GlobalSetting.DESTINATION_FOLDER_PATH = self.destination_path_lineEdit.text() def check_destination_path(self): temp_destination_path = self.destination_path_lineEdit.text() try: if temp_destination_path == "" or temp_destination_path.isspace(): temp_destination_path = "[Empty Path]" raise Exception( "[WinError 998] Empty path is Not a valid path : " + temp_destination_path) # check if system is windows so path must have # SOME_LETTER:\ if os.name == 'nt': if temp_destination_path[1:3] != ":\\" and self.destination_path_lineEdit.text()[ 1:3] != ":/": raise Exception("[WinError 999] Not a valid path : " + temp_destination_path) makedirs(temp_destination_path, exist_ok=True) ## test if i can write into this path: test_file_name = str(time.time()) + ".txt" test_file_name_absolute = os.path.join(Path(temp_destination_path), Path(test_file_name)) try: with open(test_file_name_absolute, 'w+') as test_file: test_file.write("Test") os.remove(test_file_name_absolute) except Exception as e: write_to_log_file(e) invaild_dialog = InvalidPathDialog(window_title="Permission Denied", error_message="MKV Muxing Batch GUI lacks write " "permissions on Destination folder") invaild_dialog.execute() self.destination_path_lineEdit.setText(GlobalSetting.DESTINATION_FOLDER_PATH) return False except Exception as e: write_to_log_file(e) error_message = "" if temp_destination_path == "[Empty Path]": error_message = "Enter a valid destination path" else: error_message = temp_destination_path + "\nisn't a valid path!" invalid_dialog = InvalidPathDialog(error_message=error_message) invalid_dialog.execute() self.destination_path_lineEdit.setText(GlobalSetting.DESTINATION_FOLDER_PATH) return False if Path(temp_destination_path) == Path(GlobalSetting.VIDEO_SOURCE_PATH): invalid_dialog = InvalidPathDialog( error_message="Source and destination videos can't be in the same folder") invalid_dialog.execute() self.destination_path_lineEdit.setText(GlobalSetting.DESTINATION_FOLDER_PATH) return False GlobalSetting.DESTINATION_FOLDER_PATH = temp_destination_path return True def setup_tool_tip_hint(self): self.only_keep_those_subtitles_multi_choose_comboBox.set_tool_tip_hint() self.only_keep_those_audios_multi_choose_comboBox.set_tool_tip_hint() self.make_this_subtitle_default_checkBox.set_tool_tip_hint_no_check() self.make_this_audio_default_checkBox.set_tool_tip_hint_no_check() def add_to_queue_button_clicked(self): self.job_queue_layout.setup_queue() self.enable_muxing_setting() if not GlobalSetting.JOB_QUEUE_EMPTY: self.disable_editable_widgets() self.control_queue_button.set_state_start_multiplexing() self.clear_job_queue_button.setDisabled(False) change_global_LogFilePath() else: self.enable_editable_widgets() self.setup_enable_options_for_mkv_only_options() def tab_clicked(self): self.job_queue_layout.show_necessary_table_columns() self.setup_enable_options_for_mkv_only_options() def setup_enable_options_for_mkv_only_options(self): if GlobalSetting.JOB_QUEUE_EMPTY: if GlobalSetting.VIDEO_SOURCE_MKV_ONLY: self.only_keep_those_audios_checkBox.setEnabled(True) self.only_keep_those_subtitles_checkBox.setEnabled(True) self.make_this_audio_default_checkBox.setEnabled(True) self.make_this_subtitle_default_checkBox.setEnabled(True) self.only_keep_those_audios_checkBox.setToolTip("") self.only_keep_those_subtitles_checkBox.setToolTip("") self.make_this_audio_default_comboBox.setToolTip("") self.make_this_subtitle_default_comboBox.setToolTip("") self.setup_tool_tip_hint() else: self.only_keep_those_subtitles_checkBox.setCheckState(Qt.Unchecked) self.only_keep_those_audios_checkBox.setCheckState(Qt.Unchecked) self.make_this_audio_default_checkBox.setCheckState(Qt.Unchecked) self.make_this_subtitle_default_checkBox.setCheckState(Qt.Unchecked) self.only_keep_those_audios_checkBox.setEnabled(False) self.only_keep_those_subtitles_checkBox.setEnabled(False) self.make_this_audio_default_checkBox.setEnabled(False) self.make_this_subtitle_default_checkBox.setEnabled(False) self.only_keep_those_audios_checkBox.setToolTip("<b>[Disabled]</b> Only works when video files " "are Mkv only") self.only_keep_those_subtitles_checkBox.setToolTip("<b>[Disabled]</b> Only works when video files " "are Mkv only") self.make_this_audio_default_checkBox.setToolTip("<b>[Disabled]</b> Only works when video files " "are Mkv only") self.make_this_subtitle_default_checkBox.setToolTip("<b>[Disabled]</b> Only works when video files " "are Mkv only") self.make_this_audio_default_comboBox.setToolTip("<b>[Disabled]</b> Only works when video files " "are Mkv only") self.make_this_subtitle_default_comboBox.setToolTip("<b>[Disabled]</b> Only works when video files " "are Mkv only") self.only_keep_those_audios_multi_choose_comboBox.setToolTip( "<b>[Disabled]</b> Only works when video files " "are Mkv only") self.only_keep_those_subtitles_multi_choose_comboBox.setToolTip( "<b>[Disabled]</b> Only works when video files " "are Mkv only") def clear_job_queue_button_clicked(self): self.job_queue_layout.clear_queue() self.control_queue_button.set_state_add_to_queue() self.clear_job_queue_button.setDisabled(True) self.control_queue_button.setDisabled(False) self.enable_editable_widgets() self.enable_muxing_setting() self.setup_enable_options_for_mkv_only_options() self.update_task_bar_clear_signal.emit() def disable_editable_widgets(self): self.only_keep_those_subtitles_checkBox.setEnabled(False) self.only_keep_those_subtitles_multi_choose_comboBox.setEnabled(False) self.only_keep_those_audios_checkBox.setEnabled(False) self.only_keep_those_audios_multi_choose_comboBox.setEnabled(False) self.make_this_subtitle_default_checkBox.setEnabled(False) self.make_this_subtitle_default_comboBox.setEnabled(False) self.make_this_audio_default_checkBox.setEnabled(False) self.make_this_audio_default_comboBox.setEnabled(False) def enable_editable_widgets(self): self.only_keep_those_subtitles_checkBox.setEnabled(True) self.only_keep_those_subtitles_multi_choose_comboBox.setEnabled( self.only_keep_those_subtitles_checkBox.isChecked()) self.only_keep_those_audios_checkBox.setEnabled(True) self.only_keep_those_audios_multi_choose_comboBox.setEnabled(self.only_keep_those_audios_checkBox.isChecked()) self.make_this_subtitle_default_checkBox.setEnabled(True) self.make_this_subtitle_default_comboBox.setEnabled(self.make_this_subtitle_default_checkBox.isChecked()) self.make_this_audio_default_checkBox.setEnabled(True) self.make_this_audio_default_comboBox.setEnabled(self.make_this_audio_default_checkBox.isChecked()) def only_keep_those_audios_close_list(self): GlobalSetting.MUX_SETTING_ONLY_KEEP_THOSE_AUDIOS_LANGUAGES = self.only_keep_those_audios_multi_choose_comboBox.languages GlobalSetting.MUX_SETTING_ONLY_KEEP_THOSE_AUDIOS_TRACKS = self.only_keep_those_audios_multi_choose_comboBox.tracks def only_keep_those_subtitles_close_list(self): GlobalSetting.MUX_SETTING_ONLY_KEEP_THOSE_SUBTITLES_LANGUAGES = self.only_keep_those_subtitles_multi_choose_comboBox.languages GlobalSetting.MUX_SETTING_ONLY_KEEP_THOSE_SUBTITLES_TRACKS = self.only_keep_those_subtitles_multi_choose_comboBox.tracks def disable_make_this_subtitle_default_comboBox(self, state): self.make_this_subtitle_default_comboBox.setDisabled(state) if state: self.make_this_subtitle_default_comboBox.setCurrentIndex(-1) def disable_make_this_audio_default_comboBox(self, state): self.make_this_audio_default_comboBox.setDisabled(state) if state: self.make_this_audio_default_comboBox.setCurrentIndex(-1) def make_this_audio_default_comboBox_text_changed(self): GlobalSetting.MUX_SETTING_MAKE_THIS_AUDIO_DEFAULT_TRACK = str( self.make_this_audio_default_comboBox.currentText()) def make_this_subtitle_default_comboBox_text_changed(self): GlobalSetting.MUX_SETTING_MAKE_THIS_SUBTITLE_DEFAULT_TRACK = str( self.make_this_subtitle_default_comboBox.currentText()) def update_task_bar_progress(self, new_progress): self.update_task_bar_progress_signal.emit(new_progress) def enable_muxing_setting(self): self.destination_path_lineEdit.setEnabled(True) self.destination_path_button.setEnabled(True) self.abort_on_errors_checkBox.setEnabled(True) self.keep_log_file_checkBox.setEnabled(True) def disable_muxing_setting(self): self.destination_path_lineEdit.setEnabled(False) self.destination_path_button.setEnabled(False) self.abort_on_errors_checkBox.setEnabled(False) self.keep_log_file_checkBox.setEnabled(False) @staticmethod def abort_on_errors_state_changed(state): GlobalSetting.MUX_SETTING_ABORT_ON_ERRORS = bool(state) @staticmethod def keep_log_file_state_changed(state): GlobalSetting.MUX_SETTING_KEEP_LOG_FILE = bool(state) def start_multiplexing_button_clicked(self): at_least_one_muxing_setting_has_been_selected = check_if_at_least_one_muxing_setting_has_been_selected() if at_least_one_muxing_setting_has_been_selected: destination_path_valid = self.check_destination_path() if destination_path_valid: self.setup_log_file() self.control_queue_button.set_state_pause_multiplexing() self.disable_muxing_setting() self.job_queue_layout.start_muxing() self.start_muxing_signal.emit() self.clear_job_queue_button.setDisabled(True) def pause_multiplexing_button_clicked(self): self.job_queue_layout.pause_muxing() self.control_queue_button.setDisabled(True) self.control_queue_button.set_state_pausing_multiplexing() def paused_done(self): self.control_queue_button.set_state_resume_multiplexing() self.clear_job_queue_button.setDisabled(False) self.control_queue_button.setDisabled(False) self.update_task_bar_paused_signal.emit() def cancel_done(self): self.disable_editable_widgets() self.enable_muxing_setting() self.control_queue_button.set_state_start_multiplexing() self.clear_job_queue_button.setDisabled(False) change_global_LogFilePath() def finished_all_jobs(self): self.enable_editable_widgets() self.enable_muxing_setting() self.setup_enable_options_for_mkv_only_options() self.control_queue_button.set_state_start_multiplexing() self.control_queue_button.setDisabled(True) self.clear_job_queue_button.setDisabled(False) self.update_task_bar_clear_signal.emit() GlobalSetting.JOB_QUEUE_EMPTY = True check_if_want_to_keep_log_file() def setup_log_file(self): if self.control_queue_button.state == "START": open(GlobalFiles.LogFilePath, 'w+').close()
class DatasheetView(QMainWindow): def __init__(self, pdfPath=None, openPages=[1]): super().__init__() if pdfPath: self.myPdfContext = PDFContext(pdfPath, openPages) # store diretory for debugging purposes self.svgDirectory = self.myPdfContext.directory # window dimensions self.top = 300 self.left = 800 self.width = 860 self.height = 980 self.setGeometry(self.left, self.top, self.width, self.height) # window title self.setWindowTitle("BetterSheets") # sets up main layout -- splitters self.initUILayout() self.initUIToolbar() self.initToC() # self.initPdfViewer() # must be called after initUI to ensure PDFContext object exists self.show() print(self.mainDisplay.getVisibleChild()) def initUILayout(self): # set left-side, Dynamic View self.dynamicViewDisplay = QLabel() self.vBoxA = QVBoxLayout() self.vBoxA.addWidget(self.dynamicViewDisplay) self.groupA = QGroupBox() self.groupA.setTitle("Dynamic Veiw") self.groupA.setLayout(self.vBoxA) # set left-side, Static View self.staticViewDisplay = QLabel() self.vBoxB = QVBoxLayout() self.vBoxB.addWidget(self.staticViewDisplay) self.groupB = QGroupBox() self.groupB.setTitle("Static View") self.groupB.setLayout(self.vBoxB) # add Dynamic and Static Views to resizeable left-side Splitter self.altViewSplit = QSplitter(Qt.Vertical) self.altViewSplit.addWidget(self.groupA) self.altViewSplit.addWidget(self.groupB) # set up Tools View section self.toolsTabView = QTabWidget() self.toolsTabView.setTabsClosable(True) self.toolsTabView.setMovable(True) self.toolsTabView.setDocumentMode(True) # self.toolsTabView.setTabBarAutoHide(True) # add attribute for storing page notes self.notesDB = [] self.notesDisplay = QListWidget(self) self.notesDisplay.setMaximumHeight(200) # add ToC to Tools View self.ToCListView = QListWidget() self.toolsTabView.addTab(self.ToCListView, "Table of Contents") # add notes list to tools view self.toolsTabView.addTab(self.notesDisplay, "Notes") # add tools view to the left-side splitter self.altViewSplit.addWidget(self.toolsTabView) # set up main viewport self.mainDisplay = QDatasheetPageDisplayWidget(self.myPdfContext) self.mainDisplay.renderPages(1, 4) self.mainScroller = QScrollArea(self) self.mainScroller.setWidget(self.mainDisplay) self.mainScroller.setWidgetResizable(True) self.mainScroller.setBackgroundRole(QtGui.QPalette.Dark) self.mainScroller.setFixedHeight(800) print(self.mainScroller.viewport().childrenRect()) # set up document tools self.hBoxDocTools = QHBoxLayout() self.searchLabel = QLabel("Search: ") self.searchBox = QLineEdit() self.searchBox.setPlaceholderText("Search") # self. self.vBoxMain = QVBoxLayout() self.vBoxMain.addWidget(self.mainScroller) self.notesArea = QLineEdit() self.notesArea.setPlaceholderText("Add a note about this page...") self.notesArea.returnPressed.connect(self.onAddNote) self.vBoxMain.addWidget(self.notesArea) self.mainViewGroup = QGroupBox() self.mainViewGroup.setTitle("Main View") self.mainViewGroup.setLayout(self.vBoxMain) # join both sides together self.leftRightSplit = QSplitter(Qt.Horizontal) self.leftRightSplit.addWidget(self.altViewSplit) self.leftRightSplit.addWidget(self.mainViewGroup) self.setCentralWidget(self.leftRightSplit) def initUIToolbar(self): mainMenu = self.menuBar( ) # get the menu bar already in use by this QMainWindow subclass fileMenu = mainMenu.addMenu("File") editMenu = mainMenu.addMenu("Edit") LayoutMenu = mainMenu.addMenu("Layout") AboutMenu = mainMenu.addMenu("About") saveAction = fileMenu.addAction("Save") quitAction = fileMenu.addAction("Exit Bettersheets") quitAction.triggered.connect(self.quitApp) copyAction = editMenu.addAction("Copy") resetAction = LayoutMenu.addAction("Reset Default Layout") self.toolBar = self.addToolBar("Tools") self.toolBar.addAction(saveAction) self.toolBar.addAction(copyAction) def contextMenuEvent(self, event): # return super().contextMenuEvent(event) contextMenu = QMenu() selectAction = contextMenu.addAction("Select Area") extractAction = contextMenu.addAction("Extract Content") openAction = contextMenu.addAction("Open PDF") closeAction = contextMenu.addAction("Close PDF") quitAction = contextMenu.addAction("Quit") triggered_action = contextMenu.exec_(self.mapToGlobal(event.pos())) if triggered_action == quitAction: self.quitApp() def quitApp(self): self.close() def onAddNote(self): print("note added") text = self.notesArea.text() if text: self.notesDB.append(text) self.notesDisplay.clear() self.notesDisplay.addItems(self.notesDB) self.notesArea.clear() def initPdfViewer(self, openPages: int): pass def initToC(self): # get table of contents ToC = self.myPdfContext.getToC() ToC_headings_list = [x[1] for x in ToC] self.ToCListView.clear() self.ToCListView.addItems(ToC_headings_list)
class Ui_FilewriterCtrl(object): def setupUi(self, FilewriterCtrl): FilewriterCtrl.resize(649, 450) broker_placeholder_text = "address:port/topic" self.central_widget = QWidget(FilewriterCtrl) self.vertical_layout_2 = QVBoxLayout(self.central_widget) self.vertical_layout = QVBoxLayout() self.horizontal_layout = QHBoxLayout() self.horizontal_layout.setContentsMargins(-1, -1, 0, -1) self.status_layout = QVBoxLayout() self.status_layout.setContentsMargins(-1, -1, -1, 0) self.status_topic_layout = QHBoxLayout() self.status_topic_layout.setContentsMargins(-1, -1, -1, 0) self.status_broker_label = QLabel(self.central_widget) self.status_topic_layout.addWidget(self.status_broker_label) self.status_broker_edit = QLineEdit(self.central_widget) self.status_broker_edit.setPlaceholderText(broker_placeholder_text) self.status_topic_layout.addWidget(self.status_broker_edit) self.status_layout.addLayout(self.status_topic_layout) self.line_2 = QFrame(self.central_widget) self.line_2.setFrameShape(QFrame.HLine) self.line_2.setFrameShadow(QFrame.Sunken) self.status_layout.addWidget(self.line_2) self.file_writer_table_group = QGroupBox(self.central_widget) size_policy = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Expanding) size_policy.setHorizontalStretch(0) size_policy.setVerticalStretch(1) size_policy.setHeightForWidth( self.file_writer_table_group.sizePolicy().hasHeightForWidth()) self.file_writer_table_group.setSizePolicy(size_policy) self.vertical_layout_4 = QVBoxLayout(self.file_writer_table_group) self.vertical_layout_3 = QVBoxLayout() self.file_writers_list = QTreeView(self.file_writer_table_group) self.file_writers_list.setEditTriggers( QAbstractItemView.NoEditTriggers) self.file_writers_list.setIndentation(0) self.vertical_layout_3.addWidget(self.file_writers_list) self.vertical_layout_4.addLayout(self.vertical_layout_3) self.status_layout.addWidget(self.file_writer_table_group) self.files_group = QGroupBox(self.central_widget) size_policy.setHorizontalStretch(0) size_policy.setVerticalStretch(4) size_policy.setHeightForWidth( self.files_group.sizePolicy().hasHeightForWidth()) self.files_group.setSizePolicy(size_policy) self.vertical_layout_6 = QVBoxLayout(self.files_group) self.files_list = QTreeView(self.files_group) self.files_list.setIndentation(0) self.vertical_layout_6.addWidget(self.files_list) self.vertical_layout_5 = QVBoxLayout() self.horizontal_layout_4 = QHBoxLayout() spacer = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) self.horizontal_layout_4.addItem(spacer) self.stop_file_writing_button = QPushButton(self.files_group) self.stop_file_writing_button.setEnabled(False) self.horizontal_layout_4.addWidget(self.stop_file_writing_button) self.vertical_layout_5.addLayout(self.horizontal_layout_4) self.vertical_layout_6.addLayout(self.vertical_layout_5) self.status_layout.addWidget(self.files_group) self.horizontal_layout.addLayout(self.status_layout) self.line = QFrame(self.central_widget) self.line.setFrameShape(QFrame.VLine) self.line.setFrameShadow(QFrame.Sunken) self.horizontal_layout.addWidget(self.line) self.command_layout = QVBoxLayout() self.command_layout.setContentsMargins(-1, 0, -1, 0) self.command_broker_layout = QHBoxLayout() self.command_broker_label = QLabel(self.central_widget) self.command_broker_layout.addWidget(self.command_broker_label) self.command_broker_edit = QLineEdit(self.central_widget) self.command_broker_edit.setPlaceholderText(broker_placeholder_text) self.command_broker_layout.addWidget(self.command_broker_edit) self.command_layout.addLayout(self.command_broker_layout) self.command_widget = FilewriterCommandWidget(FilewriterCtrl) self.command_layout.addWidget(self.command_widget) self.horizontal_layout.addLayout(self.command_layout) self.vertical_layout.addLayout(self.horizontal_layout) self.vertical_layout_2.addLayout(self.vertical_layout) FilewriterCtrl.setCentralWidget(self.central_widget) self.status_broker_label.setText("Status broker") self.file_writer_table_group.setTitle("File-writers") self.files_group.setTitle("Files") self.stop_file_writing_button.setText("Stop file-writing") self.command_broker_label.setText("Command broker") self.command_broker_edit.setPlaceholderText("address:port/topic") QMetaObject.connectSlotsByName(FilewriterCtrl)
class Card(QWidget): def __init__(self, parent: QWidget, card_details: Dict[str, Any]): super().__init__() if parent is not None: self.setParent(parent) self.model = create_card(card_details) self.setupUi() def get_card_background_colour(self): if isinstance(self.model, SpellCard): return QColor(CardColours[CardType.SPELL]) elif isinstance(self.model, TrapCard): return QColor(CardColours[CardType.TRAP]) else: pass def setupUi(self): self.main_layout = QVBoxLayout() self.name_attr_layout = QHBoxLayout() self.name_label = QLabel(self.model.name) font = self.name_label.font() font.setBold(True) font.setCapitalization(QFont.AllUppercase) font.setPointSize(12) self.name_label.setFont(font) self.name_label.setMargin(5) pixmap = get_attr_icon(self.model.attribute) self.attr_icon = QLabel() self.attr_icon.setPixmap(pixmap) self.attr_icon.setAlignment(Qt.AlignRight) self.name_attr_layout.addWidget(self.name_label) self.name_attr_layout.addWidget(self.attr_icon) self.main_layout.addLayout(self.name_attr_layout) self.level_layout = QHBoxLayout() self.main_layout.addLayout(self.level_layout) self.picture_frame = QFrame() self.picture_frame.setFixedSize(250, 250) self.picture_frame.setFrameStyle(QFrame.Box | QFrame.Plain) self.picture_frame.setFrameShadow(QFrame.Shadow.Raised) self.picture_frame.setLineWidth(1) self.picture_frame.setContentsMargins(0, 0, 0, 0) self.picture_frame.setLayout(QGridLayout()) self.image_holder = QLabel() pixmap = self._get_card_image() self.image_holder.setPixmap( pixmap.scaled( self.picture_frame.width(), self.picture_frame.height(), Qt.KeepAspectRatio, )) self.picture_frame.layout().addWidget(self.image_holder) self.main_layout.addWidget(self.picture_frame) # Card sets here? self.desc_group_box = QGroupBox() self.desc_group_box.setMaximumWidth(250) self.set_up_group_box() self.main_layout.addWidget(self.desc_group_box) self.id_label = QLabel(self.model.id) self.id_label.setAlignment(Qt.AlignLeft) self.id_label.setMargin(5) self.main_layout.addWidget(self.id_label) self.setLayout(self.main_layout) pal = QPalette() pal.setColor(QPalette.Background, self.get_card_background_colour()) self.setAutoFillBackground(True) self.setPalette(pal) def _get_card_image(self): image_name = self.model.img_url.split("/")[-1] if os.path.exists(self.get_image_path(image_name)): image = Image.open(self.get_image_path(image_name)) else: image_data = requests.get(self.model.img_url).content image = Image.open(BytesIO(image_data)) image.save(self.get_image_path(image_name)) image = image.crop((44, 106, 380, 438)) # this is about correct data = image.tobytes("raw", "RGB") qimage = QImage(data, image.size[0], image.size[1], QImage.Format_RGB888) pixmap = QPixmap.fromImage(qimage) return pixmap def get_image_path(self, image_name): return os.path.join(os.getcwd(), "images", image_name) def set_up_group_box(self): self.desc_group_box.setLayout(QVBoxLayout()) self.desc_label = QLabel(self.model.desc) self.desc_label.setWordWrap(True) self.desc_group_box.layout().addWidget(self.desc_label) if isinstance(self.model, (MonsterCard)): self.desc_group_box.setTitle(self.get_group_box_title()) line = QFrame() line.setFrameShape((QFrame.HLine)) line.setFrameShadow(QFrame.Sunken) self.desc_group_box.layout().addWidget(line) label = QLabel( f"ATK/{self.model.attack} DEF/{self.model.defence}") label.setAlignment(Qt.AlignRight) self.desc_group_box.layout().addWidget(label) def get_group_box_title(self): return "[TEST/TEST]"