# -*- coding:UTF-8 -*- import re, os, sys, upcean, csv; from configparser import ConfigParser import tkinter as tk from tkinter import ttk from tkinter import messagebox as mbox from tkinter import filedialog as fdial from PIL import Image, ImageTk; import tkinter.scrolledtext as tkst class MainWin(tk.Frame): def __init__(self, master): tk.Frame.__init__(self) master.geometry(set_size(master, 520, 450)) master.resizable(False, True) master.title("Barcode generator v1.0") self.barcode_bg_color = (255, 255, 255); self.barcode_bar_color = (0, 0, 0); self.barcode_text_color = (0, 0, 0); self.barcode_list = {"EAN-13": "ean13", "EAN-8": "ean8", "EAN-5": "ean5"}; self.bcsize = tk.IntVar() self.bctype = tk.StringVar() self.bcvalue = tk.StringVar() self.ean13start = self.ean08start = self.ean05start = '' self.existcomment = '' self.filedir = '' self.filetype = 'PNG' self.edited = False self.selected = '' self.oldvalue = '' self.master = master master.rowconfigure(1, weight=1) self.frameTopLeft = tk.Frame(master) self.frameTopLeft.grid(row=0, column=0, sticky='nw', padx=(10, 0)) self.frameTopRight = tk.Frame(master, width=280) self.frameTopRight.grid(row=0, column=1, sticky='nsw', padx=(0, 0)) self.frameTopRight.grid_propagate(False) self.frameMain = ttk.Frame(master) self.frameMain.grid(row=1, column=0, columnspan=2, sticky='nswe', padx=(10, 0), pady=(0,10)) # Menubar master.option_add('*tearOff', False) self.menubar = tk.Menu(master) master.config(menu = self.menubar) self.file = tk.Menu(self.menubar) help_ = tk.Menu(self.menubar) self.menubar.add_cascade(menu = self.file, label = 'File') self.file.add_command(label = 'Save as', command = self.saveasfile) self.file.add_command(label = 'Settings', command =self.settings) self.file.add_command(label = 'Info', command =self.helpwin) self.file.entryconfig('Save as', accelerator = 'Ctrl+S') #Entries self.frameType = ttk.Frame(self.frameTopLeft, padding=(5, 5)) self.frameType.grid(row=0, column=0, sticky="nswe", padx=(0,0), pady=(2,2)) ttk.Label(self.frameType, text='Barcode type: ').grid(row=0, column=0, sticky='w', pady=(0,0)) options = ['EAN-13', 'EAN-8', 'EAN-5'] self.bcode_type = ttk.OptionMenu(self.frameType, self.bctype, options[0], *options, style = 'raised.TMenubutton') self.bcode_type.config(width=10) self.bcode_type.grid(row=0, column=1, sticky='we') self.frameSize = ttk.LabelFrame(self.frameTopLeft, text="Barcode size:", padding=(3, 3)) self.frameSize.grid(row=1, column=0, sticky="nswe", padx=(5,5), pady=(2,2)) self.bcode_size = ttk.Scale(self.frameSize, value=1, from_=1, to=10, variable=self.bcsize, command=self.setscale) self.bcode_size.grid(row=0, column=0, sticky='we', pady=(5,0)) ttk.Label(self.frameSize, text=' 1 2 3 4 5 6 7 8 9 10 ').grid(row=1, column=0, sticky='w') ttk.Label(self.frameTopLeft, text='Barcode value:').grid(row=2, column=0, sticky='w', padx=(5, 0)) self.bcode_val = ttk.Entry(self.frameTopLeft, width=17, textvariable=self.bcvalue, font=('Arial', 21)) self.bcode_val.grid(row=3, column=0, pady=(0,0)) ttk.Label(self.frameTopLeft, text='Comment:').grid(row=4, column=0, sticky='w', padx=(5, 0), pady=(5,0)) self.textFrame = ttk.Frame(self.frameTopLeft, height=50, width=180) self.textFrame.grid(row=5, column=0, pady=(0,0)) self.textFrame.columnconfigure(0, weight=1) self.bcode_comment = tkst.ScrolledText(self.textFrame, wrap=tk.WORD, width=23, height=3, font=('Arial', 15)) self.bcode_comment.grid(row=0, column=0, pady=(0,0), sticky='we') # Buttons self.frameButton = ttk.Frame(self.frameTopRight) self.frameButton.grid(row=0, column=0, sticky="nswe", padx=(0,5), pady=(5,5)) self.frameButton.grid_columnconfigure(0, weight=1) self.frameButton.grid_columnconfigure(1, weight=1) self.btnGenerate = ttk.Button(self.frameButton, text='Generate', command=self.generate) self.btnGenerate.grid(row=0, column=0, pady=(0,0), padx=(0, 2), sticky="we") self.btnSave = ttk.Button(self.frameButton, text='Save', command=self.saveasfile) self.btnSave.grid(row=0, column=1, pady=(0,0), padx=(2, 0), sticky="we") # Preview self.imagepanel = tk.Canvas(self.frameTopRight, width=250, height=175); self.imagepanel.configure(background='#c1c1c1') self.imagepanel.config(highlightbackground='#5f5f5f') self.vsb = ttk.Scrollbar(self.frameTopRight, orient="vertical", command=self.imagepanel.yview) self.hsb = ttk.Scrollbar(self.frameTopRight, orient="horizontal", command=self.imagepanel.xview) self.vsb.grid(row=1, column=1, sticky="nse") self.hsb.grid(row=2, column=0, sticky="sew") self.imagepanel.config(yscrollcommand=lambda f, l: self.autoscroll(self.vsb, f, l)) self.imagepanel.config(xscrollcommand=lambda f, l:self.autoscroll(self.hsb, f, l)) self.imagepanel.grid(row=1, column=0, sticky ="nswe", padx=(0,5), pady=(0,5)) # Table self.frameMain.rowconfigure(0, weight=1) self.tree = ttk.Treeview(self.frameMain, selectmode="extended", height=10, columns=("barcodes","type", "comment"), displaycolumns="barcodes type comment") self.tree.grid(row=0, column=0, sticky="ns", padx=(5,5), pady=(5,5)) self.vsb1 = ttk.Scrollbar(self.frameMain, orient="vertical", command=self.tree.yview) self.hsb1 = ttk.Scrollbar(self.frameMain, orient="horizontal", command=self.tree.xview) self.vsb1.grid(row=0, column=1, sticky="nse") self.hsb1.grid(row=1, column=0, sticky="sew") self.tree.config(yscrollcommand=lambda f, l: self.autoscroll(self.vsb1, f, l)) self.tree.config(xscrollcommand=lambda f, l:self.autoscroll(self.hsb1, f, l)) self.tree.heading("#0", text="#") self.tree.heading("barcodes", text="Barcodes") self.tree.heading("type", text="Type") self.tree.heading("comment", text="Comment") self.tree.column("#0",minwidth=20, width=55, stretch=True, anchor="center") self.tree.column("barcodes",minwidth=50, width=120, stretch=True, anchor="center") self.tree.column("type",minwidth=40, width=65, stretch=True, anchor="center") self.tree.column("comment",minwidth=120, width=240, stretch=True, anchor="center") self.tree.tag_configure('even', background='#d9dde2') self.tree.bind('<Double-Button-1>', self.edit) master.bind("<Escape>", self.exit_ui); master.bind('<Control-s>', self.saveasfile) self.get_from_ini() self.read_file() def updatecomment(self, value=None): self.bcode_comment.delete(1.0, tk.END) if value: self.bcode_comment.insert(tk.END, value) def clearall(self): self.bcode_comment.delete(1.0, tk.END) self.bcode_val.delete(0, 'end') def edit(self, event): w = event.widget self.selected = w.focus() self.edited = True if self.selected: values = self.tree.set(self.selected) self.oldvalue = values['barcodes'] self.bcvalue.set(values['barcodes']) self.updatecomment(values['comment']) self.bctype.set(values['type']) self.previewbarcode(values['barcodes']) def generate(self): if not self.bcvalue.get() or self.edited: self.clearall() if not self.GenerateCode(): return False self.previewbarcode(self.bcode_val.get()) self.edited = False def saveasfile(self, event=None): if self.bcode_val.get(): if event: self.savebarcode(self.bcode_val.get()) else: self.savebarcode(self.bcode_val.get(), True) self.updatetree() else: mbox.showwarning("Warning", "Generate any barcode first!"); def generatebarcode(self, bcodevalue): tmpbarcode = upcean.oopfuncs.barcode(self.barcode_list[self.bctype.get()], self.bcode_val.get()); tmpbarcode.size = self.bcode_size.get(); tmpbarcode.barcolor = self.barcode_bar_color; tmpbarcode.textcolor = self.barcode_text_color; tmpbarcode.bgcolor = self.barcode_bg_color; tmpbarcode.filename = None; return tmpbarcode def previewbarcode(self, bcodevalue): tmpbarcode = self.generatebarcode(bcodevalue) validbc = tmpbarcode.validate_draw_barcode(); if(validbc): image1 = ImageTk.PhotoImage(validbc); self.imagepanel.create_image(validbc.size[0]/2, validbc.size[1]/2, image=image1); self.imagepanel.config(scrollregion=(0,0, validbc.size[0], validbc.size[1])); self.imagepanel.image = image1; self.already_exist(False, bcodevalue) else: mbox.showerror("Error", "Barcode couldn't be generated!") def savebarcode(self, bcodevalue, autoname=False): savestate = False; fname = ""; if autoname: fname = self.filedir+'/'+ bcodevalue + '.' + self.filetype.lower() else: fname = fdial.asksaveasfilename(defaultextension='png', parent=self.master, title='Saving barcode', filetypes=[('PNG','*.png'), ('JPEG','*.jpg *.jpeg'), ('GIF','*.gif'), ('Adobe PDF','*.pdf'), ('Barcha fayllar','*.*')]); if(fname): tmpbarcode = self.generatebarcode(bcodevalue) tmpbarcode.filename = fname; savestate = tmpbarcode.validate_create_barcode(); if(not savestate): mbox.showerror("Warning", "Barcode saving error"); else: mbox.showinfo("Info", "Barcode is saved as file successfully"); def updatetree(self): bcitem = self.getvalues() if self.isunique(bcitem[0]): idd = self.last_id()+1 self.tree.insert('', 'end', idd, text=idd, values = bcitem) self.tree.focus_set() else: if self.edited: if self.oldvalue == bcitem[0]: self.tree.set(self.selected, 'comment', bcitem[2]) self.tree.selection_set(self.selected) else: return self.already_exist() else: return self.already_exist() self.clearall() self.edited = False self.write_file() return True def already_exist(self, warn=True, bcode=None): if warn: mbox.showwarning("Warning", "Barcode is already in table!"); return False else: if not self.isunique(bcode): self.updatecomment(self.existcomment) def last_id(self): if self.tree.get_children(): idmax = max([int(i) for i in self.tree.get_children()]) else: idmax = 0 return idmax def getvalues(self): return self.bcvalue.get(), self.bctype.get(), self.bcode_comment.get(1.0, '1.end') def GenerateCode(self): if self.bctype.get() == 'EAN-13': if self.ean13start.isdigit() and len(self.ean13start)>12: newcode = int(self.ean13start[:12]) nextcode = False while nextcode == False: if self.validate_ean13(newcode): if self.isunique(str(newcode) +str(self.validate_ean13(newcode))): nextcode == True break newcode += 1 self.bcvalue.set(str(newcode) +str(self.validate_ean13(newcode))) return True else: mbox.showwarning("Warning", "Enter initial value for EAN-13!"); return False elif self.bctype.get() == 'EAN-8': if self.ean08start.isdigit() and len(self.ean08start)>7: newcode = int(self.ean08start[:7]) nextcode = False while nextcode == False: if self.validate_ean08(newcode): if self.isunique(str(newcode) +str(self.validate_ean08(newcode))): nextcode == True break newcode += 1 self.bcvalue.set(str(newcode) +str(self.validate_ean08(newcode))) return True else: mbox.showwarning("Warning", "Enter initial value for EAN-08!"); return False elif self.bctype.get() == 'EAN-5': if self.ean05start.isdigit() and len(self.ean05start)==5: newcode = int(self.ean05start) nextcode = False while nextcode == False: if self.isunique(str(newcode)): nextcode == True break newcode += 1 self.bcvalue.set(str(newcode)) return True else: mbox.showwarning("Warning", "Enter initial value for EAN-05!"); return False ############################################################################ ## GIU RELATED OPERATIONS ## ############################################################################ def exit_ui(self, event): self.master.quit(); def setscale(self, var): value = self.bcode_size.get() if int(value) != value: self.bcode_size.set(round(value)) def settings(self): setwin = SettingWin(self.master) self.get_from_ini() def helpwin(self): setwin = HelpWin(self.master) def autoscroll(self, sbar, first, last): """Hide and show scrollbar as needed.""" first, last = float(first), float(last) if first <= 0 and last >= 1: sbar.grid_remove() else: sbar.grid() sbar.set(first, last) def zebra(self): childs = self.tree.get_children() if childs: n=0 for child in childs: n += 1 if (n%2==0): tag='even' else: tag='odd' self.tree.item(child, tags=(tag,)) ############################################################################ ## FILE OPERATIONS ## ############################################################################ # Initializing from config.ini file def get_from_ini(self): self.config = ConfigParser() if not os.path.isfile('config.ini'): self.check_inifile() self.config.read('config.ini') sect = 'DefaultValues' try: if self.config.get(sect, 'Type'): self.bctype.set(self.config.get(sect, 'Type')) if self.config.get(sect, 'Size'): self.bcsize.set(self.config.get(sect, 'Size')) if self.config.get(sect, 'EAN13start'): self.ean13start = self.config.get(sect, 'EAN13start') if self.config.get(sect, 'EAN08start'): self.ean08start = self.config.get(sect, 'EAN08start') if self.config.get(sect, 'EAN05start'): self.ean05start = self.config.get(sect, 'EAN05start') if self.config.get(sect, 'filedirectory'): self.filedir = self.config.get(sect, 'filedirectory') if self.config.get(sect, 'FileType'): self.filetype = self.config.get(sect, 'FileType') except: mbox.showerror("Warning", "Error occured while loading Config.ini!"); # Checks and creates if ini file is not found def check_inifile(self): text = '[DefaultValues]\nType = EAN-13\nEAN13start = 4780000000010\nEAN08start = 47800010\nEAN05start = 00000\nSize = 2\nFileType = PDF\nFileDirectory =' file = open('config.ini', 'w') file.write(text) file.close() def write_file(self): if self.tree.get_children(): with open('data.csv', 'w', encoding='utf-8') as file: fieldnames = ["id", "barcodes", "type","comment"] writer = csv.DictWriter(file, fieldnames=fieldnames, delimiter=";") writer.writeheader() for item in self.tree.get_children(): mydata = self.tree.set(item) mydata["id"] = item writer.writerow(mydata) self.zebra() def read_file(self): if os.path.isfile('data.csv'): try: with open('data.csv', encoding="utf-8") as csvfile: reader = csv.DictReader(csvfile, fieldnames = None, delimiter=";") for row in reader: self.tree.insert("", "end", row["id"], text=row["id"], values=[row["barcodes"], row["type"], row["comment"]]) self.zebra() except: mbox.showerror("Error", "Error occured while loading Data.csv!"); ############################################################################ ## BARCODE VALIDATIONS ## ############################################################################ def isunique(self, bcode): if os.path.isfile('data.csv'): with open('data.csv', encoding="utf-8") as csvfile: reader = csv.DictReader(csvfile, fieldnames = None, delimiter=";") for row in reader: if row["barcodes"] == bcode: self.existcomment = row["comment"] return False return True else: return True def validate_ean13(self, upc, return_check=False): upc = str(upc); if(len(upc)>13): fix_matches = re.findall("^(\d{13})", upc); upc = fix_matches[0]; if(len(upc)>13 or len(upc)<12): return False; upc_matches = list(upc); upc_matches = [int(x) for x in upc_matches]; upc_matches1 = upc_matches[0:][::2]; upc_matches2 = upc_matches[1:][::2]; EvenSum = (upc_matches2[0] + upc_matches2[1] + upc_matches2[2] + upc_matches2[3] + upc_matches2[4] + upc_matches2[5]) * 3; OddSum = upc_matches1[0] + upc_matches1[1] + upc_matches1[2] + upc_matches1[3] + upc_matches1[4] + upc_matches1[5]; AllSum = OddSum + EvenSum; CheckSum = AllSum % 10; if(CheckSum>0): CheckSum = 10 - CheckSum; if(not return_check and len(upc)==13): if(CheckSum!=upc_matches1[6]): return False; if(CheckSum==upc_matches1[6]): return True; if(return_check): return str(CheckSum); if(len(upc)==12): return str(CheckSum); def validate_ean08(self, upc, return_check=False): upc = str(upc); if(len(upc)>8): fix_matches = re.findall("^(\d{8})", upc); upc = fix_matches[0]; if(len(upc)>8 or len(upc)<7): return False; upc_matches = list(upc); upc_matches = [int(x) for x in upc_matches]; upc_matches1 = upc_matches[0:][::2]; upc_matches2 = upc_matches[1:][::2]; EvenSum = (upc_matches1[0] + upc_matches1[1] + upc_matches1[2] + upc_matches1[3]) * 3; OddSum = upc_matches2[0] + upc_matches2[1] + upc_matches2[2]; AllSum = OddSum + EvenSum; CheckSum = AllSum % 10; if(CheckSum>0): CheckSum = 10 - CheckSum; if(not return_check and len(upc)==8): if(CheckSum!=upc_matches2[3]): return False; if(CheckSum==upc_matches2[3]): return True; if(return_check): return str(CheckSum); if(len(upc)==7): return str(CheckSum); class SettingWin(tk.Frame): def __init__(self, master): tk.Frame.__init__(self) self.top = tk.Toplevel() self.top.resizable(False, False) self.top.geometry(set_size(self.top, 230, 330)) self.top.title("Default settings") self.default_type = tk.StringVar() self.default_size = tk.IntVar() self.default_filetype = tk.StringVar() self.default_dir = tk.StringVar() self.ean13 = tk.StringVar() self.ean08 = tk.StringVar() self.ean05 = tk.StringVar() self.frameMain = ttk.Frame(self.top) self.frameMain.grid(row=0, column=0, sticky='nswe', padx=(10,0)) self.bottom = ttk.Frame(self.top) self.bottom.grid(row=1, column=0, sticky='nswe', padx=(10,0)) self.bottom.columnconfigure(0, weight=1) self.bottom.columnconfigure(1, weight=1) ttk.Label(self.frameMain, text='Barcode type: ').grid(row=0, column=0, sticky='w', pady=(5,0)) options = ['EAN-13', 'EAN-8', 'EAN-5'] self.dbctype = ttk.OptionMenu(self.frameMain, self.default_type, options[0], *options, style = 'raised.TMenubutton') self.dbctype.config(width=7) self.dbctype.grid(row=0, column=1, pady=(5,0), sticky='we') ttk.Label(self.frameMain, text="Barcode size: ").grid(row=1, column=0, sticky='w', pady=(5,0)) self.dbcsize = tk.Spinbox(self.frameMain, wrap=True, width=5, from_=1, to=10, textvariable=self.default_size); self.dbcsize.grid(row=1, column=1, pady=(5,0), sticky='e') ttk.Label(self.frameMain, text="Default file type:").grid(row=2, column=0, sticky='w', pady=(5,0)) filetypes = ['PDF', 'PNG', 'JPG', 'GIF'] self.dcfiletype = ttk.OptionMenu(self.frameMain, self.default_filetype, filetypes[0], *filetypes) self.dcfiletype.config(width=7) self.dcfiletype.grid(row=2, column=1, sticky='we', pady=(5,0)) ttk.Label(self.frameMain, text='EAN-13 initial value:').grid(row=3, column=0, columnspan=2, sticky='w', pady=(5,0)) self.dean13 = ttk.Entry(self.frameMain, width=26, textvariable=self.ean13) self.dean13.grid(row=4, column=0, columnspan=2) ttk.Label(self.frameMain, text='EAN-08 initial value:').grid(row=5, column=0, columnspan=2, sticky='w', pady=(5,0)) self.dean08 = ttk.Entry(self.frameMain, width=26, textvariable=self.ean08) self.dean08.grid(row=6, column=0, columnspan=2) ttk.Label(self.frameMain, text='EAN-05 initial value:').grid(row=7, column=0, columnspan=2, sticky='w', pady=(5,0)) self.dean05 = ttk.Entry(self.frameMain, width=26, textvariable=self.ean05) self.dean05.grid(row=8, column=0, columnspan=2) self.framepdf = ttk.Frame(self.frameMain) self.framepdf.grid(row=9, column=0, columnspan=2) ttk.Label(self.framepdf, text='File saving directory:').grid(row=0, column=0, sticky='w', pady=(5,0)) self.dfiledir = ttk.Entry(self.framepdf, width=20, textvariable=self.default_dir) self.dfiledir.grid(row=1, column=0, padx=(3, 0), pady=(5,0)) self.pdfbtn = ttk.Button(self.framepdf, text='...', width=3, command=self.folder) self.pdfbtn.grid(row=1, column=1, padx=(5, 0), pady=(5, 0)) self.skpSave = ttk.Button(self.bottom, text='Save', command=self.save_list) self.skpSave.grid(row=0, column=0, sticky='we', padx=(0, 5), pady=(10, 3)) self.btcancel = ttk.Button(self.bottom, text='Cancel', command=self.cancel) self.btcancel.grid(row=0, column=1, sticky='we', padx=(5, 0), pady=(10, 3)) self.dbcsize.focus_set() self.top.bind('<Escape>', self.cancel) self.get_from_ini() self.top.grab_set() master.wait_window(self.top) def get_from_ini(self): self.partlist=[] self.config = ConfigParser() self.config.read('config.ini') sect = 'DefaultValues' self.default_type.set(self.config.get(sect, 'Type')) self.default_size.set(self.config.get(sect, 'Size')) self.default_filetype.set(self.config.get(sect, 'FileType')) self.default_dir.set(self.config.get(sect, 'FileDirectory')) self.ean13.set(self.config.get(sect, 'EAN13start')) self.ean08.set(self.config.get(sect, 'EAN08start')) self.ean05.set(self.config.get(sect, 'EAN05start')) def update_list(self): self.name.delete(0, 'end') self.code.delete(0, 'end') self.address.delete(0, 'end') self.dockname.delete(0, 'end') self.pdfaddress.delete(0, 'end') self.name.insert(0, self.compname.get()) self.code.insert(0, self.compcode.get()) self.address.insert(0, self.compaddress.get()) self.dockname.insert(0, self.dock.get()) self.pdfaddress.insert(0, self.pdfdir.get()) def folder(self): dirpath = fdial.askdirectory(mustexist=False, parent=self.master, title='Choose the folder') if dirpath: self.default_dir.set(dirpath) def save_list(self): sect = 'DefaultValues' self.config.set(sect,'Type', self.default_type.get()) self.config.set(sect, 'Size', self.dbcsize.get()) self.config.set(sect, 'FileType', self.default_filetype.get()) self.config.set(sect, 'FileDirectory', self.default_dir.get()) self.config.set(sect, 'EAN13start', self.ean13.get()) self.config.set(sect, 'EAN08start', self.ean08.get()) self.config.set(sect, 'EAN05start', self.ean05.get()) with open('config.ini', 'w') as configfile: self.config.write(configfile) self.top.destroy() def cancel(self, event=None): self.top.destroy() class HelpWin(tk.Frame): def __init__(self, master): tk.Frame.__init__(self) self.top = tk.Toplevel() self.top.resizable(False, False) self.top.geometry(set_size(self.top, 220, 150)) self.top.title("Info") ttk.Label(self.top, text='Barcode generator v1.0', font=("Arial", 10, 'bold')).grid(row=0, column=0, padx=(10,10), pady=(15, 0), sticky='nswe') ttk.Label(self.top, text='Hamraqulov Boburmirzo © 2017').grid(row=1, column=0, padx=(10,10), pady=(15, 0), sticky='nswe') ttk.Label(self.top, text='Telegram: @bzimor').grid(row=2, column=0, padx=(10,10), pady=(5, 0), sticky='nswe') ttk.Label(self.top, text='Github: github.com/bzimor').grid(row=3, column=0, padx=(10,10), pady=(5, 0), sticky='nswe') ttk.Label(self.top, text='Email: bobzimor@gmail.com').grid(row=4, column=0, padx=(10,10), pady=(5, 0), sticky='nswe') self.top.grab_set() master.wait_window(self.top) def set_size(win, w=0, h=0, absolute=True, win_ratio=None): winw = win.winfo_screenwidth() winh = win.winfo_screenheight() if not absolute: w = int(winw * win_ratio) h = int(winh * win_ratio) screen = "{0}x{1}+{2}+{3}".format(w, h, str(int(winw*0.1)), str(int(winh*0.05))) else: screen = "{0}x{1}+{2}+{3}".format(w, h, str(int((winw-w)/2)), str(int((winh-h)/2))) return screen def resource_path(relative_path): """ Get absolute path to resource, works for dev and for PyInstaller """ try: # PyInstaller creates a temp folder and stores path in _MEIPASS base_path = sys._MEIPASS except Exception: base_path = os.path.abspath(".") return os.path.join(base_path, relative_path).replace("\\","/") root = tk.Tk() app = MainWin(root) try: root.iconbitmap(default=resource_path('app.ico')) except: pass root.mainloop()