class PopupFrameView(Toplevel): # СОРТИРОВКА ФИЛЬМОВ; def __init__(self, x, y, *data): super().__init__() self.x = x self.y = y self.vr = data self.init_frame() self.db = db self.view = appl self.view_record() def init_frame(self): self.title('Просмотр записей') self.geometry('440x392+%d+%d' % (self.x + 180, self.y + 65)) self.resizable(False, False) # НИЖНЯЯ ПАНЕЛЬ для КОЛИЧЕСТВА ЗАПИСЕЙ; TB_BOT = Frame(self, bg='#EDF0F5', bd=1) TB_BOT.pack(side=BOTTOM, fill=X) # ВЫВОД КОЛИЧЕСТВА ЗАПИСЕЙ на НИЖНЮЮ ПАНЕЛЬ; self.count = Label(TB_BOT, background='#EDF0F5', foreground='#425370') self.count.pack() _yscroll_ = Scrollbar(self) self.tree = Treeview(self, columns=('id', 'name'), height=18, show='headings', yscrollcommand=_yscroll_.set) _yscroll_.config(command=self.tree.yview) self.tree.column('id', width=50, anchor=CENTER) self.tree.column('name', width=370) self.tree.heading('id', text='№') self.tree.heading('name', text='Название') _yscroll_.pack(side=RIGHT, fill=Y) self.tree.pack() self.tree.bind('<Button-1>', lambda event: 'break' if self.tree.identify_region(event.x, event.y) == 'separator' else None) # УДЕРЖИВАЕМ НАШЕ ДИАЛОГОВОЕ ОКНО 'НА ВЕРХУ'; self.grab_set() self.focus_set() def view_record(self): # ПРОСМОТР ОТСОРТИРОВАННЫХ ДАННЫХ; num = 0 if (self.vr[0][0] != '' and self.vr[0][1] == '' and self.vr[0][2] == ''): self.db.c.execute(''' SELECT id, name FROM films WHERE mors=? ''', (self.vr[0][0], )) if (self.vr[0][0] == '' and self.vr[0][1] != '' and self.vr[0][2] == ''): self.db.c.execute(''' SELECT id, name FROM films WHERE janr=? ''', (self.vr[0][1], )) if (self.vr[0][0] == '' and self.vr[0][1] == '' and self.vr[0][2] != ''): self.db.c.execute(''' SELECT id, name FROM films WHERE flag=? ''', (self.vr[0][2], )) if (self.vr[0][0] != '' and self.vr[0][1] != '' and self.vr[0][2] != ''): self.db.c.execute(''' SELECT id, name FROM films WHERE mors=? AND janr=? AND flag=? ''', (self.vr[0][0], self.vr[0][1], self.vr[0][2])) [ self.tree.delete(i) for i in self.tree.get_children() ] for row in self.db.c.fetchall(): [ self.tree.insert('', 'end', values=row) ] num += 1 self.count['text'] = 'Количество записей: %d' % num
class Library: """ Main class. Combines GUI, functionality and Database. Args: root (instance): tkinter's root instance. """ appName = "Knihovna" appVersion = "0.2" tabList = [["Knihy", ["ID", "Název knihy", "Autor", "Ilustrátor", "Rok"]]] def __init__(self, root): """Initialises Library class. Args: root (instance): tkinter's root instance. """ self.root = root self.root.geometry('1000x500') self.root.configure(background='#bdc3c7') self.root.minsize(1000, 500) self.root.title(Library.appName + " v" + Library.appVersion) self.toplevel = None self.notebook = Autoresized_Notebook(self.root) self.tables = [] self.tabs = [] i = 0 for tab in Library.tabList: tabframe = Frame(self.notebook) self.notebook.add(tabframe, text=f"{tab[0]}") # zjistí, který tab je právě otevřený a zavolá funkci windowCreate, které předá název tabu Button(tabframe, text='+', command=lambda: self.windowCreate(), height=1).pack(fill=X) if len(tab) >= 2: columnList = "" e = 0 for columnName in tab[1]: if e != 0: columnList += ", " columnList += f"{e}" e = e + 1 # + editovací tlačítko columnList += ", " + str((int(e) + 1)) self.treeview = Treeview(tabframe, columns=(columnList), show="headings", height=10) self.treeview.bind("<ButtonRelease-1>", self.bookEditBind) f = 0 for columnName in tab[1]: self.treeview.column(f, minwidth=0, width=150, anchor=N, stretch=TRUE) self.treeview.heading(f, text=f"{columnName}", anchor=W) f = f + 1 i = i + 1 self.treeview.column(f + 1, minwidth=0, width=150, anchor=N, stretch=TRUE) self.treeview.heading(f + 1, text="jiné", anchor=W) self.updateTable() self.tables.append( self.treeview.pack(fill=X, side=TOP, expand=1)) Button(tabframe, text='Exit', command=root.destroy).pack(padx=100, pady=100) self.notebook.pack(fill=BOTH, expand=1) def windowCreate(self, id=None, deleteCallback=None): """Creates another window. Args: id (int): id of selected book (default None). deleteCallback (function): callback of inserted function. """ if (self.toplevel is not None) and self.toplevel.exists == True: return self.toplevel = Window(self.root, id, saveNewBook=self.save, deleteBook=deleteCallback) def bookEditBind(self, event): """Binds event when clicking to 'edit' book info. Args: event (instance): event. """ button = self.treeview.identify_column(event.x) region = self.treeview.identify_region(event.x, event.y) if button != '#6' or region != 'cell': return item = self.treeview.focus() id = self.treeview.item(item)['values'][0] self.windowCreate(id, self.delete) def getBooks(self): """Clears self.books, reselects book info and its metadata and reinserts itself to self.books.""" self.books = [] booksInfo = Database.select("SELECT * FROM books") for book in booksInfo: info = { "ID": book[0], "authors": [], "illustrators": [], "title": book[1], "year": book[2] } meta = Database.select( f"SELECT meta.role, meta.name FROM bookWorkers LEFT JOIN (SELECT workers.ID, (people.forename || ' ' || people.surname) as name, roles.name as role FROM workers LEFT JOIN people ON people.ID = workers.peopleID LEFT JOIN roles ON workers.roleID = roles.ID) meta ON bookWorkers.workersID = meta.ID WHERE bookID = {book[0]}" ) for person in meta: info[person[0] + "s"].append(person[1]) self.books.append(info) def updateTable(self): """Deletes data from table and calls getBooks to reinsert data.""" self.getBooks() self.treeview.delete(*self.treeview.get_children()) for book in self.books: if (len(book["authors"]) >= 2): authors = ", ".join(book["authors"]) else: authors = book["authors"][0] if (len(book["illustrators"]) >= 2): illustrators = ", ".join(book["illustrators"]) elif not book["illustrators"]: illustrators = "" else: illustrators = book["illustrators"][0] self.treeview.insert("", END, values=(book["ID"], book["title"], authors, illustrators, book["year"], "upravit")) def delete(self, id): """Deletes selected book and updates table immediately after. Args: id (int): id of selected (edited) book. """ Database.execute(f"DELETE FROM books WHERE ID = {id}") Database.execute(f"DELETE FROM bookWorkers WHERE bookID = {id}") self.updateTable() def save(self, data, id): """Saves data to Database using class of the same name. Args: data (array): example: [{'forename': 'dd', 'surname': 'dd'}], 'illustrators': [{'forename': 'dd', 'surname': 'dd'}], 'title': None, 'year': None} id (integer): id of selected book. """ bookID = Database.execute( f"INSERT INTO books (title, year) VALUES ('{data['title']}', '{data['year']}')" ) for role in data["roles"]: for person in data["roles"][role]: personID = Database.select( f"SELECT ID FROM people WHERE forename = '{person['forename']}' AND surname = '{person['surname']}'" ) if not personID: personID = Database.execute( f"INSERT INTO people (forename, surname) VALUES ('{person['forename']}', '{person['surname']}')" ) else: personID = personID[0][0] workerID = Database.select( f"SELECT ID FROM workers WHERE peopleID = '{personID}' AND roleID = (SELECT ID FROM roles WHERE name = '{role}')" ) if not workerID: workerID = Database.execute( f"INSERT INTO workers (peopleID, roleID) VALUES ({personID}, (SELECT ID FROM roles WHERE name = '{role}'))" ) else: workerID = workerID[0][0] bookWorkerID = Database.select( f"SELECT ID FROM bookWorkers WHERE workersID = '{workerID}' AND roleID = (SELECT ID FROM roles WHERE name = '{role}')" ) if not bookWorkerID: bookWorkerID = Database.execute( f"INSERT INTO bookWorkers (bookID, workersID) VALUES ('{bookID}', '{workerID}')" ) else: bookWorkerID = bookWorkerID[0][0] self.updateTable()
class PreviewDataTable: """ PreviewDataTable show the user the head of the data that they have imported @methods: ---------- update_table: remove column names and rows, get column names from ImportDataManager, append data to each row Problem: treeview is resizing to the width of the screen size, when it's told explcitly not to (stretch=False) """ def __init__(self, mainframe): self.mainframe = mainframe self.treeview = Treeview(mainframe.root) self.treeview['columns'] = ("column 1", "column 2", "column 3", "column 4", "column 5") self.treeview['show'] = 'headings' # removes empty identifier column for column in self.treeview['columns']: self.treeview.heading(column, text=str(column), anchor="w") self.treeview.column(column, anchor="center", width=80, stretch=False) for i in range(5): self.treeview.insert('', 'end') self.treeview.bind('<Button-1>', self.handle_click) def update_table(self, dataframe=None): if isinstance(dataframe, pd.DataFrame) or isinstance( self.mainframe.importExportDataManager.get_data(), pd.DataFrame): # delete everything from treeview for child in self.treeview.get_children(): self.treeview.delete(child) # create columns self.treeview[ 'columns'] = self.mainframe.importExportDataManager.get_column_names( ) for column in self.treeview['columns']: self.treeview.heading(column, text=str(column), anchor="center") self.treeview.column(column, anchor="center", width=80, stretch=False) # insert data from head of pandas dataframe if dataframe is None and self.mainframe.importExportDataManager.get_data( ) is not None: df = self.mainframe.importExportDataManager.get_data().copy() else: df = dataframe.copy() self.format_data(df) for i, j in df.head().iterrows(): append_data = [] for k in j: append_data.append(k) self.treeview.insert('', 'end', value=append_data) def format_data(self, df): if isinstance(df, pd.DataFrame): for column in df.columns: if df[column].dtype == "float64": df[column] = df[column].round(decimals=int( self.mainframe.optionsWindow.settings.get( "decimal places"))) # makes columns unresizeable def handle_click(self, event): if self.treeview.identify_region(event.x, event.y) == "separator": return "break"
class SearchApplication(GenericFrame): FAVICON = "../assets/favicon.ico" def __init__(self, parent=None, app_window=None): self.lastValue = None self.category_option = StringVar("") self.column_id = [ 'ProductDescription', 'ManufacturerName', 'ManufacturerPartNumber', 'DigiKeyPartNumber', 'Category' ] Frame.__init__(self, parent) self.pack() self.parent = parent self.app_window = app_window self.selectedField = None self.parent.title("Partlocater - Advanced Database Search") self.parent.iconbitmap(self.FAVICON) self.menubar = Frame(self, background='white') self.menubar.pack(side=TOP, fill=X, expand=YES) self.win_frame = Frame(self) self.win_frame.pack(side=TOP, fill=BOTH, expand=YES) self.editbutton = Menubutton(self.menubar, text='Edit', background='grey98') self.editbutton.pack(side=LEFT, fill=X) self.editmenu = Menu(self.editbutton, tearoff=0) self.editbutton.config(menu=self.editmenu) self.copySourcesMenu = Menu(self.editbutton, tearoff=0) self.editmenu.add_cascade(label='Copy', menu=self.copySourcesMenu) self.copySourcesMenu.add_command(label='Part Number', state=DISABLED, command=self.on_copy_partnumber) self.partnumber_index = 0 self.copySourcesMenu.add_command(label='Selected Parameter', state=DISABLED, command=self.on_copy_parameters) self.selectedParameter_index = 1 self.copySourcesMenu.add_command(label='Selected Part All Parameters', state=DISABLED, command=self.on_copy_all_parameters) self.allParameters_index = 2 self.editmenu.add_command(label='Delete Part', state=DISABLED, command=self.on_delete) self.searchLF = LabelFrame(self.win_frame, text="Search") self.searchLF.pack(side=LEFT, fill=X, expand=YES, pady=4, padx=6) self.searchLeftF = Frame(self.searchLF) self.searchLeftF.pack(side=LEFT, anchor=W) self.searchRightF = Frame(self.searchLF) self.searchRightF.pack(side=LEFT, anchor=N) self.searchLabelWidth = 20 self.catF = Frame(self.searchLeftF) self.catF.pack(side=TOP, anchor=W) self.catL = Label(self.catF, text='Category', width=self.searchLabelWidth, anchor=W, justify=LEFT) self.catL.pack(side=LEFT, fill=X, expand=YES) self.cat = StringVar() self.catE = Entry(self.catF, textvariable=self.cat, width=50, state=DISABLED) self.catE.config(disabledbackground=self.catE.cget("bg")) self.catE.config(disabledforeground=self.catE.cget("fg")) self.catE.pack(side=LEFT, fill=X, expand=YES, pady=4) self.category_option = StringVar() self.cat.set("All") option_list = ['All', 'All'] + Config().tables self.catM = OptionMenu(self.searchRightF, self.category_option, *option_list, command=self.on_category) self.catM.pack(side=TOP, anchor=N, fill=X, expand=YES) self.manF = Frame(self.searchLeftF) self.manF.pack(side=TOP, anchor=W) self.manL = Label(self.manF, text='ManufacturerName', width=self.searchLabelWidth, anchor=W, justify=LEFT) self.manL.pack(side=LEFT, fill=X, expand=YES, pady=4) self.man = StringVar() self.manE = Entry(self.manF, width=50, textvariable=self.man) self.manE.pack(side=LEFT, fill=X, expand=YES, pady=4) self.mpnF = Frame(self.searchLeftF) self.mpnF.pack(side=TOP, anchor=W) self.mpnL = Label(self.mpnF, text='ManufacturerPartNumber', width=self.searchLabelWidth, anchor=W, justify=LEFT) self.mpnL.pack(side=LEFT, fill=X, expand=YES, pady=4) self.mpn = StringVar() self.mpnE = Entry(self.mpnF, width=50, textvariable=self.mpn) self.mpnE.pack(side=LEFT, fill=X, expand=YES, pady=4) self.spnF = Frame(self.searchLeftF) self.spnF.pack(side=TOP, anchor=W) self.spnL = Label(self.spnF, text='DigiKeyPartNumber', width=self.searchLabelWidth, anchor=W, justify=LEFT) self.spnL.pack(side=LEFT, fill=X, expand=YES, pady=4) self.spn = StringVar() self.spnE = Entry(self.spnF, width=50, textvariable=self.spn) self.spnE.pack(side=LEFT, fill=X, expand=YES, pady=4) self.descF = Frame(self.searchLeftF) self.descF.pack(side=TOP, anchor=W) self.descL = Label(self.descF, text='ProductDescription', width=self.searchLabelWidth, anchor=W, justify=LEFT) self.descL.pack(side=LEFT, fill=X, expand=YES, pady=4) self.desc = StringVar() self.descE = Entry(self.descF, width=50, textvariable=self.desc) self.descE.pack(side=LEFT, fill=X, expand=YES, pady=4) self.descE.focus_force() self.findF = Frame(self.searchLeftF) self.findF.pack(side=TOP, anchor=E) self.findB = ttk.Button(self.findF, text="Find", width=12, command=lambda event=None: self.do_find(event)) self.findB.pack(side=LEFT, pady=4) self.clearB = ttk.Button(self.findF, text="Clear", width=6, command=self.on_clear_search) self.clearB.pack(side=LEFT, pady=4) self.partsLF = LabelFrame(self, text="Found Components") self.partsLF.pack(side=TOP, fill=X, expand=YES, pady=4, padx=4) self.partsF = Frame(self.partsLF) self.partsF.pack(side=TOP, pady=4, padx=4) # change treeview for search here self.partsTV = Treeview(self.partsF, selectmode=BROWSE, show='tree headings', columns=self.column_id) self.partsTV.bind('<Double-Button-1>', self.on_edit_item) self.partsTV.bind('<<TreeviewSelect>>', self.fieldChanged) self.partsTV.bind('<Escape>', self.clearSelection) self.partsTV.bind('<MouseWheel>', self.mousewheel) self.partsTV.bind('<Button-4>', self.mousewheel) self.partsTV.bind('<Button-5>', self.mousewheel) vcmd = (self.register(self.validateEntry), '%P') self.editfield = ttk.Entry(self.partsTV, validate='key', validatecommand=vcmd) self.editfield.bind('<Return>', self.updateField) self.editfield.bind('<Escape>', self.clearSelection) self.partsTV.bind('<Control-c>', self.on_copy_element) self.partsTV.column("#0", minwidth=0, width=18, stretch=NO) for t in self.column_id: self.partsTV.heading(t, text=Config().parameter[t]) self.partsTV.column('Category', width=60) self.scrollbar = Scrollbar(self.partsF, orient='vertical', command=self.partsTV.yview) self.scrollbar.pack(side=RIGHT, fill=Y, expand=YES, anchor=E) self.partsTV.configure(yscroll=self.scrollbar.set) self.scrollbar.config(command=self.yview) self.partsTV.pack(side=TOP, anchor=W, fill=X, expand=YES) self.partsTV.delete(*self.partsTV.get_children()) # end change of treeview # change the following to menu item #self.part_buttonF = Frame(self.partsLF) #self.delete_partB = ttk.Button(self.partsLF, text="Delete Part from Database", command=self.on_delete, #state=DISABLED) #self.delete_partB.pack(side=RIGHT, anchor=W, expand=NO, pady=4, padx=6) #self.partsB = ttk.Button(self.partsLF, text="Copy Selected To Part Find", command=self.on_copy, state=DISABLED) #self.partsB.pack(side=RIGHT, anchor=W, expand=NO, pady=4, padx=6) #self.part_buttonF.pack(side=BOTTOM) # start remove vvv #self.element_labelframe = LabelFrame(self, text="Modify Name/Value") #self.element_labelframe.pack(side=TOP, fill=X, expand=YES, pady=4, padx=6) #self.element_frame = Frame(self.element_labelframe) #self.element_frame.pack(side=TOP) #self.element_name = StringVar() #self.element_label = Label(self.element_frame, textvariable=self.element_name, width=30, anchor=W, justify=LEFT) #self.element_label.pack(side=LEFT, anchor=W, fill=X, expand=YES, pady=4) #self.element_value = StringVar() #self.element_entry = Entry(self.element_frame, width=50, textvariable=self.element_value) #self.element_entry.pack(side=LEFT, fill=X, expand=YES, pady=4) #self.default_color = self.element_entry.cget('background') #self.element_update = ttk.Button(self.element_frame, text="Update", command=self.on_update_element, #state=DISABLED) #self.element_update.pack(side=LEFT, fill=X, expand=YES, pady=4) #self.element_cancel = ttk.Button(self.element_frame, text="Cancel", command=self.on_clear_element, #state=DISABLED) #self.element_cancel.pack(side=LEFT, fill=X, expand=YES, pady=4) # end remove ^^^ self.statusLF = LabelFrame(self, text="Status") self.statusLF.pack(side=BOTTOM, fill=X, expand=YES, pady=4, padx=6) self.statusF = Frame(self.statusLF) self.statusF.pack(side=TOP, fill=X, expand=YES, padx=6) self.status = self.StatusBar(self.statusF, self) def validateEntry(self, P): if (len(P) <= 120): return True else: self.bell() return False # scroll bar event def yview(self, *args): if self.selectedField is not None: self.editfield.place_forget() self.selectedField = None self.partsTV.yview(*args) # mousewheel and button4/5 event def mousewheel(self, event): if self.selectedField is not None: self.editfield.place_forget() self.selectedField = None # escape event in treeview or editfield def clearSelection(self, event): self.editfield.place_forget() self.selectedField = None self.partsTV.selection_remove(self.partsTV.selection()) self.status.set("") # double button event def on_edit_item(self, event): if self.partsTV.parent(self.partsTV.selection() ) == '': # testing should not edit a parent self.selectedField = None return if (self.partsTV.identify_region(event.x, event.y) == 'cell'): self.selectedField = self.partsTV.identify_row(event.y) x, y, width, height = self.partsTV.bbox(self.selectedField, '#2') v = self.partsTV.set(self.selectedField, 1) self.editfield.pack() self.editfield.delete(0, len(self.editfield.get())) self.editfield.insert(0, v) self.editfield.selection_range(0, 'end') self.editfield.focus_force() self.editfield.place(x=x, y=y, width=width, height=height) # find button event def on_find(self): category = self.cat.get() search_list = [] col_list = [] search_str = self.man.get() if not (validate(search_str)): raise Exception("Invalid Manufacture Name") search_list.append(search_str) col_list.append(Config().parameter['ManufacturerName']) search_str = self.mpn.get() if not (validate(search_str)): raise Exception("Invalid Manufacture Part Number") search_list.append(search_str) col_list.append(Config().parameter['ManufacturerPartNumber']) search_str = self.spn.get() if not (validate(search_str)): raise Exception("Invalid Supplier Part Number") search_list.append(search_str) col_list.append(Config().parameter['DigiKeyPartNumber']) search_str = self.desc.get().split() if not (validate(search_str)): raise Exception("Invalid Description") search_list += search_str col_list.append(Config().parameter['ProductDescription']) select = "SELECT * FROM `" + Config().loaded_db.name + "`." where = "WHERE" like = "" i = 0 for item in search_list: if len(item) > 0: item = item.replace('%', '\\%') item = item.replace('"', '') item = item.replace("'", "") if i < 3: like += where + " `" + col_list[ i] + "` LIKE '" + item + "%'" else: like += where + " (`" + col_list[i] + "` LIKE '" + item + "%' OR `" + \ col_list[i] + "` LIKE '% " + item + "%')" where = " AND" i = i + 1 if (i < 3) else i self.partsTV.delete(*self.partsTV.get_children()) count = 0 if category == "All": for table in Config().tables: qry = select + "`" + table + "` " + like result = Config().loaded_db.query(qry) for record in result: v = [] spn = record[Config().parameter['DigiKeyPartNumber']] count += 1 for id in self.column_id: if id == 'Category': v.append(table) else: v.append(record[Config().parameter[id]]) id = self.partsTV.insert('', 'end', iid=spn, text=spn, values=v) for params in record: if record[params] is not None: self.partsTV.insert(id, 'end', text=spn, values=(params, record[params])) else: qry = select + "`" + category + "` " + like result = Config().loaded_db.query(qry) for record in result: v = [] count += 1 spn = record[Config().parameter['DigiKeyPartNumber']] for id in self.column_id: if id == 'Category': v.append(category) else: v.append(record[Config().parameter[id]]) id = self.partsTV.insert('', 'end', iid=spn, text=spn, values=v) for params in record: if record[params] is not None: self.partsTV.insert(id, 'end', text=spn, values=(params, record[params])) self.status.set(("No" if count == 0 else str(count)) + " items found") # return event def updateField(self, event): value = self.editfield.get() self.editfield.place_forget() name = self.partsTV.item(self.selectedField, "text") if not validate(value): self.status.seterror("Invalid value, must not have quotes") return self.partsTV.set(self.selectedField, "#2", value) key = self.partsTV.set(self.selectedField, "#1") self.editfield.place_forget() element_parent = self.partsTV.parent(self.selectedField) table_name = self.partsTV.item( element_parent, "values")[self.column_id.index('Category')] part_number = self.partsTV.item( element_parent, "values")[self.column_id.index('DigiKeyPartNumber')] set_param = "SET `" + key + "` = '" + value + "' " where = "WHERE `" + Config( ).parameter['DigiKeyPartNumber'] + "` = '" + part_number + "'" qry = "UPDATE `" + Config( ).loaded_db.name + "`.`" + table_name + "` " + set_param + where print(qry) try: Config().loaded_db.query(qry) except Exception as e: self.status.seterror("Database query failed: %s", e) return self.status.set("Changed " + key + " to " + value + " for part " + part_number + ".") self.partsTV.see(self.selectedField) # clear button in search frame def on_clear_search(self): self.man.set("") self.mpn.set("") self.spn.set("") self.desc.set("") self.cat.set("All") self.category_option.set("All") self.partsTV.delete(*self.partsTV.get_children()) def do_flash(self): current_color = self.element_entry.cget("background") if current_color == self.default_color: self.element_entry.config(background="red") else: self.element_entry.config(background=self.default_color) return self.after(250, self.do_flash) # category option menu def on_category(self, value): self.catE.config(state=NORMAL) self.cat.set(value) self.catE.config(state=DISABLED) #def on_copy(self): #selected = self.partsTV.selection()[0] #key = self.partsTV.item(selected, "values")[self.column_id.index('DigiKeyPartNumber')] #self.app_window.part_num_string.set(key) #self.status.set("Part Number '" + key + "' copied to Part Find") # Edit -> Delete menu def on_delete(self): selected = self.partsTV.selection()[0] key = self.partsTV.item( selected, "values")[self.column_id.index('DigiKeyPartNumber')] table = self.partsTV.item(selected, "values")[self.column_id.index('Category')] if messagebox.askokcancel( "Delete", "Click OK if you really want to delete '" + key + "' from database?"): Config().loaded_db.query("DELETE FROM `" + table + "` WHERE `" + Config().parameter['DigiKeyPartNumber'] + "` = '" + key + "'") self.status.set("Part Number '" + key + "' deleted from database") # treeview select event def fieldChanged(self, event): selected = self.partsTV.selection() if len(selected) > 0: self.copySourcesMenu.entryconfig(self.partnumber_index, state=NORMAL) self.copySourcesMenu.entryconfig(self.allParameters_index, state=NORMAL) else: self.copySourcesMenu.entryconfig(self.partnumber_index, state=DISABLED) self.copySourcesMenu.entryconfig(self.allParameters_index, state=DISABLED) return if self.partsTV.parent(selected) == '': self.copySourcesMenu.entryconfig(self.selectedParameter_index, state=DISABLED) else: self.copySourcesMenu.entryconfig(self.selectedParameter_index, state=NORMAL) if selected != self.selectedField: self.editfield.place_forget() self.selectedField = None def on_copy_parameters(self): selected = self.partsTV.selection() if len(selected) == 0 or self.partsTV.parent(selected) == '': return try: property = self.partsTV.item(selected, "values") self.parent.clipboard_clear() self.parent.clipboard_append(property[0] + '\t' + property[1]) self.parent.update() self.status.set(property[0] + ' ' + property[1] + " copied to clipboard") except Exception as e: pass def on_copy_partnumber(self): selected = self.partsTV.selection() if len(selected) == 0 or self.partsTV.parent(selected) == '': return try: if self.partsTV.parent(selected) != '': selected = self.partsTV.parent(selected) partnumber = self.partsTV.item( selected, "values")[self.column_id.index('DigiKeyPartNumber')] self.parent.clipboard_clear() self.parent.clipboard_append(partnumber) self.parent.update() self.status.set(" '" + partnumber + "' copied to clipboard") except Exception as e: pass def on_copy_all_parameters(self): selected = self.partsTV.selection() if len(selected) == 0: return try: if self.partsTV.parent(selected) != '': selected = self.partsTV.parent(selected) partnumber = self.partsTV.item( selected, "values")[self.column_id.index('DigiKeyPartNumber')] elements = self.partsTV.get_children(selected) self.parent.clipboard_clear() self.parent.clipboard_clear() for i in elements: element = self.partsTV.item(i, "values") self.parent.clipboard_append(element[0] + "\t" + element[1] + "\n") self.parent.update() self.status.set("All properties of " + partnumber + " copied to clipboard") except Exception as e: pass # deprecate def on_copy_element(self, event): try: selected = self.partsTV.selection()[0] if self.partsTV.parent(selected) == '': partnumber = self.partsTV.item elements = self.partsTV.get_children(selected) self.parent.clipboard_clear() for i in elements: element = self.partsTV.item(i, "values") self.parent.clipboard_append(element[0] + "\t" + element[1] + "\n") self.parent.update() self.status.set("All properties of " + self.partsTV.item(selected, "values")[3] + " copied to clipboard") else: key = self.partsTV.item(selected, "values")[0] val = self.partsTV.item(selected, "values")[1] self.parent.clipboard_clear() self.parent.clipboard_append(val) self.parent.update() self.status.set(key + " '" + val + "' copied to clipboard") except Exception as e: pass def do_find(self, event): try: self.on_find() except Exception as e: self.status.seterror(e)
class CollectionOfFilms(Frame): # ГЛАВНЫЙ КЛАСС; def __init__(self, root, x, y): super().__init__(root) self.x = x self.y = y self.init_main() self.db = db self.update_records() def init_main(self): # СТИЛЬ ШРИФТА; font_style = ('Consolas', '12') # СТИЛЬ ТАБЛИЦ и КНОПОК в ВСПЛЫВАЮЩИХ ОКНАХ; Style().configure("Treeview.Heading", font=font_style, foreground='#425370') Style().configure('Treeview', font=font_style, foreground='#425370') Style().configure('TButton', font=('Consolas', '10')) Style().configure('TLabel', font=font_style, background='#EDF0F5', foreground='#425370') # ВЕРХНЯЯ и НИЖНЯЯ ПАНЕЛЬ для КНОПОК и ПОДСКАЗОК; TB_TOP = Frame(self, bg='#EDF0F5', bd=1) TB_BOT = Frame(self, bg='#EDF0F5', bd=1) TB_TOP.pack(side=TOP, fill=X) TB_BOT.pack(side=BOTTOM, fill=X) # КНОПКИ на ВЕРХНЕЙ ПАНЕЛИ; btn_add_ = Button(TB_TOP, text='Добавить', compound=TOP, command=self.open_dlg_add, bg='#EDF0F5', activebackground='#425370', activeforeground='white', width=15, height=1, font=font_style, relief=GROOVE, overrelief=GROOVE) btn_edit = Button(TB_TOP, text='Редактировать', compound=TOP, command=self.open_dlg_edit, bg='#EDF0F5', activebackground='#425370', activeforeground='white', width=15, height=1, font=font_style, relief=GROOVE, overrelief=GROOVE) btn_del_ = Button(TB_TOP, text='Удалить', compound=TOP, command=self.open_dlg_del, bg='#EDF0F5', activebackground='#425370', activeforeground='white', width=15, height=1, font=font_style, relief=GROOVE, overrelief=GROOVE) btn_view = Button(TB_BOT, text='Просмотр', compound=TOP, command=self.open_dlg_view, bg='#EDF0F5', activebackground='#425370', activeforeground='white', width=10, height=1, font=font_style, relief=FLAT, overrelief=FLAT) btn_add_.pack(side=LEFT) btn_edit.pack(side=LEFT) btn_del_.pack(side=RIGHT) btn_view.pack(side=RIGHT) btn_add_.bind('<Enter>', lambda event: btn_add_.configure(bg='#8E9FBD', fg='white')) btn_add_.bind('<Leave>', lambda event: btn_add_.configure(bg='#EDF0F5', fg='black')) btn_edit.bind('<Enter>', lambda event: btn_edit.configure(bg='#8E9FBD', fg='white')) btn_edit.bind('<Leave>', lambda event: btn_edit.configure(bg='#EDF0F5', fg='black')) btn_del_.bind('<Enter>', lambda event: btn_del_.configure(bg='#8E9FBD', fg='white')) btn_del_.bind('<Leave>', lambda event: btn_del_.configure(bg='#EDF0F5', fg='black')) btn_view.bind('<Enter>', lambda event: btn_view.configure(bg='#8E9FBD', fg='white')) btn_view.bind('<Leave>', lambda event: btn_view.configure(bg='#EDF0F5', fg='black')) # ВЫВОД ОШИБОК и КОЛ-ВА ЗАПИСЕЙ на НИЖНЮЮ ПАНЕЛЬ; self.error = Label(TB_BOT, foreground='red') self.count = Label(TB_BOT) self.error.pack(side=RIGHT) self.count.pack(side=LEFT) # ПОЛОСА ПРОКРУТКИ и ТАБЛИЦА; _yscroll_ = Scrollbar(self) self.tree = Treeview(self, columns=('id', 'name', 'mors', 'janr', 'flag'), height=20, show='headings', yscrollcommand=_yscroll_.set) _yscroll_.config(command=self.tree.yview) self.tree.column('id', width=50, minwidth=50, anchor=CENTER) self.tree.column('name', width=370, minwidth=370) self.tree.column('mors', width=110, minwidth=110) self.tree.column('janr', width=110, minwidth=110) self.tree.column('flag', width=140, minwidth=140) self.tree.heading('id', text='№') self.tree.heading('name', text='Название') self.tree.heading('mors', text='Кино/Сериал') self.tree.heading('janr', text='Жанр') self.tree.heading('flag', text='Просмотр') _yscroll_.pack(side=RIGHT, fill=Y) self.tree.pack() self.tree.bind('<Button-1>', lambda event: 'break' if self.tree.identify_region(event.x, event.y) == 'separator' else None) def update_records(self): # ОБНОВЛЕНИЕ ДАННЫХ; num = 0 self.db.c.execute(''' SELECT * FROM films ''') [ self.tree.delete(i) for i in self.tree.get_children() ] for row in self.db.c.fetchall(): [ self.tree.insert('', 'end', values=row) ] num += 1 self.count['text'] = ' Количество записей: %d' % (num) def add_record(self, name, mors, janr, flag): # ДОБАВЛЕНИЕ; if (name != ''): self.error['text'] = '' flag_record = False self.db.c.execute(''' SELECT name FROM films ''') for row in self.db.c.fetchall(): # Проверка на схожую запись; if (name == row[0]): flag_record = True if (not flag_record): self.db.add_data(name, mors, janr, flag) else: self.error['text'] = 'Такая запись уже существует! ' else: self.error['text'] = 'Данные не введены в поле! ' self.update_records() def edit_record(self, name, mors, janr, flag): # РЕДАКТИРОВАНИЕ; if (name != ''): self.error['text'] = '' self.db.c.execute(''' UPDATE films SET name=?, mors=?, janr=?, flag=? WHERE id=? ''', (name, mors, janr, flag, self.tree.set(self.tree.selection()[0], '#1'))) else: self.error['text'] = 'Данные не введены в поле! ' self.db.conn.commit() self.update_records() def delete_record(self): # УДАЛЕНИЕ; for item in self.tree.selection(): self.db.c.execute(''' DELETE FROM films WHERE id=? ''', (self.tree.set(item)['id'],)) self.db.conn.commit() self.update_records() def open_dlg_add(self): # ОТКРЫВАЕМ ОКНО ДОБАВЛЕНИЯ; self.error['text'] = '' AddData(self.x, self.y) def open_dlg_edit(self): # ОТКРЫВАЕМ ОКНО РЕДАКТИРОВАНИЯ; if self.tree.selection(): self.error['text'] = '' EditData(self.x, self.y, self.tree.item(self.tree.selection()[0])['values'][1]) else: self.error['text'] = 'Не выбрана запись для редактирования! ' def open_dlg_del(self): # ОТКРЫВАЕМ ОКНО УДАЛЕНИЯ; if (self.tree.selection()): self.error['text'] = '' DeleteData(self.x, self.y) else: self.error['text'] = 'Нет записей для удаления! ' def open_dlg_view(self): # ОТКРЫВАЕМ ОКНО ПРОСМОТРА; self.error['text'] = '' SelectForViewRecords(self.x, self.y)