def testDictionary(self): confFile = tempfile.NamedTemporaryFile(delete=False) s = QSettings(confFile.name, QSettings.IniFormat) # Save value s.setValue('x', {1: 'a'}) s.sync() del s # Restore value s = QSettings(confFile.name, QSettings.IniFormat) self.assertEqual(s.value('x'), {1: 'a'})
def saveGeomerty(self): settings = QSettings(sGeomertyIniFile, QSettings.IniFormat) settings.setValue(sGeometry, self.saveGeometry())
def writeSettings(self): settings = QSettings('Trolltech', 'MDI Example') settings.setValue('pos', self.pos()) settings.setValue('size', self.size())
def read_settings(self): settings = QSettings() settings.beginGroup('playlist') self.widget.saved_playlists_path = settings.value('path') settings.endGroup()
def __init__( self, document: Optional[vp.Document] = None, view_mode: ViewMode = ViewMode.PREVIEW, show_pen_up: bool = False, show_points: bool = False, parent=None, ): super().__init__(parent) self._settings = QSettings() self._settings.beginGroup("viewer") self.setWindowTitle("vpype viewer") self.setStyleSheet(""" QToolButton:pressed { background-color: rgba(0, 0, 0, 0.2); } """) self._viewer_widget = QtViewerWidget(parent=self) # setup toolbar self._toolbar = QToolBar() self._icon_size = QSize(32, 32) self._toolbar.setIconSize(self._icon_size) view_mode_grp = QActionGroup(self._toolbar) if _DEBUG_ENABLED: act = view_mode_grp.addAction("None") act.setCheckable(True) act.setChecked(view_mode == ViewMode.NONE) act.triggered.connect( functools.partial(self.set_view_mode, ViewMode.NONE)) act = view_mode_grp.addAction("Outline Mode") act.setCheckable(True) act.setChecked(view_mode == ViewMode.OUTLINE) act.triggered.connect( functools.partial(self.set_view_mode, ViewMode.OUTLINE)) act = view_mode_grp.addAction("Outline Mode (Colorful)") act.setCheckable(True) act.setChecked(view_mode == ViewMode.OUTLINE_COLORFUL) act.triggered.connect( functools.partial(self.set_view_mode, ViewMode.OUTLINE_COLORFUL)) act = view_mode_grp.addAction("Preview Mode") act.setCheckable(True) act.setChecked(view_mode == ViewMode.PREVIEW) act.triggered.connect( functools.partial(self.set_view_mode, ViewMode.PREVIEW)) self.set_view_mode(view_mode) # VIEW MODE # view modes view_mode_btn = QToolButton() view_mode_menu = QMenu(view_mode_btn) act = view_mode_menu.addAction("View Mode:") act.setEnabled(False) view_mode_menu.addActions(view_mode_grp.actions()) view_mode_menu.addSeparator() # show pen up act = view_mode_menu.addAction("Show Pen-Up Trajectories") act.setCheckable(True) act.setChecked(show_pen_up) act.toggled.connect(self.set_show_pen_up) self._viewer_widget.engine.show_pen_up = show_pen_up # show points act = view_mode_menu.addAction("Show Points") act.setCheckable(True) act.setChecked(show_points) act.toggled.connect(self.set_show_points) self._viewer_widget.engine.show_points = show_points # preview mode options view_mode_menu.addSeparator() act = view_mode_menu.addAction("Preview Mode Options:") act.setEnabled(False) # pen width pen_width_menu = view_mode_menu.addMenu("Pen Width") act_grp = PenWidthActionGroup(0.3, parent=pen_width_menu) act_grp.triggered.connect(self.set_pen_width_mm) pen_width_menu.addActions(act_grp.actions()) self.set_pen_width_mm(0.3) # pen opacity pen_opacity_menu = view_mode_menu.addMenu("Pen Opacity") act_grp = PenOpacityActionGroup(0.8, parent=pen_opacity_menu) act_grp.triggered.connect(self.set_pen_opacity) pen_opacity_menu.addActions(act_grp.actions()) self.set_pen_opacity(0.8) # debug view if _DEBUG_ENABLED: act = view_mode_menu.addAction("Debug View") act.setCheckable(True) act.toggled.connect(self.set_debug) # rulers view_mode_menu.addSeparator() act = view_mode_menu.addAction("Show Rulers") act.setCheckable(True) val = bool(self._settings.value("show_rulers", True)) act.setChecked(val) act.toggled.connect(self.set_show_rulers) self._viewer_widget.engine.show_rulers = val # units units_menu = view_mode_menu.addMenu("Units") unit_action_grp = QActionGroup(units_menu) unit_type = UnitType(self._settings.value("unit_type", UnitType.METRIC)) act = unit_action_grp.addAction("Metric") act.setCheckable(True) act.setChecked(unit_type == UnitType.METRIC) act.setData(UnitType.METRIC) act = unit_action_grp.addAction("Imperial") act.setCheckable(True) act.setChecked(unit_type == UnitType.IMPERIAL) act.setData(UnitType.IMPERIAL) act = unit_action_grp.addAction("Pixel") act.setCheckable(True) act.setChecked(unit_type == UnitType.PIXELS) act.setData(UnitType.PIXELS) unit_action_grp.triggered.connect(self.set_unit_type) units_menu.addActions(unit_action_grp.actions()) self._viewer_widget.engine.unit_type = unit_type view_mode_btn.setMenu(view_mode_menu) view_mode_btn.setIcon(load_icon("eye-outline.svg")) view_mode_btn.setText("View") view_mode_btn.setPopupMode(QToolButton.InstantPopup) view_mode_btn.setStyleSheet( "QToolButton::menu-indicator { image: none; }") self._toolbar.addWidget(view_mode_btn) # LAYER VISIBILITY self._layer_visibility_btn = QToolButton() self._layer_visibility_btn.setIcon( load_icon("layers-triple-outline.svg")) self._layer_visibility_btn.setText("Layer") self._layer_visibility_btn.setMenu(QMenu(self._layer_visibility_btn)) self._layer_visibility_btn.setPopupMode(QToolButton.InstantPopup) self._layer_visibility_btn.setStyleSheet( "QToolButton::menu-indicator { image: none; }") self._toolbar.addWidget(self._layer_visibility_btn) # FIT TO PAGE fit_act = self._toolbar.addAction(load_icon("fit-to-page-outline.svg"), "Fit") fit_act.triggered.connect(self._viewer_widget.engine.fit_to_viewport) # RULER # TODO: not implemented yet # self._toolbar.addAction(load_icon("ruler-square.svg"), "Units") # MOUSE COORDINATES> self._mouse_coord_lbl = QLabel("") self._mouse_coord_lbl.setMargin(6) self._mouse_coord_lbl.setAlignment(Qt.AlignVCenter | Qt.AlignRight) self._mouse_coord_lbl.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum) self._toolbar.addWidget(self._mouse_coord_lbl) # noinspection PyUnresolvedReferences self._viewer_widget.mouse_coords.connect( self.set_mouse_coords) # type: ignore # setup horizontal layout for optional side widgets self._hlayout = QHBoxLayout() self._hlayout.setSpacing(0) self._hlayout.setMargin(0) self._hlayout.addWidget(self._viewer_widget) widget = QWidget() widget.setLayout(self._hlayout) # setup global vertical layout layout = QVBoxLayout() layout.setSpacing(0) layout.setMargin(0) layout.addWidget(self._toolbar) layout.addWidget(widget) self.setLayout(layout) if document is not None: self.set_document(document)
class EditorWindow(QMainWindow): """Widget which contain the editor.""" def __init__(self, window_handler): super(EditorWindow, self).__init__() self.plugin_manager = PluginManager(self) self.setGeometry(400, 200, 1280, 720) self.widget = EditorWidget(self.plugin_manager) self.settings = QSettings(c.SETTINGS_PATH, QSettings.IniFormat) self.keyboard_settings = QSettings(c.KEYBOARD_SETTINGS_PATH, QSettings.IniFormat) self.theme = self.settings.value(c.THEME, defaultValue=c.THEME_D) self.init_menu_and_toolbar() self.setCentralWidget(self.widget) self.window_handler = window_handler self.last_saved = None def init_menu_and_toolbar(self): """Initialize the menu- and toolbar""" self.menu = self.menuBar() self.file_menu = self.menu.addMenu("File") self.file_menu_new = QAction( QIcon(os.path.join(c.ICON_PATH, self.theme, "new.png")), "New", self) self.file_menu_new.triggered.connect(self.new_project) self.file_menu_open = QAction( QIcon(os.path.join(c.ICON_PATH, self.theme, "open.png")), "Open", self) self.file_menu_open.triggered.connect(self.open_project_w_file_picker) self.file_menu_save = QAction( QIcon(os.path.join(c.ICON_PATH, self.theme, "save.png")), "Save", self) self.file_menu_save.setShortcut( QKeySequence( self.keyboard_settings.value(c.SAVE_KEY, defaultValue=""))) self.file_menu_save.triggered.connect(self.save_project) self.file_menu.addAction(self.file_menu_new) self.file_menu.addAction(self.file_menu_open) self.file_menu.addAction(self.file_menu_save) self.edit_menu = self.menu.addMenu("Edit") self.edit_menu_undo = QAction( QIcon(os.path.join(c.ICON_PATH, self.theme, "undo.png")), "Undo", self) self.edit_menu_undo.triggered.connect(self.undo) self.edit_menu_undo.setShortcut(QKeySequence("CTRL+Z")) self.edit_menu_redo = QAction( QIcon(os.path.join(c.ICON_PATH, self.theme, "redo.png")), "Redo", self) self.edit_menu_redo.triggered.connect(self.redo) self.edit_menu_redo.setShortcut(QKeySequence("CTRL+Shift+Z")) self.edit_menu_copy = QAction( QIcon(os.path.join(c.ICON_PATH, self.theme, "copy.png")), "Copy", self) self.edit_menu_copy.triggered.connect(self.copy) self.edit_menu_copy.setShortcut(QKeySequence("CTRL+C")) self.edit_menu_paste = QAction( QIcon(os.path.join(c.ICON_PATH, self.theme, "paste.png")), "Paste", self) self.edit_menu_paste.triggered.connect(self.paste) self.edit_menu_paste.setShortcut(QKeySequence("CTRL+V")) self.edit_menu.addAction(self.edit_menu_undo) self.edit_menu.addAction(self.edit_menu_redo) self.edit_menu.addAction(self.edit_menu_copy) self.edit_menu.addAction(self.edit_menu_paste) self.settings_menu = self.menu.addMenu("Settings") self.settings_menu_open = QAction( QIcon(os.path.join(c.ICON_PATH, self.theme, "settings.png")), "Open Settings", self) self.settings_menu_open.triggered.connect(self.open_settings) self.settings_menu.addAction(self.settings_menu_open) self.settings_menu_text = QAction( QIcon(os.path.join(c.ICON_PATH, self.theme, "receipt.png")), "Text modules", self) self.settings_menu_text.triggered.connect(self.open_text_modules) self.settings_menu.addAction(self.settings_menu_text) self.help_menu = self.menu.addMenu("Help") self.help_menu_open = QAction( QIcon(os.path.join(c.ICON_PATH, self.theme, "help.png")), "Open Help", self) self.help_menu_open.triggered.connect(self.open_help) self.help_menu_open.setShortcut(QKeySequence().fromString( self.keyboard_settings.value(c.HELP_KEY, defaultValue=""))) self.help_menu.addAction(self.help_menu_open) self.help_menu_licence = QAction( QIcon(os.path.join(c.ICON_PATH, self.theme, "snippet.png")), "Licences", self) self.help_menu_licence.triggered.connect(self.open_licences) self.help_menu.addAction(self.help_menu_licence) self.setMenuBar(self.menu) self.show_video = QAction( QIcon(os.path.join(c.ICON_PATH, self.theme, "video.png")), "Open-Video", self) self.show_video.triggered.connect(self.widget.show_video) self.activate_tm = QAction( QIcon(os.path.join(c.ICON_PATH, self.theme, "receipt.png")), "Activate Text modules", self) self.activate_tm.setCheckable(True) self.activate_tm.triggered.connect(self.activate_text_modules) self.show_chars = QAction( QIcon(os.path.join(c.ICON_PATH, self.theme, "format.png")), "Show special Characters", self) self.show_chars.setCheckable(True) self.show_chars.triggered.connect(self.show_special_characters) self.toolbar = QToolBar() self.addToolBar(self.toolbar) self.toolbar.addAction(self.file_menu_open) self.toolbar.addAction(self.file_menu_save) self.toolbar.addAction(self.show_video) self.toolbar.addAction(self.activate_tm) self.toolbar.addAction(self.show_chars) self.word_by_word_prev = QAction( QIcon(os.path.join(c.ICON_PATH, self.theme, "prev.png")), "Word by word prev", self) self.word_by_word_prev.triggered.connect(self.on_word_by_word_prev) self.word_by_word_prev.setShortcut(QKeySequence().fromString( self.keyboard_settings.value(c.WORD_BY_WORD_KEY_PREV, defaultValue=""))) self.toolbar.addAction(self.word_by_word_prev) self.word_by_word_next = QAction( QIcon(os.path.join(c.ICON_PATH, self.theme, "next.png")), "Word by word next", self) self.word_by_word_next.triggered.connect(self.on_word_by_word) self.word_by_word_next.setShortcut(QKeySequence().fromString( self.keyboard_settings.value(c.WORD_BY_WORD_KEY_NEXT, defaultValue=""))) self.toolbar.addAction(self.word_by_word_next) self.time_stamp = QAction( QIcon(os.path.join(c.ICON_PATH, self.theme, "timestamp.png")), "Insert Timestamp", self) self.time_stamp.triggered.connect(self.insert_time_stamp) self.toolbar.addAction(self.time_stamp) for action in self.plugin_manager.get_toolbar_actions(self): self.toolbar.addAction(action) self.font_box = QComboBox() self.fonts = QFontDatabase().families() self.font_box.addItems(self.fonts) self.font_box.setCurrentIndex( self.fonts.index(QFontInfo(self.widget.font).family())) self.font_box.currentIndexChanged.connect(self.on_font_change) self.font_size = QComboBox() self.sizes = [ "8", "9", "10", "11", "12", "14", "16", "18", "20", "22", "24", "26", "28", "36", "48", "72" ] self.font_size.addItems(self.sizes) self.font_size.setCurrentIndex(6) self.font_size.currentIndexChanged.connect(self.on_font_change) self.toolbar.addWidget(self.font_box) self.toolbar.addWidget(self.font_size) self.status_bar = QStatusBar() self.language_label = QLabel() self.project_folder_path_label = QLabel() self.hint_label = QLabel() self.hint_label.setMaximumWidth(300) self.status_bar.addPermanentWidget(self.project_folder_path_label) self.status_bar.addPermanentWidget(self.language_label) self.status_bar.addWidget(self.hint_label) self.setStatusBar(self.status_bar) self.setWindowIcon( QIcon(os.path.join(c.ICON_PATH, c.THEME_NEUTRAL, "quote.png"))) self.text_modules_window = TextModuleWindow(self) self.settings_window = SettingsWindow() self.licence_window = LicenceWindow(self.plugin_manager) def new_project(self): """Opens the create new project window.""" self.window_handler.open_create_new_project_window() def open_project_w_file_picker(self): """Opens a folder dialog to open another project.""" msg_box = QMessageBox() msg_box.setText( "Do you really want to open a new Project? \nProject last saved on: " + (self.last_saved if self.last_saved is not None else "never")) msg_box.setWindowTitle("Open Project") msg_box.setStandardButtons(QMessageBox.Ok | QMessageBox.Cancel) msg_box.setWindowIcon( QIcon(os.path.join(c.ICON_PATH, c.THEME_NEUTRAL, "quote.png"))) return_val = msg_box.exec_() if return_val == QMessageBox.Cancel: return folder_path = QFileDialog.getExistingDirectory( self, "Choose a Project Folder") if folder_path == "": return self.open_project(os.path.normpath(folder_path)) def open_project(self, project_folder_path): """Opens the choosen project. Args: project_folder_path: The folder of the project which should be opened. """ self.project_folder_path = project_folder_path self.widget.open_project(self.project_folder_path) self.project_folder_path_label.setText(self.project_folder_path) self.language = file_util.get_value_from_shelve( self.project_folder_path, c.LANGUAGE) self.language_label.setText(self.language) self.setWindowTitle(os.path.basename(self.project_folder_path)) self.plugin_manager.project_loaded() def save_project(self): """Saves the current transcription.""" file_util.write_text_file(self.project_folder_path, self.widget.text.toPlainText(), c.TRANSCRIPTION) self.last_saved = datetime.now().strftime("%H:%M:%S") self.setWindowTitle( os.path.basename(self.project_folder_path) + " - last saved on: " + self.last_saved) def undo(self): self.widget.text.undo() def redo(self): self.widget.text.redo() def copy(self): self.widget.text.copy() def paste(self): self.widget.text.paste() def open_settings(self): """Opens the settings window.""" if self.settings_window.isVisible(): self.settings_window.hide() else: self.settings_window.show() def open_help(self): """Opens the manual.pdf in the installed pdf viewer.""" guide_path = os.path.join(c.ASSETS_PATH, "docs", "manual.pdf") os.system(guide_path) def on_font_change(self): """Calls the change font method of the widget.""" self.widget.change_font(self.font_box.currentText(), self.font_size.currentText()) def open_text_modules(self): """Opens the text modules window.""" if self.text_modules_window.isVisible(): self.text_modules_window.hide() else: self.text_modules_window.show() def on_text_modules_change(self): """If the text_modules change, then update then in the widget.""" self.widget.get_text_modules() def activate_text_modules(self): """Deactivates or activates the text_modules.""" self.widget.activate_text_modules = self.activate_tm.isChecked() def show_special_characters(self): """Deactivates or activates the special characters.""" self.widget.show_special_characters(self.show_chars.isChecked()) def on_word_by_word(self): """Is executed when the on word by word button is pressed.""" self.widget.on_word_by_word() def on_word_by_word_prev(self): """Is executed when the on prev. word by word button is pressed.""" self.widget.on_word_by_word_prev() def get_selection(self): """Returns the current selection Returns: Current selection. """ return self.widget.get_selection() def replace_selection(self, new_word): """Replace the current selection Args: new_word: the replacement. """ self.widget.replace_selection(new_word) def get_text(self): """Returns the current text. Returns: The current text. """ return self.widget.get_text() def set_text(self, new_text): """Sets the new_text in the editor widget. Args: new_text: The new text. """ self.widget.set_text(new_text) def get_word_at(self, pos): """Gets the word at a specific position. Args: pos: The position of the word. Returns: The word at this position. """ return self.widget.get_word_at(pos) def set_word_at(self, word, pos, replace_old): """Sets the word at the given position. Args: word: The replacement. pos: The position to place the word. replace_old: True if the old one should be replaced, false if the word is should be set before the other word. """ self.widget.set_word_at(word, pos, replace_old) def open_licences(self): """Opens the licence window.""" if self.licence_window.isVisible(): self.licence_window.hide() else: self.licence_window.show() def add_new_word_by_word_action(self, btns, name, word, word_pos): """Adds a new Word-Action (QPushButton) to the editor word by word list. Args: btns: The QPushButtons from the plugin. name: The Name of the Buttons. word: The word for which these buttons are. word_pos: The position of the word. """ self.widget.add_new_word_by_word_action(btns, name, word, word_pos) def get_language(self): """Returns the language of the current project. Returns: The language of the current project. """ return self.language def keyPressEvent(self, key_event: QKeyEvent): """Catches the Keypress-Events. In this case, if the key is esc then the word by word editing mode will be closed. Args: key_event: QKeyEvent: The key event """ super(EditorWindow, self).keyPressEvent(key_event) if key_event.key() == Qt.Key_Escape: self.widget.reset_word_by_word() def set_hint_text(self, text): """Sets the hint text (left bottom corner) in the editor. Args: text: The Hint text. """ self.hint_label.setText(text) def set_text_with_line_breaks(self, text): """Sets the Text in the editor but tries to restore the given linebreaks. Args: new_text: The new text. """ self.widget.set_text_with_line_breaks(text) def insert_time_stamp(self): """Insert a timestamp at the current cursor position.""" self.widget.insert_time_stamp() def get_project_folder_path(self): """Get the current project folder path Returns: Project folder path. """ return self.project_folder_path def closeEvent(self, event): """Catches the close event. Shows a message if the programm should really be closed. Args: event: the close event. """ msg_box = QMessageBox() msg_box.setText( "Do you really want to close this window? \nProject last saved on: " + (self.last_saved if self.last_saved is not None else "never")) msg_box.setWindowTitle("Close LazyTranscript") msg_box.setStandardButtons(QMessageBox.Ok | QMessageBox.Cancel) msg_box.setWindowIcon( QIcon(os.path.join(c.ICON_PATH, c.THEME_NEUTRAL, "quote.png"))) return_val = msg_box.exec_() if return_val == QMessageBox.Ok: event.accept() else: event.ignore()
class EditorWidget(QWidget): """Widget which contain the editor.""" def __init__(self, plugin_manager): super(EditorWidget, self).__init__() os.environ[ 'QT_MULTIMEDIA_PREFERRED_PLUGINS'] = 'windowsmediafoundation' self.plugin_manager = plugin_manager #parent layout self.v_box = QVBoxLayout() self.h_box = QHBoxLayout() # parent splitter for the text and numbers self.text_h_box = QSplitter(Qt.Horizontal) self.text_h_box.splitterMoved.connect(self.on_text_changed) self.settings = QSettings(c.SETTINGS_PATH, QSettings.IniFormat) self.keyboard_settings = QSettings(c.KEYBOARD_SETTINGS_PATH, QSettings.IniFormat) self.theme = self.settings.value(c.THEME, defaultValue=c.THEME_D) # font settings self.font = QFont( self.settings.value(c.FONT, defaultValue="Arial", type=str)) self.font.setPointSize( self.settings.value(c.FONT_SIZE, defaultValue=16, type=int)) # the text widget itself self.text = QPlainTextEdit() self.text.setFont(self.font) self.text.textChanged.connect(self.on_text_changed) self.text.setFocusPolicy(Qt.StrongFocus) # the number text widget to show the row numbers self.numbers = QPlainTextEdit() self.numbers.setFont(self.font) self.numbers.setReadOnly(True) self.numbers.setMinimumWidth(20) self.numbers.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.numbers.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.numbers.setLineWrapMode(QPlainTextEdit.NoWrap) self.numbers.setFocusPolicy(Qt.NoFocus) self.numbers.setFrameStyle(QFrame.NoFrame) self.numbers.setStyleSheet("background-color: rgba(0,0,0,0%)") # sync the text widget and number widget self.text_bar = self.text.verticalScrollBar() self.number_bar = self.numbers.verticalScrollBar() #self.number_bar.valueChanged.connect(self.text_bar.setValue) self.text_bar.valueChanged.connect(self.number_bar.setValue) # add them into their layout self.text_h_box.addWidget(self.numbers) self.text_h_box.addWidget(self.text) self.text_h_box.setSizes([10, 700]) # layout which holds the media controls in the bottom self.media_controls = QHBoxLayout() self.media_controls_settings = QVBoxLayout() self.media_controls_slider_h_box = QHBoxLayout() # direct player controls self.btn_size = 75 self.play_icon = QIcon( os.path.join(c.ICON_PATH, self.theme, "play.png")) self.pause_icon = QIcon( os.path.join(c.ICON_PATH, self.theme, "pause.png")) self.play_btn = QPushButton(icon=self.play_icon) self.play_btn.clicked.connect(self.on_play) self.play_btn.setFixedSize(self.btn_size, self.btn_size) self.play_btn.setIconSize(QSize(self.btn_size, self.btn_size)) self.play_btn.setFlat(True) self.play_btn.setShortcut(QKeySequence().fromString( self.keyboard_settings.value(c.PLAY_PAUSE_KEY, defaultValue=""))) self.forward_btn = QPushButton( icon=QIcon(os.path.join(c.ICON_PATH, self.theme, "forward.png"))) self.forward_btn.clicked.connect(self.on_forward) self.forward_btn.setFixedSize(self.btn_size, self.btn_size) self.forward_btn.setIconSize(QSize(self.btn_size, self.btn_size)) self.forward_btn.setFlat(True) self.forward_btn.setShortcut(QKeySequence().fromString( self.keyboard_settings.value(c.FORWARD_KEY, defaultValue=""))) self.backward_btn = QPushButton( icon=QIcon(os.path.join(c.ICON_PATH, self.theme, "backward.png"))) self.backward_btn.clicked.connect(self.on_backward) self.backward_btn.setFixedSize(self.btn_size, self.btn_size) self.backward_btn.setIconSize(QSize(self.btn_size, self.btn_size)) self.backward_btn.setFlat(True) self.backward_btn.setShortcut(QKeySequence().fromString( self.keyboard_settings.value(c.BACKWARDS_KEY, defaultValue=""))) # add them to the layout self.media_controls.addStretch() self.media_controls.addWidget(self.backward_btn) self.media_controls.addWidget(self.play_btn) self.media_controls.addWidget(self.forward_btn) self.media_controls.addStretch(4) # slider which shows the current time self.time_slider = QSlider(Qt.Horizontal) self.time_slider.sliderMoved.connect(self.on_time_slider_moved) # label on the right of the slider, which shows the current time self.time_label = QLabel("00:00/00:00") self.media_controls_slider_h_box.addWidget(self.time_slider) self.media_controls_slider_h_box.addWidget(self.time_label) # icons for the other sliders self.vol_icon = QIcon( os.path.join(c.ICON_PATH, self.theme, "volume.png")).pixmap(QSize(32, 32)) self.rate_icon = QIcon( os.path.join(c.ICON_PATH, self.theme, "playbackrate.png")).pixmap(QSize(32, 32)) self.rewind_icon = QIcon( os.path.join(c.ICON_PATH, self.theme, "time.png")).pixmap(QSize(32, 32)) # display the icons through labels self.vol_icon_label = QLabel() self.vol_icon_label.setPixmap(self.vol_icon) self.rate_icon_label = QLabel() self.rate_icon_label.setPixmap(self.rate_icon) self.rewind_rewind_label = QLabel() self.rewind_rewind_label.setPixmap(self.rewind_icon) # init of the other sliders self.vol_slider = QSlider(Qt.Horizontal) self.vol_slider.sliderMoved.connect(self.on_vol_slider_moved) self.vol_slider.setFixedWidth(250) self.vol_slider.setRange(1, 100) self.rate_slider = QSlider(Qt.Horizontal) self.rate_slider.sliderMoved.connect(self.on_rate_slider_moved) self.rate_slider.setFixedWidth(250) self.rate_slider.setRange(1, 20) self.rewind_time = 10 self.rewind_slider = QSlider(Qt.Horizontal) self.rewind_slider.sliderMoved.connect(self.on_rewind_slider_moved) self.rewind_slider.setFixedWidth(250) self.rewind_slider.setRange(1, 60) self.rewind_slider.setValue(self.rewind_time) # labels for the values self.vol_label = QLabel() self.rate_label = QLabel() self.rewind_label = QLabel() # create hbox for each of the three sliders self.vol_h_box = QHBoxLayout() self.vol_h_box.addWidget(self.vol_label) self.vol_h_box.addWidget(self.vol_slider) self.vol_h_box.addWidget(self.vol_icon_label) self.rate_h_box = QHBoxLayout() self.rate_h_box.addWidget(self.rate_label) self.rate_h_box.addWidget(self.rate_slider) self.rate_h_box.addWidget(self.rate_icon_label) self.rewind_h_box = QHBoxLayout() self.rewind_h_box.addWidget(self.rewind_label) self.rewind_h_box.addWidget(self.rewind_slider) self.rewind_h_box.addWidget(self.rewind_rewind_label) # group them together in a vlayout self.media_controls_settings.addLayout(self.vol_h_box) self.media_controls_settings.addLayout(self.rewind_h_box) self.media_controls_settings.addLayout(self.rate_h_box) # add this layout to the layout which already contains the buttons self.media_controls.addLayout(self.media_controls_settings) self.word_by_word_actions = QListWidget() self.word_by_word_actions.setMaximumWidth(150) self.h_box.addWidget(self.text_h_box) self.h_box.addWidget(self.word_by_word_actions) # group all ungrouped layouts and widgets to the parent layout self.v_box.addLayout(self.h_box, 10) self.v_box.addLayout(self.media_controls_slider_h_box, 1) self.v_box.addLayout(self.media_controls, 1) # set parent layout self.setLayout(self.v_box) # init media_player self.media_player = QMediaPlayer() self.video_widget = QVideoWidget() self.video_widget.setGeometry(200, 200, 500, 300) self.video_widget.setWindowTitle("Output") self.media_player.setVideoOutput(self.video_widget) self.media_player.positionChanged.connect(self.on_position_change) self.media_player.durationChanged.connect(self.on_duration_change) self.vol_slider.setValue(self.media_player.volume()) self.rate_slider.setValue(int(self.media_player.playbackRate() * 10)) self.on_vol_slider_moved(self.media_player.volume()) self.on_rate_slider_moved(self.media_player.playbackRate() * 10) self.on_rewind_slider_moved(self.rewind_time) self.activate_text_modules = False self.get_text_modules() self.text_option_on = QTextOption() self.text_option_on.setFlags( QTextOption.ShowTabsAndSpaces | QTextOption.ShowLineAndParagraphSeparators) self.text_option_off = QTextOption() self.transcription_meta_data = None self.word_pos = -1 self.word_start_time = None self.word_end_time = None self.tcf_highlight = QTextCharFormat() self.tcf_highlight.setBackground(Qt.red) self.tcf_normal = QTextCharFormat() self.tcf_normal.setBackground(Qt.transparent) self.show_empty_buttons = self.settings.value(c.SHOW_EMPTY_BUTTONS, defaultValue=True, type=bool) def on_position_change(self, position): """Is executed when media is played (position is changed) Args: position: Current position (ms) of the media player. """ self.time_slider.setValue(position) self.time_label.setText( create_time_string(position, self.media_player.duration())) if self.word_end_time is None: return if position > self.word_end_time: self.on_play() self.word_start_time = None self.word_end_time = None def on_duration_change(self, duration): """Is executed when duration of the media changes. Args: duration: duration of the media. """ self.time_slider.setRange(0, duration) self.time_label.setText( create_time_string(0, self.media_player.duration())) def on_time_slider_moved(self, value): """Is executed when the time slider was moved. Args: value: current value of the slider. """ self.media_player.setPosition(value) def on_vol_slider_moved(self, value): """Is executed when the volume slider is moved. Args: value: current value of the slider. """ self.media_player.setVolume(value) self.vol_label.setText(str(value) + "%") def on_rate_slider_moved(self, value): """Is executed when the rate slider is moved. Args: value: current value of the slider. """ self.media_player.setPlaybackRate(value / 10) self.rate_label.setText(str(value / 10) + "x") def on_rewind_slider_moved(self, value): """Is executed when the rewind slider is moved. Args: value: current value of the slider. """ self.rewind_time = value self.rewind_label.setText(str(value) + "s") def on_play(self): """Is executed when the play or pause button is pressed.""" if self.media_player.state() == QMediaPlayer.PlayingState: self.media_player.pause() self.play_btn.setIcon(self.play_icon) else: self.media_player.play() self.play_btn.setIcon(self.pause_icon) def on_forward(self): """Is executed when the forward button is pressed.""" self.media_player.setPosition(self.media_player.position() + self.rewind_time * 1000) def on_backward(self): """Is executed when the backward button is pressed.""" self.media_player.setPosition(self.media_player.position() - self.rewind_time * 1000) def on_text_changed(self): """Is executed when the text changed Calculates the line numbers and sets the text modules if activated. """ lines = int( self.text.document().documentLayout().documentSize().height()) self.numbers.setPlainText("") text = "" for i in range(1, lines + 1): text = text + str(i) + "\n" self.numbers.setPlainText(text) self.number_bar.setSliderPosition(self.text_bar.sliderPosition()) new_text = self.text.toPlainText() if self.activate_text_modules == True: for key in self.text_modules.keys(): to_replace = " " + key + " " to_replace_with = " " + self.text_modules[key] + " " new_text = new_text.replace(to_replace, to_replace_with) if self.text.toPlainText() != new_text: old_pos = self.text.textCursor().position() self.text.setPlainText(new_text) cursor = self.text.textCursor() cursor.setPosition(old_pos, QTextCursor.MoveAnchor) cursor.movePosition(QTextCursor.EndOfWord) cursor.movePosition(QTextCursor.NextCharacter) self.text.setTextCursor(cursor) def show_video(self): """Shows or hides the video feed.""" if self.video_widget.isVisible(): self.video_widget.hide() else: self.video_widget.show() def open_project(self, project_folder_path): """Opens a project. Args: project_folder_path: folder of the project which should be opened. """ self.project_folder_path = project_folder_path self.media_file = file_util.get_file(self.project_folder_path, c.CON_COPY_POSTFIX) if self.media_file is None: self.hide() return self.media_player.setMedia( QMediaContent(QUrl.fromLocalFile(self.media_file))) self.transcription_path = file_util.get_file(self.project_folder_path, c.TRANSCRIPTION) if self.transcription_path is None: self.hide() return with open(self.transcription_path, 'r') as f: text = f.read() self.text.setPlainText(text) self.transcription_meta_data = file_util.get_value_from_shelve( self.project_folder_path, c.TRANSCRIPTION_META_DATA) print(self.transcription_meta_data) def change_font(self, new_font, new_size): """Changes the font. Args: new_font: Name of the new font. new_size: New font size. """ self.font = QFont(new_font) self.font.setPointSize(int(new_size)) self.text.setFont(self.font) self.numbers.setFont(self.font) self.settings.setValue(c.FONT_SIZE, int(new_size)) self.settings.setValue(c.FONT, new_font) def get_text_modules(self): """Gets the saved text_modules from the settings.""" self.text_modules = self.settings.value(c.TEXT_MODULES, defaultValue={}) def show_special_characters(self, bol): """Displays the special characters. Args: bol: true or false. """ if bol: self.text.document().setDefaultTextOption(self.text_option_on) else: self.text.document().setDefaultTextOption(self.text_option_off) def on_word_by_word(self): """Selects the next or first word in the on word by word editing mode. For that purpose th word_postion is increased and the next word is marked via the textcursor. If everything works correctly the population of the list will be started. """ self.word_pos += 1 #if self.media_player.state() == QMediaPlayer.PlayingState: # return if self.word_pos > len(self.text.toPlainText().split()) - 1: self.reset_word_by_word() return cursor = self.text.textCursor() if self.word_pos == 0: self.show_empty_buttons = self.settings.value(c.SHOW_EMPTY_BUTTONS, defaultValue=True, type=bool) cursor.setPosition(QTextCursor.Start, QTextCursor.MoveAnchor) cursor.movePosition(QTextCursor.StartOfWord, QTextCursor.MoveAnchor) cursor.movePosition(QTextCursor.EndOfWord, QTextCursor.KeepAnchor) self.text.setEnabled(False) else: cursor.movePosition(QTextCursor.NextWord, QTextCursor.MoveAnchor) cursor.movePosition(QTextCursor.EndOfWord, QTextCursor.KeepAnchor) self.text.setTextCursor(cursor) selected_word = cursor.selectedText() if not selected_word: self.word_pos -= 1 self.on_word_by_word() return # change to find all meta data meta_data_with_word = self.find_meta_data(selected_word) self.populate_word_actions(selected_word, meta_data_with_word) def on_word_by_word_prev(self): """Same as word for word but selects to the previous word.""" if self.word_pos < 1: return self.word_pos -= 2 cursor = self.text.textCursor() count = 0 cursor.setPosition(QTextCursor.Start, QTextCursor.MoveAnchor) cursor.movePosition(QTextCursor.StartOfWord, QTextCursor.MoveAnchor) cursor.movePosition(QTextCursor.EndOfWord, QTextCursor.KeepAnchor) while count < self.word_pos: cursor.movePosition(QTextCursor.NextWord, QTextCursor.MoveAnchor) cursor.movePosition(QTextCursor.EndOfWord, QTextCursor.KeepAnchor) count += 1 self.text.setTextCursor(cursor) self.on_word_by_word() def reset_word_by_word(self): """Resets the word by word editing mode and goes back to the normal editing.""" self.word_pos = -1 self.play_to = -1 self.text.setEnabled(True) self.word_by_word_actions.clear() cleaned = self.text.textCursor() cleaned.clearSelection() self.text.setTextCursor(cleaned) def populate_word_actions(self, selected, word_meta_data): """Calls the plugin_manager to get alle the word for word buttons and initalize the hear again buttons. Args: selected: The selected word. word_meta_data: The meta_data fr the word. """ self.word_by_word_actions.clear() if self.word_pos == len(self.text.toPlainText().split()): return self.plugin_manager.get_word_by_word_actions(selected, word_meta_data, self.word_pos) btns = [] for meta_data in word_meta_data: media_btn = HearButton(self, meta_data) btns.append(media_btn) self.add_new_word_by_word_action(btns, "Hear again", selected, self.word_pos) def add_new_word_by_word_action(self, btns, name, word, word_pos): """Adds a new word by word action. Args: btns: The buttons to add. name: The (plugin-)name of the buttons. word: The word for which these buttons are. word_pos: The word position. """ if not self.show_empty_buttons and len(btns) == 0: return if self.word_pos != word_pos: print("old item", word, word_pos, self.word_pos) return group_item = QListWidgetItem() group_item.setFlags(Qt.ItemIsSelectable) label = QLabel(name) label.setFixedSize(self.word_by_word_actions.width() - 15, 30) label.setContentsMargins(5, 0, 0, 0) label.setWordWrap(True) group_item.setSizeHint(label.size()) self.word_by_word_actions.addItem(group_item) self.word_by_word_actions.setItemWidget(group_item, label) for btn in btns: btn.setFixedSize(self.word_by_word_actions.width() - 15, 30) item = QListWidgetItem() item.setSizeHint(btn.size()) item.setFlags(Qt.ItemIsSelectable) self.word_by_word_actions.addItem(item) self.word_by_word_actions.setItemWidget(item, btn) def find_meta_data(self, word): """Gets all the meta_data for the given word. Args: word: The word for which the meta_data should be found. Returns: The meta_data """ meta_data_with_word = [] for m_d in self.transcription_meta_data: if m_d.get(c.WORD) == word.lower(): meta_data_with_word.append(m_d) return meta_data_with_word def replace_selection(self, new_word): """Replace the selection with the given word Args: new_word: The replacement. """ cursor = self.text.textCursor() old_cursor_pos = cursor.position() cursor.insertText(new_word) cursor.setPosition(old_cursor_pos, QTextCursor.MoveAnchor) cursor.movePosition(QTextCursor.EndOfWord, QTextCursor.MoveAnchor) self.text.setTextCursor(cursor) self.word_by_word_actions.clear() def get_selection(self): """Returns the current selection Returns: The current selection. """ return self.text.textCursor().selectedText() def get_text(self): """Returns the current text Returns: The current text. """ return self.text.toPlainText() def set_text(self, new_text, restore_line_breaks=False): """Replace the text with the new text. Args: new_text: The new text. restore_line_breaks: If true, tries to restore the line breaks. (Default value = False) """ cursor = self.text.textCursor() old_cursor_pos = cursor.position() if restore_line_breaks: self.set_text_with_line_breaks(new_text) else: self.text.setPlainText(new_text) cursor.setPosition(old_cursor_pos, QTextCursor.MoveAnchor) self.text.setTextCursor(cursor) def get_word_at(self, pos): """Returns the word at the given position. Args: pos: The position of the word. Returns: The word at the given position. """ text = self.text.toPlainText().strip().split() if pos < 0 or pos > len(text): return None return text[pos % len(text)] def set_word_at(self, word, pos, replace_old): """Sets the word at the given position. Args: word: The replacement. pos: The position. replace_old: If true, the old word at the position will be replaced, otherwise the word will be set before the old word. """ old_word = self.get_word_at(pos) cursor = self.text.textCursor() cursor_pos = cursor.position() if pos < 0: self.text.setPlainText(word + " " + self.text.toPlainText()) cursor.setPosition(cursor_pos, QTextCursor.MoveAnchor) self.text.setTextCursor(cursor) return text = self.text.toPlainText().strip().split() if replace_old and pos < len(text): if word: text[pos] = word else: text.pop(pos) else: text.insert(pos, word) text = " ".join(text) self.set_text_with_line_breaks(text) cursor_pos += len(word) if replace_old: cursor_pos -= len(old_word) if not word: cursor_pos -= 1 else: cursor_pos += 1 words_to_cursor_pos = self.text.toPlainText()[:cursor_pos].split() self.word_pos = len(words_to_cursor_pos) - 1 cursor.setPosition(cursor_pos, QTextCursor.MoveAnchor) cursor.movePosition(QTextCursor.StartOfWord, QTextCursor.MoveAnchor) self.text.setTextCursor(cursor) def find_line_breaks(self): """Returns the lien breaks in the text. Returns: The positions of the linebreaks """ found = [] start = 0 text = self.text.toPlainText() while True: start = text.find("\n", start) if start == -1: return found found.append(start) start += len("\n") def set_text_with_line_breaks(self, text): """Sets the text with linebreaks. Args: text: the new text. """ line_breaks = self.find_line_breaks() for n in line_breaks: text = text[:n + 1] + "\n" + text[n + 1:] text = text.replace(" \n", "\n") text = text.replace("\n ", "\n") self.text.setPlainText(text) def insert_time_stamp(self): """Inserts the current timestamp at the current cursor position.""" cursor = self.text.textCursor() time = "[" + convert_ms(self.media_player.position()) + "]" cursor.insertText(time) def start_hear_again(self, start_time, end_time): """Starts the audio for the specific word from the hear again button. Args: start_time: When to start the audio. end_time: When to end the audio. """ if self.media_player.state() == QMediaPlayer.PlayingState: return self.media_player.pause() self.word_start_time = start_time self.word_end_time = end_time self.media_player.setPosition(self.word_start_time) self.on_play()
def __init__(self, app, parent=None): super(MainWindow, self).__init__(parent) self.imagesDir = app.dir + '/images/' self.setWindowIcon(QIcon(self.imagesDir + 'icon.png')) self.path = '' self.settings = QSettings() self.lastDir = self.settings.value('lastDir', '') self.setMinimumWidth(540) self.supportedFormats = [] for f in QImageReader.supportedImageFormats(): self.supportedFormats.append(str(f.data(), encoding="utf-8")) self.fileWatcher = QFileSystemWatcher() self.fileWatcher.fileChanged.connect(self.fileChanged) # widgets self.showPixmapWidget = None self.tileWidthSpinBox = QSpinBox() self.tileWidthSpinBox.setValue(16) self.tileWidthSpinBox.setFixedWidth(50) self.tileWidthSpinBox.setMinimum(1) self.tileHeightSpinBox = QSpinBox() self.tileHeightSpinBox.setValue(16) self.tileHeightSpinBox.setFixedWidth(50) self.tileHeightSpinBox.setMinimum(1) self.paddingSpinBox = QSpinBox() self.paddingSpinBox.setFixedWidth(50) self.paddingSpinBox.setMinimum(1) self.transparentCheckbox = QCheckBox("Transparent") self.transparentCheckbox.setChecked(True) self.transparentCheckbox.stateChanged.connect(self.transparentChanged) self.backgroundColorEdit = ColorEdit() self.backgroundColorEdit.setEnabled(False) self.backgroundColorLabel = QLabel("Background color:") self.backgroundColorLabel.setEnabled(False) self.forcePotCheckBox = QCheckBox("Force PoT") self.forcePotCheckBox.setChecked(True) self.forcePotCheckBox.stateChanged.connect(self.forcePotChanged) self.reorderTilesCheckBox = QCheckBox("Reorder tiles") self.generateAndExportButton = QPushButton("Generate and export") self.generateAndExportButton.setFixedHeight(32) self.generateAndExportButton.clicked.connect(self.generateAndExportClicked) self.generateAndExportButton.setEnabled(False) self.pixmapWidget = PixmapWidget() self.pixmapWidget.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.pixmapWidget.setPixmap(self.createDropTextPixmap()) self.pixmapWidget.dropSignal.connect(self.fileDropped) self.pixmapWidget.setMinimumHeight(300) # load settings self.tileWidthSpinBox.setValue(int(self.settings.value('tileWidth', 16))) self.tileHeightSpinBox.setValue(int(self.settings.value('tileHeight', 16))) self.paddingSpinBox.setValue(int(self.settings.value('padding', 1))) self.forcePotCheckBox.setChecked(True if self.settings.value('forcePot', 'true') == 'true' else False) self.reorderTilesCheckBox.setChecked(True if self.settings.value('reorderTiles', 'false') == 'true' else False) self.transparentCheckbox.setChecked(True if self.settings.value('transparent', 'false') == 'true' else False) self.backgroundColorEdit.setColorText(str(self.settings.value('backgroundColor', '#FF00FF'))) self.restoreGeometry(QByteArray(self.settings.value('MainWindow/geometry'))) self.restoreState(QByteArray(self.settings.value('MainWindow/windowState'))) # layout hl1 = QHBoxLayout() hl1.setContentsMargins(5, 5, 5, 5) hl1.addWidget(QLabel("Tile width:")) hl1.addSpacing(5) hl1.addWidget(self.tileWidthSpinBox) hl1.addSpacing(15) hl1.addWidget(QLabel("Tile height:")) hl1.addSpacing(5) hl1.addWidget(self.tileHeightSpinBox) hl1.addSpacing(15) hl1.addWidget(QLabel("Padding:")) hl1.addSpacing(5) hl1.addWidget(self.paddingSpinBox) hl1.addSpacing(15) hl1.addWidget(self.forcePotCheckBox) hl1.addSpacing(15) hl1.addWidget(self.reorderTilesCheckBox) hl1.addStretch() hl2 = QHBoxLayout() hl2.setContentsMargins(5, 5, 5, 5) hl2.addWidget(self.transparentCheckbox) hl2.addSpacing(15) hl2.addWidget(self.backgroundColorLabel) hl2.addSpacing(5) hl2.addWidget(self.backgroundColorEdit) hl2.addStretch() hl3 = QHBoxLayout() hl3.setContentsMargins(5, 5, 5, 5) hl3.addWidget(self.generateAndExportButton) vl = QVBoxLayout() vl.setContentsMargins(0, 0, 0, 0) vl.setSpacing(0) vl.addLayout(hl1) vl.addLayout(hl2) vl.addWidget(self.pixmapWidget) vl.addLayout(hl3) w = QWidget() w.setLayout(vl) self.setCentralWidget(w) self.setTitle()
def _unregister_url_scheme_windows(self): reg_path = self.WIN_REG_PATH.format(self.URL_SCHEME) reg = QSettings(reg_path, QSettings.NativeFormat) reg.remove("")
def _register_url_scheme_windows(self): app_path_ = app_path(pythonw=True) reg_path = self.WIN_REG_PATH.format(self.URL_SCHEME) reg = QSettings(reg_path, QSettings.NativeFormat) reg.setValue("Default", "angr management") reg.setValue("URL Protocol", "") # reg.beginGroup("DefaultIcon") # reg.setValue("Default", TODO) # reg.endGroup() reg.beginGroup("shell") reg.beginGroup("open") reg.beginGroup("command") reg.setValue("Default", app_path_ + ' -u "%1"') reg.endGroup() reg.endGroup() reg.endGroup()
def get_settings(): return QSettings('cobaya', 'gui')
def readSettings(self): settings = QSettings('Trolltech', 'MDI Example') pos = settings.value('pos', QPoint(200, 200)) size = settings.value('size', QSize(400, 400)) self.move(pos) self.resize(size)
from PySide2 import QtWidgets from PySide2.QtCore import QSettings from PySide2.QtGui import QPixmap from PySide2.QtWidgets import QErrorMessage, QTableWidgetItem, QMessageBox from matplotlib import MatplotlibDeprecationWarning from sympy import plot_implicit, latex, lambdify, sign, N, E, symbols from sympy.abc import e from sympy.parsing.latex import parse_latex from src import Utils from src.windows.Settings import Settings from src.windows.Window import get_window Window = get_window() x = symbols('x') settings = QSettings('settings.ini', QSettings.IniFormat) # noinspection PyMethodMayBeStatic class MainWindow(Window): equation = None __raw_equation = None display_equation = None f = None def __init__(self): super().__init__('main') # OK Button self.okButton.clicked.connect(self.equation_builder)
def _is_url_scheme_registered_windows(self): reg_path = self.WIN_REG_PATH.format(self.URL_SCHEME) reg = QSettings(reg_path, QSettings.NativeFormat) if reg.contains("Default"): reg.beginGroup("shell") reg.beginGroup("open") reg.beginGroup("command") if reg.contains("Default"): return True, reg.value("Default") return False, None
def reset(self): settings = QSettings() settings.clear() self.read_settings()
def readAppState(self): if self.tedaCommandLine.ignoreSettings: return settings = QSettings() settings.beginGroup("WCS") self.wcsSexAct.setChecked(bool(settings.value("sexagesimal", True))) self.wcsGridAct.setChecked(bool(settings.value("grid", False))) settings.endGroup() settings.beginGroup("paint") self.painterComponent.auto_center = bool( settings.value("auto_center", True)) settings.endGroup()
def find_plugins(path=None): """Find and return plugin descriptions from a directory See Also: Docstring of this module. For structure of a plugin directory. Example of yielded dict: { 'name': 'word_set', 'title': 'WordSet', 'description': 'A plugin to manage word set', 'long_description': 'Long description used with WhatsThis help', 'version': '1.0.0', 'widget': <class 'widgets.WordSetWidget'>, 'dialog': <class 'widgets.PluginDialog'> } Keyword Arguments: path(str): Folder path where plugin are Returns: (generator[dict]): A dict with classes ready to be instantiated """ # if path is None, return internal plugin path if path is None: plugin_path = os.path.join(os.path.dirname(__file__), "plugins") else: plugin_path = path # Loop over packages in plugins directory for package in pkgutil.iter_modules([plugin_path]): package_path = os.path.join(plugin_path, package.name) LOGGER.debug("Loading plugin at <%s>", package_path) spec = importlib.util.spec_from_file_location( package.name, os.path.join(package_path, "__init__.py")) # TODO: maybe could use __title__ to build class names... widget_class_name = cm.snake_to_camel(package.name) + "Widget" settings_class_name = cm.snake_to_camel( package.name) + "SettingsWidget" dialog_class_name = cm.snake_to_camel(package.name) + "Dialog" # Load __init__ file data of the module # We expect to load a plugin per module found in a plugin directory # This is the base dict of the item yielded from this function module = spec.loader.load_module() plugin_item = { "name": module.__name__, "title": module.__title__, "description": module.__description__, "long_description": module.__long_description__, "version": module.__version__, } authorized_module_classes = { "widgets": widget_class_name, "settings": settings_class_name, "dialogs": dialog_class_name, } authorized_base_clases = { "widgets": PluginWidget, "settings": PluginSettingsWidget, "dialogs": PluginDialog, } # Loop over modules in each plugin for sub_module_info in pkgutil.iter_modules([package_path]): LOGGER.debug("Loading module <%s>", sub_module_info) sub_module_type = sub_module_info.name # Filter module filenames if sub_module_type not in authorized_module_classes: continue # Dynamically load module sub_module_path = os.path.join(sub_module_info.module_finder.path, sub_module_type + ".py") spec = importlib.util.spec_from_file_location( sub_module_type, sub_module_path) sub_module = spec.loader.load_module() # Filter not wanted classes (search main classes of the module) # Classes that don't have the module name in their name class_name = authorized_module_classes[sub_module_type] if class_name not in dir(sub_module): LOGGER.error( "Plugin <%s.%s>, class <%s> not found!", module.__name__, sub_module_type, class_name, ) continue class_item = getattr(sub_module, class_name) # # Purge disabled plugins # if not class_item.ENABLE: # LOGGER.debug( # "Plugin <%s.%s> disabled", # module.__name__, # sub_module_type # ) # continue # Classes that don't inherit of the expected Plugin class # See cutevariant/gui/plugin.py if authorized_base_clases[ sub_module_type] not in class_item.__bases__: LOGGER.error( "Plugin <%s.%s>, parent class <%s> not found!", module.__name__, sub_module_type, authorized_base_clases[sub_module_type].__name__, ) continue # Remove the "s" from module name... plugin_item[sub_module_type[:-1]] = class_item # Fix plugin status by user decision via app settings if not class_item.ENABLE: class_item.ENABLE = (QSettings().value( f"plugins/{plugin_item['name']}/status") == "true") yield plugin_item @property def plugin_name(self): return self.__class__.__name__.replace("SettingsWidget", "")
def writeAppState(self): if self.tedaCommandLine.ignoreSettings: return settings = QSettings() settings.beginGroup("WCS") settings.setValue("sexagesimal", self.wcsSexAct.isChecked()) settings.setValue("grid", self.wcsGridAct.isChecked()) settings.endGroup() settings.beginGroup("paint") settings.setValue("auto_center", self.painterComponent.auto_center) settings.endGroup()
def __init__(self, plugin_manager): super(EditorWidget, self).__init__() os.environ[ 'QT_MULTIMEDIA_PREFERRED_PLUGINS'] = 'windowsmediafoundation' self.plugin_manager = plugin_manager #parent layout self.v_box = QVBoxLayout() self.h_box = QHBoxLayout() # parent splitter for the text and numbers self.text_h_box = QSplitter(Qt.Horizontal) self.text_h_box.splitterMoved.connect(self.on_text_changed) self.settings = QSettings(c.SETTINGS_PATH, QSettings.IniFormat) self.keyboard_settings = QSettings(c.KEYBOARD_SETTINGS_PATH, QSettings.IniFormat) self.theme = self.settings.value(c.THEME, defaultValue=c.THEME_D) # font settings self.font = QFont( self.settings.value(c.FONT, defaultValue="Arial", type=str)) self.font.setPointSize( self.settings.value(c.FONT_SIZE, defaultValue=16, type=int)) # the text widget itself self.text = QPlainTextEdit() self.text.setFont(self.font) self.text.textChanged.connect(self.on_text_changed) self.text.setFocusPolicy(Qt.StrongFocus) # the number text widget to show the row numbers self.numbers = QPlainTextEdit() self.numbers.setFont(self.font) self.numbers.setReadOnly(True) self.numbers.setMinimumWidth(20) self.numbers.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.numbers.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.numbers.setLineWrapMode(QPlainTextEdit.NoWrap) self.numbers.setFocusPolicy(Qt.NoFocus) self.numbers.setFrameStyle(QFrame.NoFrame) self.numbers.setStyleSheet("background-color: rgba(0,0,0,0%)") # sync the text widget and number widget self.text_bar = self.text.verticalScrollBar() self.number_bar = self.numbers.verticalScrollBar() #self.number_bar.valueChanged.connect(self.text_bar.setValue) self.text_bar.valueChanged.connect(self.number_bar.setValue) # add them into their layout self.text_h_box.addWidget(self.numbers) self.text_h_box.addWidget(self.text) self.text_h_box.setSizes([10, 700]) # layout which holds the media controls in the bottom self.media_controls = QHBoxLayout() self.media_controls_settings = QVBoxLayout() self.media_controls_slider_h_box = QHBoxLayout() # direct player controls self.btn_size = 75 self.play_icon = QIcon( os.path.join(c.ICON_PATH, self.theme, "play.png")) self.pause_icon = QIcon( os.path.join(c.ICON_PATH, self.theme, "pause.png")) self.play_btn = QPushButton(icon=self.play_icon) self.play_btn.clicked.connect(self.on_play) self.play_btn.setFixedSize(self.btn_size, self.btn_size) self.play_btn.setIconSize(QSize(self.btn_size, self.btn_size)) self.play_btn.setFlat(True) self.play_btn.setShortcut(QKeySequence().fromString( self.keyboard_settings.value(c.PLAY_PAUSE_KEY, defaultValue=""))) self.forward_btn = QPushButton( icon=QIcon(os.path.join(c.ICON_PATH, self.theme, "forward.png"))) self.forward_btn.clicked.connect(self.on_forward) self.forward_btn.setFixedSize(self.btn_size, self.btn_size) self.forward_btn.setIconSize(QSize(self.btn_size, self.btn_size)) self.forward_btn.setFlat(True) self.forward_btn.setShortcut(QKeySequence().fromString( self.keyboard_settings.value(c.FORWARD_KEY, defaultValue=""))) self.backward_btn = QPushButton( icon=QIcon(os.path.join(c.ICON_PATH, self.theme, "backward.png"))) self.backward_btn.clicked.connect(self.on_backward) self.backward_btn.setFixedSize(self.btn_size, self.btn_size) self.backward_btn.setIconSize(QSize(self.btn_size, self.btn_size)) self.backward_btn.setFlat(True) self.backward_btn.setShortcut(QKeySequence().fromString( self.keyboard_settings.value(c.BACKWARDS_KEY, defaultValue=""))) # add them to the layout self.media_controls.addStretch() self.media_controls.addWidget(self.backward_btn) self.media_controls.addWidget(self.play_btn) self.media_controls.addWidget(self.forward_btn) self.media_controls.addStretch(4) # slider which shows the current time self.time_slider = QSlider(Qt.Horizontal) self.time_slider.sliderMoved.connect(self.on_time_slider_moved) # label on the right of the slider, which shows the current time self.time_label = QLabel("00:00/00:00") self.media_controls_slider_h_box.addWidget(self.time_slider) self.media_controls_slider_h_box.addWidget(self.time_label) # icons for the other sliders self.vol_icon = QIcon( os.path.join(c.ICON_PATH, self.theme, "volume.png")).pixmap(QSize(32, 32)) self.rate_icon = QIcon( os.path.join(c.ICON_PATH, self.theme, "playbackrate.png")).pixmap(QSize(32, 32)) self.rewind_icon = QIcon( os.path.join(c.ICON_PATH, self.theme, "time.png")).pixmap(QSize(32, 32)) # display the icons through labels self.vol_icon_label = QLabel() self.vol_icon_label.setPixmap(self.vol_icon) self.rate_icon_label = QLabel() self.rate_icon_label.setPixmap(self.rate_icon) self.rewind_rewind_label = QLabel() self.rewind_rewind_label.setPixmap(self.rewind_icon) # init of the other sliders self.vol_slider = QSlider(Qt.Horizontal) self.vol_slider.sliderMoved.connect(self.on_vol_slider_moved) self.vol_slider.setFixedWidth(250) self.vol_slider.setRange(1, 100) self.rate_slider = QSlider(Qt.Horizontal) self.rate_slider.sliderMoved.connect(self.on_rate_slider_moved) self.rate_slider.setFixedWidth(250) self.rate_slider.setRange(1, 20) self.rewind_time = 10 self.rewind_slider = QSlider(Qt.Horizontal) self.rewind_slider.sliderMoved.connect(self.on_rewind_slider_moved) self.rewind_slider.setFixedWidth(250) self.rewind_slider.setRange(1, 60) self.rewind_slider.setValue(self.rewind_time) # labels for the values self.vol_label = QLabel() self.rate_label = QLabel() self.rewind_label = QLabel() # create hbox for each of the three sliders self.vol_h_box = QHBoxLayout() self.vol_h_box.addWidget(self.vol_label) self.vol_h_box.addWidget(self.vol_slider) self.vol_h_box.addWidget(self.vol_icon_label) self.rate_h_box = QHBoxLayout() self.rate_h_box.addWidget(self.rate_label) self.rate_h_box.addWidget(self.rate_slider) self.rate_h_box.addWidget(self.rate_icon_label) self.rewind_h_box = QHBoxLayout() self.rewind_h_box.addWidget(self.rewind_label) self.rewind_h_box.addWidget(self.rewind_slider) self.rewind_h_box.addWidget(self.rewind_rewind_label) # group them together in a vlayout self.media_controls_settings.addLayout(self.vol_h_box) self.media_controls_settings.addLayout(self.rewind_h_box) self.media_controls_settings.addLayout(self.rate_h_box) # add this layout to the layout which already contains the buttons self.media_controls.addLayout(self.media_controls_settings) self.word_by_word_actions = QListWidget() self.word_by_word_actions.setMaximumWidth(150) self.h_box.addWidget(self.text_h_box) self.h_box.addWidget(self.word_by_word_actions) # group all ungrouped layouts and widgets to the parent layout self.v_box.addLayout(self.h_box, 10) self.v_box.addLayout(self.media_controls_slider_h_box, 1) self.v_box.addLayout(self.media_controls, 1) # set parent layout self.setLayout(self.v_box) # init media_player self.media_player = QMediaPlayer() self.video_widget = QVideoWidget() self.video_widget.setGeometry(200, 200, 500, 300) self.video_widget.setWindowTitle("Output") self.media_player.setVideoOutput(self.video_widget) self.media_player.positionChanged.connect(self.on_position_change) self.media_player.durationChanged.connect(self.on_duration_change) self.vol_slider.setValue(self.media_player.volume()) self.rate_slider.setValue(int(self.media_player.playbackRate() * 10)) self.on_vol_slider_moved(self.media_player.volume()) self.on_rate_slider_moved(self.media_player.playbackRate() * 10) self.on_rewind_slider_moved(self.rewind_time) self.activate_text_modules = False self.get_text_modules() self.text_option_on = QTextOption() self.text_option_on.setFlags( QTextOption.ShowTabsAndSpaces | QTextOption.ShowLineAndParagraphSeparators) self.text_option_off = QTextOption() self.transcription_meta_data = None self.word_pos = -1 self.word_start_time = None self.word_end_time = None self.tcf_highlight = QTextCharFormat() self.tcf_highlight.setBackground(Qt.red) self.tcf_normal = QTextCharFormat() self.tcf_normal.setBackground(Qt.transparent) self.show_empty_buttons = self.settings.value(c.SHOW_EMPTY_BUTTONS, defaultValue=True, type=bool)
def writeWindowSettings(self): if self.tedaCommandLine.ignoreSettings: return settings = QSettings() settings.beginGroup("MainWindow") settings.setValue("size", self.size()) settings.setValue("pos", self.pos()) settings.endGroup() settings.setValue('geometry', self.saveGeometry()) settings.setValue('windowState', self.saveState()) self.headerWidget.writeSettings(settings) self.file_widget.writeSettings(settings)
from gettext import translation from os import listdir from os.path import dirname, join from sys import argv from PySide2.QtCore import QSettings path = dirname(argv[0]) translations_path = join(path, 'translations') settings = QSettings('settings.ini', QSettings.IniFormat) languages = [] for language in listdir(translations_path): if language.startswith('__'): continue languages.append(language) from random import choice, randint language = settings.value('interface/language', 'en_EN') toolBarEnable = True if settings.value('interface/toolBarEnable', 'true') == 'true' else False buttomPanelEnable = True if settings.value('interface/buttomPanelEnable', 'false') == 'true' else False statusBarEnable = True if settings.value('interface/statusBarEnable', 'true') == 'true' else False autoCompleteEnable = True if settings.value('interface/autoCompleteEnable', 'false') == 'true' else False name = settings.value('personal/name', '{alias}user{id}'.format(alias=choice(['super', 'mega', 'ultimate', 'alpha', 'beta', 'ultra']), id=str(randint(100000, 999999)))) email = settings.value('personal/email', '') country = settings.value('personal/country', 'Russia') preReleasesEnable = True if settings.value('updates/allowPreReleases', 'false') == 'true' else False def returnLanguage(language): return translation('prettycode', translations_path, [language]).gettext
def testDictionary(self): confFile = QTemporaryFile(QDir.tempPath() + '/pysidebug829_XXXXXX.ini') confFile.setAutoRemove(False) self.assertTrue(confFile.open()) confFile.close() self._confFileName = confFile.fileName() del confFile s = QSettings(self._confFileName, QSettings.IniFormat) self.assertEqual(s.status(), QSettings.NoError) # Save value s.setValue('x', {1: 'a'}) s.sync() self.assertEqual(s.status(), QSettings.NoError) del s # Restore value s = QSettings(self._confFileName, QSettings.IniFormat) self.assertEqual(s.status(), QSettings.NoError) self.assertEqual(s.value('x'), {1: 'a'})
def store(self, settings: QSettings): settings.setValue("name", self.name) settings.setValue("root", str(self.root) if self.root else "") settings.setValue( "color", self.color if self.color and self.color.isValid() else "") settings.setValue("enabled", self.enabled)
def load_image(parent, filename=None): nothing = [None] * 3 settings = QSettings() mime_filters = [ "image/jpeg", "image/png", "image/tiff", "image/gif", "image/bmp", "image/webp", "image/x-portable-pixmap", "image/x-portable-graymap", "image/x-portable-bitmap", "image/x-nikon-nef", "image/x-fuji-raf", "image/x-canon-cr2", "image/x-adobe-dng", "image/x-sony-arw", "image/x-kodak-dcr", "image/x-minolta-mrw", "image/x-pentax-pef", "image/x-canon-crw", "image/x-sony-sr2", "image/x-olympus-orf", "image/x-panasonic-raw", ] mime_db = QMimeDatabase() mime_patterns = [ mime_db.mimeTypeForName(mime).globPatterns() for mime in mime_filters ] all_formats = f"Supported formats ({' '.join([item for sub in mime_patterns for item in sub])})" raw_exts = [p[0][-3:] for p in mime_patterns][-12:] if filename is None: dialog = QFileDialog(parent, parent.tr("Load image"), settings.value("load_folder")) dialog.setOption(QFileDialog.DontUseNativeDialog, True) dialog.setFileMode(QFileDialog.ExistingFile) dialog.setViewMode(QFileDialog.Detail) dialog.setMimeTypeFilters(mime_filters) name_filters = dialog.nameFilters() dialog.setNameFilters(name_filters + [all_formats]) dialog.selectNameFilter(all_formats) if dialog.exec_(): filename = dialog.selectedFiles()[0] else: return nothing ext = os.path.splitext(filename)[1][1:].lower() if ext in raw_exts: with rawpy.imread(filename) as raw: image = cv.cvtColor(raw.postprocess(use_auto_wb=True), cv.COLOR_RGB2BGR) elif ext == "gif": capture = cv.VideoCapture(filename) frames = int(capture.get(cv.CAP_PROP_FRAME_COUNT)) if frames > 1: QMessageBox.warning( parent, parent.tr("Warning"), parent.tr("Animated GIF: importing first frame")) result, image = capture.read() if not result: QMessageBox.critical(parent, parent.tr("Error"), parent.tr("Unable to decode GIF!")) return nothing if len(image.shape) == 2: image = cv.cvtColor(image, cv.COLOR_GRAY2BGR) else: image = cv.imread(filename, cv.IMREAD_COLOR) if image is None: QMessageBox.critical(parent, parent.tr("Error"), parent.tr("Unable to load image!")) return nothing if image.shape[2] > 3: QMessageBox.warning(parent, parent.tr("Warning"), parent.tr("Alpha channel discarded")) image = cv.cvtColor(image, cv.COLOR_BGRA2BGR) settings.setValue("load_folder", QFileInfo(filename).absolutePath()) return filename, os.path.basename(filename), image
def RestoreWidgets(self): settings = QSettings(self.saveFileName, QSettings.IniFormat) for cbxRegSel in self.uiCbxRegSel: GuiRestoreWidget(cbxRegSel, settings) for edValue in self.uiEdValue: GuiRestoreWidget(edValue, settings)
def __accepted(self): settings = QSettings() settings.setValue("hostname", self._ui.hostLineEdit.text()) settings.setValue("port", self._ui.portSpinBox.value())
def readSettings(self): settings = QSettings("Trolltech", "Application Example") pos = settings.value("pos", QPoint(200, 200)) size = settings.value("size", QSize(400, 400)) self.resize(size) self.move(pos)
def loadGeomerty(self): settings = QSettings(sGeomertyIniFile, QSettings.IniFormat) self.restoreGeometry(settings.value(sGeometry))
def writeSettings(self): settings = QSettings("Trolltech", "Application Example") settings.setValue("pos", self.pos()) settings.setValue("size", self.size())
class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow): ''' ShotList MainWindow ''' APPNAME = "shotlist" APPID = "com.LespaceVision.ShotList" __version__ = "1.1.3" # ShotList Column Name define NO = 'No.' THUMB_S = 'Start Frame' THUMB_C = 'Center Frame' THUMB_E = 'End Frame' FILENAME = 'FileName' SCENE = 'Scene' CUT = 'Cut' TAKE = 'Take' COMMENT = 'Comment' CONTAINER = 'Container' CODEC = 'Codec' PIXSIZE = 'Resolution' FILESIZE_GB = 'filesize(GB)' FILESIZE_MB = 'filesize(MB)' REEL = 'Reel' FPS = 'fps' SENSORFPS = 'SensorFps' LENGTH = 'Duration' TC = 'StartTC' BIT = 'bit' ALPHA = 'alpha' COLORSPACE = 'colorspace' GAMMA = 'gamma' AUDIOCH = 'Audio ch' AUDIOSRATE = 'Audio rate' AUDIOCODEC = 'Audio codec' AUDIOBRATE = 'Audio bitrate' CREATETIME = 'Create Time' FULLPATH = 'fullpath' RELPATH = 'relpath' CHECKSUM = 'checksum' CHECKSUM_XXHASH = 'checksum(xxHash)' CHECKSUM_MD5 = 'checksum(MD5)' CHECKSUM_SHA1 = 'checksum(SHA1)' EXINFO = 'Exinfo' # hidden data DIRPATH_HIDDEN = 'base_hidden' FILENAME_HIDDEN = 'name_hidden' SEQPATH_HIDDEN = 'seq_hidden' SEQ_HIDDEN_S = 'seq_hidden_s' SEQ_HIDDEN_C = 'seq_hidden_c' SEQ_HIDDEN_E = 'seq_hidden_e' CHECK_ALGO_SHA1 = "(SHA1)" # RapidCopy cfg.usemd5=0 CHECK_ALGO_MD5 = "(MD5)" # RapidCopy cfg.usemd5=1 CHECK_ALGO_XXHASH = "(xxHash)" # RapidCopy cfg.usemd5=2 #Specification follows RapidCopy.See RapdiCopy source cfg.usemd5... CHECK_ALGO_DICT = { 0: CHECK_ALGO_SHA1, 1: CHECK_ALGO_MD5, 2: CHECK_ALGO_XXHASH } SeqRole = QtCore.Qt.UserRole + 1 #ShotList Column list def_columnlist = [ NO, THUMB_S, THUMB_C, THUMB_E, FILENAME, SCENE, CUT, TAKE, COMMENT, CONTAINER, CODEC, PIXSIZE, FILESIZE_GB, FILESIZE_MB, REEL, FPS, SENSORFPS, LENGTH, TC, BIT, ALPHA, COLORSPACE, GAMMA, AUDIOCH, AUDIOSRATE, AUDIOCODEC, AUDIOBRATE, CREATETIME, FULLPATH, RELPATH, CHECKSUM, EXINFO ] #ShotList no default Column list def_nodefaultlist = [THUMB_S, THUMB_E, CHECKSUM, FILESIZE_MB, SENSORFPS] #ShotList Column defaults data # key=Column name # value = column propetry list # [0]:itemrole method(int) 0:DisplayRole,1:DecorationRole,2:NoRole # [1]:dataset method(int) 0:item.setText,1:item.setData, # [2]:itemflags Qt::ItemFlags(int) 33:select&enable 35:33+edit def_columnpropdict = { NO: [Qt.DisplayRole, 1, 35], THUMB_S: [Qt.DecorationRole, 1, 33], THUMB_C: [Qt.DecorationRole, 1, 33], THUMB_E: [Qt.DecorationRole, 1, 33], FILENAME: [Qt.DisplayRole, 0, 33], SCENE: [Qt.DisplayRole, 0, 35], CUT: [Qt.DisplayRole, 0, 35], TAKE: [Qt.DisplayRole, 0, 35], COMMENT: [Qt.DisplayRole, 0, 35], CONTAINER: [Qt.DisplayRole, 0, 33], CODEC: [Qt.DisplayRole, 0, 33], PIXSIZE: [Qt.DisplayRole, 0, 33], FILESIZE_GB: [Qt.DisplayRole, 0, 33], FILESIZE_MB: [Qt.DisplayRole, 0, 33], REEL: [Qt.DisplayRole, 0, 33], FPS: [Qt.DisplayRole, 0, 33], SENSORFPS: [Qt.DisplayRole, 0, 33], LENGTH: [Qt.DisplayRole, 0, 33], TC: [Qt.DisplayRole, 0, 33], BIT: [Qt.DisplayRole, 0, 33], ALPHA: [Qt.DisplayRole, 0, 33], COLORSPACE: [Qt.DisplayRole, 0, 33], GAMMA: [Qt.DisplayRole, 0, 33], AUDIOCH: [Qt.DisplayRole, 0, 33], AUDIOSRATE: [Qt.DisplayRole, 0, 33], AUDIOCODEC: [Qt.DisplayRole, 0, 33], AUDIOBRATE: [Qt.DisplayRole, 0, 33], CREATETIME: [Qt.DisplayRole, 0, 33], FULLPATH: [Qt.DisplayRole, 0, 33], RELPATH: [Qt.DisplayRole, 0, 33], CHECKSUM: [Qt.DisplayRole, 0, 33], CHECKSUM_XXHASH: [Qt.DisplayRole, 0, 33], CHECKSUM_MD5: [Qt.DisplayRole, 0, 33], CHECKSUM_SHA1: [Qt.DisplayRole, 0, 33], EXINFO: [Qt.DisplayRole, 0, 33], } def_thumb_group = [THUMB_S, THUMB_C, THUMB_E] def_checksum_group = [CHECK_ALGO_MD5, CHECK_ALGO_SHA1, CHECK_ALGO_XXHASH] CORP_INFO = 'LespaceVision' Logdir = "Log" DebugDir = "Debug" msgBox = "" # OPT VALUE OPT_COLUMNLIST = 'SELECTCOLUMNS' OPT_THUMB_X = "THUMB_X" OPT_THUMB_Y = "THUMB_Y" OPT_THUMB_BRIGHT = "THUMB_BRIGHTNESS" OPT_THUMB_OFF_S = "THUMB_OFF_S" OPT_THUMB_OFF_C = "THUMB_OFF_C" OPT_THUMB_OFF_E = "THUMB_OFF_E" OPT_DISABLESEQ = "DISABLE_SEQ" OPT_STAFPS = "STA_FPS" OPT_CHECK_ALGO = "CHECK_ALGO" OPT_EYECATCH = "EYECATCH_PATH" OPT_XLSXOUTTYPE = "XLSX_OTYPE" OPT_XLSXMAXROWS = "XLSX_ROWS" OPT_LCID = "LCID" # OPT DEFAULT THUMB_DEFAULT_X = 176 # Thumbnail X default(16:9) THUMB_DEFAULT_Y = 99 # Thumbnail Y default(16:9) THUMB_DEFALUT_BRIGHT = 1.0 THUMB_DEFAULT_OFF = 0.0 THUMB_DEFAULT_OFF_E = 0.0 / -1 # for "-0.0" DISABLESEQ_DEFAULT = False STAFPS_DEFAULT = 30.0 XLSXOUTTYPE_DEFAULT = 2 # 0=book,1=sheet,2=all XLSXMAXROWS_DEFAULT = 100 LCID_DEFAULT = int(QtCore.QLocale.system().language()) def __init__(self, app): super(MainWindow, self).__init__() self.framegrab = FrameGrabber(self) self.selectedframe = None self.shot = ShotList(self, framegrab=self.framegrab) self.dochome = os.path.join( QStandardPaths.writableLocation(QStandardPaths.DocumentsLocation), self.APPNAME) self.shot.setdochome(self.dochome) if not os.path.exists(self.dochome): os.mkdir(self.dochome) if not os.path.exists(os.path.join(self.dochome, self.Logdir)): os.mkdir(os.path.join(self.dochome, self.Logdir)) self.columnlist = [] self.thumbnail_x = 0 self.thumbnail_y = 0 self.thumbnail_bright = 1.0 self.startoffset = 0.0 self.centeroffset = 0.0 self.endoffset = 0.0 self.stafps = 0.0 self.disableseq = None self.checksumalgo = self.CHECK_ALGO_XXHASH self.eyecatch = "" self.xlsxmaxrows = 0 self.lcid = 0 self.finderpath = None self.previewitem = None self.__readsettings() if (self.lcid == int(QtCore.QLocale.Japanese)): translator = QtCore.QTranslator() translator.load(":/qm/ShotList_ja_JP.qm") app.installTranslator(translator) self.setupUi(self) self.mainToolBar.hide() self.msgBox = QtWidgets.QMessageBox() self.msgBox.setWindowTitle(self.APPNAME) self.msgBox.setIcon(QtWidgets.QMessageBox.Critical) self.timerid = 0 self.dot_count = 0 self.status_label = StatusLabel("") self.main_processing = False self.haserror = False QtCore.QCoreApplication.setOrganizationName(self.CORP_INFO) verstr = "{0} v{1}".format(self.APPNAME, self.__version__) self.setWindowTitle(verstr) QtCore.QCoreApplication.setApplicationName(self.APPNAME) # make temporary directory(PySide2 bug? https://bugreports.qt.io/browse/PYSIDE-884 tempdir = QStandardPaths.writableLocation(QStandardPaths.TempLocation) tempdir = os.path.join(tempdir, self.APPID) if not os.path.isdir(tempdir): os.mkdir(tempdir) self.__initEv() self.lineEdit_SourceDir.setPlaceholderText( self.tr("input Folder path by D&D or src dialog")) def __initEv(self): self.tableWidget_shotlist.setRowCount(0) self.tableWidget_shotlist.setColumnCount(len(self.columnlist)) self.tableWidget_shotlist.setHorizontalHeaderLabels(self.columnlist) self.statusBar.setLayoutDirection(QtCore.Qt.LeftToRight) self.setAcceptDrops(True) self.lineEdit_SourceDir.setAcceptDrops(False) self.tableWidget_shotlist.setShowGrid(True) self.tableWidget_shotlist.setStyleSheet( "QTableWidget::item { padding: 0px }") self.tableWidget_shotlist.setMouseTracking(True) self.tableWidget_shotlist.cellEntered.connect(self.cell_entered) self.pushButton_xlsout.clicked.connect(self.xlsout_clicked) self.pushButton_Input.clicked.connect(self.input_clicked) self.pushButton_import.clicked.connect(self.import_clicked) self.pushButton_shotclear.clicked.connect(self.shotclear_clicked) self.pushButton_reindex.clicked.connect(self.reindex_clicked) self.shot.finished.connect(self.finishThread) self.tableWidget_shotlist.itemClicked.connect(self.item_clicked) self.tableWidget_shotlist.itemDoubleClicked.connect( self.item_doubleclicked) self.tableWidget_shotlist.customContextMenuRequested.connect( self.__menu_opened) # mainSettings connect self.settingdialog = mainSettingDialog(parent=self) self.actionSettings.triggered.connect(self.__mainsetting_triggered) # about connect self.aboutdialog = aboutDialog(parent=self) self.actionAbout_ShotList.triggered.connect(self.__about_triggered) #Thumbnail menu and actions self.thumb_menu = QtWidgets.QMenu() self.action_preview = self.thumb_menu.addAction( self.tr("Select Thumbnail(preview)")) self.action_finder = self.thumb_menu.addAction( self.tr("Open with Finder")) self.action_reindex = self.thumb_menu.addAction( self.tr("Reassign 'No.'")) self.showerrror_area(False) self.pushButton_reindex.setVisible(False) self.dummylabel = QtWidgets.QLabel(" ") self.prog_hlay = QtWidgets.QHBoxLayout(self.progressBar_import) self.prog_hlay.addWidget(self.status_label) self.prog_hlay.setContentsMargins(0, 0, 0, 0) self.progressBar_import.setAlignment(QtCore.Qt.AlignLeft) self.statusBar.addPermanentWidget(self.dummylabel) self.statusBar.addPermanentWidget(self.progressBar_import, 2) self.progressBar_import.setStyleSheet( "QProgressBar::chunk {background-color: paleturquoise;}") self.progressBar_import.setTextVisible(False) return def __readsettings(self): self.cfg = QSettings(self.dochome + "/" + self.APPNAME + ".ini", QSettings.IniFormat) default_columns = self.def_columnlist[:] default_columns.remove(self.THUMB_S) default_columns.remove(self.THUMB_E) default_columns.remove(self.CHECKSUM) default_columns.remove(self.FILESIZE_MB) default_columns.remove(self.SENSORFPS) self.columnlist = self.cfg.value(self.OPT_COLUMNLIST, default_columns) self.thumbnail_x = int( self.cfg.value(self.OPT_THUMB_X, self.THUMB_DEFAULT_X)) self.thumbnail_y = int( self.cfg.value(self.OPT_THUMB_Y, self.THUMB_DEFAULT_Y)) self.thumbnail_bright = float( self.cfg.value(self.OPT_THUMB_BRIGHT, self.THUMB_DEFALUT_BRIGHT)) self.startoffset = float( self.cfg.value(self.OPT_THUMB_OFF_S, self.THUMB_DEFAULT_OFF)) self.centeroffset = float( self.cfg.value(self.OPT_THUMB_OFF_C, self.THUMB_DEFAULT_OFF)) self.endoffset = float( self.cfg.value(self.OPT_THUMB_OFF_E, self.THUMB_DEFAULT_OFF_E)) self.disableseq = self.cfg.value(self.OPT_DISABLESEQ, self.DISABLESEQ_DEFAULT) self.stafps = float( self.cfg.value(self.OPT_STAFPS, self.STAFPS_DEFAULT)) self.checksumalgo = str( self.cfg.value(self.OPT_CHECK_ALGO, self.CHECK_ALGO_XXHASH)) self.eyecatch = str(self.cfg.value(self.OPT_EYECATCH, "")) self.xlsxouttype = int( self.cfg.value(self.OPT_XLSXOUTTYPE, self.XLSXOUTTYPE_DEFAULT)) self.xlsxmaxrows = int( self.cfg.value(self.OPT_XLSXMAXROWS, self.XLSXMAXROWS_DEFAULT)) self.lcid = int(self.cfg.value(self.OPT_LCID, self.LCID_DEFAULT)) return def __writesettings(self): pass def __makelistfromqcombo(self, combobox): itemlist = [] for i in range(combobox.count()): itemlist.append(combobox.itemText(i)) itemlist.reverse() return itemlist def input_clicked(self): dir_path = QFileDialog.getExistingDirectory(self) if not dir_path: return else: self.lineEdit_SourceDir.setText(dir_path) return def import_clicked(self): if self.shot.isRunning(): msgBox = QtWidgets.QMessageBox() msgBox.setIcon(QtWidgets.QMessageBox.Question) msgBox.setText(self.tr("Cancel import?")) msgBox.setStandardButtons(QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No) self.shot.reqsuspend(True) if (msgBox.exec_() == QtWidgets.QMessageBox.Yes): self.shot.reqcancel(True) self.shot.reqsuspend(False) return elif self.main_processing: self.main_processing = False return ipath = self.lineEdit_SourceDir.text() if not ipath or not os.path.isdir(ipath): msgBox = QtWidgets.QMessageBox() msgBox.setIcon(QtWidgets.QMessageBox.Question) msgBox.setText(self.tr("Please input folder path.")) msgBox.setStandardButtons(QtWidgets.QMessageBox.Ok) msgBox.exec_() return self.textEdit_Result.clear() self.showerrror_area(False) self.tableWidget_shotlist.setSortingEnabled(False) self.tableWidget_shotlist.clearContents() self.tableWidget_shotlist.setColumnCount(len(self.columnlist)) self.tableWidget_shotlist.setHorizontalHeaderLabels(self.columnlist) self.checkedcount = 0 self.shot.reset() self.__setEnabled(False) self.pushButton_xlsout.setEnabled(False) self.shot.setOpt(self.shot.RUNMODE, self.shot.RUNMODE_IMPORT_IMAGES) self.shot.setOpt(self.shot.INPUT_PATH, ipath) self.beginTimer() self.haserror = False self.shot.start() self.progressBar_import.setStyleSheet( "QProgressBar::chunk {background-color: paleturquoise;}") self.pushButton_import.setText(self.tr("Cancel..")) def xlsout_clicked(self): if self.tableWidget_shotlist.rowCount() == 0: return if self.shot.isRunning(): msgBox = QtWidgets.QMessageBox() msgBox.setIcon(QtWidgets.QMessageBox.Question) msgBox.setWindowIcon(QtGui.QIcon(":/ico/" + self.APPNAME + ".ico")) msgBox.setText(self.tr("Cancel xlsxout?")) msgBox.setStandardButtons(QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No) self.shot.reqsuspend(True) if (msgBox.exec_() == QtWidgets.QMessageBox.Yes): self.shot.reqcancel(True) self.shot.reqsuspend(False) return suffix_name = "" deskpath = QStandardPaths.writableLocation( QStandardPaths.DesktopLocation) writablepath = deskpath + os.sep if self.shot.optdict[self.shot.INPUT_PATH]: # print(os.path.split(self.shot.optdict[self.shot.INPUT_PATH])[1]) suffix_name = os.path.split( self.shot.optdict[self.shot.INPUT_PATH])[1] + "_" # call multi xlsx files output if self.xlsxouttype == 0: dstpaths = [] # prepare "all" xlsx filename # damn sandbox file output security.... # defaultfilename = suffix_name + ".xlsx" rowcount = self.tableWidget_shotlist.rowCount() prev_index = 1 if rowcount < self.xlsxmaxrows: next_index = rowcount else: next_index = self.xlsxmaxrows if rowcount % self.xlsxmaxrows == 0: total_fileno = rowcount / self.xlsxmaxrows else: total_fileno = math.ceil(rowcount / self.xlsxmaxrows) cur_fileno = 1 for i in range(rowcount): if i != 0 and (i + 1) % self.xlsxmaxrows == 0: filename = suffix_name + "{0}_{1}".format( prev_index, next_index) + ".xlsx" writablepath = writablepath + filename dstpath = QFileDialog.getSaveFileName( self, self.tr("Save xlsx({0}/{1})").format( cur_fileno, total_fileno), writablepath)[0] if dstpath: dstpaths.append(dstpath) else: return cur_fileno += 1 prev_index = prev_index + self.xlsxmaxrows if next_index + self.xlsxmaxrows < rowcount: next_index = next_index + self.xlsxmaxrows else: next_index = rowcount writablepath = os.path.split(dstpath)[0] + os.sep elif i == rowcount - 1: filename = suffix_name + "{0}_{1}".format( prev_index, next_index) + ".xlsx" writablepath = writablepath + filename dstpath = QFileDialog.getSaveFileName( self, self.tr("Save xlsx({0}/{1})").format( cur_fileno, total_fileno), writablepath)[0] if dstpath: dstpaths.append(dstpath) else: return else: defaultfilename = suffix_name + ".xlsx" savedialog = QFileDialog() writablepath = writablepath + defaultfilename dstpaths = QFileDialog.getSaveFileName(self, self.tr("Save xlsx"), writablepath)[0] # cancel if not dstpaths: return self.progressBar_import.setStyleSheet( "QProgressBar::chunk {background-color: paleturquoise;}") self.__prepare_xlsxout(dstpaths) self.__setEnabled(False) self.pushButton_import.setEnabled(False) self.beginTimer() self.haserror = False self.shot.start() self.pushButton_xlsout.setText(self.tr("Cancel..")) def shotclear_clicked(self): self.textEdit_Result.clear() def reindex_clicked(self): if self.tableWidget_shotlist.rowCount() == 0: return elif self.shot.isRunning(): return msgBox = QtWidgets.QMessageBox() msgBox.setIcon(QtWidgets.QMessageBox.Question) msgBox.setText( self.tr("'No.' columns value will reassign. Are you sure?")) msgBox.setStandardButtons(QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No) if (msgBox.exec_() == QtWidgets.QMessageBox.No): return for j in range(self.tableWidget_shotlist.columnCount()): if self.tableWidget_shotlist.horizontalHeaderItem( j).text() == self.NO: for i in range(self.tableWidget_shotlist.rowCount()): item = self.tableWidget_shotlist.takeItem(i, j) item.setData(QtCore.Qt.DisplayRole, i + 1) self.tableWidget_shotlist.setItem(i, j, item) # print(item.data(QtCore.Qt.DisplayRole)) msgBox.setIcon(QtWidgets.QMessageBox.Information) msgBox.setText(self.tr("'No.' columns reassigned complete.")) msgBox.setStandardButtons(QtWidgets.QMessageBox.Yes) msgBox.exec_() def cell_entered(self, x, y): item = self.tableWidget_shotlist.item(x, y) datadict = item.data(Qt.UserRole) if datadict: self.finderpath = datadict[self.DIRPATH_HIDDEN] self.previewitem = item else: self.finderpath = None self.previewitem = None def dragEnterEvent(self, event): if event.mimeData().hasUrls(): event.accept() else: event.ignore() def dropEvent(self, event): url = event.mimeData().urls()[0] path = url.toLocalFile() if (path[-1:] == "/"): path = path[:-1] if not os.path.isdir(path): self.status_label.setText( self.tr("Error:path is file. Plz input folder. path={0}"). format(path)) return self.lineEdit_SourceDir.setText(path) def closeEvent(self, cevent): if not self.shot.isRunning() or self.shot.isFinished(): cevent.accept() else: msgBox = QtWidgets.QMessageBox() msgBox.setIcon(QtWidgets.QMessageBox.Warning) msgBox.setWindowIcon(QtGui.QIcon(":/ico/" + self.APPNAME + ".ico")) msgBox.setText(self.tr("ShotList is running")) msgBox.setInformativeText( self.tr("Can't close ShotList while current task.")) msgBox.setStandardButtons(QtWidgets.QMessageBox.Ok) msgBox.exec_() cevent.ignore() def timerEvent(self, tevent): if (tevent.timerId() == self.timerid and self.shot.message): self.progressBar_import.setMaximum(self.shot.totalseqno) self.progressBar_import.setValue(self.shot.currentseqno) replstr = self.shot.message dotstr = "" for i in range(0, self.dot_count): dotstr += "." self.status_label.setText(replstr + dotstr) self.dot_count += 1 if (self.dot_count == 4): self.dot_count = 0 # did not take Lock but maybe no problem. if len((self.shot.errmessages)): self.showerrror_area(True) self.progressBar_import.setStyleSheet( "QProgressBar::chunk {background-color: orange;}") self.haserror = True for i in range(len(self.shot.errmessages)): self.textEdit_Result.append(self.shot.errmessages[i]) self.shot.errmessages.clear() def beginTimer(self): self.timerid = QObject.startTimer(self, 1000) # @QtCore.Slot() def stopTimer(self): self.status_label.clear() QObject.killTimer(self, self.timerid) @QtCore.Slot() def beginTimer(self): self.timerid = QObject.startTimer(self, 1000) @QtCore.Slot() def stopTimer(self): QObject.killTimer(self, self.timerid) @QtCore.Slot(str) def finishThread(self): self.main_processing = True self.stopTimer() # Output error message when exists if len((self.shot.errmessages)): self.showerrror_area(True) for i in range(len(self.shot.errmessages)): self.textEdit_Result.append(self.shot.errmessages[i]) # Import image if self.shot.optdict[ self.shot.RUNMODE] == self.shot.RUNMODE_IMPORT_IMAGES: if self.shot.req_cancel: self.status_label.setText(self.tr("import canceled.")) self.tableWidget_shotlist.clearContents() self.tableWidget_shotlist.setRowCount(0) else: if len(self.shot.inputresultlist): self.__setrecord(self.shot.inputresultlist) self.fitcolumns() else: errstr = self.tr("No shot(s).") self.textEdit_Result.append(errstr) self.msgBox.setText(errstr) self.msgBox.setIcon(QtWidgets.QMessageBox.Information) self.msgBox.setStandardButtons(QtWidgets.QMessageBox.Ok) self.msgBox.exec_() self.label_preview.setText(self.tr("No shot(s).")) self.status_label.setText(self.tr("Import finished")) if self.haserror: self.progressBar_import.setStyleSheet( "QProgressBar::chunk {background-color: orange;}") else: self.progressBar_import.setStyleSheet( "QProgressBar::chunk {background-color: lightgreen;}") # xlsx output else: if self.shot.req_cancel: # xlsx output canceled. self.status_label.setText(self.tr("xlsx out canceled")) else: # xlsx output finished self.status_label.setText(self.tr("xlsx out finished")) self.textEdit_Result.append( self.tr("xlsx out finished. out path = {0}".format( self.shot.optdict[self.shot.OUTPUT_PATH]))) self.msgBox.setText(self.tr("xlsx out finished.")) if self.xlsxouttype == 0: self.msgBox.setInformativeText( self.tr("xlsx out finished.")) else: self.msgBox.setInformativeText( self.tr("xlsx out finished. out path = {0}".format( self.shot.optdict[self.shot.OUTPUT_PATH]))) self.msgBox.setIcon(QtWidgets.QMessageBox.Information) self.msgBox.setStandardButtons(QtWidgets.QMessageBox.Ok) self.msgBox.exec_() self.progressBar_import.setStyleSheet( "QProgressBar::chunk {background-color: lightgreen;}") self.progressBar_import.setValue(self.progressBar_import.maximum()) # enable mainwindows buttons. self.__setEnabled(True) self.pushButton_import.setEnabled(True) self.pushButton_xlsout.setEnabled(True) self.main_processing = False self.pushButton_import.setText(self.tr("Import")) self.pushButton_xlsout.setText(self.tr("xlsx output")) self.shot.reqsuspend(False) self.shot.reqcancel(False) self.msgBox.setInformativeText("") @QtCore.Slot() def item_clicked(self, item): pass @QtCore.Slot() def item_doubleclicked(self, item): columnname = self.tableWidget_shotlist.horizontalHeaderItem( item.column()).text() if (columnname in self.def_thumb_group): itemdict = self.tableWidget_shotlist.item( item.row(), item.column()).data(Qt.UserRole) ext = os.path.splitext(itemdict[self.FILENAME_HIDDEN])[1].lower() if ext in self.shot.SUPPORT_MOVIMAGES: # QtWidgets.QDesktopServices.openUrl(QtCore.QUrl.fromLocalFile(fullpath)) fullpath = os.path.join(itemdict[self.DIRPATH_HIDDEN], itemdict[self.FILENAME_HIDDEN]) previewdialog = VideoPlayerDialog(parent=self, path=fullpath) if columnname == self.THUMB_C: previewdialog.set_slider(1) elif columnname == self.THUMB_E: previewdialog.set_slider(2) else: pass elif ext in self.shot.SUPPORT_STAIMAGES: filelist = [] # save memory usage. reconstruct fullpath... for filename in itemdict[self.SEQPATH_HIDDEN]: filelist.append( os.path.join(itemdict[self.DIRPATH_HIDDEN], filename)) seq = pyseq.Sequence(filelist) previewdialog = SequencePlayerDialog(parent=self, seq=seq) end = seq.end() start = seq.start() length = seq.end() - seq.start() if columnname == self.THUMB_S: previewdialog.slider_changed(start) elif columnname == self.THUMB_C: previewdialog.slider_changed(start + (length / 2)) elif columnname == self.THUMB_E: previewdialog.slider_changed(end) else: pass else: return if previewdialog.exec_() == QtWidgets.QDialog.Accepted: xy = self.shot.resize_xandy(self.selectedframe.width(), self.selectedframe.height()) self.selectedframe = self.selectedframe.scaled( xy[0], xy[1], Qt.KeepAspectRatio, Qt.SmoothTransformation) item.setData(QtCore.Qt.DecorationRole, self.selectedframe) @QtCore.Slot() def __mainsetting_triggered(self): if self.settingdialog.exec_() == QtWidgets.QDialog.Accepted: self.fitcolumns() @QtCore.Slot() def __about_triggered(self): self.aboutdialog.exec_() def __menu_opened(self, position): action = self.thumb_menu.exec_( self.tableWidget_shotlist.mapToGlobal(position)) if action == self.action_finder: # self.finderpath set by cell_entered SLOT if self.finderpath: QDesktopServices.openUrl("file:///" + self.finderpath) elif action == self.action_preview: if self.previewitem: self.item_doubleclicked(self.previewitem) elif action == self.action_reindex: self.reindex_clicked() else: pass def __setrecord(self, resultlist): self.tableWidget_shotlist.setRowCount(len(resultlist)) for i, rec in enumerate(resultlist): self.status_label.setText( self.tr("Setting Rows({0}/{1})").format(i, len(resultlist))) # check cancel if self.shot.req_cancel or self.main_processing is False: self.status_label.setText(self.tr("import canceled.")) self.tableWidget_shotlist.clearContents() self.tableWidget_shotlist.setRowCount(0) return False else: self.status_label.setText( self.tr("set record {0}/{1}".format(i, len(resultlist)))) for j in range(self.tableWidget_shotlist.columnCount()): columnname = self.tableWidget_shotlist.horizontalHeaderItem( j).text() item = QtWidgets.QTableWidgetItem() declist = self.def_columnpropdict[columnname] if declist[1]: if columnname in self.def_thumb_group: if isinstance(rec[columnname], str): item.setText(rec[columnname]) else: qimage = QtGui.QPixmap.fromImage(rec[columnname]) item.setData(declist[0], qimage) self.tableWidget_shotlist.setRowHeight( i, qimage.height() + 5) itemdict = {} itemdict[self.DIRPATH_HIDDEN] = rec[ self.DIRPATH_HIDDEN] itemdict[self.FILENAME_HIDDEN] = rec[ self.FILENAME_HIDDEN] if rec[self.SEQPATH_HIDDEN]: itemdict[self.SEQPATH_HIDDEN] = rec[ self.SEQPATH_HIDDEN] if columnname == self.THUMB_S and rec[ self.SEQ_HIDDEN_S]: item.setData(self.SeqRole, rec[self.SEQ_HIDDEN_S]) elif columnname == self.THUMB_C and rec[ self.SEQ_HIDDEN_C]: item.setData(self.SeqRole, rec[self.SEQ_HIDDEN_C]) elif columnname == self.THUMB_E and rec[ self.SEQ_HIDDEN_E]: item.setData(self.SeqRole, rec[self.SEQ_HIDDEN_E]) else: pass else: pass item.setData(Qt.UserRole, itemdict) else: item.setData(declist[0], rec[columnname]) else: item.setText(str(rec[columnname])) if declist[2] == 33: item.setFlags(Qt.ItemIsEnabled | Qt.ItemIsSelectable) elif declist[2] == 35: item.setFlags(Qt.ItemIsEnabled | Qt.ItemIsEditable | Qt.ItemIsEnabled) else: pass # item.setFlags(declist[2]) self.tableWidget_shotlist.setItem(i, j, item) for j in range(self.tableWidget_shotlist.columnCount()): if self.tableWidget_shotlist.horizontalHeaderItem( j).text() == self.CHECKSUM: checksum_item = self.tableWidget_shotlist.horizontalHeaderItem( j) checksum_item.setText(checksum_item.text() + self.checksumalgo) self.label_preview.setText( self.tr("{0} shots total".format(len(resultlist)))) return True def __setEnabled(self, req_bool): self.pushButton_Input.setEnabled(req_bool) self.tableWidget_shotlist.setEnabled(req_bool) self.pushButton_reindex.setEnabled(req_bool) def __setColortoRow(self, table, rowIndex, color): for j in range(table.columnCount()): table.item(rowIndex, j).setBackground(color) # output process running on execute thread,so prepare for xlsx output. def __prepare_xlsxout(self, outpaths): # We do what we can only operate on the main thread. # Throw real out to a thread if not self.tableWidget_shotlist.rowCount: return tablelist = [] for i in range(self.tableWidget_shotlist.rowCount()): self.status_label.setText( self.tr("xlsx preparing Rows({0}/{1})").format( i, self.tableWidget_shotlist.rowCount())) row_list_rec = [] for j in range(self.tableWidget_shotlist.columnCount()): if self.tableWidget_shotlist.horizontalHeaderItem(j).text() in self.def_thumb_group\ and self.tableWidget_shotlist.item(i,j).data(QtCore.Qt.DecorationRole): row_list_rec.append( self.tableWidget_shotlist.item(i, j).data( QtCore.Qt.DecorationRole)) else: row_list_rec.append( self.tableWidget_shotlist.item(i, j).text()) tablelist.append(row_list_rec) # checksum type string add. for i, columnname in enumerate(self.columnlist): if columnname == self.CHECKSUM: self.columnlist[i] = self.columnlist[i] + self.checksumalgo self.shot.setOpt(self.shot.OUTPUT_COLUMNS, self.columnlist) self.shot.setOpt(self.shot.OUTPUT_ROWS, tablelist) # xlsx output path set self.shot.setOpt(self.shot.RUNMODE, self.shot.RUNMODE_OUT_XLSX) self.shot.setOpt(self.shot.OPT_XLSXOUTTYPE, self.xlsxouttype) self.shot.setOpt(self.shot.OPT_XLSXMAXROWS, self.xlsxmaxrows) self.shot.setOpt(self.shot.OUTPUT_PATH, outpaths) def fitcolumns(self): self.tableWidget_shotlist.resizeColumnToContents(0) self.tableWidget_shotlist.resizeColumnsToContents() self.tableWidget_shotlist.setSortingEnabled(True) self.tableWidget_shotlist.sortByColumn(0, QtCore.Qt.AscendingOrder) self.tableWidget_shotlist.clearSelection() #self.tableWidget_shotlist.resizeRowsToContents() def showerrror_area(self, isvisible): self.label_log.setVisible(isvisible) self.textEdit_Result.setVisible(isvisible) self.pushButton_shotclear.setVisible(isvisible)
def create_settings(self): settings = QSettings() settings.beginGroup(self.plugin_name) return settings
def readSettings(self): settings = QSettings("Panaxtos", "newneuroSpec_Demo") # modify self.restoreGeometry(settings.value("geometry")) self.restoreState(settings.value("state"))
class MainWindow(QMainWindow): def __init__(self, app, parent=None): super(MainWindow, self).__init__(parent) self.imagesDir = app.dir + '/images/' self.setWindowIcon(QIcon(self.imagesDir + 'icon.png')) self.path = '' self.settings = QSettings() self.lastDir = self.settings.value('lastDir', '') self.setMinimumWidth(540) self.supportedFormats = [] for f in QImageReader.supportedImageFormats(): self.supportedFormats.append(str(f.data(), encoding="utf-8")) self.fileWatcher = QFileSystemWatcher() self.fileWatcher.fileChanged.connect(self.fileChanged) # widgets self.showPixmapWidget = None self.tileWidthSpinBox = QSpinBox() self.tileWidthSpinBox.setValue(16) self.tileWidthSpinBox.setFixedWidth(50) self.tileWidthSpinBox.setMinimum(1) self.tileHeightSpinBox = QSpinBox() self.tileHeightSpinBox.setValue(16) self.tileHeightSpinBox.setFixedWidth(50) self.tileHeightSpinBox.setMinimum(1) self.paddingSpinBox = QSpinBox() self.paddingSpinBox.setFixedWidth(50) self.paddingSpinBox.setMinimum(1) self.transparentCheckbox = QCheckBox("Transparent") self.transparentCheckbox.setChecked(True) self.transparentCheckbox.stateChanged.connect(self.transparentChanged) self.backgroundColorEdit = ColorEdit() self.backgroundColorEdit.setEnabled(False) self.backgroundColorLabel = QLabel("Background color:") self.backgroundColorLabel.setEnabled(False) self.forcePotCheckBox = QCheckBox("Force PoT") self.forcePotCheckBox.setChecked(True) self.forcePotCheckBox.stateChanged.connect(self.forcePotChanged) self.reorderTilesCheckBox = QCheckBox("Reorder tiles") self.generateAndExportButton = QPushButton("Generate and export") self.generateAndExportButton.setFixedHeight(32) self.generateAndExportButton.clicked.connect(self.generateAndExportClicked) self.generateAndExportButton.setEnabled(False) self.pixmapWidget = PixmapWidget() self.pixmapWidget.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.pixmapWidget.setPixmap(self.createDropTextPixmap()) self.pixmapWidget.dropSignal.connect(self.fileDropped) self.pixmapWidget.setMinimumHeight(300) # load settings self.tileWidthSpinBox.setValue(int(self.settings.value('tileWidth', 16))) self.tileHeightSpinBox.setValue(int(self.settings.value('tileHeight', 16))) self.paddingSpinBox.setValue(int(self.settings.value('padding', 1))) self.forcePotCheckBox.setChecked(True if self.settings.value('forcePot', 'true') == 'true' else False) self.reorderTilesCheckBox.setChecked(True if self.settings.value('reorderTiles', 'false') == 'true' else False) self.transparentCheckbox.setChecked(True if self.settings.value('transparent', 'false') == 'true' else False) self.backgroundColorEdit.setColorText(str(self.settings.value('backgroundColor', '#FF00FF'))) self.restoreGeometry(QByteArray(self.settings.value('MainWindow/geometry'))) self.restoreState(QByteArray(self.settings.value('MainWindow/windowState'))) # layout hl1 = QHBoxLayout() hl1.setContentsMargins(5, 5, 5, 5) hl1.addWidget(QLabel("Tile width:")) hl1.addSpacing(5) hl1.addWidget(self.tileWidthSpinBox) hl1.addSpacing(15) hl1.addWidget(QLabel("Tile height:")) hl1.addSpacing(5) hl1.addWidget(self.tileHeightSpinBox) hl1.addSpacing(15) hl1.addWidget(QLabel("Padding:")) hl1.addSpacing(5) hl1.addWidget(self.paddingSpinBox) hl1.addSpacing(15) hl1.addWidget(self.forcePotCheckBox) hl1.addSpacing(15) hl1.addWidget(self.reorderTilesCheckBox) hl1.addStretch() hl2 = QHBoxLayout() hl2.setContentsMargins(5, 5, 5, 5) hl2.addWidget(self.transparentCheckbox) hl2.addSpacing(15) hl2.addWidget(self.backgroundColorLabel) hl2.addSpacing(5) hl2.addWidget(self.backgroundColorEdit) hl2.addStretch() hl3 = QHBoxLayout() hl3.setContentsMargins(5, 5, 5, 5) hl3.addWidget(self.generateAndExportButton) vl = QVBoxLayout() vl.setContentsMargins(0, 0, 0, 0) vl.setSpacing(0) vl.addLayout(hl1) vl.addLayout(hl2) vl.addWidget(self.pixmapWidget) vl.addLayout(hl3) w = QWidget() w.setLayout(vl) self.setCentralWidget(w) self.setTitle() def setTitle(self): p = ' - ' + os.path.basename(self.path) if self.path else '' self.setWindowTitle(QCoreApplication.applicationName() + ' ' + QCoreApplication.applicationVersion() + p) def createDropTextPixmap(self): pixmap = QPixmap(481, 300) pixmap.fill(QColor("#333333")) painter = QPainter(pixmap) font = QFont("Arial") font.setPixelSize(28) font.setBold(True) fm = QFontMetrics(font) painter.setFont(font) painter.setPen(QPen(QColor("#888888"), 1)) text = "Drop the tileset image here" x = (pixmap.width()-fm.width(text))/2 y = (pixmap.height()+fm.height())/2 painter.drawText(x, y, text) del painter return pixmap def fileDropped(self, path): path = str(path) name, ext = os.path.splitext(path) ext = ext[1:] if not ext in self.supportedFormats: QMessageBox.warning(self, "Warning", "The dropped file is not supported") return pixmap = QPixmap(path) if pixmap.isNull(): QMessageBox.warning(self, "Warning", "Can't load the image") return if self.path: self.fileWatcher.removePath(self.path) self.path = path self.fileWatcher.addPath(self.path) self.pixmapWidget.setPixmap(pixmap) self.generateAndExportButton.setEnabled(True) self.setTitle() self.activateWindow() def fileChanged(self, path): #self.fileDropped(path) pass def transparentChanged(self): e = self.transparentCheckbox.isChecked() self.backgroundColorEdit.setEnabled(not e) self.backgroundColorLabel.setEnabled(not e) def forcePotChanged(self): e = self.forcePotCheckBox.isChecked() self.reorderTilesCheckBox.setEnabled(e) def generateAndExportClicked(self): g = Generator() g.tileWidth = self.tileWidthSpinBox.value() g.tileHeight = self.tileHeightSpinBox.value() g.forcePot = self.forcePotCheckBox.isChecked() g.isTransparent = self.transparentCheckbox.isChecked() g.bgColor = self.backgroundColorEdit.getColor() g.reorder = self.reorderTilesCheckBox.isChecked() g.padding = self.paddingSpinBox.value() target = g.create(self.pixmapWidget.pixmap); # export self.lastDir = os.path.dirname(self.path) targetPath = QFileDialog.getSaveFileName(self, 'Export', self.lastDir, 'PNG (*.png)') if targetPath: target.save(targetPath[0]) showPixmap = QPixmap.fromImage(target) if self.showPixmapWidget: self.showPixmapWidget.deleteLater() del self.showPixmapWidget self.showPixmapWidget = PixmapWidget() self.showPixmapWidget.setWindowIcon(self.windowIcon()) self.showPixmapWidget.setWindowTitle(os.path.basename(targetPath[0])) self.showPixmapWidget.resize(showPixmap.width(), showPixmap.height()) self.showPixmapWidget.setPixmap(showPixmap) self.showPixmapWidget.show() def closeEvent(self, event): if self.showPixmapWidget: self.showPixmapWidget.close() # save settings self.settings.setValue('tileWidth', self.tileWidthSpinBox.value()) self.settings.setValue('tileHeight', self.tileHeightSpinBox.value()) self.settings.setValue('padding', self.paddingSpinBox.value()) self.settings.setValue('forcePot', self.forcePotCheckBox.isChecked()) self.settings.setValue('reorderTiles', self.reorderTilesCheckBox.isChecked()) self.settings.setValue('transparent', self.transparentCheckbox.isChecked()) self.settings.setValue('backgroundColor', self.backgroundColorEdit.getColor().name()) self.settings.setValue('lastDir', self.lastDir) self.settings.setValue('MainWindow/geometry', self.saveGeometry()) self.settings.setValue('MainWindow/windowState', self.saveState()) super(MainWindow, self).closeEvent(event)