Skip to content

scan_selector

Treeview widget for folders

FolderScanSelector

Bases: _ScanSelector

Frame with TreeView for selection of folders

Source code in mmg_toolbox/tkguis/widgets/scan_selector.py
class FolderScanSelector(_ScanSelector):
    """Frame with TreeView for selection of folders"""

    def __init__(self, root: tk.Misc, initial_directory: str | None = None,
                 config: dict | None = None):
        logger.info('Creating FolderScanSelector')
        super().__init__(root, config)

        # Build widgets
        # self.ini_folderpath()
        self.ini_file_select()
        self.pack_treeview()  # pack treeview after ini_file_select
        self.tree.bind("<Double-1>", self.on_double_click)
        # self.tree.bind('<KeyPress>', self.on_key_press)
        self.tree.bind("<Button-3>", self.right_click_menu())

        # Populate
        if initial_directory:
            # run after mainloop starts to avoid thread issues
            root.after(0, self.add_folder, initial_directory)
        root.after(100, self.poll_files, None)

    "======================================================"
    "================= init functions ====================="
    "======================================================"

    def ini_folderpath(self):
        frm = ttk.Frame(self.root)
        frm.pack(side=tk.TOP, fill=tk.X)

        ttk.Button(frm, text='Add Folder', command=self.browse_folder).pack(side=tk.LEFT)
        ttk.Button(frm, text='Search', command=self.search_options).pack(side=tk.RIGHT)

    def ini_file_select(self):
        frm = ttk.Frame(self.root)
        frm.pack(side=tk.TOP, fill=tk.X)

        var = ttk.Entry(frm, textvariable=self.select_box, width=12)
        var.pack(side=tk.LEFT)
        var.bind("<Return>", self.select_from_box)
        var.bind('<KP_Enter>', self.select_from_box)
        ttk.Button(frm, text='-', command=self.select_box_decrease, width=2).pack(side=tk.LEFT)
        ttk.Button(frm, text='+', command=self.select_box_increase, width=2).pack(side=tk.LEFT)

        ttk.Button(frm, text='Search', command=self.search_options).pack(side=tk.RIGHT)
        ttk.Button(frm, text='Add Folder', command=self.browse_folder).pack(side=tk.RIGHT)

    "======================================================"
    "=============== populate functions ==================="
    "======================================================"

    def add_folder(self, folder_path: str):
        iid = self._add_row("", name=os.path.basename(folder_path), filepath=folder_path)
        files = list_files(folder_path, self.extension.get())
        self.populate_files(iid, *files)

    def update_files(self):
        """Check folders in the tree for new files"""
        for branch in self.tree.get_children():
            folder = self.tree.set(branch, 'filepath')
            files = list_files(folder, self.extension.get())
            for leaf in self.tree.get_children(branch):  # files
                if not self.tree.winfo_exists():
                    return
                file = self.tree.set(leaf, 'filepath')
                if file in files:
                    files.remove(file)

            logger.info(f"Updating {len(files)} in '{os.path.basename(folder)}'")
            logger.debug(f"update_files: Current thread: {current_thread()}, in process pid: {os.getpid()}")
            for file in reversed(files):
                if not self.tree.winfo_exists():
                    return
                iid = self._add_file(branch, file)
                if self.read_datasets.get():
                    self._add_data(iid)

    "======================================================"
    "============= navigation functions ==================="
    "======================================================"

    def browse_folder(self):
        filename, foldername = self.get_filepath()
        folder_directory = select_folder(initial_directory=foldername, parent=self.root)
        if folder_directory:
            self.add_folder(folder_directory)

    def on_select(self, event=None):
        if not self.tree.focus():
            return
        print(self.get_filepath())

    def on_double_click(self, event=None):
        """Action on double click of file"""
        if not self.tree.focus():
            return
        # iid = self.tree.focus()
        # item = self.tree.item(iid)
        self.open_nexus_treeview()

    "======================================================"
    "================= button functions ==================="
    "======================================================"

    def search_options(self):
        pass

on_double_click(event=None)

Action on double click of file

Source code in mmg_toolbox/tkguis/widgets/scan_selector.py
def on_double_click(self, event=None):
    """Action on double click of file"""
    if not self.tree.focus():
        return
    # iid = self.tree.focus()
    # item = self.tree.item(iid)
    self.open_nexus_treeview()

update_files()

Check folders in the tree for new files

Source code in mmg_toolbox/tkguis/widgets/scan_selector.py
def update_files(self):
    """Check folders in the tree for new files"""
    for branch in self.tree.get_children():
        folder = self.tree.set(branch, 'filepath')
        files = list_files(folder, self.extension.get())
        for leaf in self.tree.get_children(branch):  # files
            if not self.tree.winfo_exists():
                return
            file = self.tree.set(leaf, 'filepath')
            if file in files:
                files.remove(file)

        logger.info(f"Updating {len(files)} in '{os.path.basename(folder)}'")
        logger.debug(f"update_files: Current thread: {current_thread()}, in process pid: {os.getpid()}")
        for file in reversed(files):
            if not self.tree.winfo_exists():
                return
            iid = self._add_file(branch, file)
            if self.read_datasets.get():
                self._add_data(iid)

ScanViewer

Bases: _ScanSelector

Frame with TreeView for selection of scans

Source code in mmg_toolbox/tkguis/widgets/scan_selector.py
class ScanViewer(_ScanSelector):
    """Frame with TreeView for selection of scans"""

    def __init__(self, root: tk.Misc, *scan_files: str, config: dict | None = None, button_name: str = 'Close'):
        logger.info('Creating ScanViewer')
        super().__init__(root, config)
        self.pack_treeview()
        self.file_list = scan_files
        self.output_files = []

        self.tree.bind("<Button-3>", self.right_click_menu())

        ttk.Button(self.root, text=button_name, command=self.select_scans).pack(side=tk.TOP, fill=tk.X, expand=tk.YES)

        self.populate_files("", *scan_files)

    def update_metadata(self, event=None):
        """Update dataset values column for hdf files under open folders"""

        def fn():
            for file in self.tree.get_children():  # files
                if not self.tree.winfo_exists():
                    return
                self._add_data(file)

        th = Thread(target=fn)
        th.daemon = True  # runs thread in the background, outside mainloop, allowing python to close
        th.start()

    def select_scans(self):
        self.output_files = [
            self.tree.set(iid, column='filepath')
            for iid in self.tree.selection()
        ]
        self.root.destroy()

    def show(self):
        self.root.wait_window()
        return self.output_files

update_metadata(event=None)

Update dataset values column for hdf files under open folders

Source code in mmg_toolbox/tkguis/widgets/scan_selector.py
def update_metadata(self, event=None):
    """Update dataset values column for hdf files under open folders"""

    def fn():
        for file in self.tree.get_children():  # files
            if not self.tree.winfo_exists():
                return
            self._add_data(file)

    th = Thread(target=fn)
    th.daemon = True  # runs thread in the background, outside mainloop, allowing python to close
    th.start()