class Window(Frame): def __init__(self, parent): super(Window, self).__init__(parent) self.parent = parent self.grid(row=0,column=0) # Entry, Start self.entry = Entry(self) self.entry.grid(column=0, row=0, padx=1,pady=0) self.entry.bind('<Return>',self.started) self.btn_start = Button(self, text='start',command=self.started) self.btn_start.grid(column=1, row=0, padx=2, pady=2) # Result self.results=Frame(self, background='blue') self.canvas=Canvas(self.results, background='green') self.labels_frame=Frame(self.canvas, background='pink') self.scrollbar = ttk.Scrollbar(self.results, orient='vertical', command=self.canvas.yview) self.heading=Label(self.labels_frame, text='Suchergebnisse:', anchor='w',width=50) self.results.grid(row=1,column=0,sticky='w',padx=2,pady=2, columnspan=2) self.canvas.grid(row=0,column=0, padx=2,pady=2)#todo delete padding #self.labels_frame.grid(row=0,column=0, padx=2,pady=2)#benötigt obwohl canvas.create_window? self.heading.grid(column=0,row=0,columnspan=3,sticky='wesn', padx=2, pady=2) self.canvas.create_window(0, 0, anchor='nw', window=self.labels_frame)#,height=250,width=300) def started(self, events=None): self.found_foods=[] for i in range(int(self.entry.get())): self.found_foods.append(i) self.create_labels() def create_labels(self): labels=[] for found_food in self.found_foods: name_label = Label(self.labels_frame, text=found_food, anchor='w') category_label = Label(self.labels_frame, text='--missing yet--', anchor='w') labels.append([name_label,category_label]) self.update_view(labels) def update_view(self,labels): self.del_old_labels() for row,labelrow in enumerate(labels): for col,element in enumerate(labelrow): element.grid(row=row+1, column=col, padx=1,pady=1, sticky='wsen') if len(self.found_foods)>10: #10 nur als Bsp 0self.canvas.update_idletasks() #no idea what this does self.canvas.config(yscrollcommand=self.scrollbar.set) self.canvas.config(height=250,width=300) self.canvas.configure(scrollregion=self.canvas.bbox('all')) self.scrollbar.grid(row=0,column=1, sticky='ns',padx=2,pady=2) else: self.scrollbar.grid_forget() def del_old_labels(self): for label in self.labels_frame.grid_slaves(): if int(label.grid_info()["row"]) > 0: label.grid_forget()
class myApp: def __init__(self): self.root = Tk() style = ttk.Style() style.configure("Treeview.Heading", font=(None, 11), background="green") self.config = ST.Setting(self.root) self.SelDriver = SeleniumProcessor.SeleniumDriver(self.config) self.POMTreeView = TreeProcessor.POMTree(self.config) self.XML = XMLProcessor.XML() self.treeFrame = None self.tree = None self.treeValues = None self.ScreenCoverWindow = None self.root.title("POM Manager") self.root.geometry('700x600') #MENU SECTION : to create Menu # File Menu menu = Menu(self.root) self.root.config(menu=menu) filemenu = Menu(menu) menu.add_cascade(label="File", menu=filemenu) filemenu.add_command(label="Create New POM..", command=self.NewFile) filemenu.add_command(label="Open POM...", command=self.OpenFile) filemenu.add_command(label="Save POM...", command=self.SaveFile) filemenu.add_command(label="Save as POM...", command=self.SaveFileAs) filemenu.add_separator() filemenu.add_command(label="Exit", command=self.root.destroy) toolmenu = Menu(menu) menu.add_cascade(label="Tool", menu=toolmenu) toolmenu.add_command(label="Settings", command=self.Settings) helpmenu = Menu(menu) menu.add_cascade(label="Help", menu=helpmenu) helpmenu.add_command(label="About...", command=self.About) self.root.grid_columnconfigure(0, weight=1) self.root.grid_rowconfigure(1, weight=1) top = ttk.Frame(self.root, height=200) top.grid_columnconfigure(1, weight=1) top.grid(column=0, row=0, pady=10, sticky='nsew') bottom = ttk.Frame(self.root) bottom.grid(column=0, row=1, sticky='nsew') bottom.grid_columnconfigure(0, weight=1, uniform="group1") bottom.grid_columnconfigure(1, weight=1, uniform="group1") bottom.grid_rowconfigure(0, weight=1) footer = ttk.Frame(bottom, height=120) Label(top, text='Enter Base URL :').grid(column=0, row=0) self.txtURL = Entry(top) self.txtURL.grid(column=1, row=0, sticky='we') browserCombo = ttk.Combobox(top, values=['Chrome', 'IE', 'Edge', 'FireFox'], state='readonly') browserCombo.set('Chrome') browserCombo.grid(column=2, row=0, padx=5) self.Launchbtn = ttk.Button( top, text="Launch", command=lambda: self.SelDriver.LaunchBrowser( browserCombo.get(), self.txtURL.get())) self.Launchbtn.grid(column=1, row=1, pady=5) self.root.bind("<Control-s>", lambda event: self.XML.saveXML(self.POMTreeView)) self.AddNewObjectButton = ttk.Button( footer, text='Add New Object ', command=lambda: self.enable_mouseposition()) self.AddNewObjectButton.grid(column=0, row=1, padx=5, pady=20) self.ManuallyAddobject = ttk.Button( footer, text='Add Object Manually', command=lambda: self.addobjectPropertiesManually()) self.ManuallyAddobject.grid(column=2, row=1, padx=5, pady=20) self.savebutton = ttk.Button( footer, text='Save', command=lambda: self.XML.saveXML(self.tree, self.POMTreeView)) self.savebutton.grid(column=3, row=1, padx=5, pady=20) self.AddToPageButton = ttk.Button( footer, text='Add With Delay', command=lambda: self.getDelayCoordinates()) self.AddToPageButton.grid(column=1, row=1, padx=5, pady=20) self.CancelButton = ttk.Button(footer, text='Cancel', command=self.root.destroy) self.CancelButton.grid(column=4, row=1, padx=5, pady=20) self.treeFrame = Frame(bottom, borderwidth=1, relief="solid") self.treeValues = Frame(bottom, borderwidth=1, relief="solid") self.treeFrame.grid_rowconfigure(0, weight=1) self.treeFrame.grid_columnconfigure(0, weight=1) self.treeFrame.grid(row=0, column=0, sticky='nsew') self.treeValues.grid(row=0, column=1, sticky='nsew') bottom.grid_rowconfigure(0, weight=1) footer.grid(column=0, row=1, columnspan=2) mainloop() try: self.SelDriver.quit() except AttributeError: None def NewFile(self): files = [('ORFile', '*.xml.')] file = asksaveasfile(title="Select folder", filetypes=files, defaultextension=files) self.XML.filePath = file.name self.XML.fileName = ((file.name).split('/')[-1]).split('.')[0] self.createPOMTree('newfile') def OpenFile(self): filePath = filedialog.askopenfilename() if len(filePath) > 4: self.XML = XMLProcessor.XML(filePath) if self.tree != None: self.tree.destroy() self.createPOMTree() self.AddToPageButton['state'] = 'normal' def About(self): print('This is a simple example of a menu!') def SaveFile(self): self.XML.saveXML(self.tree, self.POMTreeView) def SaveFileAs(self): self.XML.saveXML(self.tree, self.POMTreeView, 'newfile') #======================================================================= # self.tree.heading('#0', text=self.XML.fileName) #======================================================================= def Settings(self): self.config.displaySettingPanel() def cancelAddObject(self, topWindow): topWindow.destroy() def getDelayCoordinates(self): try: self.root.iconify() top = Toplevel() top.geometry("+%d+%d" % (0, 0)) top.title("Counter") top.attributes('-alpha', 0.5) v = Tkinter.IntVar() ttk.Label(top, text="**hover mouse to the object you want to add", font=('Arial', 8)).pack() text = ttk.Label(top, textvariable=v) text.config(font=("Courier", 50)) text.pack() for i in range(5, -1, -1): v.set(i) text.update() time.sleep(1) top.destroy() self.SelDriver.set_webElement(PYAUTO.position()) self.createAttributePanel('delayadd') except AttributeError: messagebox.showinfo( 'Driver Not Initiated', 'Driver is not initiated.\nPlease make sure browser is Launched using tool.' ) def enable_mouseposition(self, actionType=None): try: driver = self.SelDriver.driver driver.switch_to.window( driver.window_handles[len(driver.window_handles) - 1]) self.root.after(100, self.get_WebObject(actionType)) except AttributeError: Tkinter.messagebox.showinfo( 'Driver Not Initiated', 'Driver is not initiated. \nPlease make sure browser is launched using tool.' ) def get_WebObject(self, actionType): self.ScreenCoverWindow = Toplevel() self.root.iconify() self.ScreenCoverWindow.attributes('-topmost', True) self.ScreenCoverWindow.title("Object Properties") self.ScreenCoverWindow.attributes('-alpha', 0.2) self.ScreenCoverWindow.attributes("-fullscreen", True) self.ScreenCoverWindow.focus_force() self.ScreenCoverWindow.bind( "<Button-1>", lambda event: self.createAttributePanel(actionType, event)) def createAttributePanel(self, actionType=None, event=None): if actionType != 'delayadd': self.SelDriver.set_webElement((event.x, event.y), self.ScreenCoverWindow) attributePanelWindow = Toplevel() attributePanelWindow.geometry("600x500") attributePanelWindow.attributes('-topmost', True) attributePanelWindow.title("Object Properties") attributePanelWindow.grid_columnconfigure(0, weight=1) attributePanelWindow.grid_rowconfigure(0, weight=1) top = ttk.Frame(attributePanelWindow) top.grid(column=0, row=0, sticky='nsew') top.grid_columnconfigure(0, weight=1, uniform="group1") top.grid_columnconfigure(1, weight=1, uniform="group1") top.grid_rowconfigure(0, weight=1) self.attributeTreeFrame = Frame(top, borderwidth=1, relief="solid") self.attributetreeValues = Frame(top, borderwidth=1, relief='solid') self.attributeTreeFrame.grid_rowconfigure(0, weight=1) self.attributeTreeFrame.grid_columnconfigure(0, weight=1) self.attributeTreeFrame.grid(row=0, column=0, sticky='nsew') self.attributetreeValues.grid(row=0, column=1, sticky="nsew") footer = ttk.Frame(top, height=120) footer.grid(column=0, row=1, columnspan=2) ttk.Button(footer, text='Cancel', command=attributePanelWindow.destroy).grid(column=2, row=1, padx=5, pady=10) ttk.Button(footer, text='Add Object', command=lambda: self.updatePOMTree( attributePanelWindow, self.ObjectPropertyTree.getObjectDict())).grid(column=1, row=1, padx=5, pady=10) self.createAttributeTree(self.SelDriver.attributeList, actionType) def createAttributeTree(self, attrsList, processType=None): self.attributeTree = ttk.Treeview(self.attributeTreeFrame) self.yscrollbar = Util.AutoScrollbar(self.attributeTreeFrame, orient='vertical', command=self.attributeTree.yview) self.attributeTree.configure(yscrollcommand=self.yscrollbar.set) self.attributeTree.grid(row=0, column=0, sticky='nsew') self.yscrollbar.grid(row=0, column=1, sticky='ns') self.ObjectPropertyTree = TreeProcessor.ObjectPropertyTree( self.attributeTree, attrsList, processtype=processType) self.attributeTree.bind( "<<TreeviewSelect>>", lambda event: self.displayProperties( self.attributetreeValues, self.ObjectPropertyTree.getObjectDict())) def displayProperties(self, attributes, newObjectTreeDict, actiontype=None): propertyNum = 0 for widget in attributes.winfo_children(): widget.destroy() currentItem = self.attributeTree.focus() currObject = newObjectTreeDict[currentItem] attributes.grid_columnconfigure(1, weight=1) ttk.Label(attributes, text='Display Name', justify='left').grid(column=0, row=0, padx=5, pady=1, sticky='w') DefaultVal = StringVar(attributes, value=currObject.DisplayName) Entry(attributes, textvariable=DefaultVal).grid(column=1, row=0, padx=5, pady=1, sticky='we', columnspan=1) for oProperty in currObject.propertyList: isPropSelected = oProperty.Selected isUsed = Tkinter.IntVar() propertyCheckButton = ttk.Checkbutton(attributes, text=oProperty.propertyName, variable=isUsed) propertyCheckButton.is_selected = isUsed propertyCheckButton.grid(column=0, row=propertyNum + 1, padx=5, pady=1, sticky='w') DefaultVal = StringVar(attributes, value=oProperty.Value) PropertyVal = Entry(attributes, textvariable=DefaultVal) PropertyVal.grid(column=1, row=propertyNum + 1, padx=5, pady=1, sticky='we', columnspan=2) if isPropSelected == '1' or isPropSelected == 1: propertyCheckButton.var = isUsed propertyCheckButton.var.set(1) else: propertyCheckButton.var = isUsed propertyCheckButton.var.set(0) propertyNum = propertyNum + 1 UpdateButton = ttk.Button(attributes, text='Update') UpdateButton.grid(column=1, row=propertyNum + 1, padx=10, pady=20, sticky='w') if actiontype == 'manual': AddChildButton = ttk.Button(attributes, text='Add child Object ') AddChildButton['command'] = lambda: self.AddChildToAttributeTree() AddChildButton.grid(column=0, row=propertyNum + 1, padx=10, pady=20, sticky='w') UpdateButton['command'] = lambda: self.UpdateProperties( self.scrollable_frame, currentItem) else: UpdateButton['command'] = lambda: self.UpdateProperties( self.attributetreeValues, currentItem) def UpdateProperties(self, treeVal, key): self.ObjectPropertyTree.updateObjectDict(treeVal, key) def updatePOMTree(self, propertyWindow, objDict, actionType=None): currItem = self.attributeTree.focus() objectToAdd = objDict[currItem] currObject = objectToAdd addToObject = '' objList = [currObject.ObjectID] if self.tree == None: self.createPOMTree() propertyWindow.attributes('-topmost', False) if self.tree.exists(currObject.ObjectID): messagebox.showinfo( 'Object Present with ID: =' + currObject.ObjectID, 'Object Present with ID: ' + currObject.ObjectID + '. \nPlease Change the Name or Update object Directly from Attribute Window' ) else: self.POMTreeView.treeDict[currObject.ObjectID] = currObject while currObject.ParentID != None and len(currObject.ParentID) > 0: if self.tree.exists(currObject.ParentID): addToObject = currObject.ParentID self.POMTreeView.treeDict[addToObject].childList.append( currObject) break else: currObject = objDict[currObject.ParentID] self.POMTreeView.treeDict[currObject.ObjectID] = currObject objList.insert(0, currObject.ObjectID) for childtree in objList: childObj = objDict[childtree] self.tree.insert(addToObject, 'end', iid=childObj.ObjectID, text=childObj.DisplayName) addToObject = childObj.ObjectID propertyWindow.destroy() Util.focusTree(self.tree, objectToAdd.ObjectID) print('Object to Focus :' + currObject.ObjectID) def AddChildToAttributeTree(self): for widget in self.scrollable_frame.winfo_children(): widget.destroy() self.addObjectIndentificationFields(self.attributeTree, self.scrollable_frame, 'child') def addobjectPropertiesManually(self): self.attributePanelWindow = Toplevel() self.attributePanelWindow.geometry("600x500") self.attributePanelWindow.attributes('-topmost', True) self.attributePanelWindow.title("Object Properties") self.attributePanelWindow.grid_columnconfigure(0, weight=1) self.attributePanelWindow.grid_rowconfigure(0, weight=1) top = ttk.Frame(self.attributePanelWindow) top.grid(column=0, row=0, sticky='nsew') top.grid_columnconfigure(0, weight=1, uniform="group1") top.grid_columnconfigure(1, weight=1, uniform="group1") top.grid_rowconfigure(0, weight=1) self.attributeTreeFrame = Frame(top, borderwidth=1, relief="solid") self.attributetreeValues = Frame(top, borderwidth=1, relief="solid") self.attributeTreeFrame.grid_rowconfigure(0, weight=1) self.attributeTreeFrame.grid_columnconfigure(0, weight=1) self.attributeTreeFrame.grid(row=0, column=0, sticky='nsew') self.attributetreeValues.grid_rowconfigure(0, weight=1) self.attributetreeValues.grid_columnconfigure(0, weight=1) self.attributetreeValues.grid(row=0, column=1, sticky='nsew') self.scrollable_frame = Util.ScrollableFrame(self.attributetreeValues, 'both') self.attributeTree = ttk.Treeview(self.attributeTreeFrame) self.attributeTree.grid(row=0, column=0, sticky="nsew") self.attributeTree.bind( "<<TreeviewSelect>>", lambda event: self.displayProperties( self.scrollable_frame, self.ObjectPropertyTree.getObjectDict(), 'manual')) footer = ttk.Frame(top, height=120) footer.grid(column=0, row=1, columnspan=2) ttk.Button(footer, text='Cancel', command=self.attributePanelWindow.destroy).grid(column=0, row=1, padx=5, pady=10) ttk.Button(footer, text='Add Object', command=lambda: self.updatePOMTree( self.attributePanelWindow, self.ObjectPropertyTree.getObjectDict())).grid(column=1, row=1, padx=5, pady=10) self.addObjectIndentificationFields(self.attributeTree, self.scrollable_frame) def addObjectIndentificationFields(self, objTree, Scrollableframe, objtype=None): objectTypeList = ['POM_Page'] if len( objTree.get_children()) == 0 else ['POM_frame', 'POM_Object'] ttk.Label(Scrollableframe, text='Object Type', justify='left').grid(column=0, row=0, padx=5, sticky='w') ObjectTypeCombo = ttk.Combobox(Scrollableframe, values=objectTypeList, state='readonly') ObjectTypeCombo.grid(column=1, row=0, sticky='we') ttk.Label(Scrollableframe, text='Display Name', justify="left").grid(column=0, row=1, padx=5, sticky='w') comboExample = ttk.Combobox(Scrollableframe, values=[]) comboExample.grid(column=1, row=1, sticky='we') ObjectTypeCombo.bind( "<<ComboboxSelected>>", lambda event: self.getObjectList( Scrollableframe, ObjectTypeCombo, comboExample)) self.addPropertywidget(Scrollableframe, 2, objtype) def getObjectList(self, Scrollableframe, ObjectTypeCombo, comboExample): listObjectName = [] if ObjectTypeCombo.get() == 'POM_Page': if self.tree != None: for child in self.tree.get_children(): listObjectName.append(child) comboExample['values'] = listObjectName def addPropertywidget(self, propertyWindow, addPropRow, objtype=None): ttk.Label(propertyWindow, text=' ', justify='left').grid(column=0, row=addPropRow, padx=5, sticky='w') ttk.Label(propertyWindow, text='Property Name:', justify='left').grid(column=0, row=addPropRow + 1, padx=5, sticky='w') PropertyType = Entry(propertyWindow) PropertyType.grid(column=1, row=addPropRow + 1, sticky='we') ttk.Label(propertyWindow, text='Property Value:', justify='left').grid(column=0, row=addPropRow + 2, padx=5, sticky='w') PropertyValue = Entry(propertyWindow) PropertyValue.grid(column=1, row=addPropRow + 2, sticky='we') AddPropButton = ttk.Button(propertyWindow, text='Add Property.. ') AddPropButton.grid(row=addPropRow + 3, column=0, padx=5, pady=5, sticky='e') AddPropButton['command'] = lambda: self.addAttribute( propertyWindow, addPropRow, objtype) buttonFrame = Frame(propertyWindow) buttonFrame.grid(column=0, row=addPropRow + 4, columnspan=2) if objtype == 'child': ttk.Button(buttonFrame, text='Add to Tree', command=lambda: self.AddManualobjectToTree( propertyWindow, objtype)).grid(column=0, row=0, padx=5, pady=20) else: ttk.Button(buttonFrame, text='Add to Tree', command=lambda: self.AddManualobjectToTree( propertyWindow)).grid(column=0, row=0, padx=5, pady=20) cancelbutton = ttk.Button( buttonFrame, text='Cancel ', command=lambda: self.refreshAddManualobjectPanel()) cancelbutton.grid(column=1, row=0, padx=5, pady=20) def refreshAddManualobjectPanel(self): for widget in self.scrollable_frame.winfo_children(): widget.destroy() if len(self.attributeTree.get_children()) > 0: currItem = self.attributeTree.focus() Util.focusTree(self.attributeTree, currItem) else: self.addObjectIndentificationFields(self.attributeTree, self.scrollable_frame) def addAttribute(self, propertyWindow, addProp, objtype=None): PropertyName = (propertyWindow.grid_slaves(addProp + 1, 1)[0]).get() PropertyVal = (propertyWindow.grid_slaves(addProp + 2, 1)[0]).get() v = Tkinter.IntVar() for i in range(addProp, addProp + 5): for w in propertyWindow.grid_slaves(row=i): w.grid_forget() c = Checkbutton(propertyWindow, text=PropertyName, variable=v) c.grid(column=0, row=addProp, padx=5, sticky='w') c.is_selected = v DefaultVal = StringVar(self.root, value=PropertyVal) Entry(propertyWindow, textvariable=DefaultVal).grid(column=1, row=addProp, sticky='we') self.addPropertywidget(propertyWindow, addProp + 1, objtype) def AddManualobjectToTree(self, treeManual, objtype=None): if (treeManual.grid_slaves( 0, 1)[0]).get() == '' or (treeManual.grid_slaves( 0, 1)[0]).get() == None or (treeManual.grid_slaves( 1, 1)[0]).get() == '' or (treeManual.grid_slaves( 1, 1)[0]).get() == None: messagebox.showinfo( 'Object Not Created', 'Please provide Object Name and at least one property to add object.' ) else: if objtype == 'child': currentItem = self.attributeTree.focus() currParentObj = self.ObjectPropertyTree.objectDict[currentItem] currObj = self.ObjectPropertyTree.createTreeObject( currParentObj)[1] else: self.ObjectPropertyTree = TreeProcessor.ObjectPropertyTree( self.attributeTree, treevals=treeManual) currObj = self.ObjectPropertyTree.createTreeObject()[1] Util.focusTree(self.attributeTree, currObj.ObjectID) def createPOMTree(self, processType=None): if self.tree != None: self.tree.destroy() self.tree = Util.scrollableTree(self.treeFrame, 'both') self.tree.heading('#0', anchor='w') self.tree.grid(row=0, column=0, sticky="nsew") if self.POMTreeView == None: print('IT IS NULL') self.POMTreeView.setTree(self.tree) if self.XML.filePath != None: self.POMTreeView.createTree(self.XML, self.tree, processType) self.tree.bind("<<TreeviewSelect>>", lambda event: self.displayObjectProperties(event)) def displayObjectProperties(self, currentItem=None): propertyNum = 1 for widget in self.treeValues.winfo_children(): widget.destroy() self.currentItem = self.tree.focus() self.POMTreeView.ORObject = self.currentItem currObject = self.POMTreeView.ORObject ttk.Label(self.treeValues, text='Display Name', justify='left').grid(column=0, row=0, padx=5, sticky='w') DefaultVal = StringVar(self.treeValues, value=currObject.DisplayName) Entry(self.treeValues, textvariable=DefaultVal, state='readonly').grid(column=1, row=0, sticky='we', columnspan=2) ttk.Label(self.treeValues, text='Object ID', justify='left').grid(column=0, row=propertyNum, padx=5, sticky='w') DefaultVal = StringVar(self.treeValues, value=currObject.ObjectID) Entry(self.treeValues, textvariable=DefaultVal, state='readonly').grid(column=1, row=propertyNum, sticky='we', columnspan=2) self.treeValues.grid_columnconfigure(1, weight=1) for oProperty in currObject.propertyList: isPropSelected = oProperty.Selected isUsed = Tkinter.IntVar() propertyCheckButton = ttk.Checkbutton(self.treeValues, text=oProperty.propertyName, variable=isUsed, state='disabled') propertyCheckButton.is_selected = isUsed propertyCheckButton.grid(column=0, row=propertyNum + 1, padx=5, sticky='w') DefaultVal = StringVar(self.treeValues, value=oProperty.Value) PropertyVal = Entry(self.treeValues, textvariable=DefaultVal, state='readonly') PropertyVal.grid(column=1, row=propertyNum + 1, sticky='we', columnspan=2) if isPropSelected == '1' or isPropSelected == 1: propertyCheckButton.var = isUsed propertyCheckButton.var.set(1) else: propertyCheckButton.var = isUsed propertyCheckButton.var.set(0) propertyNum = propertyNum + 1 EditButton = ttk.Button(self.treeValues, text=' Edit ') EditButton['command'] = lambda: self.editProperties( EditButton, propertyNum + 1) EditButton.grid(column=1, row=propertyNum + 1, padx=10, pady=20, sticky='w') def editProperties(self, EditButton, propertyNum): EditButton['text'] = 'Update' EditButton.grid(column=2) ttk.Button(self.treeValues, text='Add Custom Property', command=lambda: self.addCutomProperty()).grid( column=1, row=propertyNum, pady=20, sticky='w') for widget in self.treeValues.winfo_children(): widget['state'] = 'normal' self.treeValues.grid_slaves(1, 1)[0]['state'] = 'readonly' self.isPropertySaved = False EditButton['command'] = lambda: self.updateObjectProperty(EditButton) def addCutomProperty(self): addPropRow = 0 customAttributeWindow = Toplevel() customAttributeWindow.geometry("300x100") customAttributeWindow.attributes("-topmost", True) customAttributeWindow.title("Add Property") customAttributeWindow.grid_columnconfigure(1, weight=1) ttk.Label(customAttributeWindow, text='Property Name:', justify='left').grid(column=0, row=addPropRow, padx=5, pady=5, sticky='w') PropertyType = Entry(customAttributeWindow) PropertyType.grid(column=1, row=addPropRow, sticky='we') ttk.Label(customAttributeWindow, text='Property Value:', justify='left').grid(column=0, row=addPropRow + 1, padx=5, pady=5, sticky='w') PropertyValue = Entry(customAttributeWindow) PropertyValue.grid(column=1, row=addPropRow + 1, sticky='we') AddPropButton = ttk.Button(customAttributeWindow, text='Add Property') AddPropButton.grid(row=addPropRow + 2, column=1, padx=5, pady=10, sticky='w') currentItem = self.tree.focus() AddPropButton['command'] = lambda: self.POMTreeView.addProperty( self.tree, currentItem, customAttributeWindow) def updateObjectProperty(self, actionType=None): currObj = self.POMTreeView.updateObjectProperty( self.tree, self.treeValues, self.currentItem) self.currentItem = currObj.ObjectID Util.focusTree(self.tree, currObj.ObjectID) self.displayObjectProperties()
class BasicCalendar(Frame): def __init__(self,parent,month=None,mode=0): super().__init__(parent) self.month = month if self.month is None: print('Month is None') self.month = Month(Date.today().year,Date.today().month) self.mode=mode self.active=False self._container_days = [] self.clicked_day=None self.padx_frame = 20 self.pady_frame = 10 self.padx=1 self.pady=1 self.calendar_month_frame=Frame(parent) self.calendar_month_frame.grid(column=0,row=0, padx=self.padx_frame,pady=self.pady_frame,rowspan=25, sticky='N') #rowspan anpassen parent.grid_rowconfigure(0,minsize=100) #header self.button_former_month = Button(self.calendar_month_frame,text='<',command=self.goto_previous_month,relief='flat') self.month_heading = Label(self.calendar_month_frame,font=Fonts.hel_10) self.button_next_month = Button(self.calendar_month_frame,text='>',command=self.goto_next_month,relief='flat') self.button_former_month.grid(column=0,row=0,padx=self.padx,pady=self.pady,sticky='nsew') self.month_heading.grid(column=1,row=0,padx=self.padx,pady=self.pady,columnspan=5,sticky='nsew') self.button_next_month.grid(column=6,row=0,padx=self.padx,pady=self.pady,sticky='nsew') #days weekday_labels=[] for weekday in ['Mo','Di','Mi','Do','Fr','Sa','So']: weekday_labels.append(Label(self.calendar_month_frame, text=weekday, font=Fonts.hel_8_b)) for column,weekday in enumerate(weekday_labels): weekday.grid(column=column,row=1,padx=self.padx,pady=self.pady,sticky='nsew') self.draw_container_days() self.update_displayed_month() @property def get_clicked_day(self): for day in self.days: if day.was_double_clicked: return day.day return False @property def days(self): days=[] for week in self._container_days: for day in week: days.append(day) return days def goto_next_month(self): self.month = self.month.next() self.update_displayed_month() def goto_previous_month(self): self.month = self.month.previous() self.update_displayed_month() def update_displayed_month(self): self.month_heading['text']=f"{self.month.name} {self.month.year}" self.update_display_days(self.month.calendardays) def position_widget_list(self,widget_list, column=0): for row,widget in enumerate(widget_list): widget.grid(column=column, row=row, padx=self.padx, pady=self.pady,sticky='nsew') def draw_container_days(self): self._container_days = [] for x in range(6): line = [] for y in range(7): line.append(CalendarDay(self.calendar_month_frame,mode=self.mode)) self._container_days.append(line) self.position_container_days(self._container_days,self.calendar_month_frame,row_offset=2) def position_container_days(self,widget_list, master=None, row_offset=0): for row,widgetline in enumerate(widget_list): for column,widget in enumerate(widgetline): widget.grid(column=column, row=row+row_offset, padx=self.padx, pady=self.pady,sticky='nsew') if master: master.grid_rowconfigure(row,weight=1) def update_display_days(self,days): unpositioned_weeks=[] for container_week in self._container_days: unpositioned_week = [] for container_day in container_week: if days: container_day.change_day(days[0].number) container_day.change_textcolor(days[0].color) del days[0] if not container_day.grid_info(): unpositioned_week.append(container_day) else: container_day.grid_forget() unpositioned_weeks.append(unpositioned_week) self.position_container_days(unpositioned_weeks,self.calendar_month_frame,row_offset=self.calendar_month_frame.grid_size()[1]) def clear_days(self, startitem=0): count = 0 for slave in self.calendar_month_frame.grid_slaves(): if type(slave) == CalendarDay: count+=1 if count>startitem: slave.forget() def popup(self, event): self.menu_food.tk_popup(event.x_root, event.y_root) self.print_found_foods()
class PlatformFrame(Frame): '''Controls widgets relating to a particular Ad Platform''' def __init__(self, *args, name, row, init_states=None, **kwargs): super().__init__(*args, **kwargs) self.configure(bg='grey') self.columnconfigure((0, 1), weight=1) self.name = name # Whether it is needed to display additional Client ID column self.has_client_id = True if name in ['Facebook', 'MyTarget' ] else False self.DEL_BTN_COL = 10 # Frame with Platform Name self.name_frame = Frame(self) Label(self.name_frame, text=self.name, padx=2, pady=2).pack(padx=2, pady=2, expand=True) self.name_frame.grid(row=0, column=0, sticky='nsew', padx=2) # Frame with Campaign Rows self.rows_frame = Frame(self) ColumnRow(self.rows_frame, self.has_client_id) self.campaigns = OrderedDict() if init_states: for i, init_state in enumerate(init_states): self.campaigns[i + 1] = Row(self.rows_frame, i + 1, self.has_client_id, init_state=init_state) Button(self.rows_frame, text='Удалить', command=lambda x=i + 1: self.delete_row(x)).grid( row=i + 1, column=self.DEL_BTN_COL) Button(self.rows_frame, text=f'Добавить кампанию {self.name}', command=self.append_row).grid(row=1 + len(self.campaigns), column=0, columnspan=self.DEL_BTN_COL, sticky="nsew", pady=2) self.rows_frame.grid(row=0, column=1, sticky="nsew") # Gridding Frames immedeately on initialization self.grid(row=row, column=0, sticky="nsew", pady=2, padx=2) def append_row(self): ''' Creates data container and widgets for newly added campaign row ''' logger.info(f"Appending row to {self.name}") last_key = next(reversed(self.campaigns)) if self.campaigns else 0 columns, rows = self.rows_frame.grid_size() if rows - 1 == last_key + 1: self.rows_frame.grid_slaves(row=last_key + 1, column=0)[0].grid_forget() self.campaigns[last_key + 1] = Row(self.rows_frame, last_key + 1, self.has_client_id) Button(self.rows_frame, text='Удалить', command=lambda x=last_key + 1: self.delete_row(x)).grid( row=last_key + 1, column=self.DEL_BTN_COL) if rows - 1 == last_key + 1: Button(self.rows_frame, text=f'Добавить кампанию {self.name}', command=self.append_row).grid(row=last_key + 2, column=0, columnspan=self.DEL_BTN_COL, sticky="nsew", pady=2) def delete_row(self, row): ''' Deletes data container and widgets for unnecessary campaign row ''' logger.info(f"Deleting {row} row in {self.name} block") self.campaigns[row].forget() self.rows_frame.grid_slaves(row=row, column=self.DEL_BTN_COL)[0].grid_forget() self.campaigns.pop(row) def get(self): ''' Collects data from all Platforms rows ''' return {self.name: [self.campaigns[i].get() for i in self.campaigns]}
class StatisticsPanel(Frame): def __init__(self, parent): super().__init__(parent) self.__initView() def __initView(self): self.grid_columnconfigure(0, weight=1) self.grid_rowconfigure(0, weight=1) tabControl = Notebook(self) tabControl.grid(row=0, column=0, sticky='NSWE') ################################################################################################# self.playsByWeekdayFrame = Frame(tabControl) self.playsByWeekdayFrame.grid_columnconfigure(0, weight=1) self.playsByWeekdayFrame.grid_rowconfigure(0, weight=1) tabControl.add(self.playsByWeekdayFrame, text=PLAYS_BY_WEEKDAY) ################################################################################################# self.playsByHourFrame = Frame(tabControl) self.playsByHourFrame.grid_columnconfigure(0, weight=1) self.playsByHourFrame.grid_rowconfigure(0, weight=1) tabControl.add(self.playsByHourFrame, text=PLAYS_BY_HOUR) ################################################################################################# self.topMusicUsageInAlbumFrame = Frame(tabControl) self.topMusicUsageInAlbumFrame.grid_columnconfigure(0, weight=1) self.topMusicUsageInAlbumFrame.grid_rowconfigure(0, weight=1) tabControl.add(self.topMusicUsageInAlbumFrame, text=TOP_MUSIC_USAGE_IN_ALBUMS) def displayStatistics(self, statistics: Statistics): self.__attachPlaysByWeekDay(statistics.playsByWeekday.categories, statistics.playsByWeekday.values) self.__attachPlaysByHour(statistics.playsByHour.categories, statistics.playsByHour.values) self.__attachTopMusicUsage(statistics.musicUsageInAlbums.categories, statistics.musicUsageInAlbums.values) def __attachPlaysByWeekDay(self, categories, values): for widget in self.playsByWeekdayFrame.grid_slaves(): widget.grid_forget() fig = Figure(figsize=(5,4), dpi=100) fig.add_subplot(111).bar(categories, values) canvas = FigureCanvasTkAgg(fig, master=self.playsByWeekdayFrame) canvas.draw() canvas.get_tk_widget().grid(row=0, column=0, sticky='NSWE') def __attachPlaysByHour(self, categories, values): for widget in self.playsByHourFrame.grid_slaves(): widget.grid_forget() fig = Figure(figsize=(5,4), dpi=100) subplot = fig.add_subplot(111) subplot.bar(categories, values) subplot.set_xlim([-1, 24]) canvas = FigureCanvasTkAgg(fig, master=self.playsByHourFrame) canvas.draw() canvas.get_tk_widget().grid(row=0, column=0, sticky='NSWE') def __attachTopMusicUsage(self, categories, values): for widget in self.topMusicUsageInAlbumFrame.grid_slaves(): widget.grid_forget() fig = Figure(figsize=(5,4), dpi=100) subplot = fig.add_subplot(111) bar_plot = subplot.bar([i + 1 for i in range(len(categories))], values) for idx, rect in enumerate(bar_plot): height = rect.get_height() subplot.text(rect.get_x() + rect.get_width() / 2., 0.1, categories[idx], ha='center', va='bottom', rotation=90) canvas = FigureCanvasTkAgg(fig, master=self.topMusicUsageInAlbumFrame) canvas.draw() canvas.get_tk_widget().grid(row=0, column=0, sticky='NSWE')
class Dayview(Frame): ''' Todo's: * Breite fixieren * Tag mit Scrollbar versehen (siehe Suche) * food_drop_event ''' def __init__(self, parent, date): super().__init__(parent) self._date = date self._today = Day(self._date) locale.setlocale(locale.LC_ALL, "") #self.grid() self.dayframe = Frame(self, background=Fonts.action_bg) self.dayframe.grid(column=0, row=0, padx=Fonts.framedistance, pady=Fonts.framedistance) # headline self.headline = Frame( self.dayframe, background='gainsboro') #todo edit color and add to Fonts self.heading = Label(self.headline, text='', font=Fonts.hel_11_b, bg=self.headline['background']) self.btn_previous = Button(self.headline, text='<', command=self.previous_day, relief='flat', bg=self.headline['background']) self.btn_next = Button(self.headline, text='>', command=self.next_day, relief='flat', bg=self.headline['background']) self.headline.grid(row=0, column=0, padx=Fonts.table_cell_distance, pady=(Fonts.table_cell_distance, 0), sticky='nsew') #columnspan self.heading.grid(row=0, column=1, sticky='nsew') self.btn_previous.grid(row=0, column=0) self.btn_next.grid(row=0, column=2) self.headline.columnconfigure(1, weight=1) # table self.table_entries = Frame(self.dayframe, background=Fonts.table_bg) self.table_entries.grid(row=1, column=0, padx=Fonts.table_cell_distance, pady=(0, Fonts.table_cell_distance), sticky='nsew') header = ['Name', 'Menge', 'kCal'] for col, columnheader in enumerate(header): temp_label = Label( self.table_entries, text=columnheader, font=Fonts.hel_8_b ) #todo später eigene Klasse, um Filtern zu ermöglichen temp_label.grid(column=col, row=0, padx=1, pady=1, sticky='nswe') self.update_day_view() def add(self, foods): for food in foods: Amount(self, food) self._today.add(food) self.update_day_view() def update_day_view(self): self.heading['text'] = self._date.strftime('%A %d. %B %Y') self._today = Day(self._date) self.delete_former_food_entries() self.draw_food_entries() def draw_food_entries(self): for row, entry in enumerate(self._today.food_entries): temp_row = [] temp_row.append( Label(self.table_entries, text=entry.name, anchor='w')) temp_row.append(Label(self.table_entries, text=entry.amount)) temp_row.append(Label(self.table_entries, text=entry.calories)) self.draw_food_entry_line(temp_row, row + 1) sum_name = Label(self.table_entries, text='GESAMT', bg=self.headline['background']) sum_amount = Label(self.table_entries, text='', bg=self.headline['background']) sum_calories = Label(self.table_entries, text=self._today.calories, bg=self.headline['background']) self.draw_food_entry_line([sum_name, sum_amount, sum_calories], self.table_entries.grid_size()[1]) self.table_entries.grid_columnconfigure(1, weight=1) self.table_entries.grid_columnconfigure(2, weight=1) def draw_food_entry_line(self, widgetlist, row_offset): for col, widget in enumerate(widgetlist): widget.grid(column=col, row=row_offset, padx=1, pady=1, sticky='nswe') def next_day(self): self._date += timedelta(days=1) self.update_day_view() def previous_day(self): self._date -= timedelta(days=1) self.update_day_view() def delete_former_food_entries(self): for element in self.table_entries.grid_slaves(): if int(element.grid_info()["row"]) > 0: element.grid_forget()
class GUI(Tk): def __init__(self): Tk.__init__(self) self.user_frame = Frame() self.back_button = Button(self.user_frame, text="Back", command=self.back_to_home_gui) self.segmentation_button = Button(self.user_frame, text="Segmentation", command=self.segmentation_gui, height=2, width=10) self.analysis_button = Button(self.user_frame, text="Analysis", command=self.analysis_gui, height=2, width=10) self.progress = Progressbar(self.user_frame, orient=HORIZONTAL, length=200, mode='indeterminate') self.progress_label = Label(self.user_frame) # output folder self.output_path = StringVar("") self.output_label = Label(self.user_frame, text="please select " "output path") self.output_input = Entry(self.user_frame, textvariable=self.output_path, width=40) self.select_output = Button(self.user_frame, text=" ", command=self.select_output_folder) # original image self.file_path = StringVar("") self.file_label = Label(self.user_frame, text="please select the CT " "scan") self.file_input = Entry(self.user_frame, textvariable=self.file_path, width=40) self.select_file = Button( self.user_frame, text=" ", command=lambda: self.select_nifti_file(self.file_path)) # seeds self.seeds_path = StringVar("") self.seeds_label = Label(self.user_frame, text="please select the " "marking") self.seeds_input = Entry(self.user_frame, textvariable=self.seeds_path, width=40) self.select_seeds = Button( self.user_frame, text=" ", command=lambda: self.select_nifti_file(self.seeds_path)) # run buttons self.segmentation_run = Button(self.user_frame, text="Run " "Segmentation", command=self.run_segmentation) self.analysis_run = Button(self.user_frame, text="Run Analysis", command=self.run_analysis) self.default_background = self.output_input.cget("background") self.scaphoid = None self.radius = None self.initilize_gui() def __del__(self): del self.user_frame del self.back_button del self.segmentation_button del self.analysis_button del self.progress del self.progress_label del self.output_path del self.output_label del self.output_input del self.select_output del self.file_path del self.file_label del self.file_input del self.select_file del self.seeds_path del self.seeds_label del self.seeds_input del self.select_seeds del self.segmentation_run del self.analysis_run del self.default_background del self.scaphoid del self.radius def select_output_folder(self): """Select an output folder""" path = filedialog.askdirectory() self.output_path.set(path) self.output_input.config(background=self.default_background) del path def select_nifti_file(self, var): """Select a nifti file""" input_path = filedialog.askopenfilename() var.set(input_path) self.user_frame.grid_slaves( int(str(var)[-1]) + 1, 1)[0].config(background=self.default_background) del input_path def back_to_home_gui(self): """forgets the other gui and reload the home gui""" self.forget_non_home_gui() self.seeds_path.set("") self.initilize_gui() def initilize_gui(self): """Initial GUI""" self.title("Scaphoid Fracture Segmentation and analysis") self.user_frame.grid() self.segmentation_button.grid(row=0, column=0, padx=(100, 50), pady=(30, 30)) self.analysis_button.grid(row=0, column=1, padx=(50, 100), pady=(30, 30)) def segmentation_gui(self): """Initial GUI of the segmentation""" self.segmentation_button.grid_forget() self.analysis_button.grid_forget() self.back_button.grid(row=0, pady=(2, 2)) self.title("Scaphoid Fracture Segmentation") self.seeds_label.config(text="please select the marking") self.output_label.grid(row=1, column=0) self.output_input.grid(row=1, column=1) self.select_output.grid(row=1, column=2) self.file_label.grid(row=2, column=0) self.file_input.grid(row=2, column=1) self.select_file.grid(row=2, column=2) self.seeds_label.grid(row=3, column=0) self.seeds_input.grid(row=3, column=1) self.select_seeds.grid(row=3, column=2) self.segmentation_run.grid(row=4, columnspan=3, sticky=N + S + E + W) def analysis_gui(self): """Initial the analysis GUI""" self.segmentation_button.grid_forget() self.analysis_button.grid_forget() self.back_button.grid(row=0, pady=(2, 2)) self.title("Scaphoid Fracture analysis") self.seeds_label.config(text="please select the segmentation") self.output_label.grid(row=1, column=0) self.output_input.grid(row=1, column=1) self.select_output.grid(row=1, column=2) self.file_label.grid(row=2, column=0) self.file_input.grid(row=2, column=1) self.select_file.grid(row=2, column=2) self.seeds_label.grid(row=3, column=0) self.seeds_input.grid(row=3, column=1) self.select_seeds.grid(row=3, column=2) self.analysis_run.grid(row=4, columnspan=3, sticky=N + S + E + W) def forget_non_home_gui(self): """Forgets the grid of segmentation GUI""" collect() self.back_button.grid_forget() self.output_label.grid_forget() self.output_input.grid_forget() self.select_output.grid_forget() self.file_label.grid_forget() self.file_input.grid_forget() self.select_file.grid_forget() self.seeds_label.grid_forget() self.seeds_input.grid_forget() self.select_seeds.grid_forget() self.segmentation_run.grid_forget() self.analysis_run.grid_forget() def validate_data(self): """This function make sure that the data the user selected is valid""" valid = True if not exists(self.output_path.get()): valid = False self.output_input.config(background="tomato") file_path = self.file_path.get() seeds_path = self.seeds_path.get() if not (file_path.endswith(".nii.gz") and exists(file_path)): valid = False self.file_input.config(background="tomato") if not (seeds_path.endswith(".nii.gz") and exists(seeds_path)): valid = False self.seeds_input.config(background="tomato") return valid def run_segmentation(self): """Run the segmentation algorithm while updating the progressbar""" def threaded_prog(): self.progress_label.grid(row=5, column=0) self.progress.grid(row=5, column=1, columnspan=2) self.progress.start() self.progress_label.config(text="Running Segmentation") self.segmentation_process() self.progress.stop() self.progress_label.grid_forget() self.progress.grid_forget() self.back_to_home_gui() if self.validate_data(): Thread(target=threaded_prog).start() else: messagebox.showinfo("Error with the input", "Error with the input") def segmentation_process(self): """Creates the segmentation of the scaphoid and the fracture""" self.progress_label.config(text="Getting seeds") scaphoid_seeds, fracture_seeds = generate_scaphoid_seeds( self.seeds_path.get()) self.progress_label.config(text="Isolating The Scaphoid") self.scaphoid = Scaphoid(self.file_path.get(), scaphoid_seeds, fracture_seeds, 6) self.scaphoid.region_growing_from_input(SCAPHOID_COLOR) self.progress_label.config(text="Isolating The Fracture") self.scaphoid.segment_fracture_region_growing_mean( FRACTURE_COLOR, SCAPHOID_COLOR) self.progress_label.config(text="Saving Files") save_scaphoid_segmentations(self.scaphoid, self.output_path.get()) self.progress_label.config(text="Finishing") self.scaphoid = None del scaphoid_seeds, fracture_seeds messagebox.showinfo("Process Finished Successfully", "Process Finished Successfully") def run_analysis(self): """runs the analysis algorithm while updating the progress bar""" def threaded_prog(): self.progress_label.grid(row=5, column=0) self.progress.grid(row=5, column=1, columnspan=2) self.progress.start() self.progress_label.config(text="Running Analysis") self.analysis_process() self.progress.stop() self.progress_label.grid_forget() self.progress.grid_forget() self.back_to_home_gui() if self.validate_data(): Thread(target=threaded_prog).start() else: messagebox.showinfo("Error with the input", "Error with the input") def analysis_process(self): """The main analysis process""" self.progress_label.config(text="Getting the fracture") self.scaphoid = Scaphoid(self.file_path.get(), [], [], 1) self.scaphoid.load_bone_fracture(self.seeds_path.get()) self.scaphoid.load_fracture_from_bone_fracture() self.progress_label.config(text="Getting seeds") radius_seeds, capitate_seg = generate_analysis_seeds( self.seeds_path.get()) self.progress_label.config(text="Isolating The Radius") self.radius = Radius(self.file_path.get(), radius_seeds, 6) self.radius.region_growing_from_input(RADIUS_COLOR) self.progress_label.config(text="Getting PCA from radius") pca = self.radius.extract_PCA_components() self.progress_label.config(text="Dividing the bone") self.scaphoid.divide_bone_into_quarters(pca) self.progress_label.config(text="Dividing the fracture") self.scaphoid.divide_fracture_into_quarters(pca) self.progress_label.config(text="Getting geometric information") geo_features = self.scaphoid.get_geometric_features() geo_features["Angle between Radius and Capitate"] = \ str(create_direction_vector_for_2_points_cloud( capitate_seg, pca[0])) self.progress_label.config(text="Saving Files") save_analysis_segmentation(self.scaphoid, self.output_path.get()) file_name = str( abspath(self.scaphoid.get_original_path()).split("\\")[-1].split( ".")[0]) save_geometric_features(geo_features, self.output_path.get(), file_name) self.progress_label.config(text="Finishing") self.scaphoid = None self.radius = None del pca, geo_features messagebox.showinfo("Process Finished Successfully", "Process Finished Successfully")
class TicTacToe: """ The main widget for the game """ def __init__(self, master, field_size: Tuple[int, int], buttons_size: Tuple[int, int]): self.field = full((field_size[0], field_size[1]), '') self.steps = cycle(('X', '0')) # Create frame for Tic-Tac-Toe with step buttons self.frame = Frame(master) for i in range(0, self.field.shape[0]): for j in range(0, self.field.shape[1]): button = Button(self.frame, width=buttons_size[0], height=buttons_size[1], font=('helvetica', 15)) button.bind('<Button-1>', self.step) button.grid(row=i, column=j) self.game_state = Label() self.new_game_btn = Button(master, text="New game", width=20) self.new_game_btn['command'] = self.new_game self.frame.pack(padx=20, pady=20) self.new_game_btn.pack() self.game_state.pack() def step(self, event): """ Marks a step on the playing field and checks the field for winning steps """ btn = event.widget # If button is not clocked - commit step if btn['text'] == '': info = event.widget.grid_info() row = info['row'] column = info['column'] current_step = next(self.steps) btn['text'] = current_step self.field[row][column] = current_step # If win - stop game if is_win(self.field, current_step): self.game_state['text'] = f'{current_step} won!' self.stop_game() def new_game(self): """ Resets the game to its original state when the "New game" button is pressed """ # Reload steps iterator self.steps = cycle(('X', '0')) # Erase game field self.field.fill(None) # Activate buttons for btn in self.frame.grid_slaves(): btn.config(state="normal", text="") btn.bind('<Button-1>', self.step) # Erase information about winner self.game_state['text'] = '' def stop_game(self): """ Stops the game and makes the buttons inactive """ # Deactivate all buttons for btn in self.frame.grid_slaves(): btn.bind('<Button-1>', self.new_game) btn.config(state="disabled")
class ScrollableTable(Frame): def __init__(self, master, columns, column_weights=None, column_minwidths=None, height=500, minwidth=20, minheight=20, padx=5, pady=5, cell_font=None, cell_foreground="black", cell_background="white", cell_anchor=W, header_font=None, header_background="white", header_foreground="black", header_anchor=CENTER, bordercolor="#999999", innerborder=True, outerborder=True, stripped_rows=("#EEEEEE", "white"), on_change_data=None, mousewheel_speed=2, scroll_horizontally=False, scroll_vertically=True): outerborder_width = 1 if outerborder else 0 Frame.__init__(self, master, bd=0) self._cell_background = cell_background self._cell_foreground = cell_foreground self._cell_font = cell_font self._cell_anchor = cell_anchor self._stripped_rows = stripped_rows self._padx = padx self._pady = pady self._bordercolor = bordercolor self._innerborder_width = 1 if innerborder else 0 self._data_vars = [] self._columns = columns self._number_of_rows = 0 self._number_of_columns = len(columns) self.grid_columnconfigure(0, weight=1) self.grid_rowconfigure(1, weight=1) self._head = Frame(self, highlightbackground=bordercolor, highlightcolor=bordercolor, highlightthickness=outerborder_width, bd=0) self._head.grid(row=0, column=0, sticky=E + W) header_separator = False if outerborder else True for j in range(len(columns)): column_name = columns[j] header_cell = Header_Cell(self._head, text=column_name, borderwidth=self._innerborder_width, font=header_font, background=header_background, foreground=header_foreground, padx=padx, pady=pady, bordercolor=bordercolor, anchor=header_anchor, separator=header_separator) header_cell.grid(row=0, column=j, sticky=N + E + W + S) add_scrollbars = scroll_horizontally or scroll_vertically if add_scrollbars: if scroll_horizontally: xscrollbar = Scrollbar(self, orient=HORIZONTAL) xscrollbar.grid(row=2, column=0, sticky=E + W) else: xscrollbar = None if scroll_vertically: yscrollbar = Scrollbar(self, orient=VERTICAL) yscrollbar.grid(row=1, column=1, sticky=N + S) else: yscrollbar = None scrolling_area = Scrolling_Area( self, width=self._head.winfo_reqwidth(), height=height, scroll_horizontally=scroll_horizontally, xscrollbar=xscrollbar, scroll_vertically=scroll_vertically, yscrollbar=yscrollbar) scrolling_area.grid(row=1, column=0, sticky=E + W) self._body = Frame(scrolling_area.innerframe, highlightbackground=bordercolor, highlightcolor=bordercolor, highlightthickness=outerborder_width, bd=0) self._body.pack() def on_change_data(): scrolling_area.update_viewport() else: self._body = Frame(self, height=height, highlightbackground=bordercolor, highlightcolor=bordercolor, highlightthickness=outerborder_width, bd=0) self._body.grid(row=1, column=0, sticky=N + E + W + S) if column_weights is None: for j in range(len(columns)): self._body.grid_columnconfigure(j, weight=1) else: for j, weight in enumerate(column_weights): self._body.grid_columnconfigure(j, weight=weight) if column_minwidths is not None: for j, minwidth in enumerate(column_minwidths): if minwidth is None: header_cell = self._head.grid_slaves(row=0, column=j)[0] minwidth = header_cell.winfo_reqwidth() self._body.grid_columnconfigure(j, minsize=minwidth) else: for j in range(len(columns)): header_cell = self._head.grid_slaves(row=0, column=j)[0] minwidth = header_cell.winfo_reqwidth() self._body.grid_columnconfigure(j, minsize=minwidth) self._on_change_data = on_change_data def _append_n_rows(self, n): number_of_rows = self._number_of_rows number_of_columns = self._number_of_columns for i in range(number_of_rows, number_of_rows + n): list_of_vars = [] for j in range(number_of_columns): var = StringVar() list_of_vars.append(var) if self._stripped_rows: cell = Data_Cell(self._body, borderwidth=self._innerborder_width, variable=var, bordercolor=self._bordercolor, padx=self._padx, pady=self._pady, background=self._stripped_rows[i % 2], foreground=self._cell_foreground, font=self._cell_font, anchor=self._cell_anchor) else: cell = Data_Cell(self._body, borderwidth=self._innerborder_width, variable=var, bordercolor=self._bordercolor, padx=self._padx, pady=self._pady, background=self._cell_background, foreground=self._cell_foreground, font=self._cell_font, anchor=self._cell_anchor) cell.grid(row=i, column=j, sticky=N + E + W + S) self._data_vars.append(list_of_vars) if number_of_rows == 0: for j in range(self.number_of_columns): header_cell = self._head.grid_slaves(row=0, column=j)[0] data_cell = self._body.grid_slaves(row=0, column=j)[0] data_cell.bind("<Configure>", lambda event, header_cell=header_cell: header_cell.configure(width=event.width), add="+") self._number_of_rows += n def _pop_n_rows(self, n): number_of_rows = self._number_of_rows number_of_columns = self._number_of_columns for i in range(number_of_rows - n, number_of_rows): for j in range(number_of_columns): self._body.grid_slaves(row=i, column=j)[0].destroy() self._data_vars.pop() self._number_of_rows -= n def set_data(self, data): n = len(data) m = len(data[0]) number_of_rows = self._number_of_rows if number_of_rows > n: self._pop_n_rows(number_of_rows - n) elif number_of_rows < n: self._append_n_rows(n - number_of_rows) for i in range(n): for j in range(m): self._data_vars[i][j].set(data[i][j]) if self._on_change_data is not None: self._on_change_data() def get_data(self): number_of_rows = self._number_of_rows number_of_columns = self.number_of_columns data = [] for i in range(number_of_rows): row = [] row_of_vars = self._data_vars[i] for j in range(number_of_columns): cell_data = row_of_vars[j].get() row.append(cell_data) data.append(row) return data @property def number_of_rows(self): return self._number_of_rows @property def number_of_columns(self): return self._number_of_columns def row(self, index, data=None): if data is None: row = [] row_of_vars = self._data_vars[index] for j in range(self.number_of_columns): row.append(row_of_vars[j].get()) return row else: number_of_columns = self.number_of_columns if len(data) != number_of_columns: raise ValueError("data has no %d elements: %s" % (number_of_columns, data)) row_of_vars = self._data_vars[index] for j in range(number_of_columns): row_of_vars[index][j].set(data[j]) if self._on_change_data is not None: self._on_change_data() def column(self, index, data=None): number_of_rows = self._number_of_rows if data is None: column = [] for i in range(number_of_rows): column.append(self._data_vars[i][index].get()) return column else: if len(data) != number_of_rows: raise ValueError("data has no %d elements: %s" % (number_of_rows, data)) for i in range(number_of_columns): self._data_vars[i][index].set(data[i]) if self._on_change_data is not None: self._on_change_data() def clear(self): number_of_rows = self._number_of_rows number_of_columns = self._number_of_columns for i in range(number_of_rows): for j in range(number_of_columns): self._data_vars[i][j].set("") if self._on_change_data is not None: self._on_change_data() def delete_row(self, index): i = index while i < self._number_of_rows: row_of_vars_1 = self._data_vars[i] row_of_vars_2 = self._data_vars[i + 1] j = 0 while j < self.number_of_columns: row_of_vars_1[j].set(row_of_vars_2[j]) i += 1 self._pop_n_rows(1) if self._on_change_data is not None: self._on_change_data() def insert_row(self, data, index=END): self._append_n_rows(1) if index == END: index = self._number_of_rows - 1 i = self._number_of_rows - 1 while i > index: row_of_vars_1 = self._data_vars[i - 1] row_of_vars_2 = self._data_vars[i] j = 0 while j < self.number_of_columns: row_of_vars_2[j].set(row_of_vars_1[j]) j += 1 i -= 1 list_of_cell_vars = self._data_vars[index] for cell_var, cell_data in zip(list_of_cell_vars, data): cell_var.set(cell_data) if self._on_change_data is not None: self._on_change_data() def cell(self, row, column, data=None): """Get the value of a table cell""" if data is None: return self._data_vars[row][column].get() else: self._data_vars[row][column].set(data) if self._on_change_data is not None: self._on_change_data() def __getitem__(self, index): if isinstance(index, tuple): row, column = index return self.cell(row, column) else: raise Exception("Row and column indices are required") def __setitem__(self, index, value): if isinstance(index, tuple): row, column = index self.cell(row, column, value) else: raise Exception("Row and column indices are required") def on_change_data(self, callback): self._on_change_data = callback
class Input_Window(Frame): def __init__(self, parent): super(Input_Window, self).__init__(parent) self.parent = parent self.drag_n_drop = DragAndDrop(self) self.active = False self.grid(row=0, column=0) self.dragged_food = None self.category = '' # searchline self.searchline = Frame(self) self.search_entry = Entry(self.searchline) self.search_entry.bind('<Return>', self.search_triggered) self.category_box = ttk.Combobox( self.searchline, values=[ 'Früchte', 'Süssigkeiten', 'Getreideprodukte, Hülsenfrüchte und Kartoffeln', 'Gemüse', 'Brote, Flocken und Frühstückscerealien', 'Nüsse, Samen und Ölfrüchte', 'Gerichte', 'Fette und Öle', 'Fisch', 'Speziallebensmittel', 'Salzige Snacks', 'Eier', 'Milch und Milchprodukte', 'Fleisch- und Wurstwaren', 'Fleisch und Innereien', 'Alkoholhaltige Getränke', '' ]) #todo: Kategorien auslagern self.category_box.bind("<<ComboboxSelected>>", self.category_changed) #vlt doch noch auf Listbox umändern, dann könnte man mehrere Kategorien auswählen self.search_btn = Button( self.searchline, text='Suchen') #, command=self.search_triggered()) todo self.searchline.grid(row=0, column=0, padx=Fonts.framedistance, pady=Fonts.framedistance, sticky='w') self.search_entry.grid(row=0, column=0, padx=Fonts.framedistance, pady=0) self.category_box.grid(row=0, column=1, padx=Fonts.framedistance, pady=0) self.search_btn.grid(row=0, column=2, padx=Fonts.framedistance, pady=0) # input_navigation self.input_navigation = Frame(self) self.input_navigation_buttons = [] self.input_navigation_buttons.append( Button(self.input_navigation, text='Oft verwendete')) self.input_navigation_buttons.append( Button(self.input_navigation, text='Favouriten')) self.input_navigation_buttons.append( Button(self.input_navigation, text='Gestern', command=self.yesterday)) self.input_navigation_buttons.append( Button(self.input_navigation, text='Tag wählen', command=self.choose_day)) self.input_navigation.grid(row=1, column=0, padx=Fonts.framedistance, pady=Fonts.framedistance, sticky='w') for col, input_navigation_button in enumerate( self.input_navigation_buttons): input_navigation_button.grid(column=col, row=0, padx=Fonts.framedistance, pady=0, sticky='w') # found_food self.results = Frame(self) self.canvas = Canvas(self.results) self.scrollbar = ttk.Scrollbar(self.results, orient='vertical', command=self.canvas.yview) self.canvas.bind('<MouseWheel>', self.onMouseWheel) self.found_food_frame = Frame(self.canvas, background=Fonts.table_bg) self.found_food_frame.bind('<MouseWheel>', self.onMouseWheel) self.canvas.create_window(0, 0, anchor='nw', window=self.found_food_frame) self.canvas.config(yscrollcommand=self.scrollbar.set) self.found_food_header = Label(self.found_food_frame, text='Suchergebnisse:', anchor='w', font=Fonts.hel_11_b) self.results.grid(row=3, column=0, sticky='w', padx=Fonts.framedistance, pady=Fonts.framedistance) self.canvas.grid(row=0, column=0) self.found_food_header.grid(column=0, row=0, columnspan=3, sticky='wesn', padx=2, pady=2) # Dayview self.day_frame = Dayview(self, Date.today()) self.day_frame.grid(column=3, row=0, rowspan=3) self.drag_n_drop.add_target(self.day_frame) def onMouseWheel(self, event): self.canvas.yview("scroll", event.delta, "units") return def yesterday(self): yesterday = Day(Date.today() - timedelta(days=1)) self.found_foods = yesterday.food_entries self.create_new_found_food_labels() def choose_day(self): print('iwie Kalender hier instanzieren und Datum zurück geben') Calendar = BasicCalendar(self, mode=1) #while not Calendar.get_clicked_day: # time.sleep(5) # print('in loop') day = Calendar.get_clicked_day if not day: day = 1 date = Date(Calendar.month.year, Calendar.month.month, day) day = Day(date) self.found_foods = Day(date).food_entries self.create_new_found_food_labels() def category_changed(self, event): self.category = self.category_box.get() self.create_new_found_food_labels() def search_triggered(self, event): food_search = Search(Searchterm(self.search_entry.get())) self.found_foods = food_search.get_basicfood_objects self.create_new_found_food_labels() def del_old_found_foods(self): for label in self.found_food_frame.grid_slaves(): if int(label.grid_info()["row"]) > 0: label.grid_forget() def create_new_found_food_labels(self): self.del_old_found_foods() found_food_labels = [] for found_food in self.found_foods: if self.category: if not self.category == found_food.category: continue found_food_labels.append( FoodLabel(self.found_food_frame, found_food)) self.update_found_food_view(found_food_labels) def update_found_food_view(self, found_food_labels): self.del_old_found_foods() for row, food_label in enumerate(found_food_labels): food_label.grid(row=row + 1, column=0, padx=1, pady=1, sticky='wsen') self.drag_n_drop.add_dragable(food_label) for element in food_label.grid_slaves(): self.drag_n_drop.add_dragable(element) if len( self.found_foods ) > 10: #10 nur als bsp... todo: besseren wert überlegen, vlt skalierbar self.canvas.update_idletasks() self.canvas.configure(scrollregion=self.canvas.bbox('all')) self.scrollbar.grid(row=0, column=1, sticky='ns') else: self.scrollbar.grid_forget() def motion_active(self, event): self['cursor'] = 'fleur' def motion_stopped(self, event): self['cursor'] = 'left_ptr'