class LueWidget(ttk.Frame): def __init__(self, master=None, **kw): super(LueWidget, self).__init__(master, **kw) ##main() self.orient = IntVar() self.color = IntVar() # path = "" self.title = ttk.Label(self) self.title.configure(anchor='ne', compound='top', font='TkTextFont') self.title.configure(justify='left', padding='5', takefocus=True, text='Comic title') self.title.grid(column='0', row='0') self.title_entry = ttk.Entry(self) _text_ = '''Comic''' self.title_entry.delete('0', 'end') self.title_entry.insert('0', _text_) self.title_entry.grid(column='0', row='1') self.author = ttk.Label(self) self.author.configure(compound='bottom', padding='5', takefocus=False) self.author.configure(text='Author') self.author.grid(column='0', row='2') self.author_entry = ttk.Entry(self) self.author_entry.configure(cursor='arrow', justify='left') _text_ = '''Author''' self.author_entry.delete('0', 'end') self.author_entry.insert('0', _text_) self.author_entry.grid(column='0', row='3') self.html = ttk.Label(self) self.html.configure(compound='top', cursor='arrow', justify='left', padding='5') self.html.configure(text='Image Directory') self.html.grid(column='0', row='4') self.html_entry = PathChooserInput(self) self.html_entry.configure(type='directory') self.html_entry.grid(column='0', row='5') self.orientation = ttk.Label(self) self.orientation.configure(padding='5', text='Reading orientation') self.orientation.grid(column='0', row='6') self.v_orientation = ttk.Radiobutton(self) self.v_orientation.configure(text='Vertical', variable=self.orient, value=1) self.v_orientation.grid(column='0', row='7') self.h_orientation = ttk.Radiobutton(self) self.h_orientation.configure(text='Horizontal', variable=self.orient, value=2) self.h_orientation.grid(column='0', row='8') self.bg = ttk.Label(self) self.bg.configure(anchor='n', justify='left', padding='5', text='Background color') self.bg.grid(column='0', row='9') self.l_bg = ttk.Radiobutton(self) self.l_bg.configure(text='Light', variable=self.color, value=1) self.l_bg.grid(column='0', row='10') self.d_bg = ttk.Radiobutton(self) self.d_bg.configure(text='Dark', variable=self.color, value=2) self.d_bg.grid(column='0', row='11') self.button1 = ttk.Button(self) self.button1.configure(text='Render', command=lambda : submit(self)) self.button1.grid(column='0', row='12')
def _build_frame_dst(self): self.frame_dst = ttk.Labelframe(self.window) self.path_dst = PathChooserInput(self.frame_dst) self.path_dst.configure(mustexist="true", title="Destination Directory", type="directory") self.path_dst.pack(expand="true", fill="x", side="top") self.path_dst.bind("<<PathChooserPathChanged>>", self._callback_path_dst, add="") self.frame_dst.configure(padding="5", text="Destination Directory:") self.frame_dst.pack(expand="true", fill="x", side="top")
def __init__(self, master): self.mainwindow = ttk.Frame(master) self.participantLabel = ttk.Label(self.mainwindow) self.participantLabel.configure(text='Имена участников') self.participantLabel.grid(columnspan='1') self.participantText = tk.Text(self.mainwindow) self.participantText.configure(height='40', relief='ridge', state='normal', undo='true') self.participantText.configure(width='50') self.participantText.grid(columnspan='2', row='1') self.gradeLabel = ttk.Label(self.mainwindow) self.gradeLabel.configure(text='Классы участников') self.gradeLabel.grid(column='3', row='0') self.gradeText = tk.Text(self.mainwindow) self.gradeText.configure(blockcursor='false', height='40', relief='ridge', state='normal') self.gradeText.configure(undo='true', width='20') self.gradeText.grid(column='3', row='1') self.namelessPath = PathChooserInput(self.mainwindow) self.namelessPath.configure(type='directory') self.namelessPath.grid(column='1', columnspan='3', row='2') self.namelessLabel = ttk.Label(self.mainwindow) self.namelessLabel.configure(text='Директрория с безымянными') self.namelessLabel.grid(column='0', row='2') self.destinationLabel = ttk.Label(self.mainwindow) self.destinationLabel.configure(text='Директория для переименованных') self.destinationLabel.grid(column='0', row='3') self.destinationPath = PathChooserInput(self.mainwindow) self.destinationPath.configure(type='directory') self.destinationPath.grid(column='1', columnspan='3', row='3') self.renameButton = ttk.Button(self.mainwindow) self.renameButton.configure(text='Переименовать') self.renameButton.grid(column='3', row='7') self.renameButton.bind('<1>', self.rename_files, add='') self.suffixEntry = ttk.Entry(self.mainwindow) suffix = tk.StringVar() self.suffixEntry.configure(font='TkDefaultFont', textvariable=suffix) self.suffixEntry.grid(column='0', row='6') self.suffixLabel = ttk.Label(self.mainwindow) self.suffixLabel.configure(text='Суффикс') self.suffixLabel.grid(column='0', row='5') self.mainwindow.configure(borderwidth='10', height='200', width='200') self.mainwindow.pack(side='top') # Main widget self.mainwindow = self.mainwindow
def _build_frame_src(self): self.frame_src = ttk.Labelframe(self.window) self.path_src = PathChooserInput(self.frame_src) self.path_src.configure(mustexist="true", title="Source Directory", type="directory") self.path_src.pack(expand="true", fill="x", side="top") self.path_src.bind("<<PathChooserPathChanged>>", self._callback_path_src, add="") self.frame_src.configure(height="200", padding="5", text="Source Directory:", width="0") self.frame_src.pack(expand="true", fill="x", side="top")
class _GuiApp: # pylint: disable=too-many-instance-attributes,too-few-public-methods def __init__(self, master=None): # build ui self.window = tk.Tk() if master is None else tk.Toplevel(master) self._build_frame_src() self._build_frame_key() self._build_frame_dst() self._build_frame_opt() self._build_frame_act() _set_window_icon(self.window) self.window.title( f"RPGMaker MV Decoder / Encoder v{rpgmaker_mv_decoder.__version__}" ) self.window.configure(height="200", padx="10", pady="5", width="500") self.window.resizable(0, 0) self.progress = _ProgressUI(self.window) self.about = _AboutUI(self.window) # Main widget self.main_window = self.window self.dialog_shown: bool = False self.src_path = "" self.dst_path = "" self.gui_key = "" self.callbacks = Callbacks(self.progress.set_progress, prompt_callback=_prompt_cb) def _build_frame_act(self): self.frame_action = ttk.Frame(self.window) self.button_decode = ttk.Button(self.frame_action) self.button_decode.configure(state="disabled", text="Decode", underline="0") self.button_decode.grid(column="0", row="0", sticky="w") self.button_decode.configure(command=self._decode) self.button_encode = ttk.Button(self.frame_action) self.button_encode.configure(state="disabled", text="Encode", underline="0") self.button_encode.grid(column="2", row="0") self.button_encode.configure(command=self._encode) self.button_about = ttk.Button(self.frame_action) self.img_about = tk.PhotoImage(data=ABOUT_ICON["data"], format=ABOUT_ICON["format"]) self.button_about.configure(default="normal", image=self.img_about, text="About") self.button_about.grid(column="4", row="0", sticky="e") self.button_about.configure(command=self._about) self.frame_action.configure(height="0", width="0") self.frame_action.pack(fill="x", pady="5", side="top") self.frame_action.columnconfigure("0", uniform="3") self.frame_action.columnconfigure("1", minsize="60") self.frame_action.columnconfigure("2", uniform="3", weight="1") self.frame_action.columnconfigure("3", minsize="60") def _build_frame_opt(self): self.frame_options = ttk.Labelframe(self.window) self.checkbox_detect_ext = ttk.Checkbutton(self.frame_options) self.detect_file_ext = tk.StringVar(value="") self.checkbox_detect_ext.configure(text="Detect File Extensions", underline="7", variable=self.detect_file_ext) self.checkbox_detect_ext.grid(column="0", row="0", sticky="w") self.checkbox_overwrite = ttk.Checkbutton(self.frame_options) self.overwrite = tk.StringVar(value="") self.checkbox_overwrite.configure(text="Overwrite Files", underline="0", variable=self.overwrite) self.checkbox_overwrite.grid(column="2", row="0") self.frame_options.configure(height="0", padding="10", text="Options:", width="0") self.frame_options.pack(expand="true", fill="x", pady="5", side="top") self.frame_options.columnconfigure("1", minsize="120") def _build_frame_dst(self): self.frame_dst = ttk.Labelframe(self.window) self.path_dst = PathChooserInput(self.frame_dst) self.path_dst.configure(mustexist="true", title="Destination Directory", type="directory") self.path_dst.pack(expand="true", fill="x", side="top") self.path_dst.bind("<<PathChooserPathChanged>>", self._callback_path_dst, add="") self.frame_dst.configure(padding="5", text="Destination Directory:") self.frame_dst.pack(expand="true", fill="x", side="top") def _build_frame_key(self): self.frame_key = ttk.Labelframe(self.window) self.entry_key = ttk.Entry(self.frame_key) self.entry_key.configure(font="TkFixedFont", state="normal", validate="all", width="32") self.entry_key.grid(column="0", padx="5", pady="5", row="0", sticky="w") _validatecmd = (self.entry_key.register(self._validate_text), "%P") self.entry_key.configure(validatecommand=_validatecmd) self.button_detect = ttk.Button(self.frame_key) self.button_detect.configure(state="disabled", text="Detect Key", underline="7") self.button_detect.grid(column="1", padx="5", pady="5", row="0", sticky="w") self.button_detect.configure(command=self._detect) self.frame_key.configure(height="0", text="Encoding / Decoding Key:", width="0") self.frame_key.pack(fill="x", ipadx="5", pady="5", side="top") self.frame_key.columnconfigure("1", minsize="160") def _build_frame_src(self): self.frame_src = ttk.Labelframe(self.window) self.path_src = PathChooserInput(self.frame_src) self.path_src.configure(mustexist="true", title="Source Directory", type="directory") self.path_src.pack(expand="true", fill="x", side="top") self.path_src.bind("<<PathChooserPathChanged>>", self._callback_path_src, add="") self.frame_src.configure(height="200", padding="5", text="Source Directory:", width="0") self.frame_src.pack(expand="true", fill="x", side="top") def run(self): """`run` Runs the UI""" self.src_path = "" self.dst_path = "" self.gui_key = "" self.main_window.mainloop() def _about(self): self._show_about() def _disable_buttons(self): self.button_detect["state"] = tk.DISABLED self.button_decode["state"] = tk.DISABLED self.button_encode["state"] = tk.DISABLED def _set_button_state(self): if self.src_path != "": if self.gui_key == "": self.button_detect["state"] = tk.NORMAL if self.src_path != "" and self.dst_path != "": if self.gui_key == "" or len(self.gui_key) == 32: self.button_decode["state"] = tk.NORMAL if self.src_path != "" and self.dst_path != "" and len( self.gui_key) == 32: self.button_encode["state"] = tk.NORMAL def _callback_path_src(self, _event=None): self.src_path = self.path_src.entry.get() self._set_button_state() def _callback_path_dst(self, _event=None): self.dst_path = self.path_dst.entry.get() self._set_button_state() def _show_about(self): if self.about is None: self.about = _AboutUI(self.window) self.about.run() else: self.about.show() def _show_dialog(self, title: str, text: str): self.dialog_shown = True if self.progress is None: self.progress = _ProgressUI(self.window) self.progress.set_title(title) self.progress.set_label(text) self.progress.run() else: self.progress.set_title(title) self.progress.set_label(text) self.progress.show() def _hide_dialog(self): if self.progress is not None: if self.dialog_shown: self.progress.close() self.dialog_shown = False def _validate_text(self, new_text: str) -> bool: data = new_text.replace(" ", "") if data == "": self.gui_key = data self._disable_buttons() self._set_button_state() return True try: int(data, 16) self.gui_key = data self._disable_buttons() self._set_button_state() return True except ValueError: return False def _detect(self, decode: bool = False): def _detect_key(): self._disable_buttons() def _show_dialog(): self._show_dialog("Key Detection", "Searching for key") threading.Thread(target=_show_dialog).start() try: self.gui_key = ProjectKeyFinder(self.src_path, self.callbacks).find_key() self.entry_key.delete(0, tk.END) self.entry_key.insert(0, self.gui_key) except NoValidFilesFound: pass if not decode: self._set_button_state() self._hide_dialog() if not decode: threading.Thread(target=_detect_key).start() else: _detect_key() def _decode(self): if self.gui_key == "": self._detect(True) def _show_dialog_decode(): self._show_dialog("Decoding Files", "Decoding all files") threading.Thread(target=_show_dialog_decode).start() def _decode_files(): decoder: ProjectDecoder = ProjectDecoder(self.src_path, self.dst_path, self.entry_key.get(), self.callbacks) if self.overwrite.get() == "1": decoder.overwrite = True decoder.decode(self.detect_file_ext.get() == "1") self._hide_dialog() self._set_button_state() threading.Thread(target=_decode_files).start() self._disable_buttons() def _encode(self): def _show_dialog_encode(): self._show_dialog("Encoding Files", "Encoding all files") threading.Thread(target=_show_dialog_encode).start() def _encode_files(): encoder: ProjectEncoder = ProjectEncoder(self.src_path, self.dst_path, self.entry_key.get(), self.callbacks) if self.overwrite.get() == "1": encoder.overwrite = True encoder.encode() self._hide_dialog() self._set_button_state() threading.Thread(target=_encode_files).start() self._disable_buttons()
def __init__(self, master=None): # Create main window and frame mainwindow = tk.Tk() mainFrame = ttk.Frame(mainwindow) # Add Gwent Installation Path Chooser gwentPathFrame = ttk.LabelFrame( mainFrame, text='1. Specify Gwent Installation Path', labelanchor='n') gwentPathInfoButton = ttk.Button(gwentPathFrame, text='?', width='3') gwentPathInfoButton.pack(side='left', padx='5') gwentPathInfoButton.configure(command=lambda: GwentCardExporter.showInfo( self, "Specify the folder in which Gwent is installed, usually named 'GWENT The Witcher Card Game' or 'Gwent'.\n\nIf you have the game installed on Steam you can usually find it at:\n 'C:/Program Files (x86)/Steam/steamapps/common/GWENT The Witcher Card Game'\n\nIf you have the game installed on GOG you can usually find it at:\n 'C:/Program Files (x86)/GOG Galaxy/Games/Gwent'" )) gwentPathChooser = PathChooserInput(gwentPathFrame) gwentPathChooser.config(type='directory') gwentPathChooser.pack(fill='x', side='left', expand='true', pady='5') gwentPathFrame.pack(fill='x', pady='5', padx='5', side='top') # Open path file and load saved Gwent installation path # Create a file to save paths if one is not already made try: pathFile = open('savedPaths.txt', 'r') except: with open('savedPaths.txt', 'w') as pathFile: pass pathFile = open('savedPaths.txt', 'r') gwentPathChooser.configure(path=pathFile.readline().rstrip()) # Add Card Data File Selector and Export Button cardDataFrame = ttk.Labelframe(mainFrame, text='2. Extract or update card data', labelanchor='n') # Add Card Data Info Button cardDataInfoButton = ttk.Button(cardDataFrame, text='?', width='3') cardDataInfoButton.pack(side='left', padx='5') cardDataInfoButton.configure(command=lambda: GwentCardExporter.showInfo( self, "In order to generate card images you first need to extract the card data from the game files.\n\nTo do so click the 'Export Data' button and save the file as a .json.\n\nIt should appear in the menu here and should load the data into the card list below so you can\nchoose specific cards to generate.\n\nThese .json card data files can be found in the 'card_data' folder in the programs directory\nand can also be used for your own personal Gwent projects.\n\nRight now they only contain the data to generate images but the plan is to format all\nthe card data from the games files so this program can be used as a proper card data exporter as well." )) # Add combobox to select a json file self.currentJSON = ttk.Combobox(cardDataFrame) self.currentJSON.pack(side='left', fill='x', expand='true') # Try and list json files in 'card_data', create empty 'card_data' dir if none exists try: self.currentJSON['values'] = [ x for x in listdir('card_data') if x.endswith(".json") ] except FileNotFoundError: mkdir('card_data') self.currentJSON['values'] = [ x for x in listdir('card_data') if x.endswith(".json") ] # When a new json is selected load it into the card list view self.currentJSON.bind('<<ComboboxSelected>>', self.loadNewJSON) # Save number of files and set selection to the newest (highest version number) self.numberofFiles = len(self.currentJSON['values']) if self.numberofFiles != 0: self.currentJSON.current(self.numberofFiles - 1) # Add a button for exporting new card data exportDataButton = ttk.Button(cardDataFrame) exportDataButton.config(text='Export Data') exportDataButton.pack(side='left', padx='5', pady='5') exportDataButton.configure( command=lambda: GwentCardExporter.updateJSON( self, gwentPathChooser.cget('path'))) cardDataFrame.pack(fill='x', pady='5', padx='5', side='top') # Add Card Options cardOptionsFrame = ttk.Labelframe(mainFrame, text='3. Specify card options', labelanchor='n') # Add three checkboxes for image options addBordersBox = ttk.Checkbutton(cardOptionsFrame) self.addBorders = tk.BooleanVar() self.addBorders.set(True) addBordersBox.config(text='Add Borders', variable=self.addBorders) addBordersBox.pack(anchor='nw', side='top', padx='5') addStrengthIconsBox = ttk.Checkbutton(cardOptionsFrame) self.addStrengthIcons = tk.BooleanVar() self.addStrengthIcons.set(True) addStrengthIconsBox.config(text='Add Strength/Icons', variable=self.addStrengthIcons) addStrengthIconsBox.pack(anchor='nw', side='top', padx='5') addProvisionsBox = ttk.Checkbutton(cardOptionsFrame) self.addProvisions = tk.BooleanVar() self.addProvisions.set(True) addProvisionsBox.config(text='Add Provisions', variable=self.addProvisions) addProvisionsBox.pack(anchor='nw', side='top', padx='5') # Add dividor separator1 = ttk.Separator(cardOptionsFrame) separator1.config(orient='horizontal') separator1.pack(fill='x', pady='5', side='top', padx='5') # Add Card Data File Selector and Export Button cardQualityFrame = ttk.Frame(cardOptionsFrame) # Add a label for choosing image quality qualityLabel = ttk.Label(cardQualityFrame, text='Image Quality:') qualityLabel.pack(side='left') # Add combobox to select a json file self.imageQuality = ttk.Combobox(cardQualityFrame) self.imageQuality.pack(side='left', fill='x', expand='true') self.imageQuality['values'] = ['Low', 'Medium', 'High', 'Uber (4K)'] self.imageQuality.current(2) cardQualityFrame.pack(fill='x', pady='5', padx='5', side='top') # Add dividor separator2 = ttk.Separator(cardOptionsFrame) separator2.config(orient='horizontal') separator2.pack(fill='x', pady='5', side='top', padx='5') # Add radio buttons for all or only specfic images self.allImages = tk.IntVar() self.allImages.set(1) allImagesSelector = ttk.Radiobutton(cardOptionsFrame) allImagesSelector.config(text='All Images', variable=self.allImages, value=1) allImagesSelector.pack(anchor='nw', side='top', padx='5') specificImagesSelector = ttk.Radiobutton(cardOptionsFrame) specificImagesSelector.config(text='Specified Images', variable=self.allImages, value=0) specificImagesSelector.pack(anchor='nw', side='top', padx='5') # Add list of cards found in the card data file cardListFrame = ttk.Frame(cardOptionsFrame) # Set up treeview self.cardView = ttk.Treeview(cardListFrame, columns=('Name', 'ID')) self.cardView.config(selectmode='extended') self.cardView['show'] = 'headings' self.cardView.heading("Name", text="Name", anchor="w") self.cardView.heading("ID", text="ID", anchor="w") self.cardView.bind('<<TreeviewSelect>>', self.selectSpecifiedImages) self.cardView.pack(side='left', expand='true') # Link a scrollbar to the treeview scrollBar = ttk.Scrollbar(cardListFrame, orient="vertical") scrollBar.configure(command=self.cardView.yview) self.cardView.config(yscrollcommand=scrollBar.set) scrollBar.pack(side='left', fill='both') cardListFrame.pack(side='top', padx='5') # Add a search box to the card list cardSearchFrame = ttk.Frame(cardOptionsFrame) # label for search box searchLabel = ttk.Label(cardSearchFrame, text='Search:') searchLabel.pack(side='left') # add search box for card list self.detachedCards = [] searchText = tk.StringVar() searchText.trace( 'w', lambda name, index, mode, searchText=searchText: GwentCardExporter. filterCardlist(self, searchText.get())) self.searchBox = ttk.Entry(cardSearchFrame, textvariable=searchText) self.searchBox.pack(side='left', expand='true', fill='x') cardSearchFrame.pack(fill='x', side='top', pady='8', padx='5') # If one is selected load the json file into the card list if self.numberofFiles != 0: GwentCardExporter.loadNewJSON(self, None) cardOptionsFrame.pack(fill='x', pady='5', padx='5', side='top') # Add Image Path Installation Chooser imagePathFrame = ttk.LabelFrame(mainFrame, text='4. Choose where to save', labelanchor='n') imagePathInfoButton = ttk.Button(imagePathFrame, text='?', width='3') imagePathInfoButton.pack(side='left', padx='5') imagePathInfoButton.configure( command=lambda: GwentCardExporter.showInfo( self, "Specifiy the folder where you want to save the generated images" )) imagePathChooser = PathChooserInput(imagePathFrame) imagePathChooser.config(type='directory') imagePathChooser.pack(fill='x', side='left', expand='true', pady='5') imagePathFrame.pack(fill='x', pady='5', padx='5', side='top') # Load saved image save path and close path file imagePathChooser.configure(path=pathFile.readline().rstrip()) pathFile.close() # Add a button to generate cards generateButton = ttk.Button(mainFrame) generateButton.config(text='Generate') generateButton.pack(side='top', pady='5') generateButton.configure( command=lambda: GwentCardExporter.generateCards( self, imagePathChooser.cget('path'), gwentPathChooser.cget('path'))) # Set up final window mainFrame.config(height='690', width='400') mainFrame.pack(padx='3', pady='3', side='top') mainwindow.geometry('450x690') mainwindow.resizable(False, False) mainwindow.title('Gwent Card Image Exporter') mainwindow.iconbitmap('assets/favicon.ico') self.mainwindow = mainwindow
class LueWidget(ttk.Frame): def __init__(self, master=None, **kw): super(LueWidget, self).__init__(master, **kw) self.title = ttk.Label(self) self.title.configure(anchor='ne', compound='top', cursor='based_arrow_down', font='TkTextFont') self.title.configure(justify='left', padding='5', takefocus=True, text='Comic title') self.title.grid(column='0', row='0') self.title_entry = ttk.Entry(self) _text_ = '''entry3''' self.title_entry.delete('0', 'end') self.title_entry.insert('0', _text_) self.title_entry.grid(column='0', row='1') self.author = ttk.Label(self) self.author.configure(compound='bottom', cursor='based_arrow_down', padding='5', takefocus=False) self.author.configure(text='Author') self.author.grid(column='0', row='2') self.author_entry = ttk.Entry(self) self.author_entry.configure(cursor='arrow', justify='left') _text_ = '''entry5''' self.author_entry.delete('0', 'end') self.author_entry.insert('0', _text_) self.author_entry.grid(column='0', row='3') self.html = ttk.Label(self) self.html.configure(compound='top', cursor='arrow', justify='left', padding='5') self.html.configure(text='HTML File') self.html.grid(column='0', row='4') self.html_entry = PathChooserInput(self) self.html_entry.configure(type='file') self.html_entry.grid(column='0', row='5') self.orientation = ttk.Label(self) self.orientation.configure(padding='5', text='Reading orientation?') self.orientation.grid(column='0', row='6') self.v_orientation = ttk.Radiobutton(self) self.v_orientation.configure(text='Vertical') self.v_orientation.grid(column='0', row='7') self.h_orientation = ttk.Radiobutton(self) self.h_orientation.configure(cursor='arrow', state='normal', text='Horizontal') self.h_orientation.grid(column='0', row='8') self.bg = ttk.Label(self) self.bg.configure(anchor='n', justify='left', padding='5', text='Background color') self.bg.grid(column='0', row='9') self.l_bg = ttk.Radiobutton(self) self.l_bg.configure(takefocus=False, text='Light') self.l_bg.grid(column='0', row='10') self.d_bg = ttk.Radiobutton(self) self.d_bg.configure(text='Dark') self.d_bg.grid(column='0', row='11')
def __init__(self, master=None): # build ui self.base_ds = ttk.Frame(master) self.forms_link = ttk.Entry(self.base_ds) self.forms_link.place(anchor='nw', relx='0.01', rely='0.05', width='400', x='0', y='0') self.mail_control = ttk.Entry(self.base_ds) self.mail_control.config(exportselection='true') self.mail_control.place(anchor='nw', relx='0.01', rely='0.21', width='400', x='0', y='0') self.label_forms = ttk.Label(self.base_ds) self.label_forms.config(text='Link Forms') self.label_forms.place(anchor='nw', relx='0.01', x='0', y='0') self.label_mail = ttk.Label(self.base_ds) self.label_mail.config(text='E-mails para relatórios') self.label_mail.place(anchor='nw', relx='0.01', rely='0.16', x='0', y='0') self.separator_2 = ttk.Separator(self.base_ds) self.separator_2.config(orient='horizontal') self.separator_2.place(anchor='nw', relx='0.0', rely='0.47', width='600', y='0') self.arquivo_ch = PathChooserInput(self.base_ds) self.arquivo_ch.config(type='file') self.arquivo_ch.place(anchor='nw', relx='0.01', rely='0.38', width='465', x='0', y='0') self.label_arquivo = ttk.Label(self.base_ds) self.label_arquivo.config(text='Excel com chamados') self.label_arquivo.place(anchor='nw', relx='0.01', rely='0.33', x='0', y='0') self.progressbar_1 = ttk.Progressbar(self.base_ds) self.progressbar_1.config(maximum='100', orient='vertical', value='0') self.progressbar_1.place(anchor='nw', height='190', relx='0.61', rely='0.51', width='15', x='0', y='0') self.button_ok = ttk.Button(self.base_ds) self.button_ok.config(text='OK') self.button_ok.place(anchor='nw', relx='0.86', rely='0.92', x='0', y='0') self.button_enviar = ttk.Button(self.base_ds) self.button_enviar.config(text='Enviar') self.button_enviar.place(anchor='nw', height='80', relx='0.75', rely='0.56', width='80', y='0') self.progressbar_2 = ttk.Progressbar(self.base_ds) self.progressbar_2.config(maximum='100', orient='horizontal') self.progressbar_2.place(anchor='nw', height='6', relx='0.75', rely='0.77', width='80', x='0', y='0') self.button_config = ttk.Button(self.base_ds) self.button_config.config(text='Configurações') self.button_config.place(anchor='nw', relx='0.66', rely='0.92', x='0', y='0') self.button_config.bind('<1>', self.callback, add='') self.forms_colar = ttk.Button(self.base_ds) self.forms_colar.config(text='Colar Inteligente') self.forms_colar.place(anchor='nw', relx='0.82', rely='0.38', x='0', y='0') self.scrollbarhelper_2 = ScrollbarHelper(self.base_ds, scrolltype='both') self.output = tk.Text(self.scrollbarhelper_2.container) self.output.config(height='10', relief='flat', state='normal', undo='false') self.output.config(width='50') self.output.place(anchor='nw', width='120', x='0', y='0') self.scrollbarhelper_2.add_child(self.output) self.scrollbarhelper_2.place(anchor='nw', height='190', relx='0.01', rely='0.51', width='355', x='0', y='0') self.base_ds.config(height='400', relief='flat', width='600') self.base_ds.pack(anchor='center', expand='false', side='top') self.base_ds.pack_propagate(0) # Main widget self.mainwindow = self.base_ds #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # INICIALIZAÇÃO #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ self.forms_link.insert(0, link_forms) self.mail_control.insert(0, email_controle) self.button_enviar.config(state='disabled') #\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ # CHAMANDO FUNÇÕES #/////////////////////////////////////////////////////////////////////////////////////////// self.button_ok.config(command=self.sair) self.button_config.config(command=self.setting) self.button_enviar.config(command=self.enviar) self.arquivo_ch.bind('<<PathChooserPathChanged>>', self.arquivo_excel)
class Automail: def __init__(self, master=None): # build ui self.base_ds = ttk.Frame(master) self.forms_link = ttk.Entry(self.base_ds) self.forms_link.place(anchor='nw', relx='0.01', rely='0.05', width='400', x='0', y='0') self.mail_control = ttk.Entry(self.base_ds) self.mail_control.config(exportselection='true') self.mail_control.place(anchor='nw', relx='0.01', rely='0.21', width='400', x='0', y='0') self.label_forms = ttk.Label(self.base_ds) self.label_forms.config(text='Link Forms') self.label_forms.place(anchor='nw', relx='0.01', x='0', y='0') self.label_mail = ttk.Label(self.base_ds) self.label_mail.config(text='E-mails para relatórios') self.label_mail.place(anchor='nw', relx='0.01', rely='0.16', x='0', y='0') self.separator_2 = ttk.Separator(self.base_ds) self.separator_2.config(orient='horizontal') self.separator_2.place(anchor='nw', relx='0.0', rely='0.47', width='600', y='0') self.arquivo_ch = PathChooserInput(self.base_ds) self.arquivo_ch.config(type='file') self.arquivo_ch.place(anchor='nw', relx='0.01', rely='0.38', width='465', x='0', y='0') self.label_arquivo = ttk.Label(self.base_ds) self.label_arquivo.config(text='Excel com chamados') self.label_arquivo.place(anchor='nw', relx='0.01', rely='0.33', x='0', y='0') self.progressbar_1 = ttk.Progressbar(self.base_ds) self.progressbar_1.config(maximum='100', orient='vertical', value='0') self.progressbar_1.place(anchor='nw', height='190', relx='0.61', rely='0.51', width='15', x='0', y='0') self.button_ok = ttk.Button(self.base_ds) self.button_ok.config(text='OK') self.button_ok.place(anchor='nw', relx='0.86', rely='0.92', x='0', y='0') self.button_enviar = ttk.Button(self.base_ds) self.button_enviar.config(text='Enviar') self.button_enviar.place(anchor='nw', height='80', relx='0.75', rely='0.56', width='80', y='0') self.progressbar_2 = ttk.Progressbar(self.base_ds) self.progressbar_2.config(maximum='100', orient='horizontal') self.progressbar_2.place(anchor='nw', height='6', relx='0.75', rely='0.77', width='80', x='0', y='0') self.button_config = ttk.Button(self.base_ds) self.button_config.config(text='Configurações') self.button_config.place(anchor='nw', relx='0.66', rely='0.92', x='0', y='0') self.button_config.bind('<1>', self.callback, add='') self.forms_colar = ttk.Button(self.base_ds) self.forms_colar.config(text='Colar Inteligente') self.forms_colar.place(anchor='nw', relx='0.82', rely='0.38', x='0', y='0') self.scrollbarhelper_2 = ScrollbarHelper(self.base_ds, scrolltype='both') self.output = tk.Text(self.scrollbarhelper_2.container) self.output.config(height='10', relief='flat', state='normal', undo='false') self.output.config(width='50') self.output.place(anchor='nw', width='120', x='0', y='0') self.scrollbarhelper_2.add_child(self.output) self.scrollbarhelper_2.place(anchor='nw', height='190', relx='0.01', rely='0.51', width='355', x='0', y='0') self.base_ds.config(height='400', relief='flat', width='600') self.base_ds.pack(anchor='center', expand='false', side='top') self.base_ds.pack_propagate(0) # Main widget self.mainwindow = self.base_ds #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # INICIALIZAÇÃO #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ self.forms_link.insert(0, link_forms) self.mail_control.insert(0, email_controle) self.button_enviar.config(state='disabled') #\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ # CHAMANDO FUNÇÕES #/////////////////////////////////////////////////////////////////////////////////////////// self.button_ok.config(command=self.sair) self.button_config.config(command=self.setting) self.button_enviar.config(command=self.enviar) self.arquivo_ch.bind('<<PathChooserPathChanged>>', self.arquivo_excel) #\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ #//////////////////////////////////////////////////////////////////////////////////////////// def callback(self, event=None): pass def run(self): self.mainwindow.mainloop() #-------------------------------------------------------------------------------------------- # FUNÇÕES #--------------------------------------------------------------------------------------------- def sair(self): root.destroy() if obs == 1: root_config.destroy() ############################################################################## #!!! EMAIL def enviar(self): global corpo_email, excel excel['Envio email'] = "nan" ncolunas = len(excel.columns) nlinhas = len(excel.index) ## TRATAMENTO DOS DADOS for i in range(nlinhas): # Pegando valores da base dados campo_chamado = excel.columns[int(coluna_chamado)] try: numero_chamado = int(excel.loc[i][int(coluna_chamado)]) except: excel.iat[i, ncolunas] = "Falta n° chamado" continue nome_chamado = excel.loc[i][int(coluna_assunto)] #cliente = excel.loc[i][13] responsavel = excel.loc[i][int(coluna_responsavel_chm)] email_destino = excel.loc[i][int(coluna_email)] if str(nome_chamado) == 'nan': excel.iat[i, ncolunas] = "Falta Assunto do chamado" recusa.append(" {};".format(numero_chamado)) continue if str(email_destino) == "nan": excel.iat[i, ncolunas] = "Falta email" recusa.append(" {};".format(numero_chamado)) continue else: excel.iat[i, ncolunas] = "Em preparação" # filtrando os reponsaveis pelos chamados if not resp: resp.append(responsavel) elif responsavel not in resp: resp.append(responsavel) corpo_emailhtml = corpo_email.replace('\n', '<br>') assinatura_emailhtml = assinatura_email.replace('\n', '<br>') outlook = win32com.client.Dispatch('Outlook.Application') email = outlook.CreateItem(0) email.BodyFormat = 2 email.Subject = assunto_email email.To = email_destino email.HTMLBody = (corpo_emailhtml + "<p>" + assinatura_emailhtml + "<\p>") if email_remetente == "": pass else: email.SentOnBehalfOfName = email_remetente email.Display(False) # self.output.insert("0.0", corpo_email) ############################################################################## def arquivo_excel(self, event=None): global excel, colunas, X, excel_config, bz bz = 0 excel = self.arquivo_ch.cget('path') try: excel_config = pd.read_excel(excel) excel = pd.read_excel(excel) colunas = list(excel_config) X = 1 print('Arquivo carregado') self.button_enviar.config(state='enabled') self.output.insert("end", "Arquivo carregado\n-----------------\n") except: self.arquivo_ch.configure(path="") if bz == 0: print("Arquivo não pode ser carregado") self.output.insert( "end", "Arquivo não pode ser carregado, extensão não suportada, extensão necessária: XLSX\n------------------------------\n" ) X = 0 # self.arquivo_ch.configure(path="") self.button_enviar.config(state='disabled') bz = 1 def clean(self): self.arquivo_ch.configure(path="") #$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ #$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ class AutomailConfig: def __init__(self, master=None): # build ui self.frame_5 = ttk.Frame(master) self.label_6 = ttk.Label(self.frame_5) self.label_6.config(anchor='center', font='{Arial} 20 {bold}', text='Configurações') self.label_6.place(anchor='nw', relx='0.29', rely='0.04', x='0', y='0') self.notebook_2 = ttk.Notebook(self.frame_5) self.frame_6 = ttk.Frame(self.notebook_2) self.n_chamado = ttk.Entry(self.frame_6) self.n_chamado.config(justify='center') self.n_chamado.place(anchor='nw', relx='0.23', rely='0.05', width='30', x='0', y='0') self.n_assunto = ttk.Entry(self.frame_6) self.n_assunto.config(justify='center') self.n_assunto.place(anchor='nw', relx='0.55', rely='0.05', width='30', x='0', y='0') self.n_email = ttk.Entry(self.frame_6) self.n_email.config(justify='center') self.n_email.place(anchor='nw', relx='0.89', rely='0.05', width='30', x='0', y='0') self.label_7 = ttk.Label(self.frame_6) self.label_7.config(text='Coluna Chamado') self.label_7.place(anchor='nw', relx='0.01', rely='0.05', x='0', y='0') self.label_8 = ttk.Label(self.frame_6) self.label_8.config(text='Coluna E-mail') self.label_8.place(anchor='nw', relx='0.7', rely='0.05', x='0', y='0') self.label_9 = ttk.Label(self.frame_6) self.label_9.config(text='Coluna Assunto') self.label_9.place(anchor='nw', relx='0.35', rely='0.05', x='0', y='0') self.scrollbarhelper_3 = ScrollbarHelper(self.frame_6, scrolltype='both') self.treeview_1 = ttk.Treeview(self.scrollbarhelper_3.container) self.treeview_1.pack(side='top') self.scrollbarhelper_3.add_child(self.treeview_1) self.scrollbarhelper_3.place(anchor='nw', relx='0.01', rely='0.15', width='480', x='0', y='0') self.frame_6.config(height='150', width='150') self.frame_6.place(anchor='nw', relx='0.0', x='0', y='0') self.notebook_2.add(self.frame_6, text='Planilha') self.frame_7 = ttk.Frame(self.notebook_2) self.notebook_1_2 = ttk.Notebook(self.frame_7) self.frame_1 = ttk.Frame(self.notebook_1_2) self.campo_de = ttk.Entry(self.frame_1) self.campo_de.place(anchor='nw', relx='0.21', rely='0.06', width='250', x='0', y='0') self.label_1 = ttk.Label(self.frame_1) self.label_1.config(text='De\Remetente:') self.label_1.place(anchor='nw', relx='0.01', rely='0.06', x='0', y='0') self.label_2 = ttk.Label(self.frame_1) self.label_2.config(text='Assunto:') self.label_2.place(anchor='nw', relx='0.08', rely='0.18', x='0', y='0') self.campo_assunto = ttk.Entry(self.frame_1) self.campo_assunto.place(anchor='nw', relx='0.21', rely='0.18', width='250', x='0', y='0') self.frame_1.config(height='200', width='200') self.frame_1.pack(side='top') self.notebook_1_2.add(self.frame_1, text='Envio') self.frame_2 = ttk.Frame(self.notebook_1_2) self.text_msg = tk.Text(self.frame_2) self.text_msg.config(blockcursor='false', cursor='arrow', font='TkDefaultFont', height='10') self.text_msg.config(insertunfocussed='none', setgrid='false', takefocus=False, width='50') self.text_msg.place(anchor='nw', height='235', relx='0.01', rely='0.01', width='460', x='0', y='0') self.frame_2.config(height='200', width='200') self.frame_2.pack(side='top') self.notebook_1_2.add(self.frame_2, text='Texto') self.frame_3 = ttk.Frame(self.notebook_1_2) self.text_ass = tk.Text(self.frame_3) self.text_ass.config(height='10', width='50') self.text_ass.place(anchor='nw', height='180', relx='0.01', rely='0.01', width='460', x='0', y='0') self.editor_online = ttk.Button(self.frame_3) self.editor_online.config(text='Editor Online') self.editor_online.place(anchor='nw', relx='0.81', rely='0.82', x='0', y='0') self.button_config_copy = ttk.Button(self.frame_3) self.button_config_copy.config(compound='top', text='Copiar') self.button_config_copy.place(anchor='nw', relx='0.64', rely='0.82', x='0', y='0') self.frame_3.config(height='200', width='200') self.frame_3.pack(side='top') self.notebook_1_2.add(self.frame_3, text='Assinatura') self.notebook_1_2.config(height='260', width='475') self.notebook_1_2.place(anchor='nw', relx='0.01', rely='0.05', x='0', y='0') self.frame_7.config(height='200', width='200') self.frame_7.pack(side='top') self.notebook_2.add(self.frame_7, state='normal', text='E-mail') self.notebook_2.config(height='280', width='490') self.notebook_2.place(anchor='center', relx='0.50', rely='0.52', x='0', y='0') self.button_config_ok = ttk.Button(self.frame_5) self.button_config_ok.config(text='OK') self.button_config_ok.place(anchor='nw', relx='0.81', rely='0.93', x='0', y='0') self.button_preview = ttk.Button(self.frame_5) self.button_preview.config(text='Preview') self.button_preview.place(anchor='nw', relx='0.02', rely='0.93', x='0', y='0') self.button_save = ttk.Button(self.frame_5) self.button_save.config(text='Save') self.button_save.place(anchor='nw', relx='0.64', rely='0.93', x='0', y='0') self.frame_5.config(height='400', width='500') self.frame_5.pack(side='top') # Main widget self.mainwindow = self.frame_5 #\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ # CHAMANDO FUNÇÕES #/////////////////////////////////////////////////////////////////////////////////////////// self.button_save.config(command=self.save) self.button_config_ok.config(command=self.ok_config) self.button_preview.config(command=self.preview) # self.mainwindow.protocol("WM_DELETE_WINDOW",self.sair_config) #++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # INICIALIZAÇÃO #++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ self.n_chamado.insert(0, coluna_chamado) self.n_assunto.insert(0, coluna_assunto) self.n_email.insert(0, coluna_email) self.campo_assunto.insert(0, assunto_email) self.campo_de.insert(0, email_remetente) self.text_msg.insert("0.0", corpo_email) self.text_ass.insert("0.0", assinatura_email) global excel_config, colunas, X if not X == 0: index_c = list(range(1, (1 + (len(excel_config.columns))))) colunas_excel = list(index_c) self.treeview_1.config(selectmode="none") self.treeview_1['columns'] = colunas_excel for i in colunas_excel: self.treeview_1.column(i, width=100, anchor='n') self.treeview_1.heading(i, text=i) self.treeview_1.insert("", 'end', text=0, values=colunas) for index, row in excel_config.iterrows(): self.treeview_1.insert("", 'end', text=(index + 1), values=list(row)) # definindo largura da coluna de INDEX self.treeview_1.column('#0', width=30) def run(self): self.mainwindow.mainloop() #--------------------------------------------------------------------------------- # FUNÇÕES CONFIGURAÇÕES #-------------------------------------------------------------------------------- def sair_config(): global obs obs = 0 print('Fechou') def save(self): global obs, coluna_chamado, coluna_assunto, coluna_email global assunto_email, email_remetente, corpo_email, assinatura_email coluna_chamado = self.n_chamado.get() coluna_assunto = self.n_assunto.get() coluna_email = self.n_email.get() assunto_email = self.campo_assunto.get() email_remetente = self.campo_de.get() corpo_email = self.text_msg.get("0.0", 'end-1c') assinatura_email = self.text_ass.get("0.0", 'end-1c') # Janela Principal padrao['link_forms'] = link_forms padrao_email['controle'] = email_controle # # Janela Configuraçoes padrao_email['remetente'] = self.campo_de.get() padrao_email['assunto'] = self.campo_assunto.get() padrao_email['corpo'] = self.text_msg.get("0.0", 'end-1c') padrao_email['assinatura'] = self.text_ass.get("0.0", 'end-1c') padrao_planilha['colunaChamados'] = self.n_chamado.get() padrao_planilha['colunaEmails'] = self.n_email.get() padrao_planilha['colunaAssuntos'] = self.n_assunto.get() #Salvando arquivo config with open('Configuracao.ini', 'w') as stg: default.write(stg) def ok_config(self): global obs, coluna_chamado, coluna_assunto, coluna_email global assunto_email, email_remetente, corpo_email, assinatura_email coluna_chamado = self.n_chamado.get() coluna_assunto = self.n_assunto.get() coluna_email = self.n_email.get() assunto_email = self.campo_assunto.get() email_remetente = self.campo_de.get() corpo_email = self.text_msg.get("0.0", 'end-1c') assinatura_email = self.text_ass.get("0.0", 'end-1c') root_config.destroy() obs = 0 def preview(self): global corpo_email, assunto_email, email_remetente corpo_emailhtml = corpo_email.replace('\n', '<br>') assinatura_emailhtml = assinatura_email.replace('\n', '<br>') outlook = win32com.client.Dispatch('Outlook.Application') email = outlook.CreateItem(0) email.BodyFormat = 2 email.Subject = assunto_email email.HTMLBody = (corpo_emailhtml + "<p>" + assinatura_emailhtml + "<\p>") if email_remetente == "": pass else: email.SentOnBehalfOfName = email_remetente email.Display(False) # self.output.insert("end", (corpo_email+"\n------------\n")) def setting(self): global root_config, link_forms, obs, email_controle print('ok') if obs == 0: root_config = tk.Tk() w2 = 550 h2 = 300 ws = root.winfo_screenwidth() hs = root.winfo_screenheight() x2 = (ws / 2) - (w2 / 2) y2 = (hs / 2) - (h2 / 2) root_config.geometry('+%d+%d' % (x2, y2)) self.AutomailConfig(root_config) obs = 1 ## HINT Get informações link_forms = self.forms_link.get() print(link_forms) email_controle = self.mail_control.get() def sair_config(): global obs obs = 0 print('Fechou') root_config.destroy() # try: root_config.protocol("WM_DELETE_WINDOW", sair_config)
class RenameMainApp: def __init__(self, master): self.mainwindow = ttk.Frame(master) self.participantLabel = ttk.Label(self.mainwindow) self.participantLabel.configure(text='Имена участников') self.participantLabel.grid(columnspan='1') self.participantText = tk.Text(self.mainwindow) self.participantText.configure(height='40', relief='ridge', state='normal', undo='true') self.participantText.configure(width='50') self.participantText.grid(columnspan='2', row='1') self.gradeLabel = ttk.Label(self.mainwindow) self.gradeLabel.configure(text='Классы участников') self.gradeLabel.grid(column='3', row='0') self.gradeText = tk.Text(self.mainwindow) self.gradeText.configure(blockcursor='false', height='40', relief='ridge', state='normal') self.gradeText.configure(undo='true', width='20') self.gradeText.grid(column='3', row='1') self.namelessPath = PathChooserInput(self.mainwindow) self.namelessPath.configure(type='directory') self.namelessPath.grid(column='1', columnspan='3', row='2') self.namelessLabel = ttk.Label(self.mainwindow) self.namelessLabel.configure(text='Директрория с безымянными') self.namelessLabel.grid(column='0', row='2') self.destinationLabel = ttk.Label(self.mainwindow) self.destinationLabel.configure(text='Директория для переименованных') self.destinationLabel.grid(column='0', row='3') self.destinationPath = PathChooserInput(self.mainwindow) self.destinationPath.configure(type='directory') self.destinationPath.grid(column='1', columnspan='3', row='3') self.renameButton = ttk.Button(self.mainwindow) self.renameButton.configure(text='Переименовать') self.renameButton.grid(column='3', row='7') self.renameButton.bind('<1>', self.rename_files, add='') self.suffixEntry = ttk.Entry(self.mainwindow) suffix = tk.StringVar() self.suffixEntry.configure(font='TkDefaultFont', textvariable=suffix) self.suffixEntry.grid(column='0', row='6') self.suffixLabel = ttk.Label(self.mainwindow) self.suffixLabel.configure(text='Суффикс') self.suffixLabel.grid(column='0', row='5') self.mainwindow.configure(borderwidth='10', height='200', width='200') self.mainwindow.pack(side='top') # Main widget self.mainwindow = self.mainwindow def get_fios(self): return list( filter(lambda x: x != '', self.participantText.get("1.0", "end").split('\n'))) def get_grades(self): return list( filter(lambda x: x != '', self.gradeText.get("1.0", "end").split('\n'))) def get_suffix(self): suffix = self.suffixEntry.get() if suffix != '': return '_' + suffix return '' def get_new_filenames(self): fios = replace_yo(self.get_fios()) grades = self.get_grades() if len(fios) != len(grades): tkinter.messagebox.showerror( title='Предупреждение', message= 'Количество учеников не соответствует количеству их классов. Хотите продолжить?' ) return suffix = self.get_suffix() new_filenames = [] count_of_students = len(fios) for i in range(count_of_students): fio = fios[i].split(' ') new_filenames.append(fio[0] + '_' + fio[1] + '_' + grades[i] + 'кл' + suffix + '.pdf') return new_filenames def rename_files(self, event): old_directory = self.namelessPath.cget('path') new_directory = self.destinationPath.cget('path') print(old_directory) if old_directory == '': tk.messagebox.showerror( title='Ошибка!', message='Не выбрана директория с файлами для переименовывания') return if new_directory == '': tk.messagebox.showerror( title='Ошибка!', message='Не выбрана директория для переименованных файлов') return old_filenames = sorted(get_filenames_from_dir(old_directory), key=lambda str: str[:str.rfind('.') - 1]) new_filenames = self.get_new_filenames() if new_filenames == None: return if len(old_filenames) != len(new_filenames): tk.messagebox.showerror( title='Ошибка!', message= 'Количество файлов для переименования не соответствует количеству учеников' ) return popup = tk.Toplevel() tk.Label(popup, text="Files have renamed").grid(row=0, column=0, columnspan=2) log_field = tk.Text(popup, width=100) log_field.grid(row=1, column=0, columnspan=2) progress = 0 progress_var = tk.DoubleVar() progress_bar = ttk.Progressbar(popup, length=400, variable=progress_var, maximum=100) progress_bar.grid( row=2, column=0) # .pack(fill=tk.X, expand=1, side=tk.BOTTOM) popup.pack_slaves() counter = tk.Label(popup) counter.grid(row=2, column=1) progress_step = float(100.0 / len(old_filenames)) popup.update() log = '' for i in range(len(old_filenames)): copy_file(old_filenames[i], new_filenames[i]) progress += progress_step progress_var.set(progress) log += old_filenames[i] + ' -> ' + new_filenames[i] + '\n' log_field.delete(1.0, "end") log_field.insert("end", log) counter['text'] = str(i + 1) + '/' + str(len(old_filenames)) popup.update() def run(self): self.mainwindow.mainloop()