コード例 #1
0
def init_progress(progress_widget: ttk.Progressbar, max_level: int):
    '''Initialize a progress bar.
    Arguments:
        progress_widget {ttk.Progressbar} -- The progress bar to be
            initialized.
        max_level {int} -- The maximum level for the progress bar.
    '''
    progress_widget.configure(maximum=max_level)
    progress_widget["value"] = 0
    progress_widget.update_idletasks()
コード例 #2
0
class Loading_class:
    def __init__(self):
        self.top = Tk()
        self.top.geometry("791x376+268+88")
        self.top.title("BANKING SOLUTIONS")
        self.top.configure(background="#FFFFCC")

        self.Label1 = Label(self.top)
        self.Label1.place(relx=0.24, rely=0.0, height=82, width=443)
        self.Label1.configure(background="#FFFFCC")
        img1 = ImageTk.PhotoImage(Image.open("images/rahul2.jpg"))
        self.Label1.configure(image=img1)

        self.v1 = IntVar()  #it will hold the current value of progress bar

        self.Label2 = Label(self.top)
        self.Label2.place(relx=0.08, rely=0.43, height=41, width=374)
        self.Label2.configure(background="#FFFFCC")
        self.Label2.configure(width=374)

        self.pb = Progressbar(self.top, orient=HORIZONTAL)
        self.pb.config(mode='determinate', maximum=100)
        self.pb.config(variable=self.v1)

        self.pb.place(relx=0.08,
                      rely=0.56,
                      relwidth=0.87,
                      relheight=0.0,
                      height=22)
        self.pb.configure(length="690")
        tup = (101, )
        self.t1 = threading.Thread(target=self.move, args=tup, name='first')
        self.t1.start()
        self.top.after(500, self.check)
        self.top.mainloop()

    def move(self, a):
        for i in range(a):
            self.v1.set(i)
            self.Label2.configure(text='LOADING ' + str(self.v1.get()) + '%')
            time.sleep(.05)

    def check(self):
        if self.v1.get() != 100:
            self.top.after(500, self.check)
        else:
            self.top.destroy()
            o1 = Login.Login_Class()


#obj = Loading_class()
コード例 #3
0
class load_class:
    def __init__(self):
        self.rt = Tk()
        self.rt.title("YOUR BANKING SOLUTIONS")
        self.rt.config(background="#ccffcc")
        self.rt.geometry("1145x500+160+100")
        #self.rt.geometry("920x450+200+180")

        self.l1 = Label(self.rt)
        self.l1.place(relx=0.25, rely=0.0, height=200, width=650)
        self.l1.config(background="#ccffcc")
        img1 = ImageTk.PhotoImage(Image.open("bank_images/load.gif"))
        self.l1.configure(image=img1)

        self.label1 = Label(self.rt)
        self.label1.place(relx=0.26, rely=0.29, height=200, width=650)
        self.label1.config(background="#ccffcc")
        imgq = ImageTk.PhotoImage(Image.open("bank_images/l.gif"))
        self.label1.configure(image=imgq)

        self.v1 = IntVar()  #has the current value of progressbar

        self.l2 = Label(self.rt)
        self.l2.place(relx=0.06, rely=0.71, height=40, width=380)
        self.l2.configure(background="#ccffcc")
        self.l2.configure(width=380)

        self.pb = Progressbar(self.rt, orient=HORIZONTAL)
        self.pb.configure(mode='determinate', maximum=100)
        self.pb.configure(variable=self.v1)

        self.pb.place(relx=0.08,
                      rely=0.80,
                      relwidth=0.90,
                      relheight=0.0,
                      height=49)
        self.pb.configure(length="650")

        tup = (101, )
        self.t1 = threading.Thread(target=self.move, args=tup, name='first')
        self.t1.start()
        self.rt.after(500, self.check)
        self.rt.mainloop()

    def move(self, a):
        for i in range(a):
            self.v1.set(i)
            self.l2.configure(text="Loading " + str(self.v1.get()) + "%")
            time.sleep(0.01)

    def check(self):
        if self.v1.get() != 100:
            self.rt.after(500, self.check)
        else:
            self.rt.destroy()
            object = Login_new.Login_Class()


#ob=load_class()
コード例 #4
0
class StatusBar(Frame):
    def __init__(self, master, progressMax=100, **kwargs):
        Frame.__init__(self, master, **kwargs)

        self.label = Label(self, text="Ready...")
        self.label.pack(anchor=Tkc.W)

        self.progressVar = IntVar()
        self.progress = Progressbar(self,
                                    mode='determinate',
                                    maximum=abs(progressMax),
                                    length="150",
                                    variable=self.progressVar)

    def showText(self, message):
        self.label.configure(text=message)
        self.progress.stop()
        self.progress.pack_forget()
        self.label.pack(anchor=Tkc.W)

    def showProgress(self):
        self.progress.configure(mode='determinate')
        self.label.pack_forget()
        self.progress.pack(anchor=Tkc.W)
        self.update_idletasks()

    def setProgress(self, value):
        self.progressVar.set(value)
        self.update_idletasks()

    def setProgressMax(self, value):
        self.progress.configure(maximum=abs(value))

    def showActivity(self):
        self.progress.configure(mode='indeterminate')
        self.progress.start()
        self.showProgress()
コード例 #5
0
class waitWindowProgressBar(Toplevel):
    def __init__(self, parent=None):
        """
        Initialises the calculate wait window. Waits for other processes to finish, then packs everything. 
        messages, setup_dataset and stop are the functions that change the layout of the frame.
        """
        super().__init__(parent)
        self.title("Setting up.......")
        #self.attributes("-topmost", True)
        self.pb_val = IntVar(self)
        self.pb_val.set(0)
        self.pb = Progressbar(self, length=400, variable=self.pb_val)
        self.pb.pack(pady=20, padx=20)
        self.pb.configure(maximum=10)
        self.labeltext = StringVar()
        self.labeltext.set("Waiting for other process.....")
        self.waiting_label = Label(self, textvariable=self.labeltext)
        self.waiting_label.configure(anchor="center")
        self.waiting_label.pack(pady=20, padx=20, fill='both', expand=True)
        self.stopbutton = Button(self,
                                 text="Stop!",
                                 compound="bottom",
                                 command=self.stop)
        self.stopbutton.pack(side="left", fill="x", expand=True)
        self.stopflag = 0
        self.update()

    def stop(self):
        """
        Sets the stopflag to 1, thus stopping the calculation.
        """
        self.stopflag = 1

    def setup_dataset(self, dataset):
        """
        Sets up the calculation wait window for the different stages of calculation.
        """
        self.dataset = dataset
        self.title("Calculating Dataset %s" % os.path.basename(dataset.path))
        self.waiting_label.pack(pady=20, padx=20)
        self.update()

    def errormessage(self, dataset):
        messagebox.showwarning(
            "Invalid parameters",
            "Dataset %s was skipped in the computation because of invalid parameters. Please configure Cut-off frequency and / or Filter type."
            % os.path.basename(dataset.path))

    def return_function(self):
        """
        Returns two functions for further use in the model.
        """
        @ri.rternalize
        def messages(i, r, each):
            """
            Messages function given to the R environment.
            Gives feedback on the state of the Monte-Carlo simulation. 
            """
            self.pb.step()
            count = np.asarray((i, r))
            if (count[0] == -1):
                self.title("Computation for Dataset %s" %
                           os.path.basename(self.dataset.path))
                self.pb.pack(pady=20, padx=20)
                self.pb_val.set(0)
                self.stopbutton["state"] = "normal"
                if self.dataset.metadata[
                        "Method"] == "HILDE-Homogeneous" or self.dataset.metadata[
                            "Method"] == "HILDE-Heterogeneous":
                    self.pb.configure(maximum=int(
                        self.dataset.metadata["Repetitions_Hilde"]))
                else:
                    self.pb.configure(
                        maximum=int(self.dataset.metadata["Repetitions"]))
                self.labeltext.set(
                    "Currently computing quantile for Dataset:\n%s \n Press Stop! button to stop computation for current dataset."
                    % os.path.basename(self.dataset.path))
            if (count[0] == -2):
                self.pb.pack_forget()
                self.labeltext.set(
                    "Calculating fit for Dataset:\n%s\nThis computation cannot be interrupted and may take a few minutes."
                    % os.path.basename(self.dataset.path))
                self.stopbutton["state"] = "disabled"
                self.waiting_label.pack(pady=20, padx=20)
            self.update()
            return self.stopflag

        return messages, self.setup_dataset, self.errormessage
コード例 #6
0
class RedditApp(Frame):
    def __init__(self, master=None):
        """
        Initialize the main application Frame and load it with other widgets.
        """
        super().__init__(master)
        self.root = master
        self.pack()
        self.setup_main_frame()
        self.create_menubar()
        self.create_widgets()

    def setup_main_frame(self):
        self.root.resizable(0, 0)
        self.root.wm_title('(sub)Reddit Downloader')

    def create_menubar(self):
        menubar = Menu(self.root)
        menubar.add_command(label='About', command=AboutWindow.about)
        menubar.add_command(label='Exit', command=self.root.quit)
        self.root.config(menu=menubar)

    def create_widgets(self):
        """
        Create widgets to populate the applications frame.
        """
        # URL, Pages, Destination
        paths_frame = Frame(self)

        lbl_url = Label(paths_frame, text='URL:')
        lbl_pages = Label(paths_frame, text='Pages:')
        lbl_destination = Label(paths_frame, text='Destination:')

        lbl_pages_help = Label(paths_frame,
                               text='(Leave zero to crawl all pages)')

        self.url_var = StringVar()
        self.pages_var = IntVar()
        self.destination_var = StringVar()

        url = Entry(paths_frame, textvariable=self.url_var)
        pages = Entry(paths_frame, textvariable=self.pages_var)
        destination = Entry(paths_frame, textvariable=self.destination_var)

        btn_chooser = Button(paths_frame,
                             text='Destination',
                             command=self.choose_directory)

        pad_x = 5
        pad_y = 7

        r = 0
        lbl_url.grid(row=r, column=0, sticky=E, padx=pad_x, pady=pad_y)
        url.grid(row=r, column=1)

        r += 1
        lbl_pages.grid(row=r, column=0, sticky=E)
        pages.grid(row=r, column=1, padx=pad_x, pady=pad_y)
        lbl_pages_help.grid(row=r, column=2)

        r += 1
        lbl_destination.grid(row=r, column=0, sticky=E)
        destination.grid(row=r, column=1, padx=pad_x, pady=pad_y)
        btn_chooser.grid(row=r, column=2, sticky=E + W)

        paths_frame.pack(side=TOP, padx=10, pady=10)

        # Download button
        download_frame = Frame(self)

        self.btn_download = Button(download_frame,
                                   text='Download',
                                   command=self.download_reddit)
        self.btn_download.pack(padx=10, pady=10)

        download_frame.pack(side=TOP)

        # Progress label
        progress_info = Frame(self)

        self.lbl_progress_info = Label(progress_info, text='')
        self.lbl_progress_info.pack(padx=10, pady=10)

        progress_info.pack(side=TOP)

    def add_progress_bar(self):
        """
        Add progress bar to root frame.
        """
        self.progress_frame = Frame(self)

        self.progress_bar = Progressbar(self.progress_frame,
                                        orient='horizontal',
                                        length=400,
                                        mode='indeterminate')
        self.progress_bar.pack(padx=10, pady=10)
        self.progress_frame.pack(side=TOP)

    def remove_progress_bar(self):
        """
        Remove progress bare from root frame.
        """
        self.progress_bar.destroy()
        self.progress_frame.destroy()

    def change_progress_label(self, text):
        """
        Change text of progress bar label.
        """
        self.lbl_progress_info.configure(text=text, fg='red', font=(font.BOLD))

    def choose_directory(self):
        """
        Update the destination path entry filed with the chosen path.
        """
        destination_path = filedialog.askdirectory(initialdir='~')
        self.destination_var.set(destination_path)

    def download_reddit(self):
        """
        Download images from subreddit.
        """
        try:
            self.reddit = Reddit(self.url_var.get(), self.pages_var.get())
        except RedditException:
            messagebox.showerror('Error', 'Please input valid link')
            return
        except TclError:
            messagebox.showerror('Error', 'Please input only whole numbers')
            return
        except Exception as e:
            print(e)
            messagebox.showerror('Error', 'Something went wrong with Reddit.')
            return

        try:
            self.downloader = Downloader(self.reddit,
                                         self.destination_var.get())
        except DownloaderException:
            messagebox.showerror('Error', 'Invalid download path')
            return
        except Exception as e:
            print(e)
            messagebox.showerror('Error',
                                 'Something went wrong with Downloader.')
            return

        self.btn_download.configure(text='Cancel',
                                    command=self.cancel_download)
        self.change_progress_label('Fetching data...')

        self.add_progress_bar()
        self.progress_bar.start()
        self.queue = Queue()

        self.reddit_listener = RedditListener()
        self.reddit.register(self.reddit_listener)

        self.downloader_listener = DownloaderListener()
        self.downloader.register(self.downloader_listener)

        DownloadThread(self.queue, self.reddit, self.downloader).start()
        self.root.after(100, self.process_queue)

    def process_queue(self):
        """
        Stop the progress bar if the thread has yielded control. If download was
        canceled, re-enable download button only after thread has yielded control.
        Reset progress bar and download button, and unregister all listeners when
        downloading is finished or canceled.
        """
        try:
            msg = self.queue.get(0)

            if self.btn_download['text'] == 'Cancel':
                # self.reddit.fetch = True
                # self.downloader.downloading = True

                self.btn_download.configure(text='Download',
                                            command=self.download_reddit)
                self.remove_progress_bar()
                self.change_progress_label('Download finished.')

            if self.btn_download['state'] == DISABLED:
                self.btn_download.configure(state=NORMAL)

            self.reddit.unregister()
            self.downloader.unregister()

            print(msg)
        except queue.Empty:
            if getattr(self.reddit_listener, 'fetched', None):
                print(self.reddit_listener.maximum)

                self.progress_bar.configure(mode='determinate')
                self.progress_bar['value'] = 0
                self.progress_bar['maximum'] = self.reddit_listener.maximum

                self.reddit_listener.fetched = False

            if (getattr(self.downloader_listener, 'currently_at', None)
                    and self.downloader.downloading):
                print(self.downloader_listener.currently_at)
                self.progress_bar[
                    'value'] = self.downloader_listener.currently_at

            self.root.after(100, self.process_queue)

    def cancel_download(self):
        """
        Cancel fetching or downloading process.
        """
        self.reddit.fetch = False
        self.downloader.downloading = False
        self.btn_download.configure(text='Download',
                                    command=self.download_reddit)
        self.remove_progress_bar()
        self.change_progress_label('Download canceled.')
        self.btn_download.configure(state=DISABLED)
コード例 #7
0
ファイル: sync.py プロジェクト: j4321/FolderSync
class Sync(Tk):
    """FolderSync main window."""
    def __init__(self):
        Tk.__init__(self, className='FolderSync')
        self.title("FolderSync")
        self.geometry("%ix%i" %
                      (self.winfo_screenwidth(), self.winfo_screenheight()))
        self.protocol("WM_DELETE_WINDOW", self.quitter)
        self.icon = PhotoImage(master=self, file=IM_ICON)
        self.iconphoto(True, self.icon)
        self.rowconfigure(2, weight=1)
        self.columnconfigure(0, weight=1)

        # --- icons
        self.img_about = PhotoImage(master=self, file=IM_ABOUT)
        self.img_open = PhotoImage(master=self, file=IM_OPEN)
        self.img_plus = PhotoImage(master=self, file=IM_PLUS)
        self.img_moins = PhotoImage(master=self, file=IM_MOINS)
        self.img_sync = PhotoImage(master=self, file=IM_SYNC)
        self.img_prev = PhotoImage(master=self, file=IM_PREV)
        self.img_expand = PhotoImage(master=self, file=IM_EXPAND)
        self.img_collapse = PhotoImage(master=self, file=IM_COLLAPSE)

        self.original = ""
        self.sauvegarde = ""
        # list of files / folders to delete before starting the copy because
        # they are not of the same type on the original and the backup
        self.pb_chemins = []
        self.err_copie = False
        self.err_supp = False

        # --- init log files
        l = [f for f in listdir(PATH) if match(r"foldersync[0-9]+.pid", f)]
        nbs = []
        for f in l:
            with open(join(PATH, f)) as fich:
                old_pid = fich.read().strip()
            if exists("/proc/%s" % old_pid):
                nbs.append(int(search(r"[0-9]+", f).group()))
            else:
                remove(join(PATH, f))
        if not nbs:
            i = 0
        else:
            nbs.sort()
            i = 0
            while i in nbs:
                i += 1
        self.pidfile = PID_FILE % i
        open(self.pidfile, 'w').write(str(getpid()))

        self.log_copie = LOG_COPIE % i
        self.log_supp = LOG_SUPP % i

        self.logger_copie = setup_logger("copie", self.log_copie)
        self.logger_supp = setup_logger("supp", self.log_supp)
        date = datetime.now().strftime('%d/%m/%Y %H:%M')
        self.logger_copie.info("\n###  %s  ###\n" % date)
        self.logger_supp.info("\n###  %s  ###\n" % date)

        # --- filenames and extensions that will not be copied
        exclude_list = split(r'(?<!\\) ',
                             CONFIG.get("Defaults", "exclude_copie"))
        self.exclude_names = []
        self.exclude_ext = []
        for elt in exclude_list:
            if elt:
                if elt[:2] == "*.":
                    self.exclude_ext.append(elt[1:])
                else:
                    self.exclude_names.append(elt.replace("\ ", " "))

        # --- paths that will not be deleted
        self.exclude_path_supp = [
            ch.replace("\ ", " ") for ch in split(
                r'(?<!\\) ', CONFIG.get("Defaults", "exclude_supp")) if ch
        ]
        #        while "" in self.exclude_path_supp:
        #            self.exclude_path_supp.remove("")

        self.q_copie = Queue()
        self.q_supp = Queue()
        # True if a copy / deletion is running
        self.is_running_copie = False
        self.is_running_supp = False

        self.style = Style(self)
        self.style.theme_use("clam")
        self.style.configure("TProgressbar",
                             troughcolor='lightgray',
                             background='#387EF5',
                             lightcolor="#5D95F5",
                             darkcolor="#2758AB")
        self.style.map("TProgressbar",
                       lightcolor=[("disabled", "white")],
                       darkcolor=[("disabled", "gray")])
        self.style.configure("folder.TButton", padding=0)
        # --- menu
        self.menu = Menu(self, tearoff=False)
        self.configure(menu=self.menu)

        # -------- recents
        self.menu_recent = Menu(self.menu, tearoff=False)
        if RECENT:
            for ch_o, ch_s in RECENT:
                self.menu_recent.add_command(
                    label="%s -> %s" % (ch_o, ch_s),
                    command=lambda o=ch_o, s=ch_s: self.open(o, s))
        else:
            self.menu.entryconfigure(0, state="disabled")

        # -------- favorites
        self.menu_fav = Menu(self.menu, tearoff=False)
        self.menu_fav_del = Menu(self.menu_fav, tearoff=False)
        self.menu_fav.add_command(label=_("Add"),
                                  image=self.img_plus,
                                  compound="left",
                                  command=self.add_fav)
        self.menu_fav.add_cascade(label=_("Remove"),
                                  image=self.img_moins,
                                  compound="left",
                                  menu=self.menu_fav_del)
        for ch_o, ch_s in FAVORIS:
            label = "%s -> %s" % (ch_o, ch_s)
            self.menu_fav.add_command(
                label=label, command=lambda o=ch_o, s=ch_s: self.open(o, s))
            self.menu_fav_del.add_command(
                label=label, command=lambda nom=label: self.del_fav(nom))
        if not FAVORIS:
            self.menu_fav.entryconfigure(1, state="disabled")

        # -------- log files
        menu_log = Menu(self.menu, tearoff=False)
        menu_log.add_command(label=_("Copy"), command=self.open_log_copie)
        menu_log.add_command(label=_("Removal"),
                             command=self.open_log_suppression)

        # -------- settings
        menu_params = Menu(self.menu, tearoff=False)
        self.copy_links = BooleanVar(self,
                                     value=CONFIG.getboolean(
                                         "Defaults", "copy_links"))
        self.show_size = BooleanVar(self,
                                    value=CONFIG.getboolean(
                                        "Defaults", "show_size"))
        menu_params.add_checkbutton(label=_("Copy links"),
                                    variable=self.copy_links,
                                    command=self.toggle_copy_links)
        menu_params.add_checkbutton(label=_("Show total size"),
                                    variable=self.show_size,
                                    command=self.toggle_show_size)
        self.langue = StringVar(self, CONFIG.get("Defaults", "language"))
        menu_lang = Menu(menu_params, tearoff=False)
        menu_lang.add_radiobutton(label="English",
                                  value="en",
                                  variable=self.langue,
                                  command=self.change_language)
        menu_lang.add_radiobutton(label="Français",
                                  value="fr",
                                  variable=self.langue,
                                  command=self.change_language)
        menu_params.add_cascade(label=_("Language"), menu=menu_lang)
        menu_params.add_command(label=_("Exclude from copy"),
                                command=self.exclusion_copie)
        menu_params.add_command(label=_("Exclude from removal"),
                                command=self.exclusion_supp)

        self.menu.add_cascade(label=_("Recents"), menu=self.menu_recent)
        self.menu.add_cascade(label=_("Favorites"), menu=self.menu_fav)
        self.menu.add_cascade(label=_("Log"), menu=menu_log)
        self.menu.add_cascade(label=_("Settings"), menu=menu_params)
        self.menu.add_command(image=self.img_prev,
                              compound="center",
                              command=self.list_files_to_sync)
        self.menu.add_command(image=self.img_sync,
                              compound="center",
                              state="disabled",
                              command=self.synchronise)
        self.menu.add_command(image=self.img_about,
                              compound="center",
                              command=lambda: About(self))
        # --- tooltips
        wrapper = TooltipMenuWrapper(self.menu)
        wrapper.add_tooltip(4, _('Preview'))
        wrapper.add_tooltip(5, _('Sync'))
        wrapper.add_tooltip(6, _('About'))

        # --- path selection
        frame_paths = Frame(self)
        frame_paths.grid(row=0, sticky="ew", pady=(10, 0))
        frame_paths.columnconfigure(0, weight=1)
        frame_paths.columnconfigure(1, weight=1)
        f1 = Frame(frame_paths, height=26)
        f2 = Frame(frame_paths, height=26)
        f1.grid(row=0, column=0, sticky="ew")
        f2.grid(row=0, column=1, sticky="ew")
        f1.grid_propagate(False)
        f2.grid_propagate(False)
        f1.columnconfigure(1, weight=1)
        f2.columnconfigure(1, weight=1)

        # -------- path to original
        Label(f1, text=_("Original")).grid(row=0, column=0, padx=(10, 4))
        f11 = Frame(f1)
        f11.grid(row=0, column=1, sticky="nsew", padx=(4, 0))
        self.entry_orig = Entry(f11)
        self.entry_orig.place(x=1, y=0, bordermode='outside', relwidth=1)
        self.b_open_orig = Button(f1,
                                  image=self.img_open,
                                  style="folder.TButton",
                                  command=self.open_orig)
        self.b_open_orig.grid(row=0, column=2, padx=(0, 7))
        # -------- path to backup
        Label(f2, text=_("Backup")).grid(row=0, column=0, padx=(8, 4))
        f22 = Frame(f2)
        f22.grid(row=0, column=1, sticky="nsew", padx=(4, 0))
        self.entry_sauve = Entry(f22)
        self.entry_sauve.place(x=1, y=0, bordermode='outside', relwidth=1)
        self.b_open_sauve = Button(f2,
                                   image=self.img_open,
                                   width=2,
                                   style="folder.TButton",
                                   command=self.open_sauve)
        self.b_open_sauve.grid(row=0, column=5, padx=(0, 10))

        paned = PanedWindow(self, orient='horizontal')
        paned.grid(row=2, sticky="eswn")
        paned.rowconfigure(0, weight=1)
        paned.columnconfigure(1, weight=1)
        paned.columnconfigure(0, weight=1)

        # --- left side
        frame_left = Frame(paned)
        paned.add(frame_left, weight=1)
        frame_left.rowconfigure(3, weight=1)
        frame_left.columnconfigure(0, weight=1)

        # -------- files to copy
        f_left = Frame(frame_left)
        f_left.columnconfigure(2, weight=1)
        f_left.grid(row=2,
                    columnspan=2,
                    pady=(4, 2),
                    padx=(10, 4),
                    sticky="ew")

        Label(f_left, text=_("To copy")).grid(row=0, column=2)
        frame_copie = Frame(frame_left)
        frame_copie.rowconfigure(0, weight=1)
        frame_copie.columnconfigure(0, weight=1)
        frame_copie.grid(row=3,
                         column=0,
                         sticky="eswn",
                         columnspan=2,
                         pady=(2, 4),
                         padx=(10, 4))
        self.tree_copie = CheckboxTreeview(frame_copie,
                                           selectmode='none',
                                           show='tree')
        self.b_expand_copie = Button(f_left,
                                     image=self.img_expand,
                                     style="folder.TButton",
                                     command=self.tree_copie.expand_all)
        TooltipWrapper(self.b_expand_copie, text=_("Expand all"))
        self.b_expand_copie.grid(row=0, column=0)
        self.b_expand_copie.state(("disabled", ))
        self.b_collapse_copie = Button(f_left,
                                       image=self.img_collapse,
                                       style="folder.TButton",
                                       command=self.tree_copie.collapse_all)
        TooltipWrapper(self.b_collapse_copie, text=_("Collapse all"))
        self.b_collapse_copie.grid(row=0, column=1, padx=4)
        self.b_collapse_copie.state(("disabled", ))
        self.tree_copie.tag_configure("warning", foreground="red")
        self.tree_copie.tag_configure("link",
                                      font="tkDefaultFont 9 italic",
                                      foreground="blue")
        self.tree_copie.tag_bind("warning", "<Button-1>", self.show_warning)
        self.tree_copie.grid(row=0, column=0, sticky="eswn")
        self.scroll_y_copie = Scrollbar(frame_copie,
                                        orient="vertical",
                                        command=self.tree_copie.yview)
        self.scroll_y_copie.grid(row=0, column=1, sticky="ns")
        self.scroll_x_copie = Scrollbar(frame_copie,
                                        orient="horizontal",
                                        command=self.tree_copie.xview)
        self.scroll_x_copie.grid(row=1, column=0, sticky="ew")
        self.tree_copie.configure(yscrollcommand=self.scroll_y_copie.set,
                                  xscrollcommand=self.scroll_x_copie.set)
        self.pbar_copie = Progressbar(frame_left,
                                      orient="horizontal",
                                      mode="determinate")
        self.pbar_copie.grid(row=4,
                             columnspan=2,
                             sticky="ew",
                             padx=(10, 4),
                             pady=4)
        self.pbar_copie.state(("disabled", ))

        # --- right side
        frame_right = Frame(paned)
        paned.add(frame_right, weight=1)
        frame_right.rowconfigure(3, weight=1)
        frame_right.columnconfigure(0, weight=1)

        # -------- files to delete
        f_right = Frame(frame_right)
        f_right.columnconfigure(2, weight=1)
        f_right.grid(row=2,
                     columnspan=2,
                     pady=(4, 2),
                     padx=(4, 10),
                     sticky="ew")
        Label(f_right, text=_("To remove")).grid(row=0, column=2)
        frame_supp = Frame(frame_right)
        frame_supp.rowconfigure(0, weight=1)
        frame_supp.columnconfigure(0, weight=1)
        frame_supp.grid(row=3,
                        columnspan=2,
                        sticky="eswn",
                        pady=(2, 4),
                        padx=(4, 10))
        self.tree_supp = CheckboxTreeview(frame_supp,
                                          selectmode='none',
                                          show='tree')
        self.b_expand_supp = Button(f_right,
                                    image=self.img_expand,
                                    style="folder.TButton",
                                    command=self.tree_supp.expand_all)
        TooltipWrapper(self.b_expand_supp, text=_("Expand all"))
        self.b_expand_supp.grid(row=0, column=0)
        self.b_expand_supp.state(("disabled", ))
        self.b_collapse_supp = Button(f_right,
                                      image=self.img_collapse,
                                      style="folder.TButton",
                                      command=self.tree_supp.collapse_all)
        TooltipWrapper(self.b_collapse_supp, text=_("Collapse all"))
        self.b_collapse_supp.grid(row=0, column=1, padx=4)
        self.b_collapse_supp.state(("disabled", ))
        self.tree_supp.grid(row=0, column=0, sticky="eswn")
        self.scroll_y_supp = Scrollbar(frame_supp,
                                       orient="vertical",
                                       command=self.tree_supp.yview)
        self.scroll_y_supp.grid(row=0, column=1, sticky="ns")
        self.scroll_x_supp = Scrollbar(frame_supp,
                                       orient="horizontal",
                                       command=self.tree_supp.xview)
        self.scroll_x_supp.grid(row=1, column=0, sticky="ew")
        self.tree_supp.configure(yscrollcommand=self.scroll_y_supp.set,
                                 xscrollcommand=self.scroll_x_supp.set)
        self.pbar_supp = Progressbar(frame_right,
                                     orient="horizontal",
                                     mode="determinate")
        self.pbar_supp.grid(row=4,
                            columnspan=2,
                            sticky="ew",
                            padx=(4, 10),
                            pady=4)
        self.pbar_supp.state(("disabled", ))

        # --- bindings
        self.entry_orig.bind("<Key-Return>", self.list_files_to_sync)
        self.entry_sauve.bind("<Key-Return>", self.list_files_to_sync)

    def exclusion_supp(self):
        excl = ExclusionsSupp(self)
        self.wait_window(excl)
        # paths that will not be deleted
        self.exclude_path_supp = [
            ch.replace("\ ", " ") for ch in split(
                r'(?<!\\) ', CONFIG.get("Defaults", "exclude_supp")) if ch
        ]

    def exclusion_copie(self):
        excl = ExclusionsCopie(self)
        self.wait_window(excl)
        exclude_list = CONFIG.get("Defaults", "exclude_copie").split(" ")
        self.exclude_names = []
        self.exclude_ext = []
        for elt in exclude_list:
            if elt:
                if elt[:2] == "*.":
                    self.exclude_ext.append(elt[2:])
                else:
                    self.exclude_names.append(elt)

    def toggle_copy_links(self):
        CONFIG.set("Defaults", "copy_links", str(self.copy_links.get()))

    def toggle_show_size(self):
        CONFIG.set("Defaults", "show_size", str(self.show_size.get()))

    def open_log_copie(self):
        open_file(self.log_copie)

    def open_log_suppression(self):
        open_file(self.log_supp)

    def quitter(self):
        rep = True
        if self.is_running_copie or self.is_running_supp:
            rep = askokcancel(
                _("Confirmation"),
                _("A synchronization is ongoing, do you really want to quit?"),
                parent=self)
        if rep:
            self.destroy()

    def del_fav(self, nom):
        self.menu_fav.delete(nom)
        self.menu_fav_del.delete(nom)
        FAVORIS.remove(tuple(nom.split(" -> ")))
        save_config()
        if not FAVORIS:
            self.menu_fav.entryconfigure(1, state="disabled")

    def add_fav(self):
        sauvegarde = self.entry_sauve.get()
        original = self.entry_orig.get()
        if original != sauvegarde and original and sauvegarde:
            if exists(original) and exists(sauvegarde):
                if not (original, sauvegarde) in FAVORIS:
                    FAVORIS.append((original, sauvegarde))
                    save_config()
                    label = "%s -> %s" % (original, sauvegarde)
                    self.menu_fav.entryconfigure(1, state="normal")
                    self.menu_fav.add_command(label=label,
                                              command=lambda o=original, s=
                                              sauvegarde: self.open(o, s))
                    self.menu_fav_del.add_command(
                        label=label,
                        command=lambda nom=label: self.del_fav(nom))

    def open(self, ch_o, ch_s):
        self.entry_orig.delete(0, "end")
        self.entry_orig.insert(0, ch_o)
        self.entry_sauve.delete(0, "end")
        self.entry_sauve.insert(0, ch_s)
        self.list_files_to_sync()

    def open_sauve(self):
        sauvegarde = askdirectory(self.entry_sauve.get(), parent=self)
        if sauvegarde:
            self.entry_sauve.delete(0, "end")
            self.entry_sauve.insert(0, sauvegarde)

    def open_orig(self):
        original = askdirectory(self.entry_orig.get(), parent=self)
        if original:
            self.entry_orig.delete(0, "end")
            self.entry_orig.insert(0, original)

    def sync(self, original, sauvegarde):
        """ peuple tree_copie avec l'arborescence des fichiers d'original à copier
            vers sauvegarde et tree_supp avec celle des fichiers de sauvegarde à
            supprimer """
        errors = []
        copy_links = self.copy_links.get()
        excl_supp = [
            path for path in self.exclude_path_supp
            if commonpath([path, sauvegarde]) == sauvegarde
        ]

        def get_name(elt):
            return elt.name.lower()

        def lower(char):
            return char.lower()

        def arbo(tree, parent, n):
            """ affiche l'arborescence complète de parent et renvoie la longueur
                maximale des items (pour gérer la scrollbar horizontale) """
            m = 0
            try:
                with scandir(parent) as content:
                    l = sorted(content, key=get_name)
                for item in l:
                    chemin = item.path
                    nom = item.name
                    if item.is_symlink():
                        if copy_links:
                            tree.insert(parent,
                                        'end',
                                        chemin,
                                        text=nom,
                                        tags=("whole", "link"))
                            m = max(m, len(nom) * 9 + 20 * (n + 1))
                    elif ((nom not in self.exclude_names)
                          and (splitext(nom)[-1] not in self.exclude_ext)):
                        tree.insert(parent,
                                    'end',
                                    chemin,
                                    text=nom,
                                    tags=("whole", ))
                        m = max(m, len(nom) * 9 + 20 * (n + 1))
                        if item.is_dir():
                            m = max(m, arbo(tree, chemin, n + 1))
            except NotADirectoryError:
                pass
            except Exception as e:
                errors.append(str(e))
            return m

        def aux(orig, sauve, n, search_supp):
            m_copie = 0
            m_supp = 0
            try:
                lo = listdir(orig)
                ls = listdir(sauve)
            except Exception as e:
                errors.append(str(e))
                lo = []
                ls = []
            lo.sort(key=lambda x: x.lower())
            ls.sort(key=lambda x: x.lower())
            supp = False
            copie = False
            if search_supp:
                for item in ls:
                    chemin_s = join(sauve, item)
                    if chemin_s not in excl_supp and item not in lo:
                        supp = True
                        self.tree_supp.insert(sauve,
                                              'end',
                                              chemin_s,
                                              text=item,
                                              tags=("whole", ))
                        m_supp = max(m_supp, int(len(item) * 9 + 20 * (n + 1)),
                                     arbo(self.tree_supp, chemin_s, n + 1))

            for item in lo:
                chemin_o = join(orig, item)
                chemin_s = join(sauve, item)
                if ((item not in self.exclude_names)
                        and (splitext(item)[-1] not in self.exclude_ext)):
                    if item not in ls:
                        # le dossier / fichier n'est pas dans la sauvegarde
                        if islink(chemin_o):
                            if copy_links:
                                copie = True
                                self.tree_copie.insert(orig,
                                                       'end',
                                                       chemin_o,
                                                       text=item,
                                                       tags=("whole", "link"))
                                m_copie = max(
                                    m_copie,
                                    (int(len(item) * 9 + 20 * (n + 1))))
                        else:
                            copie = True
                            self.tree_copie.insert(orig,
                                                   'end',
                                                   chemin_o,
                                                   text=item,
                                                   tags=("whole", ))
                            m_copie = max(
                                m_copie, (int(len(item) * 9 + 20 * (n + 1))),
                                arbo(self.tree_copie, chemin_o, n + 1))
                    elif islink(chemin_o) and exists(chemin_o):
                        # checking the existence prevent from copying broken links
                        if copy_links:
                            if not islink(chemin_s):
                                self.pb_chemins.append(chemin_o)
                                tags = ("whole", "warning", "link")
                            else:
                                tags = ("whole", "link")
                            self.tree_copie.insert(orig,
                                                   'end',
                                                   chemin_o,
                                                   text=item,
                                                   tags=tags)
                            m_copie = max(m_copie,
                                          int(len(item) * 9 + 20 * (n + 1)))
                            copie = True
                    elif isfile(chemin_o):
                        # first check if chemin_s is also a file
                        if isfile(chemin_s):
                            if getmtime(chemin_o) // 60 > getmtime(
                                    chemin_s) // 60:
                                # le fichier f a été modifié depuis la dernière sauvegarde
                                copie = True
                                self.tree_copie.insert(orig,
                                                       'end',
                                                       chemin_o,
                                                       text=item,
                                                       tags=("whole", ))
                        else:
                            self.pb_chemins.append(chemin_o)
                            self.tree_copie.insert(orig,
                                                   'end',
                                                   chemin_o,
                                                   text=item,
                                                   tags=("whole", "warning"))
                    elif isdir(chemin_o):
                        # to avoid errors due to unrecognized item types (neither file nor folder nor link)
                        if isdir(chemin_s):
                            self.tree_copie.insert(orig,
                                                   'end',
                                                   chemin_o,
                                                   text=item)
                            self.tree_supp.insert(sauve,
                                                  'end',
                                                  chemin_s,
                                                  text=item)
                            c, s, mc, ms = aux(
                                chemin_o, chemin_s, n + 1, search_supp
                                and (chemin_s not in excl_supp))
                            supp = supp or s
                            copie = copie or c
                            if not c:
                                # nothing to copy
                                self.tree_copie.delete(chemin_o)
                            else:
                                m_copie = max(
                                    m_copie, mc,
                                    int(len(item) * 9 + 20 * (n + 1)))
                            if not s:
                                # nothing to delete
                                self.tree_supp.delete(chemin_s)
                            else:
                                m_supp = max(m_supp, ms,
                                             int(len(item) * 9 + 20 * (n + 1)))
                        else:
                            copie = True
                            self.pb_chemins.append(chemin_o)
                            self.tree_copie.insert(orig,
                                                   'end',
                                                   chemin_o,
                                                   text=item,
                                                   tags=("whole", "warning"))
                            m_copie = max(
                                m_copie, (int(len(item) * 9 + 20 * (n + 1))),
                                arbo(self.tree_copie, chemin_o, n + 1))
            return copie, supp, m_copie, m_supp

        self.tree_copie.insert("",
                               0,
                               original,
                               text=original,
                               tags=("checked", ),
                               open=True)
        self.tree_supp.insert("",
                              0,
                              sauvegarde,
                              text=sauvegarde,
                              tags=("checked", ),
                              open=True)
        c, s, mc, ms = aux(original, sauvegarde, 1, True)
        if not c:
            self.tree_copie.delete(original)
            self.tree_copie.column("#0", minwidth=0, width=0)
        else:
            mc = max(len(original) * 9 + 20, mc)
            self.tree_copie.column("#0", minwidth=mc, width=mc)
        if not s:
            self.tree_supp.delete(sauvegarde)
            self.tree_supp.column("#0", minwidth=0, width=0)
        else:
            ms = max(len(sauvegarde) * 9 + 20, mc)
            self.tree_supp.column("#0", minwidth=ms, width=ms)
        return errors

    def show_warning(self, event):
        if "disabled" not in self.b_open_orig.state():
            x, y = event.x, event.y
            elem = event.widget.identify("element", x, y)
            if elem == "padding":
                orig = self.tree_copie.identify_row(y)
                sauve = orig.replace(self.original, self.sauvegarde)
                showwarning(
                    _("Warning"),
                    _("%(original)s and %(backup)s are not of the same kind (folder/file/link)"
                      ) % {
                          'original': orig,
                          'backup': sauve
                      },
                    master=self)

    def list_files_to_sync(self, event=None):
        """Display in a treeview the file to copy and the one to delete."""
        self.pbar_copie.configure(value=0)
        self.pbar_supp.configure(value=0)
        self.sauvegarde = self.entry_sauve.get()
        self.original = self.entry_orig.get()
        if self.original != self.sauvegarde and self.original and self.sauvegarde:
            if exists(self.original) and exists(self.sauvegarde):
                o_s = (self.original, self.sauvegarde)
                if o_s in RECENT:
                    RECENT.remove(o_s)
                    self.menu_recent.delete("%s -> %s" % o_s)
                RECENT.insert(0, o_s)
                self.menu_recent.insert_command(
                    0,
                    label="%s -> %s" % o_s,
                    command=lambda o=self.original, s=self.sauvegarde: self.
                    open(o, s))
                if len(RECENT) == 10:
                    del (RECENT[-1])
                    self.menu_recent.delete(9)
                save_config()
                self.menu.entryconfigure(0, state="normal")
                self.configure(cursor="watch")
                self.toggle_state_gui()
                self.update_idletasks()
                self.update()
                self.efface_tree()
                err = self.sync(self.original, self.sauvegarde)
                self.configure(cursor="")
                self.toggle_state_gui()
                c = self.tree_copie.get_children("")
                s = self.tree_supp.get_children("")
                if not (c or s):
                    self.menu.entryconfigure(5, state="disabled")
                    self.b_collapse_copie.state(("disabled", ))
                    self.b_expand_copie.state(("disabled", ))
                    self.b_collapse_supp.state(("disabled", ))
                    self.b_expand_supp.state(("disabled", ))
                elif not c:
                    self.b_collapse_copie.state(("disabled", ))
                    self.b_expand_copie.state(("disabled", ))
                elif not s:
                    self.b_collapse_supp.state(("disabled", ))
                    self.b_expand_supp.state(("disabled", ))
                if err:
                    showerror(_("Errors"), "\n".join(err), master=self)
                notification_send(_("Scan is finished."))
                warnings = self.tree_copie.tag_has('warning')
                if warnings:
                    showwarning(
                        _("Warning"),
                        _("Some elements to copy (in red) are not of the same kind on the original and the backup."
                          ),
                        master=self)
            else:
                showerror(_("Error"), _("Invalid path!"), master=self)

    def efface_tree(self):
        """Clear both trees."""
        c = self.tree_copie.get_children("")
        for item in c:
            self.tree_copie.delete(item)
        s = self.tree_supp.get_children("")
        for item in s:
            self.tree_supp.delete(item)
        self.b_collapse_copie.state(("disabled", ))
        self.b_expand_copie.state(("disabled", ))
        self.b_collapse_supp.state(("disabled", ))
        self.b_expand_supp.state(("disabled", ))

    def toggle_state_gui(self):
        """Toggle the state (normal/disabled) of key elements of the GUI."""
        if "disabled" in self.b_open_orig.state():
            state = "!disabled"
            for i in range(7):
                self.menu.entryconfigure(i, state="normal")
        else:
            state = "disabled"
            for i in range(7):
                self.menu.entryconfigure(i, state="disabled")
        self.tree_copie.state((state, ))
        self.tree_supp.state((state, ))
        self.entry_orig.state((state, ))
        self.entry_sauve.state((state, ))
        self.b_expand_copie.state((state, ))
        self.b_collapse_copie.state((state, ))
        self.b_expand_supp.state((state, ))
        self.b_collapse_supp.state((state, ))
        self.b_open_orig.state((state, ))
        self.b_open_sauve.state((state, ))

    def update_pbar(self):
        """
        Dislay the progress of the copy and deletion and put the GUI back in
        normal state once both processes are done.
        """
        if not self.is_running_copie and not self.is_running_supp:
            notification_send(_("Sync is finished."))
            self.toggle_state_gui()
            self.pbar_copie.configure(value=self.pbar_copie.cget("maximum"))
            self.pbar_supp.configure(value=self.pbar_supp.cget("maximum"))
            self.menu.entryconfigure(5, state="disabled")
            self.configure(cursor="")
            self.efface_tree()
            msg = ""
            if self.err_copie:
                msg += _(
                    "There were errors during the copy, see %(file)s for more details.\n"
                ) % {
                    'file': self.log_copie
                }
            if self.err_supp:
                msg += _(
                    "There were errors during the removal, see %(file)s for more details.\n"
                ) % {
                    'file': self.log_supp
                }
            if msg:
                showerror(_("Error"), msg, master=self)
        else:
            if not self.q_copie.empty():
                self.pbar_copie.configure(value=self.q_copie.get())
            if not self.q_supp.empty():
                self.pbar_supp.configure(value=self.q_supp.get())
            self.update()
            self.after(50, self.update_pbar)

    @staticmethod
    def get_list(tree):
        """Return the list of files/folders to copy/delete (depending on the tree)."""
        selected = []

        def aux(item):
            tags = tree.item(item, "tags")
            if "checked" in tags and "whole" in tags:
                selected.append(item)
            elif "checked" in tags or "tristate" in tags:
                ch = tree.get_children(item)
                for c in ch:
                    aux(c)

        ch = tree.get_children("")
        for c in ch:
            aux(c)
        return selected

    def synchronise(self):
        """
        Display the list of files/folders that will be copied / deleted
        and launch the copy and deletion if the user validates the sync.
        """
        # get files to delete and folder to delete if they are empty
        a_supp = self.get_list(self.tree_supp)
        # get files to copy
        a_copier = self.get_list(self.tree_copie)
        a_supp_avant_cp = []
        for ch in self.pb_chemins:
            if ch in a_copier:
                a_supp_avant_cp.append(
                    ch.replace(self.original, self.sauvegarde))
        if a_supp or a_copier:
            Confirmation(self, a_copier, a_supp, a_supp_avant_cp,
                         self.original, self.sauvegarde, self.show_size.get())

    def copie_supp(self, a_copier, a_supp, a_supp_avant_cp):
        """Launch sync."""
        self.toggle_state_gui()
        self.configure(cursor="watch")
        self.update()
        self.pbar_copie.state(("!disabled", ))
        self.pbar_supp.state(("!disabled", ))
        nbtot_copie = len(a_copier) + len(a_supp_avant_cp)
        self.pbar_copie.configure(maximum=nbtot_copie, value=0)
        nbtot_supp = len(a_supp)
        self.pbar_supp.configure(maximum=nbtot_supp, value=0)
        self.is_running_copie = True
        self.is_running_supp = True
        process_copie = Thread(target=self.copie,
                               name="copie",
                               daemon=True,
                               args=(a_copier, a_supp_avant_cp))
        process_supp = Thread(target=self.supp,
                              daemon=True,
                              name="suppression",
                              args=(a_supp, ))
        process_copie.start()
        process_supp.start()
        self.pbar_copie.configure(value=0)
        self.pbar_supp.configure(value=0)
        self.update_pbar()

    def copie(self, a_copier, a_supp_avant_cp):
        """
        Copie tous les fichiers/dossiers de a_copier de original vers
        sauvegarde en utilisant la commande système cp. Les erreurs
        rencontrées au cours du processus sont inscrites dans
        ~/.foldersync/copie.log
        """
        self.err_copie = False
        orig = abspath(self.original) + "/"
        sauve = abspath(self.sauvegarde) + "/"
        chdir(orig)
        self.logger_copie.info(
            _("\n###### Copy: %(original)s -> %(backup)s\n") % {
                'original': self.original,
                'backup': self.sauvegarde
            })
        n = len(a_supp_avant_cp)
        self.logger_copie.info(_("Removal before copy:"))
        for i, ch in zip(range(1, n + 1), a_supp_avant_cp):
            self.logger_copie.info(ch)
            p_copie = run(["rm", "-r", ch], stderr=PIPE)
            self.q_copie.put(i)
            err = p_copie.stderr.decode()
            if err:
                self.err_copie = True
                self.logger_copie.error(err.strip())
        self.logger_copie.info(_("Copy:"))
        for i, ch in zip(range(n + 1, n + 1 + len(a_copier)), a_copier):
            ch_o = ch.replace(orig, "")
            self.logger_copie.info("%s -> %s" % (ch_o, sauve))
            p_copie = run(["cp", "-ra", "--parents", ch_o, sauve], stderr=PIPE)
            self.q_copie.put(i)
            err = p_copie.stderr.decode()
            if err:
                self.err_copie = True
                self.logger_copie.error(err.strip())
        self.is_running_copie = False

    def supp(self, a_supp):
        """
        Supprime tous les fichiers/dossiers de a_supp de original vers
        sauvegarde en utilisant la commande système rm. Les erreurs
        rencontrées au cours du processus sont inscrites dans
        ~/.foldersync/suppression.log.
        """
        self.err_supp = False
        self.logger_supp.info(
            _("\n###### Removal:  %(original)s -> %(backup)s\n") % {
                'original': self.original,
                'backup': self.sauvegarde
            })
        for i, ch in enumerate(a_supp):
            self.logger_supp.info(ch)
            p_supp = run(["rm", "-r", ch], stderr=PIPE)
            self.q_supp.put(i + 1)
            err = p_supp.stderr.decode()
            if err:
                self.logger_supp.error(err.strip())
                self.err_supp = True
        self.is_running_supp = False

    def unlink(self):
        """Unlink pidfile."""
        unlink(self.pidfile)

    def change_language(self):
        """Change app language."""
        CONFIG.set("Defaults", "language", self.langue.get())
        showinfo(
            _("Information"),
            _("The language setting will take effect after restarting the application"
              ))
コード例 #8
0
ファイル: UI.py プロジェクト: AverageName/Graph_Uni_Proj
class App:
    def __init__(self, mc):
        self.mc = mc
        self.window = Tk()
        self.window.title("Екатеринбург")
        self.window.geometry("1800x1000")
        self.result = ''
        self.n_1 = self.m_1 = None
        self.modes = ('fwd', 'bwd', 'fwd_bwd')

        self.load = Image.open("./images/Ekb_graph_cropped.png")
        self.image = ImageTk.PhotoImage(self.load)
        self.img = Label(self.window, image=self.image)
        self.img.grid(column=3, columnspan=100, row=1, rowspan=100)

        Label(self.window, text='').grid(row=0)
        Label(self.window, text='', width=10).grid(column=0)
        Label(self.window, width=10).grid(column=2)

        Button(self.window, text='Показать Екатеринбург',
               command=partial(self.set_image, "Ekb_graph_cropped")).grid(column=1, row=1, pady=3)
        Label(self.window, text='').grid(column=1, row=2)

        Label(self.window, text='Часть 1').grid(column=1, row=3)
        Label(self.window, text='M = ').grid(column=0, row=4, sticky=E)
        self.m_1_input = Spinbox(self.window, width=5, from_=1, to=10)
        self.m_1_input.grid(column=1, row=4, sticky=W)
        Label(self.window, text='N = ').grid(column=0, row=5, sticky=E)
        self.n_1_input = Spinbox(self.window, width=5, from_=1, to=100)
        self.n_1_input.grid(column=1, row=5, sticky=W)

        Button(self.window, text='Выбрать', command=self.set_m_n_1).grid(column=1, row=6, sticky=W, pady=1)
        self.show_chosen_1 = Button(self.window, text='Показать выбранные',
                                    command=partial(self.set_image, "points_for_1_part"))
        Label(self.window, text='mode(1): ').grid(column=0, row=8, sticky=E)
        self.mode_1 = Combobox(self.window, width=15)
        self.mode_1.grid(column=1, row=8, sticky=W)
        self.mode_1['values'] = ("Туда", "Обратно", "Туда-обратно")
        self.mode_1.current(0)
        self.task_1_1_a = Button(self.window, text='Рассчитать 1а', command=self.count_first_a)
        self.show_1_1_a = Button(self.window, text='Show', command=partial(self.set_image, 'task_1_a'))
        Label(self.window, text='X = ').grid(column=0, row=9, sticky=E)
        self.x = Entry(self.window, width=7)
        self.x.grid(column=1, row=9, sticky=W)
        self.task_1_1_b = Button(self.window, text='1б', command=self.count_first_b)
        self.show_1_1_b = Button(self.window, text='Show', command=partial(self.set_image, 'task_1_b'))

        Label(self.window, text='mode(2): ').grid(column=0, row=10, sticky=E)
        self.mode_2 = Combobox(self.window, width=15)
        self.mode_2.grid(column=1, row=10, sticky=W)
        self.mode_2['values'] = ("Туда", "Обратно", "Туда-обратно")
        self.mode_2.current(0)
        self.task_1_2 = Button(self.window, text='п. 2', command=self.count_second)
        self.show_1_2 = Button(self.window, text='Show', command=partial(self.set_image, 'task_2'))
        self.task_1_3 = Button(self.window, text='п. 3', command=self.count_third)
        self.show_1_3 = Button(self.window, text='Show', command=partial(self.set_image, 'task_3'))
        self.task_1_4 = Button(self.window, text='п. 4', command=self.count_fourth)
        self.show_1_4 = Button(self.window, text='Show', command=partial(self.set_image, 'task_4'))
        Label(self.window, text='', height=1).grid(column=1, row=13)
        self.wait_first = Label(self.window, text='', fg='red')
        self.wait_first.grid(column=1, row=14)

        Label(self.window, text='', height=2).grid(column=1, row=15)
        Label(self.window, text='Часть 2').grid(column=1, row=16)
        Button(self.window, text='Показать карту инфраструктурных объектов',
               command=partial(self.set_image, "inf_objs")).grid(column=1, row=17, pady=2)
        Label(self.window, text='N = ').grid(column=1, row=18)
        self.n_input = Spinbox(self.window, from_=1, to=100, width=5)
        self.n_input.grid(column=1, row=18, sticky=E)
        Label(self.window, text='Индекс инф. объекта: ').grid(column=1, row=19)
        self.inf_index = Spinbox(self.window, from_=0, to=21, width=5)
        self.inf_index.grid(column=1, row=19, sticky=E)
        Button(self.window, text='Рассчитать', command=self.count_sp).grid(column=1, row=20)

        Label(self.window, text='', height=2).grid(column=1, row=21)
        self.progress = Progressbar(self.window, orient=HORIZONTAL, length=0, mode='determinate')
        self.progress.grid(column=1, row=22)
        self.progress_info = Label(self.window, text='')
        self.progress_info.grid(column=1, row=23)

        Label(self.window, text='', height=2).grid(column=1, row=24)
        self.combo = Combobox(self.window, width=30)
        self.combo['values'] = (
            "Дерево кратчайших путей", "Дендрограмма",
            "Разделение на 2 кластера", "Деревья 2 центроид", "Дерево от 2 центроид до объекта",
            "Разделение на 3 кластера", "Деревья 3 центроид", "Дерево от 3 центроид до объекта",
            "Разделение на 5 кластеров", "Деревья 5 центроид", "Дерево от 5 центроид до объекта"
        )
        self.combo.current(0)
        self.show_btn = Button(self.window, text='Показать', command=self.set_combo_image)
        self.add_recount = Button(self.window, text='Добавить пункт назначения и пересчитать',
                                  command=self.add_and_recount)

        Label(self.window, text='Test').grid(column=1, row=29, pady=3, sticky=W)
        Label(self.window, text='File:').grid(column=0, row=30, pady=1, sticky=E)
        self.filename = Entry(self.window, width=15)
        self.filename.grid(column=1, row=30, sticky=W)
        Label(self.window, text='Start:').grid(column=0, row=31, pady=1, sticky=E)
        self.start_id = Entry(self.window, width=5)
        self.start_id.grid(column=1, row=31, sticky=W)
        Label(self.window, text='Dest:').grid(column=0, row=32, pady=1, sticky=E)
        self.dest_id = Entry(self.window, width=5)
        self.dest_id.grid(column=1, row=32, sticky=W)
        self.count_test = Button(self.window, text='count', command=self.count_test)
        self.count_test.grid(column=1, row=33, pady=2, sticky=W)

        Button(self.window, text='exit', command=partial(sys.exit, 0)).grid(column=1, row=34, pady=5)

    def count_test(self):
        try:
            start = int(self.start_id.get())
            dest = int(self.dest_id.get())
            file = './{}.csv'.format(self.filename.get())
            print(file)
            res = find_min_path(file, start, dest)
            messagebox.showinfo('result', 'length: {}\npath: {}'.format(res[0], res[1]))
            self.window.mainloop()
        except ValueError:
            messagebox.showinfo('error', 'check your input')

    def toggle_waiting(self, on):
        if on:
            self.wait_first.configure(text='wait please...')
        else:
            self.wait_first.configure(text='')
        self.window.update()

    def set_m_n_1(self):
        try:
            n_1 = int(self.n_1_input.get())
            m_1 = int(self.m_1_input.get())
            self.toggle_waiting(True)
            self.hide_info()
            self.mc.set_objs(n_1, m=m_1)
            self.set_image('points_for_1_part')
            self.show_first_part()
            self.toggle_waiting(False)
            self.window.mainloop()
        except ValueError:
            messagebox.showinfo('m n', 'M|N should be numeric')

    def show_first_part(self):
        self.show_chosen_1.grid(column=1, row=7, pady=1)
        self.task_1_1_a.grid(column=1, row=8, sticky=E)
        self.task_1_1_b.grid(column=1, row=9, sticky=E)
        self.task_1_2.grid(column=1, row=10, sticky=E)
        self.task_1_3.grid(column=1, row=11, pady=3, sticky=E)
        self.task_1_4.grid(column=1, row=12, sticky=E)

    def hide_first_part(self):
        self.show_chosen_1.grid_forget()
        self.task_1_1_a.grid_forget()
        self.task_1_1_b.grid_forget()
        self.task_1_2.grid_forget()
        self.task_1_3.grid_forget()
        self.task_1_4.grid_forget()
        self.show_1_1_a.grid_forget()
        self.show_1_1_b.grid_forget()
        self.show_1_2.grid_forget()
        self.show_1_3.grid_forget()
        self.show_1_4.grid_forget()

    def count_first_a(self):
        self.toggle_waiting(True)
        index = self.mode_1['values'].index(self.mode_1.get())
        res, t = self.mc.nearest(self.modes[index])
        self.set_image('task_1_a')
        self.show_1_1_a.grid(column=2, row=8, padx=1, sticky=W)
        self.toggle_waiting(False)
        messagebox.showinfo('1a', '{}\ntime: {}'.format(res, t))
        self.window.mainloop()

    def count_first_b(self):
        index = self.mode_1['values'].index(self.mode_1.get())
        try:
            x = int(self.x.get())
            self.toggle_waiting(True)
            res, t = self.mc.closer_than_x(x, self.modes[index])
            self.set_image('task_1_b')
            self.show_1_1_b.grid(column=2, row=9, padx=1, sticky=W)
            self.toggle_waiting(False)
            messagebox.showinfo('1б', '{}\ntime: {}'.format(res, t))
            self.window.mainloop()
        except ValueError:
            messagebox.showinfo('error', 'x should be numeric')
            return

    def count_second(self):
        self.toggle_waiting(True)
        index = self.mode_2['values'].index(self.mode_2.get())
        min_, min_id, t = self.mc.min_furthest_for_inf(self.modes[index])
        self.set_image('task_2')
        self.show_1_2.grid(column=2, row=10, padx=1, sticky=W)
        self.toggle_waiting(False)
        messagebox.showinfo('2', '{}\ntime: {}'.format(min_, t))
        self.window.mainloop()

    def count_third(self):
        self.toggle_waiting(True)
        min_, min_id, t = self.mc.closest_inf_in_summary()
        self.set_image('task_3')
        self.show_1_3.grid(column=2, row=11, padx=1, sticky=W)
        self.toggle_waiting(False)
        messagebox.showinfo('3', '{}\ntime: {}'.format(min_, t))
        self.window.mainloop()

    def count_fourth(self):
        self.toggle_waiting(True)
        min_, min_id, t = self.mc.min_weight_tree()
        self.set_image('task_4')
        self.show_1_4.grid(column=2, row=12, padx=1, sticky=W)
        self.toggle_waiting(False)
        messagebox.showinfo('4', '{}\ntime: {}'.format(min_, t))
        self.window.mainloop()

    def set_image(self, name):
        self.load = Image.open("./images/{}.png".format(name))
        self.image = ImageTk.PhotoImage(self.load)
        self.img.configure(image=self.image)

    def set_combo_image(self):
        img_names = (
            "routes_to_random_inf", "dendrogram",
            "2_clusters", "2_clusters_trees", "2_centroids_tree",
            "3_clusters", "3_clusters_trees", "3_centroids_tree",
            "5_clusters", "5_clusters_trees", "5_centroids_tree",
        )
        index = self.combo['values'].index(self.combo.get())
        self.set_image(img_names[index])

    def count_sp(self):
        self.hide_first_part()
        n = int(self.n_input.get())
        inf_obj_i = int(self.inf_index.get())
        self.mc.set_objs(n)
        self.mc.set_inf_obj(inf_obj_i)
        self.second_part()

    def add_and_recount(self):
        self.mc.add_obj()
        self.n_input.selection_adjust(5)
        self.second_part()

    def second_part(self):
        self.progress.configure(length=200)
        self.hide_info()
        time_wt_plot = 0
        start = time.time()
        self.update_progress(0, 'saving to csv...')
        self.mc.save_chosen_objs_to_csv()
        self.update_progress(11, 'counting tree...')
        sum_, weight, routes_list, o_w_r, tree_time = self.mc.list_to_obj_tree(self.mc.chosen_objs, self.mc.chosen_inf_obj,
                                                                   filename='./csv/min_tree.csv')
        time_wt_plot += tree_time
        # messagebox.showinfo('1', 'sum: {}\nweight: {}'.format(sum_, weight))
        self.update_progress(22, 'saving tree...')
        self.mc.save_tree_plot(routes_list, [self.mc.graph.nodes[routes_list[0][0]]], 'routes_to_random_inf', o_w_r)
        self.set_image('routes_to_random_inf')

        self.update_progress(33, 'researching clusters...')
        clusters, history, t = self.mc.objs_into_clusters(1, write=True)
        time_wt_plot += t
        self.update_progress(44, 'creating dendrogram...')
        self.mc.dendrogram(clusters, history)
        self.set_image('dendrogram')

        self.update_progress(55, 'working with 2 clusters...')
        cs_2, w_2, cs_2_c, w_2_c, t = self.mc.work_with_clusters(history, 2)
        time_wt_plot += t
        self.set_image('2_clusters')

        self.update_progress(70, 'working with 3 clusters...')
        cs_3, w_3, cs_3_c, w_3_c, t = self.mc.work_with_clusters(history, 3)
        time_wt_plot += t
        self.set_image('3_clusters')

        self.update_progress(85, 'working with 5 clusters...')
        cs_5, w_5, cs_5_c, w_5_c, t = self.mc.work_with_clusters(history, 5)
        time_wt_plot += t
        self.set_image('5_clusters')
        self.update_progress(100, 'done!')

        result = "min weight tree: \n\tsum: {}\n\tweight {}\n" \
                 "2 centroids tree: \n\tsum: {}\n\tweight {}\n\tcentroid_sum: {}\n\tcentroid_weight: {}\n" \
                 "3 centroids tree: \n\tsum: {}\n\tweight {}\n\tcentroid_sum: {}\n\tcentroid_weight: {}\n" \
                 "5 centroids tree: \n\tsum: {}\n\tweight {}\n\tcentroid_sum: {}\n\tcentroid_weight: {}\n" \
                 "tree time: {}\ntime without plotting: {}\ntime: {}"\
            .format(sum_, weight,
                    cs_2, w_2, cs_2_c, w_2_c,
                    cs_3, w_3, cs_3_c, w_3_c,
                    cs_5, w_5, cs_5_c, w_5_c,
                    tree_time, time_wt_plot, time.time() - start)
        self.set_image('routes_to_random_inf')
        messagebox.showinfo('result', result)

        self.show_info()
        self.window.mainloop()

    def update_progress(self, val, info):
        self.progress['value'] = val
        self.progress_info.configure(text=info)
        self.window.update()

    def hide_info(self):
        self.progress['value'] = 0
        self.combo.grid_forget()
        self.show_btn.grid_forget()
        self.add_recount.grid_forget()
        self.progress_info.configure(text='')
        self.window.update()

    def show_info(self):
        self.combo.grid(column=1, row=26)
        self.show_btn.grid(column=1, row=27)
        self.add_recount.grid(column=1, row=28, pady=5)
        self.window.update()

    def start_loop(self):
        self.window.mainloop()
コード例 #9
0
class PlayerControlPanel(Frame, IPlayerStateListener):
    def __init__(self, parent):
        super().__init__(parent)
        self.trackNameLabel: Label = None
        self.volumeScale: Scale = None

        self.muted = False

        self.__initView()

    def __initView(self):
        self.configure(borderwidth=3, relief=RIDGE)
        self.configure(height=HEIGHT)

        ###################################################################################

        image = Image.open(PLAY_ICON)
        image = image.resize((32, 32), Image.ANTIALIAS)
        self.play_icon = PhotoImage(image=image)

        image = Image.open(PAUSE_ICON)
        image = image.resize((32, 32), Image.ANTIALIAS)
        self.pause_icon = PhotoImage(image=image)

        self.playPauseButton = Button(self, image=self.play_icon)
        self.playPauseButton.grid(row=0, column=0)

        ###################################################################################

        image = Image.open(NEXT_TRACK_ICON)
        image = image.resize((32, 32), Image.ANTIALIAS)
        self.next_track_icon = PhotoImage(image=image)

        self.nextTrackButton = Button(self, image=self.next_track_icon)
        self.nextTrackButton.grid(row=0, column=1)

        ###################################################################################

        image = Image.open(LINEAR_ICON)
        image = image.resize((32, 32), Image.ANTIALIAS)
        self.linear_icon = PhotoImage(image=image)

        image = Image.open(REPEAT_ICON)
        image = image.resize((32, 32), Image.ANTIALIAS)
        self.repeat_icon = PhotoImage(image=image)

        self.musicSelectionModeButton = Button(self,
                                               image=self.next_track_icon)
        self.musicSelectionModeButton.grid(row=0, column=2)

        ###################################################################################

        image = Image.open(MUTE_ICON)
        image = image.resize((32, 32), Image.ANTIALIAS)
        self.mute_icon = PhotoImage(image=image)

        image = Image.open(UNMUTE_ICON)
        image = image.resize((32, 32), Image.ANTIALIAS)
        self.unmute_icon = PhotoImage(image=image)

        self.muteButton = Button(self,
                                 image=self.mute_icon,
                                 command=self.__muteButtonPressed)
        self.muteButton.grid(row=0, column=3)

        ###################################################################################

        self.volumeScale = Scale(self, from_=0, to=100, orient=HORIZONTAL)
        self.volumeScale.set(50)
        self.volumeScale.grid(row=0, column=4)

        ###################################################################################

        self.trackProgressBar = Progressbar(self,
                                            orient=HORIZONTAL,
                                            length=300,
                                            mode='determinate',
                                            maximum=MAXIMUM)
        self.trackProgressBar.grid(row=0, column=5)

        ###################################################################################

        self.timeLabel = Label(self, text='--:--/--:--')
        self.timeLabel.grid(row=0, column=6)

        self.trackNameLabel = Label(self)
        self.trackNameLabel.grid(row=0, column=7)

    def onPlayerStateUpdated(self, state: PlayerState):
        self.trackNameLabel.configure(text=state.trackName)

        if state.trackType is TrackType.MUSIC:
            self.trackProgressBar.configure(value=int(MAXIMUM *
                                                      state.trackPosition))
            self.playPauseButton.configure(state=NORMAL)
        else:
            self.trackProgressBar.configure(value=0)
            self.playPauseButton.configure(state=DISABLED)

        if state.playbackState is PlaybackState.PLAYING:
            self.playPauseButton.configure(image=self.pause_icon)
        else:
            self.playPauseButton.configure(image=self.play_icon)

        if state.musicSelectionMode is MusicSelectionMode.LINEAR:
            self.musicSelectionModeButton.configure(image=self.linear_icon)
        else:
            self.musicSelectionModeButton.configure(image=self.repeat_icon)

        self.__displayTime(state)

    def __displayTime(self, state: PlayerState):
        trackMinutes = int(state.trackLength / 60)
        trackSeconds = state.trackLength % 60

        played = int(state.trackPosition * state.trackLength)
        playedMinutes = int(played / 60)
        playedSeconds = played % 60

        if state.trackType is not TrackType.MUSIC:
            self.timeLabel.configure(text='--:--/--:--')
        else:
            self.timeLabel.configure(
                text=
                f'{playedMinutes:02d}:{playedSeconds:02d}/{trackMinutes:02d}:{trackSeconds:02d}'
            )

    def setPlayerController(self, playerController: IPlayerController):
        self.playerController = playerController

        self.volumeScale.configure(command=lambda v: self.__sendVolume())
        self.__sendVolume()

        self.trackProgressBar.bind(
            "<Button-1>",
            lambda e: self.onProgressBarClicked(e, playerController))
        self.playPauseButton.configure(
            command=playerController.onPlayPauseClicked)
        self.nextTrackButton.configure(
            command=playerController.nextTrackClicked)
        self.musicSelectionModeButton.configure(
            command=playerController.changeMusicSelectionModeClicked)

    def __sendVolume(self):
        if self.playerController is None:
            return

        if self.muted:
            self.playerController.onVolumeSelected(0)
        else:
            self.playerController.onVolumeSelected(self.volumeScale.get())

    def __muteButtonPressed(self):
        self.muted = not self.muted

        if self.muted:
            self.muteButton.configure(image=self.unmute_icon)
        else:
            self.muteButton.configure(image=self.mute_icon)

        self.__sendVolume()

    def onProgressBarClicked(self, event, playerController: IPlayerController):
        percentage = event.x / event.widget.winfo_width()
        playerController.seekTo(percentage)

    def onPlayerEndReached(self):
        pass
コード例 #10
0
class Window:
    def __init__(self,
                 width,
                 height,
                 title="MyWindow",
                 resizable=(False, False),
                 icon=r"resources/feather.ico"):
        self.root = Tk()
        self.root.title(title)
        # self.root.geometry(f"{width}x{height}+200+200")
        self.root.geometry("+600+300")
        # self.root.resizable(resizable[0], resizable[1])
        if icon:
            self.root.iconbitmap(icon)

        self.pb = Progressbar(self.root,
                              orient=HORIZONTAL,
                              mode="indeterminate",
                              length=200)
        self.sb = Spinbox(self.root,
                          from_=0,
                          to=100,
                          state='readonly',
                          command=self.change_pb)

    def run(self):
        self.draw_widgets()
        self.root.mainloop()

    def draw_widgets(self):
        self.draw_menu()
        self.sb.pack()
        self.pb.pack()
        # self.pb.configure(maximum=3)
        # self.pb.configure(value=1)

        # from time import sleep
        # for i in range(101):
        #     self.pb.configure(value=i)
        #     self.pb.update()
        #     sleep(0.05)
        # self.pb.configure(value=0)

        Button(self.root, text="StartPB", command=self.pb.start).pack()
        Button(self.root, text="StopPB", command=self.pb.stop).pack()

        value = self.pb["value"]
        self.pb["value"] = 20

    def draw_menu(self):
        menu_bar = Menu(self.root)

        file_menu = Menu(menu_bar, tearoff=0)
        file_menu.add_separator()
        file_menu.add_command(label="Выйти", command=self.exit)

        info_menu = Menu(menu_bar, tearoff=0)
        info_menu.add_command(label="О приложении", command=self.show_info)

        menu_bar.add_cascade(label="Файл", menu=file_menu)
        menu_bar.add_cascade(label="Справка", menu=info_menu)
        self.root.configure(menu=menu_bar)

    def change_pb(self):
        self.pb.configure(value=self.sb.get())
        self.pb.update()

    def show_info(self):
        mb.showinfo("Информация", "Лучшее графическое приложение на свете")

    def exit(self):
        choice = mb.askyesno("Quit", "Do you want to quit?")
        if choice:
            self.root.destroy()

    def create_child(self,
                     width,
                     height,
                     title="Child",
                     resizable=(False, False),
                     icon=None):
        ChildWindow(self.root, width, height, title, resizable, icon)
コード例 #11
0
class InstallWindow:
    def __init__(self, setpath, installpath, systemwide, type='install'):
        global root
        self.setpath = setpath
        self.installpath = installpath
        self.systemwide = systemwide

        self.type = type

        self.master = Toplevel(root)
        self.master.withdraw()
        self.master.protocol('WM_DELETE_WINDOW', self.close)
        self.master.iconbitmap(imgdir)
        self.master.title('Adb & Fastboot installer - By @Pato05')
        self.master.geometry("600x400")
        self.master.resizable(False, False)
        frame = Frame(self.master, relief=FLAT)
        frame.pack(padx=10, pady=5, fill=BOTH)
        Label(frame, text='Please wait while Adb and Fastboot are getting %s...' % (
            'updated' if type == 'update' else 'installed on your PC')).pack(fill=X)
        self.mode = 'unksize'
        self.progressbar = Progressbar(
            frame, orient=HORIZONTAL, length=100, mode='indeterminate')
        self.progressbar.pack(fill=X)
        self.progressbar.start(20)
        self.downloaded = 0
        self.progressv = Text(frame, bd=0, insertborderwidth=0,
                              state='disabled', background='#f0f0ed', font=('Segoe UI', 10))
        self.progressv.pack(fill=BOTH, pady=(10, 5))
        self.master.deiconify()
        self.downloading = threading.Thread(target=self.download)
        self.downloading.start()

    def download_progress(self, count, block_size, total_size):
        if total_size != -1 and self.mode != 'ksize':
            self.mode = 'ksize'
            self.progressbar.stop()
            self.progressbar.configure(mode='determinate', maximum=total_size)
        elif total_size == -1 and self.mode != 'unksize':
            self.mode = 'unksize'
            self.progressbar.configure(mode='indeterminate')
        if self.mode == 'ksize':
            self.downloaded += block_size
            self.progressbar.step(block_size)
            if self.downloaded == total_size:
                self.progress('Download ended.')

    def download(self):
        self.pathres = False
        self.progress('Downloading Adb and Fastboot...', False)
        from urllib.request import urlretrieve
        import urllib.error
        workingdir = scriptdir
        download = os.path.join(workingdir, 'pt.zip')
        try:
            urlretrieve('https://dl.google.com/android/repository/platform-tools-latest-windows.zip',
                        download, self.download_progress)
        except (urllib.error.HTTPError, urllib.error.URLError) as e:
            messagebox.showerror(title='Adb & Fastboot Uninstaller',
                                 message='Failed while trying to download Adb and Fastboot. Are you connected to the internet?\nError: %s' % e)
            self.error_close()
            return False
        self.progressbar.configure(
            mode='indeterminate', maximum=150, length=400, value=0)
        self.progressbar.start(20)
        self.progress('Extracting Adb and Fastboot...')
        from zipfile import ZipFile
        with ZipFile(download) as z:
            z.extractall(workingdir)
        os.remove(download)
        self.progress('Moving Adb and Fastboot to destination folder...')
        if(os.path.isdir(self.installpath)):
            rmtree(self.installpath)
            sleep(0.1)
        os.mkdir(self.installpath)
        for file in ['adb.exe', 'AdbWinApi.dll', 'AdbWinUsbApi.dll', 'fastboot.exe']:
            self.progress("Moving %s..." % file)
            copyfile(os.path.join(workingdir, 'platform-tools', file), os.path.join(self.installpath, file))
        rmtree(os.path.join(workingdir, 'platform-tools'))
        if self.setpath == 1:
            self.progress('Adding Adb & Fastboot into %s\'s path' %
                          ('system' if self.systemwide == 1 else 'user'))
            self.pathres = addToPath(self.installpath, self.systemwide == 1)
            self.progress(
                'Successfully added Adb & Fastboot into path' if self.pathres else 'Failed to add Adb & Fastboot into path')
        self.progressbar.stop()
        self.finish()

    def finish(self):
        self.app = FinishWindow(
            self.setpath, self.pathres, self.installpath, self.type)
        self.master.destroy()

    def progress(self, what, lb=True):
        self.progressv.configure(state='normal')
        self.progressv.insert(END, ('\r\n' if lb else '')+what)
        self.progressv.configure(state='disabled')

    def error_close(self):
        global root
        root.destroy()

    def close(self):
        pass
コード例 #12
0
class Worker(Frame):
    """
    Worker gui elements, does all the actual work to the images with the
    watermarker class and contains progressbar and startbutton
    """
    def __init__(self, file_selector, options_pane, master=None):
        super().__init__(master)

        self.running = False

        self.image_que = queue.Queue()

        self.file_selector = file_selector
        self.option_pane = options_pane
        self.watermarker = WaterMarker

        self.progress_var = IntVar()
        self.file_count = IntVar()
        self.counter_frame = Frame(self)
        self.progress_bar = Progressbar(self, orient="horizontal",
                                        mode="determinate", length=600)
        self.time_tracker = RemainingTime(self.counter_frame)

        self.button_frame = Frame(self)
        self.start_button = Button(self.button_frame, text="Start",
                                   command=self.apply_watermarks, width=10)
        self.stop_button = Button(self.button_frame, text="Stop",
                                  command=self.stop_work, width=10)

        self.create_widgets()

    def create_widgets(self):
        """Create GUI"""
        self.counter_frame.pack()
        self.time_tracker.pack(side=LEFT, padx=(0, 10))
        Label(self.counter_frame, textvariable=self.progress_var).pack(side=LEFT)
        Label(self.counter_frame, text="/").pack(side=LEFT)
        Label(self.counter_frame, textvariable=self.file_count).pack(side=LEFT)

        self.progress_bar.pack()

        self.stop_button.config(state=DISABLED)
        self.start_button.pack(side=LEFT, padx=15)
        self.stop_button.pack(side=LEFT)
        self.button_frame.pack(pady=10)

    def fill_que(self):
        """
        Fill the worker que from the files in file selector,
        and prepare te progress bar
        """
        files = self.file_selector.get_file_paths()
        self.file_count.set(len(files))
        self.progress_bar.configure(maximum=len(files))
        self.time_tracker.set_max(len(files))
        for file in files:
            self.image_que.put(file)

    def is_existing_files(self):
        """
        Check if there's existing files which will be overwritten by the
        watermarker
        :return: True/False
        """
        out = self.option_pane.get_output_path()
        for _file in self.file_selector.get_file_paths():
            if os.path.isfile(self.option_pane.create_output_path(_file, out)):
                return True
        return False

    def apply_watermarks(self):
        """
        Fill the que, then prepare the watermarker
        before spawning workers
        """
        if len(self.file_selector.files) < 1:
            messagebox.showerror('Nothing to mark',
                                 'Please choose one or more files '
                                 'to mark.')
            return

        if self.is_existing_files():
            kwargs = {"title": "Overwrite files?",
                      "message": "Files already exists, want to overwrite?"}
            overwrite = messagebox.askyesno(**kwargs)
        else:
            # Shouldn't matter since there's no files.
            overwrite = False

        try:
            self.watermarker = WaterMarker(self.option_pane.get_watermark_path(),
                                           overwrite=overwrite)
        except Exception as e:
            self.handle_error(e)
            return

        self.stop_button.config(state=NORMAL)
        self.start_button.config(state=DISABLED)
        self.fill_que()
        self.start_work()

    def start_work(self):
        """
        The baby factory, spawns worker thread to apply the watermark to
        the images.
        Also locks the buttons and output selector
        """
        try:
            kwargs = {"pos": self.option_pane.get_watermark_pos(),
                      "padding": self.option_pane.get_padding(),
                      "scale": self.option_pane.should_scale(),
                      "opacity": self.option_pane.get_opacity()}
            output = self.option_pane.get_output_path()
            print(output)
        except BadOptionError as e:
            self.handle_error(e)
            return
        self.running = True
        self.option_pane.output_selector.lock()
        thread = threading.Thread(target=self.work,
                                  kwargs=kwargs, args=(output, ))
        self.time_tracker.start()
        thread.start()

    def reset(self):
        """
        Reset the worker, emptying queue, resetting vars and buttons and stuff.
        """
        self.image_que = queue.Queue()
        self.watermarker = WaterMarker
        self.progress_var.set(0)
        self.progress_bar.stop()
        self.time_tracker.stop()
        self.file_count.set(0)
        self.start_button.config(state=NORMAL)
        self.stop_button.config(state=DISABLED)
        self.option_pane.output_selector.unlock()

    def handle_error(self, e):
        """
        Handle an error, showing the callback to the user.
        Is meant to be primarily used with BadOption error with a custom text.
        :param e: Error object.
        """
        self.reset()
        messagebox.showerror("Error", str(e))

    def work(self, outpath, **kwargs):
        """
        Work instructions for the child workers
        keep grabbing a new image path and then apply free_mark with
        the watermarker, using option pane to create paths.
        Controls progress bar and timer_tracker as well
        """
        while self.running:
            try:
                input_path = self.image_que.get(block=False)
            except queue.Empty:
                self.start_button.config(state=NORMAL)
                self.stop_button.config(state=DISABLED)
                self.option_pane.output_selector.unlock()
                self.progress_var.set(0)
                self.file_count.set(0)
                self.running = False
                return
            try:
                self.watermarker.apply_watermark(input_path,
                                                 self.option_pane.create_output_path(input_path, outpath),
                                                 **kwargs)
            except BadOptionError as e:
                self.handle_error(e)
                print("Bad config, stopping\n", e)
                return
            except Exception as e:
                print("Error!\n", type(e), "\n", e)
            self.progress_bar.step(amount=1)
            self.time_tracker.step()
            self.progress_var.set(self.progress_var.get()+1)

        self.reset()

    def stop_work(self):
        self.running = False