コード例 #1
0
class Program(Tk):
    """
	Main GUI container
	"""
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        # MENU AND APPEARANCE SETUP
        logger.info("GUI init")
        self.title("Auto Basya")
        self.configure(bg="grey")
        self.columnconfigure((0, ), weight=1)
        self.main_menu = Menu(self)
        self.config(menu=self.main_menu)
        self.options_menu = Menu(self.main_menu, tearoff=0)
        self.set_options_menu()

        self.backend = Backend()

        # MAIN VARIABLES

        self.pf_names = self.backend.get_pf_names()
        self.pf_count = len(self.pf_names)

        self.path_to_config = 'campaigns_config.yml'

        self.input_data = self.load_config()

        self.rows = {pf: row for row, pf in enumerate(self.pf_names)}
        self.vars = {
            pf: BooleanVar(value=(pf in self.input_data))
            for pf in self.pf_names
        }
        self.frames = {
            pf: PlatformFrame(self,
                              name=pf,
                              row=self.rows[pf],
                              init_states=self.input_data[pf])
            for pf in self.input_data
        }

        # WELCOME MESSAGE
        self.welcome_lbl = None
        if not self.input_data:
            logger.info('Welcome Message')
            self.welcome_lbl = Label(
                self,
                text=
                u"Добро пожаловать в Авто Басю.\n\nПохоже, что это первый запуск программы (либо не было сохранено ни одной кампании).\n\nЧтобы приступить к работе, зайдите в\nНастройки > Платформы,\nчтобы выбрать платформы, с которыми предстоит работать, а также в\nНастройки > Google Таблица\nчтобы внести параметры Google таблицы, в которую предстоит экспортировать данные.",
                padx=10,
                pady=10)
            self.welcome_lbl.grid(row=0, column=0, padx=20, pady=30)

        # must be in the end of init
        self.set_footer()

    def set_options_menu(self):
        '''
		Options menu setup
		'''
        logger.info("options menu setup")

        self.main_menu.add_cascade(label="Настройки", menu=self.options_menu)
        self.options_menu.add_command(label="Платформы",
                                      command=self.pf_window)
        self.options_menu.add_command(label="Google Таблица",
                                      command=lambda: GSpreadWin(self.backend))
        self.options_menu.add_command(label="Ограничения", command=Limitations)

    def pf_window(self):
        '''
		Open platforms' checklist setting window
		'''
        logger.info("platforms window call")

        pf_window = Toplevel(padx=10, pady=10)
        pf_window.title("Платформы")

        # Subject to change to grid
        tip = Label(
            pf_window,
            text=
            "Отметьте галочкой платформы, \nиз которых требуется экспортировать данные"
        ).pack()

        pf_checkboxes = Frame(pf_window)

        MAX_ROWS = 8
        i = 0
        for column in range(8):
            if i < self.pf_count:
                for row in range(MAX_ROWS):
                    if i < self.pf_count:
                        Checkbutton(
                            pf_checkboxes,
                            text=self.pf_names[i],
                            variable=self.vars[self.pf_names[i]],
                            command=lambda x=self.pf_names[i]: self.
                            show_hide_pf(x),
                        ).grid(sticky="w", row=row, column=column)
                        i += 1

        pf_checkboxes.pack(fill='both', expand=True)

        platforms_ok_btn = Button(pf_window,
                                  text="OK",
                                  command=pf_window.destroy).pack(pady=10)

    def show_hide_pf(self, pf):
        '''
		Clears table for info inserting from widgets
		'''
        if self.vars[pf].get():
            logger.info(f"Call to create {pf} frame")
            if self.welcome_lbl:
                self.welcome_lbl.grid_forget()
            self.frames.update(
                {pf: PlatformFrame(self, name=pf, row=self.rows[pf])})
        else:
            logger.info(f"Call to delete {pf} frame")
            self.frames[pf].grid_forget()
            self.frames.pop(pf)

    def save_values(self):
        '''
		Saves entered info to internal dict
		'''
        logger.info('Call to save input')
        self.input_data.clear()
        for pf in self.pf_names:
            if self.vars[pf].get():
                self.input_data.update(self.frames[pf].get())
        logger.info(f'Input {self.input_data} saved to internal dict')

    def save_config(self):
        '''Saves campaign parsing parameters to disk'''

        logger.info('Call to save config file')
        with open(self.path_to_config, 'w', encoding='utf-8') as f:
            yaml.dump(self.input_data, f, allow_unicode=True)
        logger.info('Input saved to disk')

    def load_config(self):
        '''Loads campaign parsing parameters'''

        logger.info('Call to load config')
        if path.exists(self.path_to_config):
            with open(self.path_to_config, 'r', encoding='utf-8') as y:
                conf = yaml.safe_load(y)
            logger.info(f'Config loaded {conf}')
            return conf
        logger.info('Returning empty config')
        return {}

    def set_footer(self):
        '''
		Sets up footer of the GUI with two buttons
		'''

        self.footer = Frame(self)
        save_start_btn = Button(self.footer,
                                text="Сохранить и Запустить",
                                command=self.save_start_process_btn,
                                padx=5)
        save_btn = Button(self.footer,
                          text="Сохранить",
                          command=self.save_btn,
                          padx=5)
        save_btn.grid(row=0, column=1, sticky='E', padx=5, pady=10)
        save_start_btn.grid(row=0, column=2, sticky='E', padx=5, pady=10)
        self.footer.columnconfigure((0, ), weight=1)
        self.footer.grid(row=self.pf_count, column=0, pady=2, sticky='nsew')

    def set_progress_bar(self):
        '''
		Sets up progress bar to track the execution of the main process 
		in the backend
		'''
        # TO DO
        pass

    def save_start_process_btn(self):
        logger.info('Saving values to dict and to disk')
        self.save_values()
        self.save_config()
        self.set_progress_bar()
        logger.info('Running main backend process')
        logger.debug(f"Data given to backend: {self.input_data}")
        self.gs_warning = Label(self.footer,
                                text="Не заданы настройки Google таблицы")
        if self.backend.gs_setting_complete():
            self.gs_warning.grid_forget()
            self.backend.run(self.input_data)
        else:
            self.gs_warning.grid(row=0, column=0, sticky='E', padx=5, pady=10)

        Results_window(self.backend.get_result())

    def save_btn(self):
        logger.info('Saving values to dict and to disk')
        self.save_values()
        self.save_config()

    def run(self):
        self.mainloop()