Exemple #1
0
class HDF5Viewer:
    ''' HD5Viewer
        ======================
        David Miller, 2020
        The University of Sheffield 2020
        
        Presents a graphical means for users to view and inspect the contents of a HDF5 file.
        
        The user points the GUI to a HDF5 file by clicking on the 'Open' button, travelling to a folder and either
        double clicking on a file or selecting a file and clicking the 'Open' button.

        Once the file is selected, the user clicks the 'Scan' button which opens the file in read-only mode in
        a context manager and iterates through the file. The GUI populates a treeview in the GUI with the names of
        objects, their type, shape and data type (datasets only) in a way that mirrows the structures of the file.
        If the type column describes the type of object inside the HDF5 file. If the object is a Group, the contents
        under the shape column represents the number of items stored one level under it. If the object is a Dataset,
        the shape represents the shape of the array stored in the dataset. The data type column is only updated for
        datasets and is the type of data stored in the dataset.

        This class keeps control of the specified file for the minimum amount of time only accessing it for the
        duration of scan_file.

        If the user double clicks on a dataset, a DataViewer GUI is opened in another window. This attempts to display
        the dataset, choosing the appropriate plots based on the shape of the dataset.

        Methods:
        --------------------------
        open_file(self):
            Opens a file dialog for the user to select the HDF5 file they want to inspect.
            
        explore_group(self,item,parent):
            Iterates through the objects stored under item and updates the treeview with the information it finds
            under the node/leaft with the ID parent. If it finds a Group while iterating, explore_group is called
            with the newly discovered Group passed as the item to explore and the parent node to update under.
            Used in scan_file.

        scan_file(self):
            Attempts to open the file specified by the user. If a file path has yet to be specified it returns.
            If it's successful in opening the file, it iterates through its contents updating the treeview with the=
            information it finds. It uses the function explore_group to iterate through Groups it finds under root.
    '''
        
    def __init__(self,master):
        self.master = master
        # set title of image
        master.title("HDF5 File Viewer")

        ## initialize internal variables used
        # set current file as blank
        self.curr_file = "/"
        self.status = StringVar()
        
        ## initialize widgets
        # status label indicating progress or errors
        self.status_label = Label(master,textvariable=self.status)
        self.status.set("Waiting for filename...")
        # button to scan target HDF5 file
        self.scan_button = Button(master,text="Scan File",command=self.scan_file,padx=2)
        # button to chose hdf5 file
        self.openfile_button = Button(master,text="Open File",command=self.open_file,padx=2)
        # box to display current filename
        self.name_display = Entry(master,text="Current filename")
        ## setup tree headings
        # tree view for file layout
        self.file_tree = Treeview(master,columns=("htype","shape","dtype"),show="tree")
        # add double click handler
        # <Double-1> double left click handler
        self.file_tree.bind("<Double-1>",self.create_viewer)
        # dimensions of the columns
        self.file_tree.column("htype",width=200,anchor=CENTER)
        self.file_tree.column("shape",width=200,anchor=CENTER)
        self.file_tree.column("dtype",width=200,anchor=CENTER)
        # text to display in headings
        self.file_tree.heading("htype",text="Item Type")
        self.file_tree.heading("shape",text="Shape")
        self.file_tree.heading("dtype",text="Data Type")
        self.file_tree['show']='headings'
        
        ## add scrollbar for treeview
        # define scrollbar and set the action associated with moving the scrollbar to changing
        # the yview of the tree
        self.tree_scroll=Scrollbar(master,orient="vertical",command=self.file_tree.yview)
        self.file_tree.configure(yscrollcommand=self.tree_scroll)
        
        # set grid layout for widgets using grid
        self.status_label.grid(columnspan=3,row=0)
        self.file_tree.grid(column=0,row=2,columnspan=3,sticky='nswe')
        self.scan_button.grid(column=0,row=1,sticky='we',padx=10)
        self.openfile_button.grid(column=1,row=1,sticky='we',padx=10)
        self.name_display.grid(column=2,row=1,sticky='we',padx=10)
        self.tree_scroll.grid(column=3,row=2,sticky='ns')
        # set weight parameters for control how the elements are resized when the user changes the window size
        master.columnconfigure(0,weight=1)
        master.columnconfigure(1,weight=1)
        master.columnconfigure(2,weight=1)
        master.columnconfigure(3,weight=1)
        master.rowconfigure(0,weight=1)
        master.rowconfigure(1,weight=1)
        master.rowconfigure(2,weight=1)
        master.rowconfigure(3,weight=1)
        # finish any idle tasks and set the minimum size of the window to cur
        master.update_idletasks()
        master.after_idle(lambda: master.minsize(master.winfo_width(), master.winfo_height()))
        
    # function for the user to select the HDF5 file to explore
    # opens file dialog for user to explore
    def open_file(self):
        self.status.set("Waiting for user to select file...")
        # open dialog to search for hdf5 file
        self.curr_file = filedialog.askopenfilename(initialdir=os.path.dirname(self.curr_file),title="Select HDF5 file to inspect",filetypes=[("HDF5 files","*.hdf5")])
        self.name_display.delete(0,END)
        self.name_display.insert(0,self.curr_file)
        try:
            with open(self.curr_file,'r') as file:
                self.status.set("Successfully opened target file")
        except OSError as err:
            self.status.set(err)
            
    # function to explore HDF5 group and update tree
    # if it finds another HDF5 group it calls the functions to explore that group
    def explore_group(self,item,parent):
        self.status.set(f"Exploring {item.name}")
        #print("Exploring {}...".format(item.name))
        # iterate through items
        for v in item.values():
            #print(v.name,str(type(v)))
            # if it's a dataset, update shape entry with shape of dataset
            if isinstance(v,h5py.Dataset):
                self.file_tree.insert(parent,'end',text=v.name,values=(str(type(v)),str(v.shape),str(v.dtype)),open=True)
                self.file_tree['show']='tree headings'
            # if it's a group, call function to investiage it passing last group as parent to add new nodes to
            elif isinstance(v,h5py.Group):
                pkn = self.file_tree.insert(parent,'end',text=v.name,values=(str(type(v)),f"{(len(v.keys()),)}"),open=True)
                self.explore_group(v,pkn)           
    # explores target hdf5 file and displays the the keys of each entry
    # it the entry is a group, then it calls explore_group to explore further
    def scan_file(self):
        # if target file is set
        if self.curr_file != "/":
            # clear tree
            self.file_tree.delete(*self.file_tree.get_children())
            # open file in read mode and iterate through values
            with h5py.File(self.curr_file,'r') as file:
                for v in file.values():
                    # if it's a dataset, update shape entry with shape of dataset
                    if isinstance(v,h5py.Dataset):
                        self.file_tree.insert('','end',text=v.name,values=(str(type(v)),str(v.shape),str(v.dtype)),open=True)
                    # if it's a group, call function to investiage it
                    elif isinstance(v,h5py.Group):
                        pkn = self.file_tree.insert('','end',text=v.name,values=(str(type(v)),f"{(len(v.keys()),)}"),open=True)
                        self.explore_group(v,pkn)
            # update tree display
            self.file_tree['show']='tree headings'
            self.status.set(f"Finished scanning .../{self.curr_file[self.curr_file.rfind('/')+1:]}")
            # finish idle tasks and set minimum window size to final window size
            self.master.update_idletasks()
            self.master.after_idle(lambda: self.master.minsize(self.master.winfo_width(), self.master.winfo_height()))
        else:
            self.status.set("No fime set!")
    def create_viewer(self,event):
        if self.curr_file != "/":
            # get the item selected
            iid = self.file_tree.identify('item',event.x,event.y)
            # get the values of the item to check if a dataset or group was selected
            if 'Dataset' in self.file_tree.item(iid,"values")[0]:
                self.status.set(f"Creating view for {self.file_tree.item(iid,'text')}")
                # create new child window
                t = Toplevel()
                # initialize window inside new child window
                self.data_viewer = DataViewer(t,self.file_tree.item(iid,"text"),self.curr_file)
Exemple #2
0
class Cerberus:
    def __init__(self, master, root):
        self.exportToCSV = False
        self.versionApp, self.key, self.salt = self.initApp()

        self.key = cerberusCryptography.getMasterKey()
        self.cipher_suite = Fernet(self.key)

        self.master = master
        self.master.title('Cerberus')
        self.windowWidth = 1060
        self.windowHeight = 450
        self.screenWidth = self.master.winfo_screenwidth()
        self.screenHeight = self.master.winfo_screenheight()
        self.positionRight = int(self.screenWidth / 2 - self.windowWidth / 2)
        self.positionDown = int(self.screenHeight / 3 - self.windowHeight / 2)
        self.master.geometry("{}x{}+{}+{}".format(self.windowWidth,
                                                  self.windowHeight,
                                                  self.positionRight,
                                                  self.positionDown))

        self.img = PhotoImage(data=icons.getAppIcon())
        self.master.wm_iconphoto(True, self.img)

        self.master.resizable(0, 0)

        self.menubar = Menu(master)
        filemenu = Menu(self.menubar, tearoff=0)

        self.menubar.add_cascade(label="Cerberus", menu=filemenu)
        self.addIcon = PhotoImage(data=icons.getAddIcon())
        filemenu.add_command(label="Εισαγωγή Υπηρεσίας",
                             image=self.addIcon,
                             compound='left',
                             command=self.getAddNewServiceForm)
        self.editIcon = PhotoImage(data=icons.getEditIcon())
        filemenu.add_command(label="Επεξεργασία Υπηρεσίας",
                             image=self.editIcon,
                             compound='left',
                             command=self.getEditServiceForm)
        self.deleteIcon = PhotoImage(data=icons.getDeleteIcon())
        filemenu.add_command(label="Διαγραφή Υπηρεσίας",
                             image=self.deleteIcon,
                             compound='left',
                             command=self.deleteService)
        filemenu.add_separator()
        self.excelIcon = PhotoImage(data=icons.getExcelIcon())
        filemenu.add_command(label="Εξαγωγή σε Excel",
                             image=self.excelIcon,
                             compound='left',
                             command=self.checkPasswordToExportToCSV)
        filemenu.add_separator()
        self.exitIcon = PhotoImage(data=icons.getExitIcon())
        filemenu.add_command(label="Έξοδος",
                             image=self.exitIcon,
                             compound='left',
                             command=self.exitApp)

        settingsMenu = Menu(self.menubar, tearoff=0)
        self.menubar.add_cascade(label="Ρυθμίσεις", menu=settingsMenu)
        self.settingsIcon = PhotoImage(data=icons.getSettingsIcon())
        settingsMenu.add_command(label="Επεξεργασία Στοιχείων",
                                 image=self.settingsIcon,
                                 compound='left')
        #command=self.getSettingsForm)

        aboutMenu = Menu(self.menubar, tearoff=0)
        self.menubar.add_cascade(label="Βοήθεια", menu=aboutMenu)
        self.infoIcon = PhotoImage(data=icons.getInfoIcon())
        aboutMenu.add_command(label="Περί",
                              image=self.infoIcon,
                              compound='left',
                              command=self.getAboutAppForm)

        self.master.config(menu=self.menubar)

        self.copyIcon = PhotoImage(data=icons.getCopyIcon())
        self.popup = Menu(root, tearoff=0)
        self.popup.add_command(label=" Αντιγραφή Email",
                               image=self.copyIcon,
                               compound='left',
                               command=self.copyEmail)
        self.popup.add_command(label=" Αντιγραφή Username",
                               image=self.copyIcon,
                               compound='left',
                               command=self.copyUsername)
        self.popup.add_command(label=" Αντιγραφή Κωδικού",
                               image=self.copyIcon,
                               compound='left',
                               command=self.copyPasswd)
        self.popup.add_command(label=" Αντιγραφή ID",
                               image=self.copyIcon,
                               compound='left',
                               command=self.copyID)
        self.popup.add_separator()
        self.popup.add_command(label=" Επεξεργασία Υπηρεσίας",
                               image=self.editIcon,
                               compound='left',
                               command=self.getEditServiceForm)
        self.popup.add_command(label=" Διαγραφή Υπηρεσίας",
                               image=self.deleteIcon,
                               compound='left',
                               command=self.deleteService)
        self.popup.add_separator()
        self.popup.add_command(label=" Έξοδος",
                               image=self.exitIcon,
                               compound='left',
                               command=self.exitApp)

        self.frame = Frame(self.master,
                           background="white",
                           borderwidth=1,
                           relief="sunken",
                           highlightthickness=1)
        self.frame.pack(side="top", fill="x", padx=4, pady=4)

        self.search = StringVar()

        self.searchEntry = Entry(self.frame,
                                 textvariable=self.search,
                                 borderwidth=0,
                                 highlightthickness=0,
                                 background="white")
        self.searchEntry.insert(0, 'Αναζήτηση Υπηρεσίας')
        self.searchEntry['fg'] = 'grey'
        self.search.trace(
            "w",
            lambda name, index, mode, sv=self.search: self.searchService())

        self.searchEntry.image = PhotoImage(data=icons.getSearchIcon())
        imageLabel = Label(self.frame, image=self.searchEntry.image)
        imageLabel.pack(side="left")
        imageLabel['bg'] = 'white'

        self.searchEntry.pack(side="left", fill="both", expand=True)

        # Fix BUG with Treeview colors in Python3.7
        def fixed_map(option):
            return [
                elm for elm in style.map('Treeview', query_opt=option)
                if elm[:2] != ('!disabled', '!selected')
            ]

        style = ttk.Style(root)
        style.map('Treeview',
                  foreground=fixed_map('foreground'),
                  background=fixed_map('background'))
        # Fix BUG with Treeview colors in Python3.7

        self.table = Treeview(self.master)
        self.table['show'] = 'headings'
        self.table['columns'] = ('Services', 'email', 'username', 'passwd',
                                 'id', 'category', 'url', 'ID')
        self.table["displaycolumns"] = ('Services', 'email', 'username',
                                        'passwd', 'id', 'category', 'url')

        for col in self.table['columns']:
            self.table.heading(
                col, command=lambda c=col: self.sortby(self.table, c, 0))

        self.table.heading('Services', text='Services')
        self.table.column('Services', anchor='center', width=200)

        self.table.heading('email', text='Email')
        self.table.column('email', anchor='center', width=200)

        self.table.heading('username', text='Username')
        self.table.column('username', anchor='center', width=100)

        self.table.heading('passwd', text='Password')
        self.table.column('passwd', anchor='center', width=100)

        self.table.heading('url', text='URL')
        self.table.column('url', anchor='center', width=120)

        self.table.heading('id', text='ID')
        self.table.column('id', anchor='center', width=100)

        self.table.heading('category', text='Category')
        self.table.column('category', anchor='center', width=100)

        self.table.heading('ID', text='ID')
        self.table.column('ID', anchor='center', width=200)

        self.table.tag_configure('oddrow', background='#e6eef2')
        self.table.tag_configure('evenrow', background='#b3cfdd')
        self.table.tag_configure('focus', background='#c6b6b4')
        self.last_focus = None
        self.last_focus_tag = None
        self.table.focus()
        self.table.pack(fill=BOTH, expand=1)
        self.table.bind("<<TreeviewSelect>>", self.onTableSelect)
        self.table.bind("<ButtonRelease-1>", self.openURLService)
        self.table.bind("<Motion>", self.changePointerOnHover)
        self.table.bind("<Button-3>", self.popupMenu)
        self.searchEntry.bind("<FocusIn>", self.foc_in)
        self.searchEntry.bind("<FocusOut>", self.foc_out)
        self.popup.bind("<FocusOut>", self.popupFocusOut)
        self.master.protocol("WM_DELETE_WINDOW", self.exitApp)

        self.loadTable(self)

        self.master.bind("<Escape>", self.exitApp)

    def popupFocusOut(self, event=None):
        self.popup.unpost()

    def foc_in(self, *args):
        if self.search.get() == 'Αναζήτηση Υπηρεσίας':
            self.searchEntry.delete('0', 'end')
            self.searchEntry['fg'] = 'black'

    def foc_out(self, *args):
        if not self.search.get():
            self.searchEntry.insert(0, 'Αναζήτηση Υπηρεσίας')
            self.searchEntry['fg'] = 'grey'
            self.loadTable(self)

    def changePointerOnHover(self, event):
        _iid = self.table.identify_row(event.y)

        if _iid != self.last_focus:
            if self.last_focus:
                self.table.item(self.last_focus, tags=[self.last_focus_tag])

            self.last_focus_tag = self.table.item(_iid, "tag")
            self.table.item(_iid, tags=['focus'])
            self.last_focus = _iid

        curItem = self.table.item(self.table.identify('item', event.x,
                                                      event.y))
        if curItem['values'] != '':
            col = self.table.identify_column(event.x)
            url = curItem['values'][int(col[-1]) - 1]

            if col[-1] == "7" and url != '---':
                self.master.config(cursor="hand2")
            else:
                self.master.config(cursor="")

    def openURLService(self, event):
        curItem = self.table.item(self.table.focus())
        col = self.table.identify_column(event.x)
        region = self.table.identify("region", event.x, event.y)

        if col[-1] == "7" and region != 'heading':
            url = curItem['values'][int(col[-1]) - 1]
            if url != '---':
                webbrowser.open_new_tab('http://' + str(url))

    def onTableSelect(self, event):
        for item in self.table.selection():
            item_text = self.table.item(item, "values")
            print(item_text[0])

    def getSelectedService(self, event):
        for item in self.table.selection():
            selectedRow = self.table.item(item, "value")
            return selectedRow

    def initApp(self):
        print("Initialize Cerberus App")
        try:
            conn = sqlite3.connect('cerberus.db')
        except sqlite3.Error as e:
            print(e)

        cur = conn.cursor()
        cur.execute(
            "SELECT version, masterToken, salt FROM cerberusParameters")
        row = cur.fetchone()
        cur.close()

        return row

    def copyEmail(self):
        for item in self.table.selection():
            item_text = self.table.item(item, "values")
            self.master.clipboard_clear()
            root.clipboard_append(item_text[1])

    def copyUsername(self):
        for item in self.table.selection():
            item_text = self.table.item(item, "values")
            self.master.clipboard_clear()
            root.clipboard_append(item_text[2])

    def copyPasswd(self):
        for item in self.table.selection():
            item_text = self.table.item(item, "values")
            self.master.clipboard_clear()
            root.clipboard_append(item_text[3])

    def copyID(self):
        for item in self.table.selection():
            item_text = self.table.item(item, "values")
            self.master.clipboard_clear()
            root.clipboard_append(item_text[4])

    def searchService(self):
        try:
            conn = sqlite3.connect('cerberus.db')
        except sqlite3.Error as e:
            print(e)

        cur = conn.cursor()

        if self.search.get() == 'Αναζήτηση Υπηρεσίας':
            pass
        elif self.search.get():
            cur.execute(
                "SELECT id, name, email, username, password, value, category, url FROM service WHERE name LIKE '%"
                + self.search.get() + "%' or name LIKE '%" +
                self.search.get().upper() +
                "%'")  # ('%'+self.search.get()+'%',),'Α')
        elif not self.search.get():
            cur.execute(
                "SELECT id, name, email, username, password, value, category, url FROM service "
            )

        rows = cur.fetchall()
        cur.close()

        for k in self.table.get_children():
            self.table.delete(k)

        i = 1
        for row in rows:
            if (i % 2) == 0:
                tag = "oddrow"
            else:
                tag = "evenrow"

            self.table.insert(
                '',
                'end',
                values=(
                    row[1],
                    self.cipher_suite.decrypt(row[2]).decode("utf-8").split(),
                    self.cipher_suite.decrypt(row[3]).decode("utf-8").split(),
                    self.cipher_suite.decrypt(row[4]).decode("utf-8").split(),
                    self.cipher_suite.decrypt(row[5]).decode("utf-8").split(),
                    self.cipher_suite.decrypt(row[6]).decode("utf-8").split(),
                    self.cipher_suite.decrypt(row[7]).decode("utf-8").split(),
                    row[0]),
                tags=tag)
            i = i + 1

    @staticmethod
    def exitApp(event=None):
        root.destroy()

    @staticmethod
    def getAboutAppForm():
        import aboutApp
        aboutApp.aboutApp()

    def getAddNewServiceForm(self):
        self.master.withdraw()
        import addNewServiceForm
        addNewServiceForm.addNewServiceForm(self)

    def getEditServiceForm(self):
        service = self.getSelectedService(self)

        if service is None:
            messagebox.showerror(
                "Μήνυμα Σφάλματος",
                "Παρακαλώ επιλέξτε την Υπηρεσία που θέλετε να Επεξεργαστείτε.")
        else:
            self.master.withdraw()
            import editServiceForm
            editServiceForm.editServiceForm(self, service)

    def getSettingsForm(self):
        import settingsForm
        settingsForm.settingsForm()

    def sortby(self, tree, col, descending):
        data = [(tree.set(child, col), child)
                for child in tree.get_children('')]
        data.sort(reverse=descending)
        for ix, item in enumerate(data):
            if (ix % 2) == 0:
                tag = "evenrow"
            else:
                tag = "oddrow"
            tree.move(item[1], '', ix)
            tree.item(item[1], tags=tag)
        # switch the heading so that it will sort in the opposite direction
        tree.heading(
            col,
            command=lambda x=col: self.sortby(tree, col, int(not descending)))

    @staticmethod
    def loadTable(self):
        try:
            conn = sqlite3.connect('cerberus.db')
        except sqlite3.Error as e:
            print(e)

        cur = conn.cursor()
        cur.execute(
            "SELECT id, name, email, username, password, value, category, url value FROM service"
        )

        rows = cur.fetchall()

        for row in self.table.get_children():
            self.table.delete(row)

        i = 1
        for row in rows:
            if (i % 2) == 0:
                tag = "oddrow"
            else:
                tag = "evenrow"

            self.table.insert(
                '',
                'end',
                values=(
                    row[1],
                    self.cipher_suite.decrypt(row[2]).decode("utf-8").split(),
                    self.cipher_suite.decrypt(row[3]).decode("utf-8").split(),
                    self.cipher_suite.decrypt(row[4]).decode("utf-8").split(),
                    self.cipher_suite.decrypt(row[5]).decode("utf-8").split(),
                    self.cipher_suite.decrypt(row[6]).decode("utf-8").split(),
                    self.cipher_suite.decrypt(row[7]).decode("utf-8").split(),
                    row[0]),
                tags=tag)

            i = i + 1

        conn.close()

        self.last_focus = None
        self.table.selection()

    def deleteService(self):
        service = self.getSelectedService(self)

        if service is None:
            messagebox.showerror(
                "Μήνυμα Σφάλματος",
                "Παρακαλώ επιλέξτε την Υπηρεσία που θέλετε να Διαγράξετε.")
        else:
            msgBox = messagebox.askquestion(
                'Διαγραφή: {}'.format(service[0]),
                'Είστε σίγουρος ότι θέλετε να διαγράψετε την Υπηρεσία: '
                '{}'
                ' ?'.format(service[0]),
                icon='warning')
            if msgBox == 'yes':
                try:
                    conn = sqlite3.connect('cerberus.db')
                except sqlite3.Error as e:
                    print(e)
                sql = 'DELETE FROM service WHERE id=?'
                cur = conn.cursor()
                cur.execute(sql, (service[-1], ))
                conn.commit()
                conn.close()
                self.loadTable(self)

    def popupMenu(self, event):
        serviceId = self.table.identify_row(event.y)
        if serviceId:
            self.table.selection_set(serviceId)
            try:
                self.popup.tk_popup(event.x_root, event.y_root)
            finally:
                self.popup.grab_release()

    def checkPasswordToExportToCSV(self):
        print("Check Password..")
        import logInForm
        self.master.withdraw()
        logInForm.logIn(self)

    @staticmethod
    def exportToCSV():
        print("Export Services to CSV...")
        try:
            conn = sqlite3.connect('cerberus.db')
        except sqlite3.Error as e:
            print(e)

        key = cerberusCryptography.getMasterKey()
        cipher_suite = Fernet(key)

        cur = conn.cursor()
        cur.execute(
            "SELECT category, name, email, username, password, value, url value FROM service"
        )

        rows = cur.fetchall()

        csvData = [[
            'Κατηγορία',
            'Υπηρεσία',
            'Email',
            'Όνομα Χρήστη',
            'Κωδικός',
            'ID',
            'URL',
        ]]

        for row in rows:
            csvData = csvData + [[
                cipher_suite.decrypt(row[0]).decode("utf-8").split(),
                cipher_suite.decrypt(row[1]).decode("utf-8").split(),
                cipher_suite.decrypt(row[2]).decode("utf-8").split(),
                cipher_suite.decrypt(row[3]).decode("utf-8").split(),
                cipher_suite.decrypt(row[4]).decode("utf-8").split(),
                cipher_suite.decrypt(row[5]).decode("utf-8").split(),
                cipher_suite.decrypt(row[6]).decode("utf-8").split(),
            ]]

        try:
            homeFolder = str(Path.home())
            filePath = filedialog.asksaveasfile(
                initialdir=homeFolder,
                initialfile='cerberus.csv',
                title="Επιλογή Αρχείου",
                filetypes=(("csv files", "*.csv"), ("all files", "*.*")))
            if filePath:
                try:
                    with open(filePath.name, 'w') as csvFile:
                        csvFile = csv.writer(csvFile, delimiter='\t')
                        csvFile.writerows(csvData)
                    messagebox.showinfo(
                        "Μήνυμα Επιτυχίας",
                        "Το αρχείο αποθηκέυτηκε με Επιτυχία στην τοποθεσία {}."
                        .format(filePath.name))
                except Exception as e:
                    messagebox.showerror(
                        "Μήνυμα Σφάλματος",
                        "Δεν ήταν δυνατή η Εξαγωγή του αρχείου.")
        except Exception as e:
            print(e)
            messagebox.showerror("Μήνυμα Σφάλματος",
                                 "Δεν ήταν δυνατή η Εξαγωγή του αρχείου.")
Exemple #3
0
class ListWidget:
    def __init__(self, command=None):
        self.topic_list = None
        outsideFrame = Frame()
        outsideFrame.config(padx=10, pady=10)
        outsideFrame.grid(row=1, column=0, sticky="wn")

        self.frame = LabelFrame(outsideFrame, text="Topics")
        self.frame.config(font=("Arial", 14), padx=10, pady=10)
        self.frame.grid(row=0, column=0)
        self._command = command

        self.topic_filter_input = Entry(self.frame, width=33)
        self.topic_filter_input.grid(row=0, column=0, pady=10)
        self.topic_filter_input.bind("<KeyRelease>", self.filter_topic)

        treeFrame = Frame(self.frame)
        treeFrame.grid(row=1, column=0)
        self.tree = Treeview(treeFrame, style="Custom.Treeview")
        self.tree.heading('#0', text='Topic')
        self.tree.pack()
        self.tree.bind("<ButtonRelease-1>", self.OnClick)
        self.tree.tag_configure('odd', background='#f9f9f9')
        self.tree.tag_configure('even', background='#DFDFDF')

        scroll_bar = Scrollbar(self.frame,
                               orient="vertical",
                               command=self.tree.yview)
        scroll_bar.grid(row=1, column=1, sticky='nsew')
        self.tree.configure(yscrollcommand=scroll_bar.set)

    def filter_topic(self, *args):
        inputed_topic = self.topic_filter_input.get()
        list = filter(lambda k: inputed_topic.lower() in k.lower(),
                      self.topic_list)
        self.prepare_list(list)

    def OnClick(self, event):
        item = self.tree.identify('item', event.x, event.y)
        if item == '':
            return
        selectedItem = self.tree.item(item, "text")
        self._command(selectedItem)

    def prepare_list(self, sorted_topic_list):
        self.clean()
        for topic in sorted_topic_list:
            self.insert(topic)

    def insert(self, line):
        type = 'even'
        if (len(self.tree.get_children()) % 2 == 1):
            type = 'odd'
        self.tree.insert("", "end", text=line, tags=(type, ))

    def clean(self):
        for i in self.tree.get_children():
            self.tree.delete(i)

    def destroy(self):
        self.frame.destroy()