def _load(self): '''A la hora de realizar la carga del fichero controlo si se produce un mensaje de error y lo muestro''' try: file = QFileDialog.getOpenFileName( self, 'Buscar Archivo', QDir.homePath(), "All Files (*);;Music Mp3 Files (*.mp3)") if file: print("Archivo seleccionado: ", file) except: print("Error en la carga de datos.")
def openDirectory(self): """Open a QFileDialog for selecting a local directory. Only display image and GIF files.""" directory = QFileDialog.getExistingDirectory(self, "Choose Directory", "", QFileDialog.Option.ShowDirsOnly) # Specify the file mode to only select directories if directory: # Display the selected folder text in the QLineEdit. There are other, and # possibly better, ways to handle displaying the text, but for simplicity, # this is the method used in this GUI self.folder_line.setText(directory) # Get the contents of the directory and only display files with # specified extensions file_dir = QDir(directory) filters = ["*.gif", "*.png", "*.jpg", "*.jpeg"] files_info = file_dir.entryInfoList(filters, QDir.Filter.Files) # Clear the contents of the QTreeWidget if self.files_tree.model().rowCount() > 0: # NOTE: Since files_tree is connected to the itemSelectionChanged signal, # using the clear() method below will also cause the signal to be emitted. # This causes an undesired issue because of how the items are deleted. To avoid # the signal being called, QObject.blockSignals() will halt files_tree from # emitting signals while removing items self.files_tree.blockSignals(True) # Use the convenience method clear() provided by QTreeWidget to remove # all items and selections self.files_tree.clear() self.files_tree.blockSignals(False) # Reset the QLabel and its image, and disable the movie buttons (in case the # last item selected was a GIF) self.media_label.clear() self.media_label.setPixmap(QPixmap("icons/image_label.png")) self.disableMovieButtons() # Create items for each file and add them to the tree for file in files_info: item = QTreeWidgetItem() item.setText(0, file.fileName()) self.files_tree.addTopLevelItem(item)
def download_complete_slot(self, location): # use native separators location = QDir.toNativeSeparators(location) # show the success message if self.message.information( self, 'Downloaded', f'Download complete!\nFile was successfully downloaded to :\n{location}\n\nOpen the downloaded file now ?', QMessageBox.StandardButtons.Open, QMessageBox.StandardButtons.Cancel ) is QMessageBox.StandardButtons.Open: subprocess.Popen(f'explorer /select,{location}')
def loadStoredImageData(self): """Load images from the Images directory. The Images directory is created the first time running the application.""" if not(self.image_dir.exists()): QDir().mkdir(self.images_path) elif self.image_dir.exists(): # Create a list of the files in the Images directory images = self.image_dir.entryInfoList(QDir.Filters.AllEntries | QDir.Filters.NoDotAndDotDot) for image in images: # Imported files are QFileInfo objects item_name = image.baseName() path = image.absoluteFilePath() self.createListItems(path, item_name, image)
def openVideoFile(self): # self.mediaPlayer.setMedia(QMediaContent()) if self.sender() == self.openVideoAction: self.videoFile, _ = QFileDialog.getOpenFileName( self, "Open video", QDir.homePath()) # if self.videoFile != '': # self.setWindowTitle('{} - {}'.format(os.path.basename(self.videoFile), # os.path.basename(self.projectFile))) if self.videoFile != '': self.setWindowTitle('{} - {}'.format( os.path.basename(self.videoFile), os.path.basename(self.projectFile))) self.saveProjectAction.setEnabled(True) self.maskGenAction.setEnabled(True) # self.loadGraphAction.setEnabled(True) # self.saveGraphAction.setEnabled(True) # self.drawPointAction.setEnabled(True) # self.drawLineAction.setEnabled(True) # self.drawZoneAction.setEnabled(True) creation_datetime, width, height = getVideoMetadata(self.videoFile) self.videoStartDatetime = self.videoCurrentDatetime = creation_datetime self.dateLabel.setText(creation_datetime.strftime('%a, %b %d, %Y')) self.gView.setSceneRect(0, 0, width, height) self.videoItem = QGraphicsVideoItem() self.videoItem.setAspectRatioMode( Qt.AspectRatioMode.KeepAspectRatio) self.gScene.addItem(self.videoItem) self.videoItem.mouseMoveEvent = self.gView.mouseMoveEvent self.videoItem.setSize(QSizeF(width, height)) self.mediaPlayer.setVideoOutput(self.videoItem) self.mediaPlayer.setSource(QUrl.fromLocalFile(self.videoFile)) self.gView.labelSize = width / 50 self.playButton.setEnabled(True) # self.gView.setViewport(QOpenGLWidget()) self.mediaPlayer.pause()
def saveMaskFile(self): creation_datetime, width, height = getVideoMetadata(self.videoFile) item = self.gView.gPolyItem #self.gView.unsavedZones[0] mask_polygon = item.polygon() xy = [] for p in mask_polygon: xy.append((p.x(), p.y())) img = Image.new('RGB', (width, height), color='black') img1 = ImageDraw.Draw(img) img1.polygon(xy, fill="white", outline="white") fileName, _ = QFileDialog.getSaveFileName(self, "Open database file", QDir.homePath(), "PNG files (*.png)") if fileName != '': img.save(fileName) self.gView.scene().removeItem(item) self.gView.unsavedZones = []
class Render(Op): qprog = pyqtSignal(float) fps: float = 20.0 with_audio = True with_cursor = True with_text = True with_hl: bool = True dir: Path = Path(QDir.homePath()) / "Videos" res: Tuple[int, int] = (1920, 1080) title: str = "out" format: Format = Format.Mp4 def __str__(self) -> str: return "render" def run(self, demo: Demo): """ """ # TODO add sect discrim fxn super().run(demo) log("[RenderOp.run] RUNNING RENDER OP on " + demo.title) self.started() self.render_video(demo) self.finished() @property def path(self): return self.dir / Path(f"{self.title}.{self.format.name}") @property def writer(self): return cv2.VideoWriter( filename=str(self.path), fourcc=self.format.to_codec(), apiPreference=cv2.CAP_FFMPEG, isColor=True, fps=self.fps, frameSize=self.res, ) def render_video(self, demo: Demo, verbose=False): """ Renders composite of all demo's images into video using python mmpeg """ log("[Demo.render_video] RUNNING render_video to path " + str(self.path)) # imgs: List[Image] = [] imgs: List[str] = [] for sect_i, sect in enumerate(demo): for step_i, step in enumerate(sect.steps): if step.img is not None: sd: float = 1.0 # hov = None mouse: Cursor | None = None animated = False log(f"\nSECTION {str(sect_i)}, STEP {str(step_i)} info: ") if step.img: log("IMAGE: " + str(step.img)) if step.hover: log("HOVER: " + str(step.hover)) # hov = cv2.imread(str(step.hover)) if step.hover_time: log("HOVER TIME: " + str(step.hover_time)) if step.audio: log("AUDIO: " + str(step.audio)) au = step.audio if step.animated: log("ANIMATED: " + str(step.animated)) # animated = True if (m:=step.mouse) is not None: log("MOUSE: (" + str(m[0]) + ", " + str(m[1]) + ")") mouse = Cursor((int(step.mouse[0]), int(step.mouse[1]))) if (mh := step.mouse_hover) is not None: log("MOUSE HOV: (" + str(step.mouse_hover[0]) + ", " + str(step.mouse_hover[1]) + ")") if (dl := step.delay): log("DELAY: " + str(dl), verbose) sd = float(dl) if step.time: log("TIME: " + str(step.time)) if step.transition: log("TRANSITION: " + str(step.transition)) if step.boxes["hotspot"]: log("HOTSPOT: (" + str(step.boxes["hotspot"]["x1"]) + ", " + str(step.boxes["hotspot"]["y1"]) + ")") if step.boxes["highlight"]: log("HIGHLIGHT: (" + str(step.boxes["highlight"]["x1"]) + ", " + str(step.boxes["highlight"]["y1"]) + "), color: " + str(step.boxes["highlight"]["color"])) if step.boxes["text"]: log("TEXT: (" + str(step.boxes["text"]["text"]) + " (font: " + str(step.boxes["text"]["font"]) + ", size: " + str(step.boxes["text"]["size"]) + ", color: " + str(step.boxes["text"]["color"]) + ")") nframes: int = round(self.fps * sd) simg = cv2.imread(str(step.img)) # simg = cv2.cvtColor(simg, cv2.COLOR_BGR2RGB) if step.audio: au = str(step.audio) if mouse: simg = mouse.paste(simg) h, w, layers = simg.shape for i in range(round(nframes)): imgs.append(simg)
def saveProject(self): if self.projectFile == '': fileDir = QDir.homePath() else: fileDir = self.projectFile self.projectFile, _ = QFileDialog.getSaveFileName( self, "Save project file", fileDir, "Project (*.prj)") # fileName = "/Users/Abbas/project.xml" if self.projectFile == '': return file = QFile(self.projectFile) if (not file.open(QIODevice.OpenModeFlag.WriteOnly | QIODevice.OpenModeFlag.Text)): return xmlWriter = QXmlStreamWriter(file) xmlWriter.setAutoFormatting(True) xmlWriter.writeStartDocument() xmlWriter.writeStartElement('project') xmlWriter.writeStartElement('database') xmlWriter.writeTextElement("fileName", self.obsTb.dbFilename) xmlWriter.writeEndElement() xmlWriter.writeStartElement('video') xmlWriter.writeTextElement( "fileName", self.videoFile) #mediaPlayer.media().canonicalUrl().path()) xmlWriter.writeTextElement("sliderValue", str(self.mediaPlayer.position())) xmlWriter.writeEndElement() xmlWriter.writeStartElement('trajectory') xmlWriter.writeTextElement("metadata", self.obsTb.mdbFileLedit.text()) xmlWriter.writeTextElement( "site", str(self.obsTb.siteNameCombobx.currentIndex())) xmlWriter.writeTextElement( "cam_view", str(self.obsTb.camViewCombobx.currentIndex())) xmlWriter.writeTextElement("traj_db", str(self.obsTb.trjDbCombobx.currentIndex())) xmlWriter.writeEndElement() xmlWriter.writeStartElement('window') xmlWriter.writeTextElement( "mainWin_size", "{},{}".format(int(self.width()), int(self.height()))) xmlWriter.writeTextElement( "mainWin_pos", "{},{}".format(int(self.x()), int(self.y()))) xmlWriter.writeTextElement("obsTbx_open", str(self.obsTb.isVisible())) xmlWriter.writeTextElement( "obsTbx_size", "{},{}".format(int(self.obsTb.width()), int(self.obsTb.height()))) xmlWriter.writeTextElement( "obsTbx_pos", "{},{}".format(int(self.obsTb.x()), int(self.obsTb.y()))) xmlWriter.writeEndElement() xmlWriter.writeEndElement() self.setWindowTitle('{} - {}'.format( os.path.basename(self.videoFile), os.path.basename(self.projectFile))) if self.obsTb.dbFilename != None: self.obsTb.setWindowTitle('{} - {}'.format( os.path.basename(self.obsTb.dbFilename), os.path.basename(self.projectFile)))
def openProject(self): self.projectFile, _ = QFileDialog.getOpenFileName( self, "Open project file", QDir.homePath(), "Project (*.prj)") if self.projectFile == '': return self.saveProjectAction.setEnabled(True) self.maskGenAction.setEnabled(True) # self.loadGraphAction.setEnabled(True) # self.saveGraphAction.setEnabled(True) # self.drawPointAction.setEnabled(True) # self.drawLineAction.setEnabled(True) # self.drawZoneAction.setEnabled(True) tree = ET.parse(self.projectFile) root = tree.getroot() gItems = [] for elem in root: subEelTexts = {} for subelem in elem: subEelTexts[subelem.tag] = subelem.text gItems.append([elem.tag, subEelTexts]) for key in gItems: if key[0] == 'database': item = key[1] if item['fileName'] is not None: self.obsTb.dbFilename = item['fileName'] self.obsTb.opendbFile() elif key[0] == 'video': item = key[1] if item['fileName'] is not None: self.videoFile = item['fileName'] self.openVideoFile() self.mediaPlayer.setPosition(int(item['sliderValue'])) if item['fileName'] is not None: self.loadGraphics() elif key[0] == 'trajectory': item = key[1] if item['metadata'] != None: self.obsTb.mdbFileLedit.setText(item['metadata']) self.obsTb.openMdbFile() self.obsTb.siteNameCombobx.setCurrentIndex( int(item['site'])) self.obsTb.camViewCombobx.setCurrentIndex( int(item['cam_view'])) self.obsTb.trjDbCombobx.setCurrentIndex( int(item['traj_db'])) elif key[0] == 'window': item = key[1] x, y = item['mainWin_pos'].split(',') w, h = item['mainWin_size'].split(',') self.setGeometry(int(x), int(y), int(w), int(h)) if item['obsTbx_open'] == 'True': self.obsTb.show() x, y = item['obsTbx_pos'].split(',') w, h = item['obsTbx_size'].split(',') self.obsTb.setGeometry(int(x), int(y), int(w), int(h))
class MainWindow(QMainWindow): # Create a QSettings object rather than storing values. Pass in a company # name and an application name settings = QSettings("Custom GUIs", "Image Manager GUI") #print(settings.fileName()) # NOTE: Uncomment to print the path to settings images_path = "Images" # File path to the Images directory image_dir = QDir(images_path) info_dialog = None # Create variable for modeless dialog def __init__(self): """MainWindow Constructor for Image Manager""" super().__init__() # Constructor for QMainWindow self.initializeUI() def initializeUI(self): """Set up the GUI's main window and load initial settings and data.""" self.setWindowTitle("Image Manager") self.setObjectName("ImageManager") # Set up the main window, menu, dock widgets, and initialize the GUI's settings self.setUpMainWindow() self.displayImagePreviewDock() self.createActions() self.createMenus() self.loadStoredImageData() self.getInitialSettings() self.show() # Display the main window def setUpMainWindow(self): """Set up the application's main window containing the QListWidget.""" self.image_view_lw = ImageViewerListWidget(self) # Use signals/slots to interact with the list widget self.image_view_lw.itemSelectionChanged.connect(self.updateDockInfo) self.image_view_lw.itemDoubleClicked.connect(self.displayImageInfoDialog) # Use the list widget's internal model to enable/disable menu items self.image_view_lw.model().rowsInserted.connect(self.manageMenuItems) self.image_view_lw.model().rowsRemoved.connect(self.manageMenuItems) self.setCentralWidget(self.image_view_lw) def createActions(self): """Create the application's menu actions.""" # Create actions for File menu self.import_act = QAction("Import Images...", self, triggered=self.importImages) self.import_act.setShortcut("Ctrl+I") self.preferences_act = QAction("Preferences...", self, triggered=self.showPreferencesDialog) self.quit_act = QAction("Quit Task Manager", self, triggered=self.close) self.quit_act.setShortcut(QKeySequence.StandardKey.Quit) # Ctrl+Q # Create actions for Edit menu self.select_all_act = QAction("Select All", self, triggered=self.image_view_lw.selectAll) self.select_all_act.setShortcut(QKeySequence.StandardKey.SelectAll) # Ctrl+A self.delete_act = QAction("Delete Images", self, triggered=self.deleteImages) self.delete_act.setShortcut(QKeySequence.StandardKey.Delete) # Del self.delete_act.setEnabled(False) # Create actions for View menu # Handle the visibility of the dock widget that displays images self.show_dock_act = self.image_preview_dock.toggleViewAction() self.show_dock_act.setText("Show Image View") self.sort_ascend_act = QAction("Sort Ascending", self, triggered=lambda: self.sortListItems(Qt.SortOrder.AscendingOrder)) self.sort_ascend_act.setEnabled(False) self.sort_descend_act = QAction("Sort Descending", self, triggered=lambda: self.sortListItems(Qt.SortOrder.DescendingOrder)) self.sort_descend_act.setEnabled(False) self.fullscreen_act = QAction("Show Fullscreen", self, triggered=self.displayFullScreen, checkable=True) # Create actions for Help menu self.about_act = QAction("About Image Manager", self, triggered=self.showAboutDialog) def createMenus(self): """Create the application's menu.""" if QSysInfo.productType() == "macos" or "osx": self.menuBar().setNativeMenuBar(False) self.file_menu = self.menuBar().addMenu("&File") self.file_menu.addAction(self.import_act) self.file_menu.addSeparator() self.file_menu.addAction(self.preferences_act) self.file_menu.addSeparator() self.file_menu.addAction(self.quit_act) self.edit_menu = self.menuBar().addMenu("&Edit") self.edit_menu.addAction(self.select_all_act) self.edit_menu.addSeparator() self.edit_menu.addAction(self.delete_act) self.view_menu = self.menuBar().addMenu("&View") self.view_menu.addAction(self.show_dock_act) self.view_menu.addSeparator() self.view_menu.addAction(self.sort_ascend_act) self.view_menu.addAction(self.sort_descend_act) self.view_menu.addSeparator() self.view_menu.addAction(self.fullscreen_act) self.help_menu = self.menuBar().addMenu("&Help") self.help_menu.addAction(self.about_act) def manageMenuItems(self, parent, first, last): """Slot to enable/disable menu items if rows have been added/deleted to QListWidget. The rowsInserted() and rowsRemoved() that trigger this slot return the 'parent', 'first', and 'last' values, but they are not used in this method.""" if self.image_view_lw.count() == 0: self.delete_act.setEnabled(False) self.sort_ascend_act.setEnabled(False) self.sort_descend_act.setEnabled(False) elif self.image_view_lw.count() > 0: self.delete_act.setEnabled(True) self.sort_ascend_act.setEnabled(True) self.sort_descend_act.setEnabled(True) def displayImagePreviewDock(self): """Dock widget that displays a selected image in a scrollable area and uses its file name as the dock's title.""" self.image_preview_dock = QDockWidget() self.image_preview_dock.setObjectName("PreviewDock") self.image_preview_dock.setWindowTitle("Show Image View") self.image_preview_dock.setAllowedAreas(Qt.DockWidgetAreas.RightDockWidgetArea) self.display_image_label = QLabel() self.display_image_label.setAlignment(Qt.Alignment.AlignCenter) self.view_scroll_area = QScrollArea() self.view_scroll_area.setMinimumWidth(300) self.view_scroll_area.setWidgetResizable(True) self.image_preview_dock.setWidget(self.view_scroll_area) # Set initial location of dock widget in the main window self.addDockWidget(Qt.DockWidgetAreas.RightDockWidgetArea, self.image_preview_dock) def updateDockInfo(self): """Slot to update the image that the dock widget displays.""" # Only display an image if one item is selected if (len(self.image_view_lw.selectedItems()) == 0 or len(self.image_view_lw.selectedItems()) > 1): self.image_preview_dock.setWindowTitle("Show Image View") self.display_image_label.clear() else: curr_item = self.image_view_lw.currentItem() self.image_preview_dock.setWindowTitle(curr_item.text()) self.show_dock_act.setText("Show Image View") # Get the current height of the dock widget dock_height = self.image_preview_dock.height() # Get the size of the original image/item icon_size = curr_item.icon().availableSizes()[0] icon_width = icon_size.width() # Return a pixmap from the item's icon and display in the scroll area pixmap = curr_item.icon().pixmap(QSize(icon_width, dock_height)) self.display_image_label.setPixmap(pixmap) self.view_scroll_area.setWidget(self.display_image_label) def importImages(self): """Import the images a user selects, remove duplicates, and add items to the QListWidget.""" duplicate_images = [] # Store the names of duplicate images image_paths, _ = QFileDialog.getOpenFileNames(self, "Select Image Files", "", "Images (*.png *.xpm *.jpg *.jpeg)") if image_paths: if self.image_dir.exists(): for image_path in image_paths: # Pass image path to QFileInfo object image_info = QFileInfo(image_path) file_name = image_info.fileName() item_name = image_info.baseName() # Copy the files into the Images directory, check for files # with the same name new_name = self.image_dir.absolutePath() + f"/{file_name}" file_exists = QFile.copy(image_path, new_name) if file_exists == False: duplicate_images.append(image_path) else: self.createListItems(image_path, item_name, image_info, new_name) if self.is_delete_checked == True: # Handle deleting images QFile.moveToTrash(image_path) else: QMessageBox.warning(self, "Images Location Not Found", """<p>The Images Location cannot be found. Restart the application to recreate the directory.</p>""") # Display a custom dialog to inform the user of duplicate images if len(duplicate_images) != 0: duplicates_dialog = QMessageBox(self) duplicates_dialog.setIcon(QMessageBox.Icon.Information) duplicates_dialog.setWindowTitle("Duplicate Images") duplicates_dialog.setText("""<p>Some images were not imported because they already exist.</p>""") details = '\n'.join([item for item in duplicate_images]) duplicates_dialog.setDetailedText(details) duplicates_dialog.exec() duplicate_images.clear() # Clear the list # Check if window is still in focus. If not, give it focus if self.isActiveWindow() == False: self.activateWindow() def createListItems(self, image_path, item_name, image_info, new_name=None): """Simple method for creating QListWidgetItem objects. 'image_path': the path to the file. 'item_name': the base name used for QListWidgetItem objects. 'image_info': the QFileInfo object. 'new_name': used when importing new photos, making sure the program points to the new image location.""" list_item = QListWidgetItem(QIcon(image_path), item_name) self.image_view_lw.setIconSize(QSize(80, 80)) self.image_view_lw.addItem(list_item) if new_name != None: image_info.setFile(new_name) self.image_view_lw.images_info_list.append(image_info) def sortListItems(self, order): """First, sort the items in the QListWidget using sortItems(). Then handle sorting the QFileInfo objects in the images_info_list using Python's sort() to match how the QListWidget sorts items.""" self.image_view_lw.sortItems(order) if order == Qt.SortOrder.AscendingOrder: self.image_view_lw.images_info_list.sort(key=lambda item: (item.baseName().upper(), item.baseName()[0].islower())) elif order == Qt.SortOrder.DescendingOrder: self.image_view_lw.images_info_list.sort(reverse=True, key=lambda item: (item.baseName().upper(), item.baseName()[0].islower())) def deleteImages(self): """Delete images from the QListWidget and from where images are stored on disk.""" number_of_photos = len(self.image_view_lw.selectedItems()) answer = QMessageBox.warning(self, "Delete Image(s)", f"Are you sure you want to delete {number_of_photos} image(s)?", QMessageBox.StandardButtons.No | QMessageBox.StandardButtons.Yes, QMessageBox.StandardButtons.No) if answer == QMessageBox.StandardButtons.Yes: for item in self.image_view_lw.selectedItems(): index = self.image_view_lw.indexFromItem(item).row() # Get the image's information before deletion image_info = self.image_view_lw.images_info_list[index] # Remove items from the Images directory, from the list widget, # and the images_info_list that stores QFileInfo objects QFile.moveToTrash(image_info.absoluteFilePath()) self.image_view_lw.takeItem(index) del self.image_view_lw.images_info_list[index] del item def loadStoredImageData(self): """Load images from the Images directory. The Images directory is created the first time running the application.""" if not(self.image_dir.exists()): QDir().mkdir(self.images_path) elif self.image_dir.exists(): # Create a list of the files in the Images directory images = self.image_dir.entryInfoList(QDir.Filters.AllEntries | QDir.Filters.NoDotAndDotDot) for image in images: # Imported files are QFileInfo objects item_name = image.baseName() path = image.absoluteFilePath() self.createListItems(path, item_name, image) def displayImageInfoDialog(self, item): """Display image metadata in a modeless dialog box. 'index' is the index of the item that is clicked on.""" index = self.image_view_lw.indexFromItem(item).row() if self.info_dialog == None: self.info_dialog = ImageInfoDialog(self, self.image_view_lw.images_info_list[index]) elif self.info_dialog != None: self.info_dialog.close() self.info_dialog = ImageInfoDialog(self, self.image_view_lw.images_info_list[index]) self.info_dialog.show() def showPreferencesDialog(self): """Display the application's preferences dialog. Save the value of the delete_images_checkbox in the settings.""" prefs_dialog = PreferencesDialog(self, self.image_dir, self.is_delete_checked) response = prefs_dialog.exec() if response == 1: # QDialog.DialogCode.Accepted == 1 self.settings.setValue("delete_images", prefs_dialog.delete_images_checkbox.isChecked()) self.is_delete_checked = self.settings.value("delete_images", type=bool) def displayFullScreen(self, state): """Check the state of checkable fullscreen_act. If True, show the main window as fullscreen.""" if state: self.showFullScreen() else: self.showNormal() def showAboutDialog(self): """Display the application's about dialog.""" QMessageBox.about(self, "Image Manager", """<h3 style='text-align:center'>Image Manager</h3> <p style='font-weight: normal'>The <b><i>Image Manager GUI</i></b> demonstrates how to build an application for managing photos. This program also examines some of the common features found in many GUIs.</p> <p style='font-weight: normal'>This application is part of <b><i>Building Custom UIs with PyQt</i></b>.</p> <p style='font-weight: normal'>Designed by: <b>Joshua Willman</b></p> <p style='font-weight: normal'>Icons created by: <b>Joshua Willman</b></p>""") def getInitialSettings(self): """Get initial settings of the application using QSettings upon startup.""" position = self.settings.value("position", QPoint(200, 0)) size = self.settings.value("size", QSize(800, 500)) self.is_delete_checked = self.settings.value("delete_images", type=bool) # restoreState() is used here to restore the image_preview_dock widget self.restoreState(self.settings.value("window_state", bytes(QByteArray()))) self.resize(size) self.move(position) return self.is_delete_checked def saveSettings(self): """Save the settings of the application.""" self.settings.setValue("position", self.pos()) self.settings.setValue("size", self.size()) self.settings.setValue("window_state", self.saveState()) def closeEvent(self, event): """Save the application's settings in the closeEvent().""" self.saveSettings() event.setAccepted(True)
from smseventlog.gui import (delegates, dialogs, gui, refreshtables, tables, update) log = getlog(__name__) # Deprecated in PyQt6, not sure if needed # try: # # try setting app ID for windows only # from PyQt6.QtWinExtras import QtWin # type: ignore # noqa # app_id = 'com.sms.smseventlog' # .{VERSION}' > dont include version, windows thinks its a different app # QtWin.setCurrentProcessExplicitAppUserModelID(app_id) # except ImportError: # pass # add icons path to Qt to be loaded in darkstyle.qss QDir.addSearchPath('qdark_icons', str(cf.p_res / 'images/qdark_icons')) def decorate_modules(): # decorate all classes' methods in these modules with @e error handler modules = [delegates, dialogs, gui, refreshtables, tables, update] for module in modules: er.decorate_all_classes(module=module) @er.errlog('Error in main process.') def launch(): log.info(f'\n\n\n{dt.now():%Y-%m-%d %H:%M} | init | {VERSION}') app = gbl.get_qt_app()