Path: blob/master/src/xmlpngUI.py
254 views
import sys1from PyQt5.QtCore import QSize, Qt2from PyQt5.QtGui import QIcon, QPixmap3from PyQt5.QtWidgets import QAction, QActionGroup, QApplication, QGridLayout, QInputDialog, QLineEdit, QMainWindow, QMessageBox, QProgressDialog, QPushButton, QSpacerItem, QLabel, QFileDialog4from os import path5from animationwindow import AnimationView6import engine.icongridutils as icongridutils7import engine.spritesheetutils as spritesheetutils8# from frameorderscreen import FrameOrderScreen9from xmltablewindow import XMLTableView10import json1112import engine.xmlpngengine as xmlpngengine13from mainUI import Ui_MainWindow14from spriteframe import SpriteFrame15from utils import SPRITEFRAME_SIZE, get_stylesheet_from_file16from settingswindow import SettingsWindow171819def display_progress_bar(parent, title="Sample text", startlim=0, endlim=100):20def update_prog_bar(progress, progresstext):21progbar.setValue(progress)22progbar.setLabel(QLabel(progresstext))23progbar = QProgressDialog(title, None, startlim, endlim, parent)24progbar.setWindowModality(Qt.WindowModal)25progbar.show()2627return update_prog_bar, progbar2829def set_preferences(prefdict):30try:31with open('preferences.json', 'w') as f:32json.dump(prefdict, f)33except Exception as e:34with open("error.log", 'a') as errlog:35errlog.write(str(e))3637class MyApp(QMainWindow):38def __init__(self, prefs):39super().__init__()4041self.ui = Ui_MainWindow()42self.ui.setupUi(self)43self.setWindowTitle("XML Generator")4445self.ui.generatexml_btn.clicked.connect(self.generate_xml)46self.ui.actionExport_as_Spritesheet_and_XML.triggered.connect(self.generate_xml)47self.ui.actionExport_induvidual_images.triggered.connect(self.export_bunch_of_imgs)48self.ui.frames_area.setWidgetResizable(True)49self.frames_layout = QGridLayout(self.ui.sprite_frame_content)50self.ui.frames_area.setWidget(self.ui.sprite_frame_content)5152self.num_labels = 053self.labels = []54self.selected_labels = []55# self.frame_dict = {} # dict< pose_name: str -> frames: list[SpriteFrame] >5657self.add_img_button = QPushButton()58self.add_img_button.setIcon(QIcon("./assets/AddImg.png"))59self.add_img_button.setGeometry(0, 0, SPRITEFRAME_SIZE, SPRITEFRAME_SIZE)60self.add_img_button.setFixedSize(QSize(SPRITEFRAME_SIZE, SPRITEFRAME_SIZE))61self.add_img_button.setIconSize(QSize(SPRITEFRAME_SIZE, SPRITEFRAME_SIZE))62self.add_img_button.clicked.connect(self.open_frame_imgs)6364self.frames_layout.addWidget(self.add_img_button, 0, 0, Qt.AlignmentFlag(0x1|0x20))65self.ui.myTabs.setCurrentIndex(0)6667self.setWindowIcon(QIcon("./assets/appicon.png"))68self.icongrid_zoom = 169self.ui.uploadicongrid_btn.clicked.connect(self.uploadIconGrid)70self.ui.actionImport_IconGrid.triggered.connect(self.uploadIconGrid)71self.ui.generateicongrid_btn.clicked.connect(self.getNewIconGrid)72self.ui.uploadicons_btn.clicked.connect(self.appendIcon)73self.ui.actionImport_Icons.triggered.connect(self.appendIcon)74self.ui.actionClear_IconGrid.triggered.connect(self.clearIconGrid)75self.ui.actionClear_Icon_selection.triggered.connect(self.clearSelectedIcons)7677self.action_zoom_in = QAction(self.ui.icongrid_holder_label)78self.ui.icongrid_holder_label.addAction(self.action_zoom_in)79self.action_zoom_in.triggered.connect(self.zoomInPixmap)80self.action_zoom_in.setShortcut("Ctrl+i")8182self.action_zoom_out = QAction(self.ui.icongrid_holder_label)83self.ui.icongrid_holder_label.addAction(self.action_zoom_out)84self.action_zoom_out.triggered.connect(self.zoomOutPixmap)85self.action_zoom_out.setShortcut("Ctrl+o")8687self.ui.zoom_label.setText("Zoom: 100%")8889self.iconpaths = []90self.icongrid_path = ""9192self.ui.posename_btn.clicked.connect(self.setAnimationNames)93self.ui.posename_btn.setDisabled(True)94self.ui.charname_textbox.textChanged.connect(self.onCharacterNameChange)9596self.num_cols = 697self.num_rows = 19899self.ui.actionImport_Images.triggered.connect(self.open_frame_imgs)100self.ui.action_import_existing.triggered.connect(self.open_existing_spsh_xml)101self.ui.actionImport_from_GIF.triggered.connect(self.open_gif)102103self.num_rows = 1 + self.num_labels//self.num_cols104105for i in range(self.num_cols):106self.frames_layout.setColumnMinimumWidth(i, 0)107self.frames_layout.setColumnStretch(i, 0)108for i in range(self.num_rows):109self.frames_layout.setRowMinimumHeight(i, 0)110self.frames_layout.setRowStretch(i, 0)111112vspcr = QSpacerItem(1, 1)113self.frames_layout.addItem(vspcr, self.num_rows, 0, 1, 4)114115hspcr = QSpacerItem(1, 1)116self.frames_layout.addItem(hspcr, 0, self.num_cols, self.num_rows, 1)117118self.ui.actionClear_Spritesheet_Grid.triggered.connect(self.clear_spriteframe_grid)119self.ui.myTabs.currentChanged.connect(self.handle_tab_change)120self.ui.spsh_settings_btn.clicked.connect(self.show_settings)121122self.settings_widget = SettingsWindow()123124self.anim_view_window = AnimationView()125self.ui.actionPreview_Animation.triggered.connect(self.show_anim_preview)126self.ui.actionPreview_Animation.setEnabled(len(self.labels) > 0)127# adding a QActionGroup at runtime :/128darkmode_action_group = QActionGroup(self.ui.menuDefault_Dark_mode)129theme_opts = ["Default", "Dark Mode"]130checked_action = "Default" if prefs.get("theme", 'default') != 'dark' else "Dark Mode"131for opt in theme_opts:132action = QAction(opt, self.ui.menuDefault_Dark_mode, checkable=True, checked=(opt == checked_action))133self.ui.menuDefault_Dark_mode.addAction(action)134darkmode_action_group.addAction(action)135darkmode_action_group.setExclusive(True)136darkmode_action_group.triggered.connect(self.set_dark_mode)137138self.xml_table = XMLTableView(['Image Path', 'Name', 'Width', 'Height', 'FrameX', 'FrameY', 'FrameWidth', 'FrameHeight'])139self.ui.actionView_XML_structure.triggered.connect(self.show_table_view)140self.ui.actionView_XML_structure.setEnabled(len(self.labels) > 0)141self.ui.actionFlipX.triggered.connect(lambda: self.flip_labels('X'))142self.ui.actionFlipY.triggered.connect(lambda: self.flip_labels('Y'))143144self.ui.use_psychengine_checkbox.clicked.connect(self.handle_psychengine_checkbox)145146# self.frame_order_screen = FrameOrderScreen()147# self.ui.actionChange_Frame_Ordering.triggered.connect(self.show_frame_order_screen)148# self.ui.actionChange_Frame_Ordering.setEnabled(len(self.labels) > 0)149150# Note: Add any extra windows before this if your want the themes to apply to them151if prefs.get("theme", 'default') == 'dark':152self.set_theme(get_stylesheet_from_file("assets/app-styles.qss"))153154155def ranged_selection_handler(self, selected_spriteframe):156first_selected_spriteframe = None157for sprf in self.labels:158if sprf == selected_spriteframe:159break160161if sprf.select_checkbox.checkState() != 0 and sprf != selected_spriteframe:162first_selected_spriteframe = sprf163break164165if first_selected_spriteframe is not None:166start_selecting = False167for sprf in self.labels:168if sprf == first_selected_spriteframe:169start_selecting = True170171if start_selecting:172# checks the box and adds it to the selected list173sprf.select_checkbox.setChecked(1)174175if sprf == selected_spriteframe:176break177178def ranged_deletion_handler(self, selected_spriteframe):179first_selected_spriteframe = None180for sprf in self.labels:181if sprf == selected_spriteframe:182break183184if sprf.select_checkbox.checkState() != 0 and sprf != selected_spriteframe:185first_selected_spriteframe = sprf186break187188if first_selected_spriteframe is not None:189start_selecting = False190for sprf in self.labels:191if sprf == first_selected_spriteframe:192start_selecting = True193194if start_selecting:195# unchecks the box and removes it from the selected list196sprf.select_checkbox.setChecked(0)197198if sprf == selected_spriteframe:199break200201202def open_gif(self):203gifpath = self.get_asset_path("Select the GIF file", "GIF images (*.gif)")204if gifpath != '':205update_prog_bar, progbar = display_progress_bar(self, "Extracting sprite frames....")206QApplication.processEvents()207208sprites = spritesheetutils.get_gif_frames(gifpath, update_prog_bar)209for i, spfr in enumerate(sprites):210spfr.frameparent = self211self.add_spriteframe(spfr)212update_prog_bar(50 + ((i+1)*50//len(sprites)), f"Adding frames from: {gifpath}")213progbar.close()214215self.ui.posename_btn.setDisabled(self.num_labels <= 0)216217def handle_psychengine_checkbox(self, checked):218self.ui.uploadicongrid_btn.setEnabled(not checked)219220# def show_frame_order_screen(self):221# self.frame_order_screen.set_frame_dict(self.frame_dict)222# self.frame_order_screen.show()223224def flip_labels(self, dxn='X'):225for lab in self.selected_labels:226lab.flip_img(dxn)227228for lab in list(self.selected_labels):229# this automatically removes it from self.selected_labels230lab.select_checkbox.setChecked(False)231232def show_table_view(self):233print("Showing table view...")234self.xml_table.fill_data(self.labels)235self.xml_table.show()236237def set_dark_mode(self, event):238if event.text() == "Dark Mode":239styles = get_stylesheet_from_file("./assets/app-styles.qss")240self.set_theme(styles)241else:242self.set_theme("")243244def set_theme(self, stylestr):245self.setStyleSheet(stylestr)246self.settings_widget.setStyleSheet(stylestr)247self.anim_view_window.setStyleSheet(stylestr)248self.xml_table.setStyleSheet(stylestr)249# self.frame_order_screen.setStyleSheet(stylestr)250if stylestr == "":251set_preferences({ "theme":"default" })252else:253set_preferences({ "theme":"dark" })254255def show_anim_preview(self):256self.anim_view_window.parse_and_load_frames(self.labels)257self.anim_view_window.show()258259def show_settings(self):260self.settings_widget.show()261262def handle_tab_change(self, newtabind):263self.ui.actionClear_Spritesheet_Grid.setDisabled(newtabind != 0)264self.ui.action_import_existing.setDisabled(newtabind != 0)265self.ui.actionImport_from_GIF.setDisabled(newtabind != 0)266self.ui.actionImport_Images.setDisabled(newtabind != 0)267self.ui.actionEdit_Frame_Properties.setDisabled(newtabind != 0 or len(self.selected_labels) <= 0)268self.ui.menuExport.setDisabled(newtabind != 0)269self.ui.menuEdit_Selected_Images.setDisabled(newtabind != 0)270271self.ui.actionImport_IconGrid.setDisabled(newtabind != 1)272self.ui.actionImport_Icons.setDisabled(newtabind != 1)273self.ui.actionClear_IconGrid.setDisabled(newtabind != 1)274self.ui.actionClear_Icon_selection.setDisabled(newtabind != 1)275276def onCharacterNameChange(self):277for label in self.labels:278label.img_label.setToolTip(label.get_tooltip_string(self))279280def clear_spriteframe_grid(self):281labs = list(self.labels)282for lab in labs:283lab.remove_self(self)284self.ui.actionEdit_Frame_Properties.setDisabled(len(self.selected_labels) <= 0)285286def resizeEvent(self, a0):287w = self.width()288# print("Current width", w)289if w < 1228:290self.num_cols = 6291elif 1228 <= w <= 1652:292self.num_cols = 8293else:294self.num_cols = 12295self.re_render_grid()296return super().resizeEvent(a0)297298def open_existing_spsh_xml(self):299imgpath = self.get_asset_path("Select Spritesheet File", "PNG Images (*.png)")300301if imgpath != '':302xmlpath = self.get_asset_path("Select XML File", "XML Files (*.xml)")303if xmlpath != '':304trubasenamefn = lambda fpath: path.basename(fpath).split('.')[0]305charname = trubasenamefn(xmlpath)306if trubasenamefn(imgpath) != trubasenamefn(xmlpath):307self.msgbox = QMessageBox(self)308self.msgbox.setWindowTitle("Conflicting file names")309self.msgbox.setText("The Spritesheet and the XML file have different file names.\nThe character name will not be auto-filled")310self.msgbox.setIcon(QMessageBox.Warning)311self.msgbox.addButton("OK", QMessageBox.YesRole)312cancel_import = self.msgbox.addButton("Cancel import", QMessageBox.NoRole)313x = self.msgbox.exec_()314clickedbtn = self.msgbox.clickedButton()315if clickedbtn == cancel_import:316return317charname = self.ui.charname_textbox.text() # trubasenamefn(imgpath) if clickedbtn == usespsh else trubasenamefn(xmlpath)318print("[DEBUG] Exit status of msgbox: "+str(x))319320321update_prog_bar, progbar = display_progress_bar(self, "Extracting sprite frames....")322QApplication.processEvents()323324sprites = spritesheetutils.split_spsh(imgpath, xmlpath, update_prog_bar)325for i, spfr in enumerate(sprites):326spfr.frameparent = self327self.add_spriteframe(spfr)328update_prog_bar(50 + ((i+1)*50//len(sprites)), f"Adding: {imgpath}")329progbar.close()330331self.ui.posename_btn.setDisabled(self.num_labels <= 0)332333self.ui.charname_textbox.setText(charname)334335336337def open_frame_imgs(self):338imgpaths = self.get_asset_path("Select sprite frames", "PNG Images (*.png)", True)339340if imgpaths:341update_prog_bar, progbar = display_progress_bar(self, "Importing sprite frames....", 0, len(imgpaths))342QApplication.processEvents()343344for i, pth in enumerate(imgpaths):345# self.add_img(pth)346self.add_spriteframe(SpriteFrame(self, pth))347update_prog_bar(i+1, f"Adding: {pth}")348progbar.close()349350if len(self.labels) > 0:351self.ui.posename_btn.setDisabled(False)352353def add_spriteframe(self, sp):354self.num_rows = 1 + self.num_labels//self.num_cols355356self.frames_layout.setRowMinimumHeight(self.num_rows - 1, 0)357self.frames_layout.setRowStretch(self.num_rows - 1, 0)358359vspcr = QSpacerItem(1, 1)360self.frames_layout.addItem(vspcr, self.num_rows, 0, 1, 4)361362hspcr = QSpacerItem(1, 1)363self.frames_layout.addItem(hspcr, 0, self.num_cols, self.num_rows, 1)364365self.labels.append(sp)366self.frames_layout.removeWidget(self.add_img_button)367self.frames_layout.addWidget(self.labels[-1], self.num_labels // self.num_cols, self.num_labels % self.num_cols, Qt.AlignmentFlag(0x1|0x20))368self.num_labels += 1369self.frames_layout.addWidget(self.add_img_button, self.num_labels // self.num_cols, self.num_labels % self.num_cols, Qt.AlignmentFlag(0x1|0x20))370self.ui.actionPreview_Animation.setEnabled(len(self.labels) > 0)371self.ui.actionView_XML_structure.setEnabled(len(self.labels) > 0)372# self.ui.actionChange_Frame_Ordering.setEnabled(len(self.labels) > 0)373374# self.update_frame_dict(sp.img_xml_data.pose_name, sp)375376def update_frame_dict(self, key, val, remove=False):377# TODO378return379380def re_render_grid(self):381self.num_rows = 1 + self.num_labels//self.num_cols382for i in range(self.num_cols):383self.frames_layout.setColumnMinimumWidth(i, 0)384self.frames_layout.setColumnStretch(i, 0)385for i in range(self.num_rows):386self.frames_layout.setRowMinimumHeight(i, 0)387self.frames_layout.setRowStretch(i, 0)388389vspcr = QSpacerItem(1, 1)390self.frames_layout.addItem(vspcr, self.num_rows, 0, 1, 4)391392hspcr = QSpacerItem(1, 1)393self.frames_layout.addItem(hspcr, 0, self.num_cols, self.num_rows, 1)394395for i, sp in enumerate(self.labels):396self.frames_layout.addWidget(sp, i//self.num_cols, i%self.num_cols, Qt.AlignmentFlag(0x1|0x20))397self.frames_layout.removeWidget(self.add_img_button)398self.frames_layout.addWidget(self.add_img_button, self.num_labels // self.num_cols, self.num_labels % self.num_cols, Qt.AlignmentFlag(0x1|0x20))399400def export_bunch_of_imgs(self):401savedir = QFileDialog.getExistingDirectory(caption="Save image sequence to...")402updatefn, progbar = display_progress_bar(self, "Exporting Image Sequence", startlim=0, endlim=len(self.labels))403QApplication.processEvents()404405errmsg = xmlpngengine.save_img_sequence(self.labels, savedir, updatefn)406progbar.close()407if errmsg:408self.display_msg_box("Error!", text=f"An error occured: {errmsg}", icon=QMessageBox.Critical)409else:410self.display_msg_box("Success!", text="Image sequence saved successfully!", icon=QMessageBox.Information)411412def generate_xml(self):413charname = self.ui.charname_textbox.text()414charname = charname.strip()415if self.num_labels > 0 and charname != '':416savedir = QFileDialog.getExistingDirectory(caption="Save files to...")417print("Stuff saved to: ", savedir)418if savedir != '':419update_prog_bar, progbar = display_progress_bar(self, "Generating....", 0, len(self.labels))420QApplication.processEvents()421422statuscode, errmsg = xmlpngengine.make_png_xml(423self.labels,424savedir,425charname,426update_prog_bar427)428progbar.close()429if errmsg is None:430self.display_msg_box(431window_title="Done!",432text="Your files have been generated!\nCheck the folder you had selected",433icon=QMessageBox.Information434)435else:436self.display_msg_box(437window_title="Error!",438text=("Some error occured! Error message: " + errmsg),439icon=QMessageBox.Critical440)441else:442errtxt = "Please enter some frames" if self.num_labels <= 0 else "Please enter the name of your character"443self.display_msg_box(444window_title="Error!",445text=errtxt,446icon=QMessageBox.Critical447)448449def zoomInPixmap(self):450if self.icongrid_path and self.icongrid_zoom <= 5:451self.icongrid_zoom *= 1.1452icongrid_pixmap = QPixmap(self.icongrid_path)453w = icongrid_pixmap.width()454h = icongrid_pixmap.height()455icongrid_pixmap = icongrid_pixmap.scaled(int(w*self.icongrid_zoom), int(h*self.icongrid_zoom), 1)456self.ui.icongrid_holder_label.setFixedSize(icongrid_pixmap.width(), icongrid_pixmap.height())457self.ui.scrollAreaWidgetContents_2.setFixedSize(icongrid_pixmap.width(), icongrid_pixmap.height())458self.ui.icongrid_holder_label.setPixmap(icongrid_pixmap)459self.ui.zoom_label.setText("Zoom: %.2f %%" % (self.icongrid_zoom*100))460461462def zoomOutPixmap(self):463if self.icongrid_path and self.icongrid_zoom >= 0.125:464self.icongrid_zoom /= 1.1465icongrid_pixmap = QPixmap(self.icongrid_path)466w = icongrid_pixmap.width()467h = icongrid_pixmap.height()468icongrid_pixmap = icongrid_pixmap.scaled(int(w*self.icongrid_zoom), int(h*self.icongrid_zoom), 1)469self.ui.icongrid_holder_label.setFixedSize(icongrid_pixmap.width(), icongrid_pixmap.height())470self.ui.scrollAreaWidgetContents_2.setFixedSize(icongrid_pixmap.width(), icongrid_pixmap.height())471self.ui.icongrid_holder_label.setPixmap(icongrid_pixmap)472self.ui.zoom_label.setText("Zoom: %.2f %%" % (self.icongrid_zoom*100))473474def uploadIconGrid(self):475print("Uploading icongrid...")476self.icongrid_path = self.get_asset_path("Select the Icon-grid", "PNG Images (*.png)")477icongrid_pixmap = QPixmap(self.icongrid_path)478self.ui.icongrid_holder_label.setFixedSize(icongrid_pixmap.width(), icongrid_pixmap.height())479self.ui.scrollAreaWidgetContents_2.setFixedSize(icongrid_pixmap.width(), icongrid_pixmap.height())480self.ui.icongrid_holder_label.setPixmap(icongrid_pixmap)481482def clearIconGrid(self):483self.icongrid_path = ""484self.ui.icongrid_holder_label.clear()485486def getNewIconGrid(self):487if self.ui.use_psychengine_checkbox.isChecked():488if len(self.iconpaths) > 0:489print("Using psych engine style icon grid generation....")490savepath, _ = QFileDialog.getSaveFileName(self, "Save as filename", filter="PNG files (*.png)")491492stat, problemimg, exception_msg = icongridutils.makePsychEngineIconGrid(self.iconpaths, savepath)493494if exception_msg is not None:495self.display_msg_box(496window_title="Error!",497text=f"An error occured: {exception_msg}",498icon=QMessageBox.Critical499)500else:501if stat == 0:502self.display_msg_box(503window_title="Done!",504text="Your icon-grid has been generated!",505icon=QMessageBox.Information506)507# display final image onto the icon display area508icongrid_pixmap = QPixmap(savepath)509self.ui.icongrid_holder_label.setFixedSize(icongrid_pixmap.width(), icongrid_pixmap.height())510self.ui.scrollAreaWidgetContents_2.setFixedSize(icongrid_pixmap.width(), icongrid_pixmap.height())511self.ui.icongrid_holder_label.setPixmap(icongrid_pixmap)512elif stat == 1:513self.display_msg_box(514window_title="Icon image error",515text=f"The icon {problemimg} is bigger than 150x150 and couldn't be added to the final grid\nThe final grid was generated without it",516icon=QMessageBox.Warning517)518else:519self.display_msg_box(520window_title="Error!",521text="Please select some icons",522icon=QMessageBox.Critical523)524525# no need to continue past this if in psych-engine mode526return527528if self.icongrid_path != '' and len(self.iconpaths) > 0:529print("Valid!")530# savedir = QFileDialog.getExistingDirectory(caption="Save New Icongrid to...")531# if savedir != '':532stat, newinds, problemimg, exception_msg = icongridutils.appendIconToGrid(self.icongrid_path, self.iconpaths) #, savedir)533print("[DEBUG] Function finished with status: ", stat)534errmsgs = [535'Icon grid was too full to insert a new icon',536'Your character icon: {} is too big! Max size: 150 x 150',537'Unable to find suitable location to insert your icon'538]539540if exception_msg is not None:541self.display_msg_box(542window_title="An Error occured",543text=("An Exception (Error) occurred somewhere\nError message:\n"+exception_msg),544icon=QMessageBox.Critical545)546else:547if stat == 0:548self.display_msg_box(549window_title="Done!",550text="Your icon-grid has been generated!\nYour icon's indices are {}".format(newinds),551icon=QMessageBox.Information552)553elif stat == 4:554self.display_msg_box(555window_title="Warning!",556text="One of your icons was smaller than the 150 x 150 icon size!\nHowever, your icon-grid is generated but the icon has been re-adjusted. \nYour icon's indices: {}".format(newinds),557icon=QMessageBox.Warning558)559else:560self.display_msg_box(561window_title="Error!",562text=errmsgs[stat - 1].format(problemimg),563icon=QMessageBox.Critical564)565icongrid_pixmap = QPixmap(self.icongrid_path)566self.ui.icongrid_holder_label.setFixedSize(icongrid_pixmap.width(), icongrid_pixmap.height())567self.ui.scrollAreaWidgetContents_2.setFixedSize(icongrid_pixmap.width(), icongrid_pixmap.height())568self.ui.icongrid_holder_label.setPixmap(icongrid_pixmap)569else:570errtxt = "Please add an icon-grid image" if self.icongrid_path == '' else "Please add an icon"571self.display_msg_box(572window_title="Error!",573text=errtxt,574icon=QMessageBox.Critical575)576577def appendIcon(self):578print("Appending icon")579self.iconpaths = self.get_asset_path("Select your character icons", "PNG Images (*.png)", True)580print("Got icon: ", self.iconpaths)581if len(self.iconpaths) > 0:582print("Valid selected")583self.ui.iconselected_label.setText("No. of\nicons selected:\n{}".format(len(self.iconpaths)))584else:585self.ui.iconselected_label.setText("No. of\nicons selected:\n0")586587def clearSelectedIcons(self):588self.iconpaths = []589self.ui.iconselected_label.setText("Number of\nicons selected:\n{}".format(len(self.iconpaths)))590591def setAnimationNames(self):592if len(self.selected_labels) == 0:593self.display_msg_box(window_title="Error", text="Please select some frames to rename by checking the checkboxes on them", icon=QMessageBox.Critical)594else:595text, okPressed = QInputDialog.getText(self, "Change Animation (Pose) Prefix Name", "Current Animation (Pose) prefix:"+(" "*50), QLineEdit.Normal) # very hack-y soln but it works!596if okPressed and text != '':597print("new pose prefix = ", text)598for label in self.selected_labels:599# self.update_frame_dict(label.img_xml_data.pose_name, label, remove=True)600label.data.pose_name = text601label.modified = True602# self.update_frame_dict(text, label)603label.img_label.setToolTip(label.get_tooltip_string(self))604605for label in list(self.selected_labels):606# this automatically removes it from self.selected_labels607label.select_checkbox.setChecked(False)608else:609print("Cancel pressed!")610611def display_msg_box(self, window_title="MessageBox", text="Text Here", icon=None):612self.msgbox = QMessageBox(self)613self.msgbox.setWindowTitle(window_title)614self.msgbox.setText(text)615if not icon:616self.msgbox.setIcon(QMessageBox.Information)617else:618self.msgbox.setIcon(icon)619x = self.msgbox.exec_()620print("[DEBUG] Exit status of msgbox: "+str(x))621622def get_asset_path(self, wintitle="Sample", fileformat=None, multiple=False):623if multiple:624return QFileDialog.getOpenFileNames(625caption=wintitle,626filter=fileformat,627)[0]628else:629return QFileDialog.getOpenFileName(630caption=wintitle,631filter=fileformat,632)[0]633634635636637if __name__ == '__main__':638app = QApplication(sys.argv)639640prefs = None641try:642with open('preferences.json') as f:643prefs = json.load(f)644except FileNotFoundError as fnfe:645with open("error.log", 'a') as errlog:646errlog.write(str(fnfe))647648with open('preferences.json', 'w') as f:649prefs = { "theme":"default" }650json.dump(prefs, f)651652myapp = MyApp(prefs)653myapp.show()654655try:656sys.exit(app.exec_())657except SystemExit:658print("Closing...")659660