예제 #1
0
 def init_window(self):
     self.parent.title("SupMold: SpringCalc")
     self.grid(column=0, row=0, sticky="nwse")
     mainFrame = Frame(self, relief='raised', borderwidth=1)
     mainFrame.grid(column=0, row=0, sticky='nsew')
     closeButton = Button(mainFrame, text='Cerrar', command=self.appQuit)
     closeButton.grid(column=0, row=3, padx=5, pady=5)
     nb = Notebook(mainFrame)
     tab1 = Frame(nb)
     tab2 = Frame(nb)
     tab3 = Frame(nb)
     nb.add(tab1, text="Compresión")
     nb.add(tab2, text="Extensión")
     nb.add(tab3, text="Torsión")
     nb.grid(column=0, row=1, sticky='nsew', padx=5, pady=5)
     msg = consoleFrame(mainFrame, 'Mensages')
     dataB = resource_path('wires.db')
     if not os.path.isfile(dataB):
         self.centerWindow()
         messagebox.showerror(
             "ERROR", "Base de datos {} inaccesible. "
             "Favor verificar permisos de lectura o "
             "ubicación de la misma".format(dataB))
         return
     self.sub1 = subWindow(tab1, Spring(database=dataB))
     self.sub1.init_widgets()
     self.sub2 = subWindow2(tab2, eSpring(database=dataB))
     self.sub2.init_widgets()
     self.sub3 = subWindow3(tab3, tSpring(database=dataB))
     self.sub3.init_widgets()
     self.centerWindow()
     nb.bind("<<NotebookTabChanged>>", self.tabChangedEvent)
예제 #2
0
class GuiMain:
    def __init__(self):
        """
        Main Gui Entrance
        """
        tkinter.Tk.report_callback_exception = self.throw
        # Main window
        self.destroyed = False
        LoggerGui.info("Initializing GUI")
        self.main_window = tkinter.Tk()
        self.main_window.wm_title("DRC Sim Server")
        icon = tkinter.PhotoImage(data=Resource("image/icon.gif").resource)
        self.main_window.tk.call("wm", "iconphoto", self.main_window, icon)
        self.main_window.protocol("WM_DELETE_WINDOW", self.on_closing)
        self.main_window.resizable(False, False)
        # Notebook
        self.tab_id = None
        self.notebook = Notebook(self.main_window, width=600, height=300)
        self.notebook.grid(column=0, row=0)
        self.notebook.bind("<<NotebookTabChanged>>", self.on_tab_changed)
        # Run Server Frame
        self.frame_run_server = FrameRunServer(self.notebook)
        self.notebook.add(self.frame_run_server, text="Run Server")
        # Get Key Frame
        self.frame_get_key = FrameGetKey(self.notebook)
        self.notebook.add(self.frame_get_key, text="Get Key")
        # Log Frame
        self.frame_log = FrameLog(self.notebook)
        self.notebook.add(self.frame_log, text="Log")
        # About Frame
        self.frame_about = FrameAbout(self.notebook)
        self.notebook.add(self.frame_about, text="About")

    @staticmethod
    def throw(*args):
        """
        Throw exceptions from Tkinter
        :param args: arguments
        :return: None
        """
        for arg in args:
            if isinstance(arg, Exception):
                LoggerGui.throw(arg)

    def after(self):
        """
        Empty loop to catch KeyboardInterrupt
        :return: None
        """
        self.main_window.after(1000, self.after)

    def start(self):
        """
        Start the main window loop
        :return:
        """
        LoggerGui.info("Opening GUI")
        self.after()
        self.main_window.mainloop()
        LoggerGui.info("GUI Closed")

    def stop(self):
        """
        Convenience function to call on_closing()
        :return: None
        """
        self.on_closing()

    def on_closing(self):
        """
        Close the main window and current tab
        :return: None
        """
        if self.destroyed:
            return
        self.destroyed = True
        LoggerGui.info("Closing GUI")
        if self.tab_id in self.notebook.children:
            self.notebook.children[self.tab_id].deactivate()
        try:
            self.main_window.destroy()
        except Exception as e:
            LoggerGui.exception(e)

    # noinspection PyUnusedLocal
    def on_tab_changed(self, event):
        """
        Close the previous tab and initialize a new one
        :param event: tab event
        :return: None
        """
        tab_id = self.notebook.select()
        tab_index = self.notebook.index(tab_id)
        tab_name = self.notebook.tab(tab_index, "text")
        LoggerGui.debug("Notebook tab changed to \"%s\" with id %d", tab_name,
                        tab_index)
        self.tab_id = tab_id.split(".")[len(
            tab_id.split(".")) - 1]  # Parse notebook/tab id to only tab id
        if self.notebook.children[self.tab_id].kill_other_tabs():
            for tab in self.notebook.children:
                if tab != self.tab_id:
                    self.notebook.children[tab].deactivate()
        self.notebook.children[self.tab_id].activate()
예제 #3
0
    print('y:', event.y)

    #selected = nb.identify(event.x, event.y)
    #print('selected:', selected) # it's not usefull

    clicked_tab = Tab.tk.call(Tab._w, "identify", "tab", event.x, event.y)
    print('clicked tab:', clicked_tab)

    active_tab = Tab.index(Tab.select())
    print(' active tab:', active_tab)

    if clicked_tab == 2:
        E1.focus()

    # if clicked_tab == active_tab:
    #     Tab.forget(clicked_tab)


Tab.bind('<Button-1>', on_click)

##### STATUS BAR ####
v_statusbar = StringVar()

statusbar = Label(F3,
                  textvariable=v_statusbar,
                  bd=1,
                  relief=SUNKEN,
                  anchor='w')
statusbar.pack(side=BOTTOM, fill=X)

GUI.mainloop()
class App:
    def __init__(self):
        # создание основного окна Tkinter
        self.window = Tk()
        self.window.title("Треугольники")
        self.window.geometry('520x520')
        self.window.minsize(520, 520)
        self.window.maxsize(520, 520)

        self.press_x, self.press_y = 0, 0
        self.release_x, self.release_y = 0, 0

        # флаги нажатия/отжатия кнопки
        self.pressed = False

        # размещение элементов интерфейса

        # основной элемент - Canvas
        self.canvas_x = 470
        self.canvas_y = 270
        self.c = Canvas(self.window,
                        width=self.canvas_x,
                        height=self.canvas_y,
                        bg='black')
        self.c.pack(side=TOP, padx=10, pady=(10, 10))

        # элементы управления: настройки, отображение параметров, очистка/выход
        setup = Frame(self.window, width=470)
        setup_left = Frame(setup, width=270)
        setup_right = Frame(setup, width=200)

        self.setup_notebook = Notebook(setup_left)

        setup1 = Frame(setup_left, width=250, height=140)
        setup2 = Frame(setup_left, width=250, height=140)
        setup3 = Frame(setup_left, width=250, height=140)

        # элементы управления на вкладках
        # вкладка 1
        Label(setup1, text='Длина стороны').pack(side=TOP,
                                                 pady=(10, 0),
                                                 padx=(10, 0),
                                                 anchor=W)
        self.scal_b = Scale(setup1,
                            orient=HORIZONTAL,
                            length=200,
                            from_=0,
                            to=300,
                            tickinterval=100,
                            resolution=10)
        self.scal_b.pack(side=TOP)
        self.scal_b.set(100)
        self.scal_b.bind("<ButtonRelease-1>", self.draw_triangle)
        Label(setup1, text='Угол \u03b1').pack(side=TOP,
                                               pady=(10, 0),
                                               padx=(10, 0),
                                               anchor=W)
        self.scal_alpha = Scale(setup1,
                                orient=HORIZONTAL,
                                length=200,
                                from_=0,
                                to=180,
                                tickinterval=30,
                                resolution=15)
        self.scal_alpha.pack(side=TOP)
        self.scal_alpha.set(30)
        self.scal_alpha.bind("<ButtonRelease-1>", self.draw_triangle)

        # вкладка 2
        Label(setup2, text='Угол \u03b1').pack(side=TOP,
                                               pady=(10, 0),
                                               padx=(10, 0),
                                               anchor=W)
        self.scal_alpha2 = Scale(setup2,
                                 orient=HORIZONTAL,
                                 length=200,
                                 from_=0,
                                 to=90,
                                 tickinterval=15,
                                 resolution=5)
        self.scal_alpha2.pack(side=TOP)
        self.scal_alpha2.set(60)
        self.scal_alpha2.bind("<ButtonRelease-1>", self.draw_triangle)
        Label(setup2, text='Угол \u03b2').pack(side=TOP,
                                               pady=(10, 0),
                                               padx=(10, 0),
                                               anchor=W)
        self.scal_beta = Scale(setup2,
                               orient=HORIZONTAL,
                               length=200,
                               from_=0,
                               to=90,
                               tickinterval=15,
                               resolution=5)
        self.scal_beta.pack(side=TOP)
        self.scal_beta.set(60)
        self.scal_beta.bind("<ButtonRelease-1>", self.draw_triangle)

        # вкладка 3
        Label(setup3, text='Длина стороны 2').pack(side=TOP,
                                                   pady=(10, 0),
                                                   padx=(10, 0),
                                                   anchor=W)
        self.scal_a = Scale(setup3,
                            orient=HORIZONTAL,
                            length=200,
                            from_=0,
                            to=300,
                            tickinterval=100,
                            resolution=10)
        self.scal_a.pack(side=TOP)
        self.scal_a.set(100)
        self.scal_a.bind("<ButtonRelease-1>", self.draw_triangle)
        Label(setup3, text='Длина стороны 3').pack(side=TOP,
                                                   pady=(10, 0),
                                                   padx=(10, 0),
                                                   anchor=W)
        self.scal_b2 = Scale(setup3,
                             orient=HORIZONTAL,
                             length=200,
                             from_=0,
                             to=300,
                             tickinterval=100,
                             resolution=10)
        self.scal_b2.pack(side=TOP)
        self.scal_b2.set(100)
        self.scal_b2.bind("<ButtonRelease-1>", self.draw_triangle)

        setup1.pack()
        setup2.pack()
        setup3.pack()

        self.setup_notebook.add(setup1, text='Задача 1')
        self.setup_notebook.add(setup2, text='Задача 2')
        self.setup_notebook.add(setup3, text='Задача 3')
        self.setup_notebook.bind('<<NotebookTabChanged>>', self.draw_triangle)

        self.setup_notebook.pack(side=LEFT)

        columns = ('#1', '#2')
        self.params = Treeview(setup_right,
                               show='headings',
                               columns=columns,
                               height=5)
        self.params.heading('#1', text='Параметр')
        self.params.heading('#2', text='Значение')
        self.params.column('#1', width=110, minwidth=50, stretch=NO, anchor=N)
        self.params.column('#2', width=110, minwidth=50, stretch=NO, anchor=N)
        self.params.pack(side=TOP, padx=(15, 0), pady=(15, 5))

        butframe = Frame(setup_right)
        Button(butframe, text='Очистить', width=10,
               command=self.draw_base()).pack(side=LEFT, padx=(25, 5))
        Button(butframe,
               text='Выход',
               width=10,
               command=lambda x=0: sys.exit(x)).pack(side=LEFT, padx=(0, 10))
        butframe.pack(side=TOP, pady=(17, 5))

        setup_left.pack(side=LEFT, padx=(0, 20))
        setup_right.pack(side=LEFT)
        setup.pack(side=TOP, pady=(5, 10), padx=(5, 5))

        self.window.bind('<Button-1>', self.press)
        self.window.bind('<ButtonRelease-1>', self.release)
        self.window.bind('<Motion>', self.motion)

        self.draw_base()
        self.window.mainloop()

    def motion(self, event):
        if self.pressed:
            if event.widget.master is not None:
                if event.widget.widgetName == 'canvas':
                    self.draw_base()
                    self.c.create_line(
                        [self.press_x, self.press_y, event.x, event.y],
                        dash=True,
                        fill='yellow')

    def draw_base(self):
        self.c.delete("all")
        # базовые оси
        self.c.create_line([10, 250, 460, 250], arrow=LAST, fill='white')
        self.c.create_line([20, 260, 20, 10], arrow=LAST, fill='white')

        # метки
        for i in range(1, 5):
            self.c.create_line([100 * i + 20, 247, 100 * i + 20, 253],
                               fill='white')
        for i in range(1, 3):
            self.c.create_line([17, 250 - 100 * i, 23, 250 - 100 * i],
                               fill='white')

        # надписи
        # наименование осей
        self.c.create_text(457, 258, text='x', fill='white')
        self.c.create_text(30, 15, text='y', fill='white')
        # наименование меток
        for i in range(0, 5):
            self.c.create_text(100 * i + 25,
                               260,
                               text=str(100 * i),
                               fill='white')
        for i in range(1, 3):
            self.c.create_text(34,
                               250 - 100 * i,
                               text=str(100 * i),
                               fill='white')

    def press(self, event):
        """
        Обработчик события "нажатие кнопки мыши"
        :param event:
        :return:
        """
        if event.widget.master is not None:
            if event.widget.widgetName == 'canvas':
                self.draw_base()
                self.press_x, self.press_y = event.x, event.y
                self.pressed = True

    def release(self, event):
        if event.widget.master is not None:
            if event.widget.widgetName == 'canvas':
                self.release_x, self.release_y = event.x, event.y
                if (self.release_x in range(450)) & (self.release_y
                                                     in range(250)):
                    self.draw_triangle(None)
        self.pressed = False

    def check_coordinates(self, C):
        if (C[0] < 0) | (C[1] < 0):
            return False
        if (C[0] > self.canvas_x) | (C[1] > self.canvas_y):
            return False
        return True

    def draw_triangle(self, event):
        if (self.press_x > 0) & (self.press_y > 0) & (self.release_x > 0) & (
                self.release_y > 0):
            self.draw_base()
            triangle = Math((self.press_x, self.press_y),
                            (self.release_x, self.release_y), (20, 250))
            task = self.setup_notebook.index(self.setup_notebook.select()) + 1
            if task == 1:
                data_dict = {
                    'b': self.scal_b.get(),
                    'alpha': self.scal_alpha.get()
                }
            elif task == 2:
                data_dict = {
                    'alpha': self.scal_alpha2.get(),
                    'beta': self.scal_beta.get()
                }
            elif task == 3:
                data_dict = {'a': self.scal_a.get(), 'b': self.scal_b2.get()}
            else:
                return
            C1, C2, data_dict = triangle.get_c(task, data_dict)
            if self.check_coordinates(C1) & self.check_coordinates(C2):
                self.c.create_polygon([
                    self.press_x, self.press_y, self.release_x, self.release_y,
                    C1[0], C1[1]
                ],
                                      fill='red')
                self.c.create_polygon([
                    self.press_x, self.press_y, self.release_x, self.release_y,
                    C2[0], C2[1]
                ],
                                      fill='blue')
                self.update_treeview(data_dict)
            else:
                self.c.create_text(300,
                                   100,
                                   text='Одна из точек вне области построения',
                                   fill='white')

    def update_treeview(self, data):
        """
        запись параметров в элемент Treeview
        :return: None
        """
        for x in self.params.get_children():
            self.params.delete(x)
        for key in data.keys():
            self.params.insert("", END, values=[key, data[key]])
예제 #5
0
class App(Frame):
    def __init__(self, master):
        super().__init__(master)
        self.master = master
        self.syncFunc = []

    def setupUI(self, master, theme):
        self.master = master
        self.theme = theme
        self.username = None
        self.TkBal = StringVar()
        self.Admin = None
        #
        self.MainFrame = Frame(self)
        self.headerFrame = Frame(self.MainFrame)
        self.headerFrame.grid_columnconfigure(1, weight=1)
        self.head = Label(self.headerFrame,
                          text="SVK BANKING SYSTEMS",
                          font=("Arial", 18))
        self.ballb = Label(self.headerFrame,
                           text="Balance:    ",
                           font=("Arial", 18))
        self.ballb2 = Label(self.headerFrame,
                            textvariable=self.TkBal,
                            font=("Arial", 18))
        self.head.grid(row=0, column=0, sticky="w")
        self.headerFrame.pack(fill="x")
        self.MainFrame.pack(fill="both", expand=True)
        self.update
        #
        self.login()

    def login(self):
        self.loginContainer = Login.login(self.MainFrame, self.panel,
                                          self.TkBal)
        self.loginContainer.place(relx=0.5, rely=0.5, anchor="center")

    def panel(self):
        self.ballb.grid(row=0, column=1, sticky="e")
        self.ballb2.grid(row=0, column=2, sticky="e")
        self.username = self.loginContainer.username
        mycursor.execute(
            f"SELECT AcNo FROM profile WHERE username = '******';")
        self.acno = mycursor.fetchone()[0]
        style = Style(self)
        style.configure("leftTab.TNotebook", tabposition="s")
        style.theme_settings(
            self.theme,
            {"TNotebook.Tab": {
                "configure": {
                    "padding": [10, 10]
                }
            }})
        self.notebook = Notebook(self.MainFrame,
                                 style="leftTab.TNotebook",
                                 width=800,
                                 height=500)
        self.notebook.pack(expand=True, fill="both")
        self.notebook.bind("<<NotebookTabChanged>>", self.logout)
        self.tabs = {
            "Dasboard":
            Dasboard.dasboard(self.notebook, self.username),
            "Transactions":
            Transaction.transaction(self.notebook, self.acno, self.TkBal),
            "Pay":
            Pay.pay(self.notebook, self.acno, self.TkBal),
            "Change Password":
            ChangePsswd.change(self.notebook, self.username),
            "Settings":
            Admin.user(self.notebook, self.username),
        }
        self.syncFunc = [
            Dasboard.dasboard,
            Transaction.transaction,
            Pay.pay,
            ChangePsswd.change,
            Admin.user,
        ]
        mycursor.execute(
            f"SELECT Admin FROM profile WHERE username = '******';")
        self.images = {}
        self.Tkimages = {}
        self.ImageIter = 0
        for image in [
                "Dasboard",
                "Transactions",
                "Pay",
                "Change Password",
                "Settings",
                "add_user",
                "view",
                "leave",
        ]:
            self.images[image] = Image.open(f".//assets//{image}.png")
            self.images[image].thumbnail((30, 30), Image.ANTIALIAS)
            self.Tkimages[image] = ImageTk.PhotoImage(self.images[image])

        for tab in self.tabs.keys():
            self.notebook.add(
                self.tabs[tab],
                text=tab,
                image=self.Tkimages[tab.strip()],
                compound="top",
            )
            self.ImageIter += 1

        if mycursor.fetchone()[0]:
            self.notebook.add(
                Admin.admin(self.notebook, self.username),
                text="Add/Edit Ac",
                image=self.Tkimages["add_user"],
                compound="top",
            )
            self.syncFunc.append(Admin.admin)
            self.notebook.add(
                Transaction.view(self.notebook),
                text="View Clients",
                image=self.Tkimages["view"],
                compound="top",
            )
            self.syncFunc.append(Transaction.view)

        self.notebook.add(Frame(),
                          text="Logout",
                          image=self.Tkimages["leave"],
                          compound="top")

    def logout(self, key=None):
        try:
            if key.widget.select() == self.notebook.tabs()[-1]:
                self.master.quit()
                self.master.destroy()
                mydb.close()
                with open("isExit", "w") as isExit:
                    isExit.write("true")
                sys.exit()
        except:
            pass
예제 #6
0
class App(tk.Tk):
    window = None

    def get_title(self, info):
        return "Музыка {} {} (id{})".format(info["first_name"],
                                            info["last_name"], info["id"])

    def __init__(self, audio_obj, vk_audio, info):
        #initialize self
        if (App.window is not None): return
        super().__init__()
        self.vk_audio = vk_audio
        self.geometry('733x450')
        self.columnconfigure(0, weight=1)

        self.count, self.SortDir, self.player_window = False, True, None

        #initialize notebook
        self.tabs = Notebook(self)
        self.tabs.place(x=0, y=0, relwidth=1, relheight=1)
        self.tabs.bind('<<NotebookTabChanged>>', self.tab_changed)

        self.list = []
        self.add_tab(audio_obj, info)
        App.window = self

    def add_tab(self, audio: vk_audio.Audio, info):
        if (audio in self.list):
            self.tabs.select(self.list.index(audio))
            return
        title = self.get_title(info)
        f = tk.Frame(self.tabs)
        tk.Button(f, text="Закрыть", command=self.on_close_tab_clicked).pack()
        #add_albums_frame
        if (audio.Playlists):
            AlbumsFrame(f, audio.Playlists, self.add_tab_playlist,
                        self.author_clicked).pack(side=tk.TOP,
                                                  fill=tk.BOTH,
                                                  expand=False)
        #add_audios_frame
        AudiosFrame(f, audio.Audios, True).pack(fill=tk.BOTH,
                                                expand=True,
                                                side=tk.BOTTOM)
        self.tabs.add(f, text=title)
        self.list.append(audio)
        self.focus_force()
        self.tabs.select(len(self.list) - 1)
        return self

    def on_close_tab_clicked(self):
        t = self.tabs.select()
        index = self.tabs.tabs().index(t)
        self.list.pop(index)
        if (not self.list): self.destroy()
        self.tabs.forget(t)

    def tab_changed(self, event):
        tab = self.tabs.tab(
            event.widget.index("current"
                               ) if not isinstance(event, int) else event)
        self.title(tab['text'])

    def add_tab_playlist(self, playlist: vk_audio.Playlist):
        if (playlist in self.list):
            self.tabs.select(self.list.index(playlist))
            return
        self.list.append(playlist)
        title = "Плейлист {} (id{})".format(playlist.title, playlist.owner_id)
        f = tk.Frame(self.tabs)
        tk.Button(f, text="Закрыть", command=self.on_close_tab_clicked).pack()

        #region add playlist info
        tk.Label(f, text=playlist.title, font=('times', 16)).pack()

        author = tk.Label(f,
                          text=",".join(i['name']
                                        for i in playlist.author_info),
                          font=AlbumsFrame.DEFAULT_FONT,
                          fg=AlbumsFrame.DEF_FG,
                          cursor="hand2")
        author.pack()
        author.bind("<Button-1>", lambda _: self.author_clicked(playlist))
        author.bind(
            "<Enter>", lambda _: author.config(font=AlbumsFrame.HOVER_FONT,
                                               fg=AlbumsFrame.HOVER_FG))
        author.bind(
            "<Leave>", lambda _: author.config(font=AlbumsFrame.DEFAULT_FONT,
                                               fg=AlbumsFrame.DEF_FG))

        img = tk.Canvas(f, width=160, height=160)
        img.pack(pady=5)

        AlbumsFrame.set_image_from_album(None, img, playlist)
        #endregion
        AudiosFrame(f, playlist.Audios, True).pack(fill=tk.BOTH,
                                                   expand=True,
                                                   side=tk.BOTTOM)
        self.tabs.add(f, text=title)
        self.focus_force()
        self.tabs.select(len(self.list) - 1)

    def author_clicked(self, playlist):
        if (playlist.author_hrefs):
            for i, item in enumerate(self.list):
                if (isinstance(item, vk_audio.Audio)
                        and item.owner_id == playlist.owner_id):
                    self.tabs.select(i)
                    break
            else:
                artist_music = playlist.artist_music(0)

                self.add_tab(
                    artist_music, {
                        "first_name": artist_music.nick,
                        "last_name": "",
                        "id": artist_music.owner_id
                    })
        elif (playlist.owner_id > 0):
            for i, item in enumerate(self.list):
                if (isinstance(item, vk_audio.Audio)
                        and item.owner_id == playlist.owner_id):
                    self.tabs.select(i)
                    break
            else:
                self.add_tab(self.vk_audio.load(playlist.owner_id))

        else:
            messagebox.showerror("Ошибка", "Пока брать музыку у артиста(")

    def destroy(self):
        if (App.window is self):
            App.window = None
        return super().destroy()

    @staticmethod
    def get(item=None, owner_id=None, vk_audio=None, info=None):
        if (item is None and vk_audio is not None):
            item = vk_audio.load(owner_id=owner_id)
        return App(
            audio_obj=item, info=info,
            vk_audio=vk_audio) if App.window is None else App.window.add_tab(
                item, info)
예제 #7
0
def tab_changed(event):
    """notebook handler changes width and height after a tab is selected

    Parameters
    ----------
    event : str
        bind event
    """
    event.widget.update_idletasks()
    tc1 = event.widget.nametowidget(event.widget.select())
    event.widget.configure(height=tc1.winfo_reqheight(),
                           width=tc1.winfo_reqwidth())


nb1 = Notebook(root, style='green.TNotebook')
nb1.bind("<<NotebookTabChanged>>", tab_changed)
nb1.grid(row=0, column=0)
nb1.enable_traversal()

# first page
page1 = Frame(root, background='red', height=70 * mult)

enabler = Button(page1,
                 text='Enable Tab two\n Test it out',
                 command=lambda: nb1.tab(1, state='normal'))
enabler.pack(ipadx=5, ipady=5)

nb1.add(page1, text='one', underline=0, padding=2)

# second page
page2 = Frame(root, background='yellow', height=20 * mult)
예제 #8
0
class Manager(Toplevel):
    """Note manager."""
    def __init__(self, master):
        """Create note manager to easily delete multiple notes."""
        Toplevel.__init__(self, master, class_='MyNotes')
        self.title(_("Note Manager"))
        self.minsize(width=546, height=200)
        self.grab_set()
        categories = CONFIG.options("Categories")
        categories.sort()

        self.im_del = PhotoImage(file=IM_DELETE, master=self)
        self.im_change = PhotoImage(file=IM_CHANGE, master=self)
        self.im_visible = PhotoImage(file=IM_VISIBLE_24, master=self)
        self.im_hidden = PhotoImage(file=IM_HIDDEN_24, master=self)

        tooltipwrapper = TooltipWrapper(self)

        self.notebook = Notebook(self)
        self.notebook.pack(fill='both', expand=True)

        self.texts = {}
        self.frames = {}
        self.notes = {}

        # to change notes category
        menu_cat = Menu(self, tearoff=False)
        self.category = StringVar(self)

        # create one tab per category
        for cat in categories:
            menu_cat.add_radiobutton(label=cat.capitalize(),
                                     value=cat,
                                     variable=self.category,
                                     command=self.change_cat_selection)
            self.notes[cat] = {}
            frame = Frame(self.notebook, padding=2)
            self.texts[cat] = Text(frame,
                                   width=1,
                                   height=1,
                                   bg=self.cget('bg'),
                                   relief='flat',
                                   highlightthickness=0,
                                   padx=0,
                                   pady=0,
                                   cursor='arrow')
            frame.columnconfigure(0, weight=1)
            frame.rowconfigure(1, weight=1)

            self.texts[cat].grid(row=1, column=0, sticky='ewsn')
            scrolly = Scrollbar(frame,
                                orient='vertical',
                                command=self.texts[cat].yview)
            scrolly.grid(row=1, column=1, sticky='ns', pady=(2, 0))
            scrollx = Scrollbar(frame,
                                orient='horizontal',
                                command=self.texts[cat].xview)
            scrollx.grid(row=2, column=0, sticky='ew')
            self.texts[cat].configure(xscrollcommand=scrollx.set,
                                      yscrollcommand=scrolly.set)
            self.frames[cat] = Frame(self.texts[cat],
                                     style='bg.TFrame',
                                     padding=1,
                                     height=29,
                                     width=523)
            self.frames[cat].columnconfigure(0, weight=1, minsize=170)
            headings = Frame(frame, padding=(1, 0, 1, 0))
            headings.columnconfigure(0, weight=0, minsize=20)
            headings.columnconfigure(1, weight=1, minsize=198)
            headings.columnconfigure(2, weight=1, minsize=198)
            headings.columnconfigure(3, weight=0, minsize=84)
            headings.columnconfigure(4, weight=0, minsize=22)
            Heading(headings,
                    cat,
                    'title',
                    command=self.sort_column,
                    text=_('Title')).grid(row=0, column=1, sticky='ew')
            Heading(headings,
                    cat,
                    'text',
                    command=self.sort_column,
                    text=_('Text')).grid(row=0, column=2, sticky='ew')
            Heading(headings,
                    cat,
                    'date',
                    command=self.sort_column,
                    text=_('Date')).grid(row=0, column=3, sticky='ew')
            Heading(headings,
                    cat,
                    'select_all',
                    style='select.heading.TLabel',
                    padding=0,
                    command=self.toggle_selectall).place(x=0,
                                                         y=0,
                                                         anchor='nw',
                                                         relheight=1,
                                                         width=20)
            Heading(headings, cat, 'visibility',
                    command=self.sort_column).place(relx=1,
                                                    y=0,
                                                    anchor='ne',
                                                    bordermode='outside',
                                                    width=23,
                                                    relheight=1)
            headings.place(x=0, y=2, anchor='nw')
            self.update_idletasks()
            frame.rowconfigure(0, minsize=headings.winfo_reqheight())
            self.texts[cat].window_create('1.0', window=self.frames[cat])
            b_frame = Frame(frame)
            b_frame.grid(row=3, columnspan=2)
            m = Menubutton(b_frame,
                           image=self.im_change,
                           text=_('Change category'),
                           compound='right',
                           menu=menu_cat,
                           padding=1)
            m.pack(side='left', padx=4, pady=4, fill='y')
            tooltipwrapper.add_tooltip(m,
                                       _('Change category of selected notes'))
            b_show = Button(b_frame,
                            image=self.im_visible,
                            padding=1,
                            command=self.show_selection)
            b_show.pack(side='left', padx=4, pady=4)
            tooltipwrapper.add_tooltip(b_show, _('Show selected notes'))
            b_hide = Button(b_frame,
                            image=self.im_hidden,
                            padding=1,
                            command=self.hide_selection)
            b_hide.pack(side='left', padx=4, pady=4)
            tooltipwrapper.add_tooltip(b_hide, _('Hide selected notes'))
            b_del = Button(b_frame,
                           image=self.im_del,
                           command=self.del_selection,
                           padding=1)
            b_del.pack(side='left', padx=4, pady=4, fill='y')
            tooltipwrapper.add_tooltip(b_del, _('Delete selected notes'))

            self.notebook.add(frame,
                              text=cat.capitalize(),
                              sticky="ewsn",
                              padding=0)
        # display notes by category
        for key, note_data in self.master.note_data.items():
            self.display_note(key, note_data)

        for txt in self.texts.values():
            txt.configure(state='disabled')
        self.geometry('410x450')
        self.bind("<Button-4>", lambda e: self.scroll(-1))
        self.bind("<Button-5>", lambda e: self.scroll(1))
        self.notebook.bind('<<NotebookTabChanged>>', self.on_change_tab)

    def toggle_selectall(self, event):
        heading = event.widget
        cat = heading.category
        sel = self.get_selection(cat)
        if len(sel) == len(self.notes[cat]):
            for widget in self.notes[cat].values():
                widget.state(('!selected', ))
        else:
            for widget in self.notes[cat].values():
                widget.state(('selected', ))

    def show_selection(self):
        cat = self.notebook.tab('current', 'text').lower()
        sel = self.get_selection(cat)
        if sel:
            for key in sel:
                self.notes[cat][key].visibility.set(True)
                self.toggle_visibility(key, True)

    def hide_selection(self):
        cat = self.notebook.tab('current', 'text').lower()
        sel = self.get_selection(cat)
        if sel:
            for key in sel:
                self.notes[cat][key].visibility.set(False)
                self.toggle_visibility(key, False)

    def select_all(self):
        cat = self.notebook.tab('current', 'text').lower()
        for widget in self.notes[cat].values():
            widget.state(('selected', ))

    def deselect_all(self):
        cat = self.notebook.tab('current', 'text').lower()
        for widget in self.notes[cat].values():
            widget.state(('!selected', ))

    def sort_column(self, event):
        """Sort column."""
        heading = event.widget
        notes = [(item.get(heading.column), item.get_values(), item)
                 for item in self.notes[heading.category].values()]
        notes.sort(reverse=heading.reverse, key=lambda x: x[:-1])
        for i, (val, values, item) in enumerate(notes):
            item.grid_configure(row=i)
        heading.reverse = not heading.reverse
        heading.state(['!' * heading.reverse + 'alternate'])

    def toggle_visibility(self, key, visible):
        if visible:
            if key not in self.master.notes:
                self.master.show_note(key)
        else:
            if key in self.master.notes:
                self.master.notes[key].hide()
        self.after(2, self.focus_set)
        self.after(4, self.grab_set)

    def display_note(self, key, note_data):
        """Display note in note manager."""
        cat = note_data["category"]
        c, r = self.frames[cat].grid_size()
        self.notes[cat][key] = ManagerItem(
            self.frames[cat], note_data,
            lambda vis: self.toggle_visibility(key, vis))
        self.notes[cat][key].grid(row=r, sticky='ew')

    def on_change_tab(self, event):
        self.category.set(self.notebook.tab("current", "text").lower())

    def del_selection(self):
        """Delete selected notes."""
        cat = self.notebook.tab('current', 'text').lower()
        sel = self.get_selection(cat)
        if sel:
            rep = askokcancel(_("Confirmation"),
                              _("Delete the selected notes?"))
            if rep:
                for key in sel:
                    self.master.delete_note(key)
                    self.notes[cat][key].destroy()
                    del self.notes[cat][key]
                    self.update_idletasks()

    def change_cat_selection(self):
        """Change selected notes category."""
        cat = self.notebook.tab('current', 'text').lower()
        new_cat = self.category.get()
        sel = self.get_selection(cat)
        if sel and new_cat != cat:
            rep = askokcancel(_("Confirmation"),
                              _("Change the category of the selected notes?"))
            if rep:
                for key in sel:
                    self.master.change_note_category(key, new_cat)
                    self.notes[cat][key].destroy()
                    del self.notes[cat][key]
                    self.display_note(key, self.master.note_data[key])
                    self.update_idletasks()
        self.category.set(cat)
        self.grab_set()

    def get_selection(self, cat):
        sel = []
        for key, widget in self.notes[cat].items():
            if 'selected' in widget.state():
                sel.append(key)
        return sel

    def scroll(self, delta):
        cat = self.notebook.tab("current", "text").lower()
        top, bottom = self.texts[cat].yview()
        top += delta * 0.05
        top = min(max(top, 0), 1)
        self.texts[cat].yview_moveto(top)
예제 #9
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.tabs_control = Notebook(self.root,
                                     height=100,
                                     width=30,
                                     padding=(10, 20, 30, 40))
        self.tabs_control.enable_traversal()
        self.tab_1 = Frame(self.tabs_control)
        self.tabs_control.add(self.tab_1, text="First tab", underline=0)

        self.tab_2 = Frame(self.tabs_control)
        self.tabs_control.add(self.tab_2, text="Second tab", underline=1)

        self.tabs_control.bind("<<NotebookTabChanged>>", self.tab_changed)

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

    def draw_widgets(self):
        self.draw_menu()
        self.tabs_control.pack(fill=BOTH, expand=1)

        Label(self.tab_1, text="Hello on the fist tab!", height=5,
              bg="green").pack()
        Text(self.tab_2).pack()

        # self.tabs_control.forget(self.tab_2)
        # self.tabs_control.forget(1)

        tab_3 = Frame(self.tabs_control)
        # self.tabs_control.insert(END, tab_3, text="Third tab")
        self.tabs_control.insert("end", tab_3, text="Third tab")

        tab_4 = Frame(self.tabs_control)
        self.tabs_control.insert(2, tab_4, text="Fourth tab")

        self.tabs_control.select(tab_3)
        print(f"Selected tab: {self.tabs_control.select()}")

        print(f"tab_4 params: {self.tabs_control.tab(tab_4)}")
        print(f"tab_4 params: {self.tabs_control.tab(tab_4, 'sticky')}")
        self.tabs_control.tab(tab_4, text="4th tab", underline=1)
        print(f"tab_4 params: {self.tabs_control.tab(tab_4)}")

        print(f"Managed tabs: {self.tabs_control.tabs()}")

        print(f"Params: {self.tabs_control.tab(0)}")
        print(f"Params: {self.tabs_control.tab('current')}")
        # print(f"Params: {self.tabs_control.tab(CURRENT)}")
        print(f"Params: {self.tabs_control.tab(self.tab_2)}")

    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 tab_changed(self, event):
        print(f"Changed tab to: {self.tabs_control.select()}")

    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)
예제 #10
0
class OptionsView:
    def __init__(self, settings, root, textFrameManager):
        self._settings = settings
        self._root = root
        self._textFrameManager = textFrameManager

        self._highlightWorker = None
        self._guiWorker = None

        self._showing = False
        self._saving = False

        self._textFrame: TF.TextFrame = None

    def linkWorkers(self, workers):
        self._highlightWorker = workers.highlightWorker
        self._guiWorker = workers.guiWorker

    def linkTextFrame(self, textFrame):
        self._textFrame = textFrame

    def _onClosing(self, savingSettings=False):

        # Delete all variable observers
        for settingsLine in list(self._setsDict.values()):
            for entry in list(settingsLine.entries.values()):
                try:
                    entry.var.trace_vdelete("w", entry.observer)
                except:
                    pass

        # Delete all view elements
        del self._setsDict

        # Close window
        self._view.destroy()

        if not savingSettings:
            self._showing = False

    class SettingsLineTemplate:
        def __init__(self, setGroup, setId, setDisplayName, setType):
            self.setGroup = setGroup
            self.setId = setId
            self.setDisplayName = setDisplayName
            self.setType = setType

    class SettingsLine:
        def __init__(self, group):
            self.group = group
            self.entries = dict()

    class LineColorSettingsLine(SettingsLine):
        def __init__(self, group):
            super().__init__(group)
            self.lineFrame = None

    class Entry:
        def __init__(self, entryType, entryVar):
            self.label: tk.Label = None
            self.var = None
            self.observer = None
            self.input: tk.Entry = None
            self.button: tk.Button = None
            self.data = OptionsView.EntryData(entryType, entryVar)

        def isVarUpdated(self):
            updated = False
            try:
                updated = self.var.get() != self.data.entryVar
            except AttributeError:
                traceLog(LogLevel.ERROR,
                         "Tkinter var in OptionsView not initiated")
                updated = True
            return updated

    class EntryData:
        def __init__(self, entryType, entryVar):
            self.entryType = entryType
            self.entryVar = entryVar
            self.validation = OptionsView.EntryDataValidation(
                OptionsView.ENTRY_VALIDATION_OK, "white", "")

    class EntryDataValidation:
        def __init__(self, status, backgroundColor, infoText):
            self.status = status
            self.backgroundColor = backgroundColor
            self.infoText = infoText

    ENTRY_TYPE_COLOR = "typeColor"
    ENTRY_TYPE_STRING = "typeString"
    ENTRY_TYPE_INT = "typeInt"
    ENTRY_TYPE_REGEX = "typeRegex"
    ENTRY_TYPE_TOGGLE = "typeToggle"
    ENTRY_TYPE_OTHER = "typeOther"

    ENTRY_VALIDATION_OK = "entryValidationOk"
    ENTRY_VALIDATION_FAILED = "entryValidationFailed"
    ENTRY_VALIDATION_DUPLICATE = "entryValidationDuplicate"

    GROUP_TEXT_AREA = "groupTextArea"
    GROUP_SEARCH = "groupSearch"
    GROUP_LOGGING = "groupLogging"
    GROUP_LINE_COLORING = "groupLineColoring"

    EDIT_UP = "editUp"
    EDIT_DOWN = "editDown"
    EDIT_DELETE = "editDelete"

    ROW_HIGHLIGHT_COLOR = "gray"

    LOG_EXAMPLE_FILE = r"appdata\log_example.txt"

    def _loadLogExample(self):
        log = "[12:34:56.789] Main::test\n[12:34:56.789] Main::TestTwo"
        try:
            with open(
                    os.path.join(self._settings.get(Sets.CT_HOMEPATH_FULL),
                                 self.LOG_EXAMPLE_FILE), "r") as file:
                log = file.read()
        except FileNotFoundError:
            traceLog(LogLevel.WARNING,
                     "Log example file not found. Using default example")
        return log

    def show(self):

        # Only allow one options view at a time # TODO Can be done with a global var, then a global instance of OptionsView is not needed
        if not self._showing:

            self._showing = True

            self._lineColorMap = self._textFrame.getLineColorMap()

            self._view = tk.Toplevel(self._root)
            self._view.title("Options")
            self._view.protocol("WM_DELETE_WINDOW", self._onClosing)

            self._view.iconbitmap(self._settings.get(Sets.ICON_PATH_FULL))

            self._setsDict = dict()

            ##############################
            # TAB CONTROL

            self._tabsFrame = tk.Frame(self._view)
            self._tabsFrame.grid(row=0, column=0, sticky="nsew")
            self._view.columnconfigure(0, weight=1)
            self._view.rowconfigure(0, weight=1)

            self._tabControl = Notebook(self._tabsFrame, padding=10)

            self._tabControl.grid(row=0, column=0, sticky=tk.N)
            self._tabList = list()

            ##############################
            # TEXT EXAMPLE

            logExample = self._loadLogExample()
            exampleTextFrameHeightMin = 400
            exampleTextFrameWidth = 650

            self._exampleTextFrame = tk.Frame(self._tabsFrame,
                                              height=exampleTextFrameHeightMin,
                                              width=exampleTextFrameWidth)
            self._exampleTextFrame.grid(row=0,
                                        column=1,
                                        padx=(0, 10),
                                        pady=(10, 10),
                                        sticky="nsew")
            self._exampleTextFrame.grid_propagate(False)
            self._tabsFrame.columnconfigure(1, weight=1)
            self._tabsFrame.rowconfigure(0, weight=1)

            tFont = Font(family=self._settings.get(Sets.TEXTAREA_FONT_FAMILY),
                         size=self._settings.get(Sets.TEXTAREA_FONT_SIZE))
            self._exampleText = tk.Text(self._exampleTextFrame,height=1, width=2,\
                                            background=self._settings.get(Sets.TEXTAREA_BACKGROUND_COLOR),\
                                            selectbackground=self._settings.get(Sets.TEXTAREA_SELECT_BACKGROUND_COLOR),\
                                            foreground=self._settings.get(Sets.TEXTAREA_COLOR),\
                                            font=tFont)
            self._exampleText.grid(row=0,
                                   column=0,
                                   padx=(0, 0),
                                   pady=(10, 0),
                                   sticky="nsew")
            self._exampleTextFrame.columnconfigure(0, weight=1)
            self._exampleTextFrame.rowconfigure(0, weight=1)

            self._updateExampleTextLineWrap(
                self._settings.get(Sets.TEXTAREA_LINE_WRAP))

            self._exampleText.insert(1.0, logExample)

            xscrollbar = tk.Scrollbar(self._exampleTextFrame,
                                      orient=tk.HORIZONTAL,
                                      command=self._exampleText.xview)
            xscrollbar.grid(row=1, column=0, sticky=tk.W + tk.E)
            self._exampleText["xscrollcommand"] = xscrollbar.set

            yscrollbar = tk.Scrollbar(self._exampleTextFrame,
                                      orient=tk.VERTICAL,
                                      command=self._exampleText.yview)
            yscrollbar.grid(row=0, column=1, sticky=tk.N + tk.S)
            self._exampleText["yscrollcommand"] = yscrollbar.set

            ###############
            # Tab: Line Coloring

            self._lineColoringFrame = tk.Frame(self._tabControl,
                                               padx=5,
                                               pady=5)
            self._lineColoringFrame.grid(row=0, column=0, sticky=tk.N)
            self._tabControl.add(self._lineColoringFrame, text="Line Coloring")
            self._tabList.append(self.GROUP_LINE_COLORING)

            self._setsDict.update(
                self._createLineColorRows(self._lineColoringFrame,
                                          self._lineColorMap))

            upButton = tk.Button(self._lineColoringFrame,
                                 text="UP",
                                 command=partial(self._editLineColorRow,
                                                 self.EDIT_UP))
            upButton.grid(row=0, column=2, padx=2)

            downButton = tk.Button(self._lineColoringFrame,
                                   text="DOWN",
                                   command=partial(self._editLineColorRow,
                                                   self.EDIT_DOWN))
            downButton.grid(row=1, column=2, padx=2)

            deleteButton = tk.Button(self._lineColoringFrame,
                                     text="Delete",
                                     command=partial(self._editLineColorRow,
                                                     self.EDIT_DELETE))
            deleteButton.grid(row=2, column=2, padx=2)
            self._lastFocusInRowId = ""
            self._lastFocusOutRowId = ""

            self._newButtonRow = len(self._lineColorMap)
            self._newButton = tk.Button(self._lineColoringFrame,
                                        text="New Line",
                                        command=partial(
                                            self._addNewEmptyLineColor))
            self._newButton.grid(row=self._newButtonRow,
                                 column=0,
                                 sticky=tk.W,
                                 padx=(2, 100),
                                 pady=2)

            self._deletedLineColorRows = list()

            ###############
            # Tab: Text Area

            self._textAreaFrame = tk.Frame(self._tabControl, padx=5, pady=5)
            self._textAreaFrame.grid(row=0, column=0, sticky=tk.N)
            self._tabControl.add(self._textAreaFrame, text="Text Area")
            self._tabList.append(self.GROUP_TEXT_AREA)

            setLines = list()
            setLines.append(
                self.SettingsLineTemplate(self.GROUP_TEXT_AREA,
                                          Sets.TEXTAREA_BACKGROUND_COLOR,
                                          "Background Color",
                                          self.ENTRY_TYPE_COLOR))
            setLines.append(
                self.SettingsLineTemplate(
                    self.GROUP_TEXT_AREA,
                    Sets.TEXTAREA_SELECT_BACKGROUND_COLOR,
                    "Background Color Select", self.ENTRY_TYPE_COLOR))
            setLines.append(
                self.SettingsLineTemplate(self.GROUP_TEXT_AREA,
                                          Sets.TEXTAREA_COLOR, "Text Color",
                                          self.ENTRY_TYPE_COLOR))
            setLines.append(
                self.SettingsLineTemplate(self.GROUP_TEXT_AREA,
                                          Sets.TEXTAREA_FONT_FAMILY,
                                          "Font Family",
                                          self.ENTRY_TYPE_STRING))
            setLines.append(
                self.SettingsLineTemplate(self.GROUP_TEXT_AREA,
                                          Sets.TEXTAREA_FONT_SIZE, "Font Size",
                                          self.ENTRY_TYPE_INT))
            setLines.append(
                self.SettingsLineTemplate(self.GROUP_TEXT_AREA,
                                          Sets.TEXTAREA_LINE_WRAP, "Line Wrap",
                                          self.ENTRY_TYPE_TOGGLE))

            self._setsDict.update(
                self._createStandardRows(self._textAreaFrame, setLines, 0))

            ###############
            # Tab: Search

            self._searchFrame = tk.Frame(self._tabControl, padx=5, pady=5)
            self._searchFrame.grid(row=0, column=0, sticky=tk.N)
            self._tabControl.add(self._searchFrame, text="Search")
            self._tabList.append(self.GROUP_SEARCH)

            setLines = list()
            setLines.append(
                self.SettingsLineTemplate(self.GROUP_SEARCH,
                                          Sets.SEARCH_MATCH_COLOR,
                                          "Search match background color",
                                          self.ENTRY_TYPE_COLOR))
            setLines.append(
                self.SettingsLineTemplate(self.GROUP_SEARCH,
                                          Sets.SEARCH_SELECTED_COLOR,
                                          "Search selected background color",
                                          self.ENTRY_TYPE_COLOR))
            setLines.append(
                self.SettingsLineTemplate(
                    self.GROUP_SEARCH, Sets.SEARCH_SELECTED_LINE_COLOR,
                    "Search selected line background color",
                    self.ENTRY_TYPE_COLOR))

            self._setsDict.update(
                self._createStandardRows(self._searchFrame, setLines, 0))

            ###############
            # Tab: Logging

            self._loggingFrame = tk.Frame(self._tabControl, padx=5, pady=5)
            self._loggingFrame.grid(row=0, column=0, sticky=tk.N)
            self._tabControl.add(self._loggingFrame, text="Logging")
            self._tabList.append(self.GROUP_LOGGING)

            setLines = list()
            setLines.append(
                self.SettingsLineTemplate(self.GROUP_LOGGING,
                                          Sets.LOG_FILE_PATH, "Log file path",
                                          self.ENTRY_TYPE_OTHER))
            setLines.append(
                self.SettingsLineTemplate(self.GROUP_LOGGING,
                                          Sets.LOG_FILE_BASE_NAME,
                                          "Log file base name",
                                          self.ENTRY_TYPE_OTHER))
            setLines.append(
                self.SettingsLineTemplate(self.GROUP_LOGGING,
                                          Sets.LOG_FILE_TIMESTAMP,
                                          "Time stamp", self.ENTRY_TYPE_OTHER))

            self._setsDict.update(
                self._createStandardRows(self._loggingFrame, setLines, 0))

            ##############################
            # CONTROL ROW

            self._optionsControlFrame = tk.Frame(self._view)
            self._optionsControlFrame.grid(row=1,
                                           column=0,
                                           padx=(10, 10),
                                           pady=(0, 10),
                                           sticky=tk.W + tk.E)

            self._optionsInfoLabel = tk.Label(self._optionsControlFrame,
                                              text="",
                                              justify=tk.LEFT)
            self._optionsInfoLabel.grid(row=0, column=0, sticky=tk.W)
            self._optionsControlFrame.columnconfigure(0, weight=1)

            self._optionsCancelButton = tk.Button(self._optionsControlFrame,
                                                  text="Cancel",
                                                  command=self._onClosing)
            self._optionsCancelButton.grid(row=0,
                                           column=1,
                                           padx=5,
                                           sticky=tk.E)

            self._optionsSaveButton = tk.Button(self._optionsControlFrame,
                                                text="Save",
                                                command=self._saveSettings)
            self._optionsSaveButton.grid(row=0, column=2, sticky=tk.E)
            if self._saving:
                self._optionsSaveButton.config(state=tk.DISABLED)
            else:
                self._optionsSaveButton.config(state=tk.NORMAL)

            self._tabControl.bind("<<NotebookTabChanged>>", self._tabChanged)

            # print("Number of settings " + str(len(self._setsDict)))

    def _saveSettings(self):

        saveSettingsThread = threading.Thread(target=self._saveSettingsProcess,
                                              name="SaveSettings")
        saveSettingsThread.start()

        self._saving = True

    def _setSaveButtonState(self, state):
        if self._showing:
            try:
                self._optionsSaveButton.config(state=state)
            except:
                # Catch if function is called while save button does not exist
                traceLog(LogLevel.ERROR, "Error updating save button state")

    def _saveSettingsProcess(self):
        # Saving will block, so must be done in different thread

        # setsDict will be deleted in the onClosing function
        tempSetsDict = self._setsDict

        # Close options view
        self._root.after(10, self._onClosing, True)

        # Get registered textFrames
        textFrames = self._textFrameManager.getTextFrames()

        # Show saving message
        for textFrame in textFrames:
            textFrame.showSpinner("Reloading View")

        # Stop workers using the settings
        self._highlightWorker.stopWorker(emptyQueue=False)
        self._guiWorker.stopWorker()

        # Save all settings
        tempLineColorMap = dict()
        tempLineColorRows = dict()
        # Sort settings to guarantee right order of line coloring
        for rowId in sorted(tempSetsDict.keys()):

            if Sets.LINE_COLOR_MAP in rowId:
                tempLineColorMap[rowId] = dict()
                tempLineColorRows[rowId] = tempSetsDict[rowId]

            for entryName in tempSetsDict[rowId].entries.keys():
                setting = tempSetsDict[rowId].entries[entryName].var.get()
                if Sets.LINE_COLOR_MAP in rowId:
                    tempLineColorMap[rowId][entryName] = setting
                else:
                    self._settings.setOption(rowId, setting)

        self._settings.setOption(Sets.LINE_COLOR_MAP, tempLineColorMap)

        # Once settings have been saved, allow for reopen of options view
        self._showing = False

        # Delete line color tags
        for deletedRowData in self._deletedLineColorRows:
            for textFrame in textFrames:
                textFrame.deleteTextTag(deletedRowData["tagName"])

        # Process added or updated line color rows
        for rowId in tempLineColorRows.keys():
            if tempLineColorRows[rowId].entries["regex"].isVarUpdated():
                if tempLineColorRows[rowId].entries["regex"].data.entryVar:
                    oldTagName = TF.createLineColorTagName(
                        tempLineColorRows[rowId].entries["regex"].data.entryVar
                    )
                    for textFrame in textFrames:
                        textFrame.deleteTextTag(oldTagName)
                    # print("Delete edited row id: " + rowId)
                for textFrame in textFrames:
                    textFrame.createAndAddLineColorTag(
                        tempLineColorRows[rowId].entries["regex"].var.get(),
                        tempLineColorRows[rowId].entries["color"].var.get())
                # print("Added line color row: " + rowId)

            elif tempLineColorRows[rowId].entries["color"].isVarUpdated():
                tagName = TF.createLineColorTagName(
                    tempLineColorRows[rowId].entries["regex"].var.get())
                for textFrame in textFrames:
                    textFrame.updateTagColor(
                        tagName,
                        tempLineColorRows[rowId].entries["color"].var.get())

        # Reorder line color tags
        rowIds = sorted(tempLineColorRows.keys())
        if rowIds:
            preTagName = TF.createLineColorTagName(
                tempLineColorRows[rowIds[0]].entries["regex"].var.get())
            for rowId in rowIds[1:-1]:
                tagName = TF.createLineColorTagName(
                    tempLineColorRows[rowId].entries["regex"].var.get())
                for textFrame in textFrames:
                    textFrame.textArea.tag_raise(tagName, aboveThis=preTagName)
                preTagName = tagName

        # print(*self._textFrame.textArea.tag_names(),sep=", ")

        # Reload main interface
        for textFrame in textFrames:
            textFrame.reloadLineColorMap()
            textFrame.reloadTextFrame()

        # Start workers
        self._highlightWorker.startWorker()
        self._guiWorker.startWorker()

        # Remove spinners
        for textFrame in textFrames:
            textFrame.closeSpinner()

        # Update save button, if window has been opened again
        self._root.after(10, self._setSaveButtonState, tk.NORMAL)
        self._saving = False

    ####################################
    # View Creation

    def _addNewEmptyLineColor(self):
        # print("New Button " + str(self.newButtonRow))

        self._newButton.grid(row=self._newButtonRow + 1)

        rowId = self._getRowId(self._newButtonRow)
        self._setsDict[rowId] = self._createSingleLineColorRow(
            self._lineColoringFrame, self._newButtonRow, rowId, "", "white")

        self._newButtonRow += 1

    def _editLineColorRow(self, edit):
        # print("Last focus in " + self.lastFocusInRowId)
        # print("Last focus out " + self.lastFocusOutRowId)

        # If lastFocusIn is not the same as lastFocusOut,
        # we know that lastFocusIn is currently selected.
        if self._lastFocusInRowId != self._lastFocusOutRowId:
            if Sets.LINE_COLOR_MAP in self._lastFocusInRowId:
                # print("EDIT: " + self.lastFocusInRowId)

                # Get row number
                # TODO Use getRowNum??
                rowNum = int(
                    self._lastFocusInRowId.replace(Sets.LINE_COLOR_MAP, ""))

                # Find index of rows to edit
                indexToChange = list()
                if edit == self.EDIT_UP:
                    if rowNum > 0:
                        indexToChange = [rowNum - 1, rowNum]
                elif edit == self.EDIT_DOWN:
                    if rowNum < (self._newButtonRow - 1):
                        indexToChange = [rowNum, rowNum + 1]
                elif edit == self.EDIT_DELETE:
                    indexToChange = range(rowNum, self._newButtonRow)

                if indexToChange:

                    tempTextColorMap = list()
                    for i in indexToChange:
                        # Save regex and color
                        rowId = self._getRowId(i)
                        tempTextColorMap.append((self._setsDict[rowId].entries["regex"].var.get(), \
                                                 self._setsDict[rowId].entries["regex"].data, \
                                                 self._setsDict[rowId].entries["color"].var.get(), \
                                                 self._setsDict[rowId].entries["color"].data))

                        # Remove rows to edit from view
                        self._setsDict[rowId].lineFrame.destroy()
                        del self._setsDict[rowId]

                    # Reorder or delete saved rows
                    newRowNum = -1
                    if edit == self.EDIT_UP:
                        tempTextColorMap[1], tempTextColorMap[
                            0] = tempTextColorMap[0], tempTextColorMap[1]
                        newRowNum = rowNum - 1
                    elif edit == self.EDIT_DOWN:
                        tempTextColorMap[1], tempTextColorMap[
                            0] = tempTextColorMap[0], tempTextColorMap[1]
                        newRowNum = rowNum + 1
                    elif edit == self.EDIT_DELETE:
                        deletedRowData = dict()
                        deletedRowData["tagName"] = TF.createLineColorTagName(
                            tempTextColorMap[0][0])
                        self._deletedLineColorRows.append(deletedRowData)
                        del tempTextColorMap[0]

                    # Recreate saved rows
                    for i, (regexVar, regexData, colorVar,
                            colorData) in enumerate(tempTextColorMap):
                        rowId = self._getRowId(indexToChange[i])
                        self._setsDict[rowId] = self._createSingleLineColorRow(
                            self._lineColoringFrame, indexToChange[i], rowId,
                            regexVar, colorVar)
                        self._setsDict[rowId].entries["regex"].data = regexData
                        self._setsDict[rowId].entries["color"].data = colorData

                    # If move up or down, refocus
                    if newRowNum > -1:
                        rowId = self._getRowId(newRowNum)
                        self._focusInSet(rowId)
                    # If delete, update row count and move newButton
                    else:
                        self._newButtonRow = self._newButtonRow - 1
                        self._newButton.grid(row=self._newButtonRow)
                        self._lastFocusInRowId = ""

                    self._updateExampleText(self.GROUP_LINE_COLORING)

    def _createLineColorRows(self, parent, lineColorMap):
        setDict = dict()
        for rowId in sorted(lineColorMap.keys()):
            rowNum = int(rowId.replace(Sets.LINE_COLOR_MAP, ""))
            setDict[rowId] = self._createSingleLineColorRow(
                parent, rowNum, rowId, lineColorMap[rowId]["regex"],
                lineColorMap[rowId]["color"])

        return setDict

    def _createSingleLineColorRow(self, parent, row, rowId, regex, color):
        colorLine = self.LineColorSettingsLine(self.GROUP_LINE_COLORING)

        colorLine.lineFrame = tk.Frame(parent,
                                       highlightcolor=self.ROW_HIGHLIGHT_COLOR,
                                       highlightthickness=2)
        colorLine.lineFrame.grid(row=row, column=0)
        colorLine.lineFrame.bind("<Button-1>", partial(self._focusInSet,
                                                       rowId))
        colorLine.lineFrame.bind("<FocusOut>", partial(self._focusOut, rowId))

        regexEntry = self.Entry(self.ENTRY_TYPE_REGEX, regex)
        entryName = "regex"

        regexEntry.label = tk.Label(colorLine.lineFrame, text="Regex")
        regexEntry.label.grid(row=0, column=0)
        regexEntry.label.bind("<Button-1>", partial(self._focusInSet, rowId))
        regexEntry.var = tk.StringVar(colorLine.lineFrame)
        regexEntry.var.set(regex)
        regexEntry.observer = regexEntry.var.trace(
            "w", partial(self._validateInput, rowId, entryName))

        regexEntry.input = tk.Entry(colorLine.lineFrame,
                                    textvariable=regexEntry.var,
                                    width=30,
                                    takefocus=False)
        regexEntry.input.grid(row=0, column=1)
        regexEntry.input.bind("<Button-1>", partial(self._focusInLog, rowId))

        colorLine.entries[entryName] = regexEntry

        colorEntry = self.Entry(self.ENTRY_TYPE_COLOR, color)
        entryName = "color"

        colorEntry.label = tk.Label(colorLine.lineFrame, text="Color")
        colorEntry.label.grid(row=0, column=2)
        colorEntry.label.bind("<Button-1>", partial(self._focusInSet, rowId))

        colorEntry.var = tk.StringVar(colorLine.lineFrame)
        colorEntry.var.set(color)
        colorEntry.observer = colorEntry.var.trace(
            "w", partial(self._validateInput, rowId, entryName))
        colorEntry.input = tk.Entry(colorLine.lineFrame,
                                    textvariable=colorEntry.var,
                                    width=10,
                                    takefocus=False)
        colorEntry.input.grid(row=0, column=3)
        colorEntry.input.bind("<Button-1>", partial(self._focusInLog, rowId))

        colorEntry.button = tk.Button(colorLine.lineFrame,
                                      bg=color,
                                      width=3,
                                      command=partial(self._getColor, rowId,
                                                      entryName, True))
        colorEntry.button.grid(row=0, column=4, padx=4)
        colorEntry.button.bind("<Button-1>", partial(self._focusInSet, rowId))

        colorLine.entries[entryName] = colorEntry

        return colorLine

    def _createStandardRows(self, parent, setLines, startRow):
        setDict = dict()

        # Find longest entry in settings
        maxLen = 0
        for setLine in setLines:
            setLen = len(str(self._settings.get(setLine.setId)))
            if setLen > maxLen:
                maxLen = setLen

        row = startRow
        for setLine in setLines:
            setRow = self.SettingsLine(setLine.setGroup)
            entry = self.Entry(setLine.setType,
                               self._settings.get(setLine.setId))

            entryName = "entry"

            # TODO Add frame and highlight to colors (remember column widths and alignment)

            entry.label = tk.Label(parent, text=setLine.setDisplayName)
            entry.label.grid(row=row, column=0, sticky=tk.W)

            ########
            # Entry variable
            if setLine.setType == self.ENTRY_TYPE_INT:
                entry.var = tk.IntVar(parent)
            else:
                entry.var = tk.StringVar(parent)

            # Init entry var
            entry.var.set(self._settings.get(setLine.setId))
            # TODO use tkinter validateCommand
            entry.observer = entry.var.trace(
                "w", partial(self._validateInput, setLine.setId, entryName))

            ########
            # Input field
            if setLine.setType == self.ENTRY_TYPE_TOGGLE:
                # TODO create better toggle values (link to specific settings)
                toggleButtonFrame = tk.Frame(parent)
                toggleButtonFrame.grid(row=row, column=1, sticky=tk.E + tk.W)
                toggleButtonFrame.grid_columnconfigure(0, weight=1)
                toggleButtonFrame.grid_columnconfigure(1, weight=1)
                onButton = tk.Radiobutton(toggleButtonFrame,
                                          text="On",
                                          variable=entry.var,
                                          indicatoron=False,
                                          value="on")
                onButton.grid(row=0, column=0, sticky=tk.E + tk.W)
                offButton = tk.Radiobutton(toggleButtonFrame,
                                           text="Off",
                                           variable=entry.var,
                                           indicatoron=False,
                                           value="off")
                offButton.grid(row=0, column=1, sticky=tk.E + tk.W)
            else:
                # TODO Find better solution for entry width
                entry.input = tk.Entry(parent,
                                       textvariable=entry.var,
                                       width=int(maxLen * 1.5),
                                       takefocus=False)
                entry.input.grid(row=row, column=1)

            ########
            # Color button
            if setLine.setType == self.ENTRY_TYPE_COLOR:
                entry.button = tk.Button(parent,
                                         bg=self._settings.get(setLine.setId),
                                         width=3,
                                         command=partial(
                                             self._getColor, setLine.setId,
                                             entryName))
                entry.button.grid(row=row, column=2, padx=4)

            setRow.entries[entryName] = entry
            setDict[setLine.setId] = setRow

            row += 1

        return setDict

    ####################################
    # View Interaction

    def _focusOut(self, rowId, event):
        self._lastFocusOutRowId = rowId

    def _focusInSet(self, rowId, event=0):
        self._setsDict[rowId].lineFrame.focus_set()
        self._focusInLog(rowId, event)

    def _focusInLog(self, rowId, event=0):
        self._lastFocusInRowId = rowId
        if self._lastFocusOutRowId == rowId:
            self._lastFocusOutRowId = ""

    def _getColor(self, rowId, entry, highlight=False):

        if highlight:
            hg = self._setsDict[rowId].lineFrame.cget("highlightbackground")
            self._setsDict[rowId].lineFrame.config(
                highlightbackground=self.ROW_HIGHLIGHT_COLOR)

        currentColor = self._setsDict[rowId].entries[entry].button.cget("bg")

        if not self._isValidColor(currentColor):
            currentColor = None

        color = askcolor(initialcolor=currentColor, parent=self._view)

        if color[1] != None:
            self._setsDict[rowId].entries[entry].var.set(color[1])
            self._setsDict[rowId].entries[entry].button.config(bg=color[1])

        if highlight:
            self._setsDict[rowId].lineFrame.config(highlightbackground=hg)
            self._focusInLog(rowId)

    # class WidgetSize:
    #     def __init__(self,width,height,posx,posy):
    #         self.width = width
    #         self.height = height
    #         self.posx = posx
    #         self.posy = posy

    # def _getWidgetSize_(self,widget):

    #     width = widget.winfo_width()
    #     height = widget.winfo_height()
    #     posx = widget.winfo_x()
    #     posy = widget.winfo_y()

    #     return self.WidgetSize(width,height,posx,posy)

    def _tabChanged(self, event):
        self._view.focus_set()
        self._exampleText.tag_remove("sel", 1.0, tk.END)
        self._updateExampleText(
            self._tabList[self._tabControl.index("current")])

    def _updateExampleText(self, group):

        #####################
        # Setup

        # Delete all search tags
        self._exampleText.tag_delete(Sets.SEARCH_SELECTED_LINE_COLOR)
        self._exampleText.tag_delete(Sets.SEARCH_MATCH_COLOR)
        self._exampleText.tag_delete(Sets.SEARCH_SELECTED_COLOR)

        # Delete all current line color tags
        tagNames = self._exampleText.tag_names()
        for tagName in tagNames:
            if Sets.LINE_COLOR_MAP in tagName:
                self._exampleText.tag_delete(tagName)

        entryName = "entry"
        if group == self.GROUP_TEXT_AREA:
            # General text area
            try:
                tFont = Font(family=self._setsDict[Sets.TEXTAREA_FONT_FAMILY].entries[entryName].var.get(),\
                            size=self._setsDict[Sets.TEXTAREA_FONT_SIZE].entries[entryName].var.get())
                self._exampleText.config(background=self._setsDict[Sets.TEXTAREA_BACKGROUND_COLOR].entries[entryName].var.get(),\
                                                selectbackground=self._setsDict[Sets.TEXTAREA_SELECT_BACKGROUND_COLOR].entries[entryName].var.get(),\
                                                foreground=self._setsDict[Sets.TEXTAREA_COLOR].entries[entryName].var.get(),\
                                                font=tFont)

                lineWrapString = self._setsDict[
                    Sets.TEXTAREA_LINE_WRAP].entries[entryName].var.get()
                if lineWrapString == "on":
                    self._updateExampleTextLineWrap(Sets.LINE_WRAP_ON)
                elif lineWrapString == "off":
                    self._updateExampleTextLineWrap(Sets.LINE_WRAP_OFF)

            except tk.TclError:
                pass

        elif group == self.GROUP_SEARCH:

            searchString = "Main"

            # Create search tags
            self._exampleText.tag_configure(Sets.SEARCH_SELECTED_LINE_COLOR, \
                                            background=self._setsDict[Sets.SEARCH_SELECTED_LINE_COLOR].entries[entryName].var.get(),\
                                            selectbackground=util.lightOrDarkenColor(self._setsDict[Sets.SEARCH_SELECTED_LINE_COLOR].entries[entryName].var.get(),Sets.SELECTED_LINE_DARKEN_COLOR))
            self._exampleText.tag_configure(Sets.SEARCH_MATCH_COLOR, \
                                            background=self._setsDict[Sets.SEARCH_MATCH_COLOR].entries[entryName].var.get(),\
                                            selectbackground=util.lightOrDarkenColor(self._setsDict[Sets.SEARCH_MATCH_COLOR].entries[entryName].var.get(),Sets.SELECTED_LINE_DARKEN_COLOR))
            self._exampleText.tag_configure(Sets.SEARCH_SELECTED_COLOR, \
                                            background=self._setsDict[Sets.SEARCH_SELECTED_COLOR].entries[entryName].var.get(), \
                                            selectbackground=util.lightOrDarkenColor(self._setsDict[Sets.SEARCH_SELECTED_COLOR].entries[entryName].var.get(),Sets.SELECTED_LINE_DARKEN_COLOR))

            # Do search
            countVar = tk.StringVar()
            results = list()
            start = 1.0
            while True:
                pos = self._exampleText.search(searchString,
                                               start,
                                               stopindex=tk.END,
                                               count=countVar,
                                               nocase=False,
                                               regexp=False)
                if not pos:
                    break
                else:
                    results.append((pos, pos + "+" + countVar.get() + "c"))
                    start = pos + "+1c"

            # Add search tags
            first = True
            for result in results:
                self._exampleText.tag_add(Sets.SEARCH_MATCH_COLOR, result[0],
                                          result[1])
                if first:
                    first = False
                    self._exampleText.tag_add(Sets.SEARCH_SELECTED_COLOR,
                                              result[0], result[1])
                    selectLine = result[0].split(".")[0]
                    self._exampleText.tag_add(Sets.SEARCH_SELECTED_LINE_COLOR,
                                              selectLine + ".0",
                                              selectLine + ".0+1l")

        if group == self.GROUP_LINE_COLORING or group == self.GROUP_SEARCH:

            # Get line color map from view
            tempLineColorMap = list()
            for rowId in sorted(self._setsDict.keys()):
                if Sets.LINE_COLOR_MAP in rowId:
                    lineInfo = dict()
                    lineInfo["regex"] = self._setsDict[rowId].entries[
                        "regex"].var.get()
                    lineInfo["color"] = self._setsDict[rowId].entries[
                        "color"].var.get()
                    lineInfo["tagName"] = TF.createLineColorTagName(
                        lineInfo["regex"])
                    tempLineColorMap.append(lineInfo)

            # Apply new line colors
            for lineInfo in tempLineColorMap:
                self._exampleText.tag_configure(lineInfo["tagName"],
                                                foreground=lineInfo["color"])

                countVar = tk.StringVar()
                start = 1.0
                while True:
                    pos = self._exampleText.search(lineInfo["regex"],
                                                   start,
                                                   stopindex=tk.END,
                                                   count=countVar,
                                                   nocase=False,
                                                   regexp=True)
                    if not pos:
                        break
                    else:
                        self._exampleText.tag_add(
                            lineInfo["tagName"], pos,
                            pos + "+" + countVar.get() + "c")
                        start = pos + "+1c"

    def _updateExampleTextLineWrap(self, lineWrapState):

        if lineWrapState == Sets.LINE_WRAP_ON:
            self._exampleText.config(wrap=tk.CHAR)
        else:
            self._exampleText.config(wrap=tk.NONE)

    ####################################
    # Entry Validation

    def _validateInput(self, rowId, entryName, *args):

        # Get variable
        try:
            settingsLine: self.SettingsLine = self._setsDict[rowId]
            entry: self.Entry = settingsLine.entries[entryName]
            varIn = entry.var.get()
            validationStatus = self.ENTRY_VALIDATION_OK
        except tk.TclError:
            # print("Tcl Error")
            validationStatus = self.ENTRY_VALIDATION_FAILED

        if validationStatus == self.ENTRY_VALIDATION_OK:

            # Check Colors
            if entry.data.entryType == self.ENTRY_TYPE_COLOR:
                if self._isValidColor(varIn):
                    # print("Color " + str(color))
                    entry.button.config(background=varIn)
                    validationStatus = self.ENTRY_VALIDATION_OK
                else:
                    validationStatus = self.ENTRY_VALIDATION_FAILED

            # Check regex
            if entry.data.entryType == self.ENTRY_TYPE_REGEX:

                # Validate regex
                if self._isValidRegex(varIn):
                    entry.data.validation.status = self.ENTRY_VALIDATION_OK
                else:
                    entry.data.validation.status = self.ENTRY_VALIDATION_FAILED

                self._updateAllRegexEntries()

                validationStatus = entry.data.validation.status

            # Check font family
            if rowId == Sets.TEXTAREA_FONT_FAMILY:
                if self._isValidFontFamily(varIn):
                    validationStatus = self.ENTRY_VALIDATION_OK
                else:
                    validationStatus = self.ENTRY_VALIDATION_FAILED

            # Check font size
            if rowId == Sets.TEXTAREA_FONT_SIZE:
                if self._isValidFontSize(varIn):
                    validationStatus = self.ENTRY_VALIDATION_OK
                else:
                    validationStatus = self.ENTRY_VALIDATION_FAILED

        #######
        # Update validation info

        if validationStatus == self.ENTRY_VALIDATION_OK:
            entry.data.validation.status = self.ENTRY_VALIDATION_OK
            entry.data.validation.backgroundColor = "white"
            entry.data.validation.infoText = ""
        elif validationStatus == self.ENTRY_VALIDATION_FAILED:
            entry.data.validation.status = self.ENTRY_VALIDATION_FAILED
            entry.data.validation.backgroundColor = "red"
            entry.data.validation.infoText = "Non-valid input."

        if not entry.data.entryType == self.ENTRY_TYPE_TOGGLE:
            entry.input.config(
                background=entry.data.validation.backgroundColor)

        infoText = ""
        for key in self._setsDict.keys():
            for (entryKey, entryItem) in self._setsDict[key].entries.items():
                if entryItem.data.validation.status != self.ENTRY_VALIDATION_OK:
                    entryId = key + "_" + entryKey
                    if infoText:
                        infoText += "\n"
                    infoText += entryId + ": " + entryItem.data.validation.infoText

        if infoText:
            self._optionsInfoLabel.config(text=infoText)
            self._setSaveButtonState(tk.DISABLED)
        else:
            self._optionsInfoLabel.config(text="")
            self._setSaveButtonState(tk.NORMAL)
            self._updateExampleText(settingsLine.group)

    def _isValidColor(self, colorString):
        isValid = True
        try:
            tk.Label(None, background=colorString)
        except tk.TclError:
            # print("Color Error")
            isValid = False
        return isValid

    def _isValidFontFamily(self, family):
        fontList = tk.font.families()
        return family in fontList

    def _isValidFontSize(self, size):
        isValid = True
        try:
            Font(size=size)
        except tk.TclError:
            # print("Font Size Error")
            isValid = False

        if isValid:
            if int(size) < 1:
                isValid = False

        return isValid

    def _isValidRegex(self, regex):
        isValid = True
        try:
            # re.compile(regex) # Tkinter does not allow all regex, so this cannot be used
            self._exampleText.search(regex, 1.0, stopindex=tk.END, regexp=True)
        except:
            isValid = False
        return isValid

    def _updateAllRegexEntries(self):
        # Get all regex
        regexList = list()
        for key in self._setsDict.keys():
            try:
                value = self._setsDict[key].entries["regex"].var.get()
                regexList.append(value)
            except KeyError:
                pass

        # Find any duplicate entries
        regexListCount = Counter(regexList)
        regexDuplicateList = [
            regex for regex, count in regexListCount.items() if count > 1
        ]

        # Update all duplicate regex entries
        for key in self._setsDict.keys():
            try:
                regexEntry = self._setsDict[key].entries["regex"]
                # Only update status if entry validation status is not currently failed
                if regexEntry.data.validation.status != self.ENTRY_VALIDATION_FAILED:
                    # Mark duplicates
                    if regexEntry.var.get() in regexDuplicateList:
                        # print("New duplicate: " + regexEntry.var.get())
                        regexEntry.data.validation.status = self.ENTRY_VALIDATION_DUPLICATE
                        regexEntry.data.validation.backgroundColor = "yellow"
                        regexEntry.data.validation.infoText = "Duplicate regex entry not allowed."
                    else:
                        # Clear previous duplicates that are now valid
                        if regexEntry.data.validation.status == self.ENTRY_VALIDATION_DUPLICATE:
                            # print("Clear duplicate: " + regexEntry.var.get())
                            regexEntry.data.validation.status = self.ENTRY_VALIDATION_OK
                            regexEntry.data.validation.backgroundColor = "white"
                            regexEntry.data.validation.infoText = ""

                    regexEntry.input.config(
                        background=regexEntry.data.validation.backgroundColor)
            except KeyError:
                pass

    ####################################
    # Misc

    def _getRowId(self, rowNum):
        return Sets.LINE_COLOR_MAP + "{:02d}".format(rowNum)
예제 #11
0
    def __init__(self, *args, **kwargs):
        '''
node_name:   The name of this node. Usually set by ModelNode.__setattr__ automatically.
figure_meta: Meta information of figure.
The rest parameters are passed to PanedWindow.__init__.
'''
        node_name    = kwargs.pop('node_name', '')
        super().__init__(node_name=node_name)

        figure_meta = None if 'figure_meta' not in kwargs \
            else kwargs.pop('figure_meta')
        kwargs['orient'] = 'horizontal'
        
        paned_window = PanedWindow(*args, **kwargs)

        paned_window.config(sashwidth=4, sashrelief='groove', bg='forestgreen')        
       
#        figureTabsStyle = Style()
#        figureTabsStyle.configure('Figure.TNotebook', tabposition='sw')       
#        figureTabs    = Notebook(paned_window, style='Figure.TNotebook')
        figureTabs  = Notebook(paned_window)
        
        self.figureTabs   = figureTabs
        figureTabs.bind('<<NotebookTabChanged>>', self._on_tab_change)
        self.lock_attribute('figureTabs')
        
        if figure_meta:
            self.make_figures(figure_meta)
            
        self.lock_elements()    
        
        paned_window.add(figureTabs, stretch='always')
        

        listPan     = PanedWindow(paned_window, orient='vertical')
        listPan.config(sashwidth=4, sashrelief='groove', bg='forestgreen')        
        paned_window.add(listPan, stretch='never')

        
        listFrm     = Frame(listPan)
        listPan.add(listFrm, stretch='always')        
        Label(listFrm, text='Curves', bg='#b5d6b0').pack(side='top', fill='x')
        self.__list = ScrolledList(listFrm, relief='groove')
        self.__list.list_config(width=20)
        self.__list.list_click_callback = self._on_list_click
        self.__list.pack(fill='both', expand='yes')

        listFrm     = Frame(listPan)        
        listPan.add(listFrm, stretch='never')
        Label(listFrm, text='Indicators', bg='#b5d6b0').pack(side='top', fill='x')
        self.__indicator_listbox = ScrolledList(listFrm, relief='groove')
        self.__indicator_listbox.list_config(width=20)
        self.__indicator_listbox.pack(fill='both', expand='yes')
                      
        with self.attribute_lock:
            set_attributes(self,
                paned_window = paned_window,
                grid_group_observer = self.GridGroupObserver(self), 
                axis_group_observer = self.AxisGroupObserver(self),
                clear_group_observer = self.ClearGroupObserver(self),
                label_group_observer = self.LabelGroupObserver(self),
                indicator_group_observer = self.IndicatorGroupObserver(self),
                data_figure_observer = self.DataFigureObserver(self),
                data_pool    = []
            )
예제 #12
0

root = Tk()
root.wm_title("Arduino Tables")
root.wm_iconbitmap('../_static/ben1.ico')
root.geometry('+170+200')
s = Style()
s.theme_use('clam')

#csvDelimiter = '$'
fr = Frame(root)
fr.pack(fill='both', expand=1)

nb = Notebook(fr)
nb.pack(fill='both', padx=2, pady=3, expand=1)
nb.bind("<<NotebookTabChanged>>", on_tab_changed)
nb.enable_traversal()

page1 = Frame(nb)
csvfiles = []
for file in glob("../csv_data/*.csv"):
    csvfiles.append(file)
#csv_value = StringVar()
#cb = Combobox(page1, values=csvfiles, state="readonly",
#textvariable=csv_value, width=30)
#cb.set(csvfiles[0])
#cb.grid(column=0, row=1)
#cb.bind('<<ComboboxSelected>>', csvSel)

nb.add(
    page1,
예제 #13
0
class TabsPanel(Frame):
    """All tabs in main screen"""
    def __init__(self, parent, app):
        Frame.__init__(self, parent)
        self.app = app
        self.initUI()

    def initUI(self):
        # self.tabs = []

        # init tabs
        self.tab = Notebook(self)
        self.tab.bind('<<NotebookTabChanged>>', self.on_tab_changed)
        created_tab = [
            self.make_code_tab(),
            self.make_triples_tab(),
            self.make_upload_tab(),
            self.make_download_tab(),
        ]
        for frame, name in created_tab:
            self.tab.add(frame, text=name)
        self.tab.grid(column=0, row=0)

    def updateUI(self):
        self.check_code_modified()
        self.check_triples_exist()

    def make_code_tab(self):
        f = Frame(self.tab)
        Label(f, text='Open .c file or paste code here').pack()

        self.code_edit = scrolledtext.ScrolledText(f,
                                                   wrap="word",
                                                   width=70,
                                                   height=20)
        self.code_edit.pack()

        self.code_var = StringVar(self.code_edit)
        attach_StrVar_to_Text(self.code_var, self.code_edit)
        # listen code changes
        self.code_var.trace_add('write', self.check_code_modified)

        self.code_used_str = None

        self.code_modified = False
        self.code_modified_label = Label(f,
                                         text='no code yet...',
                                         justify='left')
        # self.code_modified_label.pack(expand=True, fill=X)
        self.code_modified_label.pack(side=LEFT)

        self.get_triples_button = Button(f,
                                         text="Convert code to triples ...",
                                         padx="15",
                                         bg='#bbddbb',
                                         command=self.on_get_triples_button)
        self.get_triples_button.pack(side=RIGHT)
        # self.code_modified_label["text"] = 'ABCDE!'

        self.load_file('default.c')

        return (f, 'Code')

    def load_file(self, filepath):
        try:
            with open(filepath) as f:
                t = f.read()
            self.code_var.set(t)
            self.code_modified_label["text"] = "loaded file: " + filepath
        except:
            err_msg = "file no found: " + filepath
            self.code_modified_label["text"] = err_msg
            print(err_msg)

        if hasattr(self, "triples_list"):  # tabs not ready workaround
            self.tab.select(0)

    def check_code_modified(self, *_):
        if self.code_var.get() == self.code_used_str:
            text = 'code not modified'
            self.code_modified = False
        else:
            text = 'code was changed'
            self.code_modified = True

        button_state = NORMAL if self.code_modified else DISABLED
        self.get_triples_button["state"] = button_state

        if self.code_used_str is None:
            text = 'no code in use'
            self.code_modified = False

        self.code_modified_label["text"] = text

    def on_get_triples_button(self):
        self.code_used_str = self.code_var.get()
        self.code_modified = False
        # call app action ...
        error = self.app.parse_code(self.code_used_str)
        if error:
            messagebox.showinfo('Code error', error)
            # print(error)
            self.code_used_str = None
            return

        triples, error = self.app.get_code_triples()
        if error:
            messagebox.showinfo('Triples obtaining error', error)
            # print(error)
            self.code_used_str = None
            return
        self.triples_list = triples
        self.tab.select(1)

        self.set_upload_status("Ready to upload triples to server")

    def on_format_code(self):
        self.tab.select(0)
        # call app action ...
        error = self.app.parse_code(self.code_var.get())
        if error:
            messagebox.showinfo('Code parse error', error)
            self.highlight_char_by_error(error)
        else:
            formatted_code = self.app.get_code_norm_format()
            self.code_var.set(formatted_code)

    def highlight_char_by_error(self, err_string):
        sep = ':'
        # print(err_string)
        dd = err_string.strip(sep).split(sep)
        # print(dd)
        try:
            r, c = dd[:2]
            r = int(r)
            c = int(c)
        except:
            return
        # f = "%d.%d" % (r,c)
        # t = "%d.%d" % (r,c+1)
        f = "%d.0" % (r, )
        t = "%d.end" % (r, )
        # self.code_edit.selection_set(f,t)
        # print(f,t)
        self.code_edit.tag_add(SEL, f, t)

    def make_triples_tab(self):
        f = Frame(self.tab)
        Label(
            f,
            text=
            'Triples obtained from code. Changes to this text have no effect on stored triples.'
        ).pack()

        self.triples_edit = scrolledtext.ScrolledText(f,
                                                      wrap="word",
                                                      width=70,
                                                      height=20)
        self.triples_edit.pack()

        self.triples_list = None

        self.triples_count_label = Label(
            f, text='Click "Code to Triples" button first', justify='left')
        self.triples_count_label.pack(side=LEFT)

        self.goto_upload_button = Button(f,
                                         text="Proceed to upload ...",
                                         padx="15",
                                         bg='#bbddbb',
                                         command=lambda *_: self.tab.select(2))
        self.goto_upload_button.pack(side=RIGHT)

        return (f, 'Triples')

    def check_triples_exist(self):
        button_state = NORMAL if self.triples_list else DISABLED
        self.goto_upload_button["state"] = button_state
        self.run_upload_button["state"] = button_state

        if self.triples_list:
            count_text = 'Triples count: %d' % len(self.triples_list)
        else:
            count_text = 'No triples'
        self.triples_count_label["text"] = count_text
        self.show_triples()

    def show_triples(self):
        if self.triples_list:
            triples_str = '\n'.join(map(str, self.triples_list))
        else:
            triples_str = 'No triples generated from code'
        self.triples_edit.delete(1.0, END)
        self.triples_edit.insert(1.0, triples_str)

    def make_upload_tab(self):
        f = Frame(self.tab)
        Label(f, text='Set up connection and click "Upload"').pack()

        # Remote configuration
        g = LabelFrame(f, text="Remote configuration")

        row = 0

        Label(g, text='Stardog server location:').grid(row=row,
                                                       column=0,
                                                       rowspan=1,
                                                       sticky=E,
                                                       padx=20,
                                                       pady=5)

        self.server_url_var = StringVar()
        serv_url = Entry(g, width=60, textvariable=self.server_url_var)
        self.server_url_var.set("http://localhost:5820")
        serv_url.grid(row=row, column=1, sticky=W)

        row += 1

        Label(g,
              text='(Using default username & password: admin, admin)').grid(
                  row=row, column=0, columnspan=2)

        row += 1

        Label(g, text='Stardog database name:').grid(row=row,
                                                     column=0,
                                                     rowspan=1,
                                                     sticky=E,
                                                     padx=20,
                                                     pady=5)

        self.server_dbname_var = StringVar()
        serv_dbname = Entry(g, width=60, textvariable=self.server_dbname_var)
        self.server_dbname_var.set("sem_alg_db")
        serv_dbname.grid(row=row, column=1, sticky=W)

        row += 1

        Label(g, text='Ontology schema file:').grid(row=row,
                                                    column=0,
                                                    rowspan=1,
                                                    sticky=E,
                                                    padx=20,
                                                    pady=5)

        self.schema_file_var = StringVar()
        serv_dbname = Entry(g, width=60, textvariable=self.schema_file_var)
        self.schema_file_var.set("c_schema_2020-01.rdf")
        serv_dbname.grid(row=row, column=1, sticky=W)

        row += 1

        self.server_db_create_var = BooleanVar()
        self.server_db_create_var.set(1)
        chk = Checkbutton(g,
                          text="Create a new DB on server",
                          variable=self.server_db_create_var,
                          onvalue=1,
                          offvalue=0)
        chk.grid(row=row, column=1, sticky=W)

        row += 1

        self.server_db_drop_var = BooleanVar()
        self.server_db_drop_var.set(0)
        chk = Checkbutton(g,
                          text="Drop DB on closing connection",
                          variable=self.server_db_drop_var,
                          onvalue=1,
                          offvalue=0)
        chk.grid(row=row, column=1, sticky=W)
        # text="Drop DB after whole data export"

        g.pack(expand=1, padx=20, fill=X)

        self.run_upload_button = Button(f,
                                        text="Upload !",
                                        bg='#ff99dd',
                                        command=self.on_upload_button)
        self.run_upload_button.pack(expand=1, fill=BOTH, padx=50, pady=25)

        self.upload_status_label = Label(f,
                                         text='No upload performed',
                                         justify='left')
        self.upload_status_label.pack(side=LEFT)

        return (f, 'Upload data')

    def make_download_tab(self):
        f = Frame(self.tab)
        Label(f, text='Click "Download" to export ontology and store locally'
              ).pack()

        # Export configuration
        g = LabelFrame(f, text="Export configuration")

        row = 0

        Label(g, text='Source database name:').grid(row=row,
                                                    column=0,
                                                    rowspan=1,
                                                    sticky=E,
                                                    padx=20,
                                                    pady=5)

        self.export_dbname_label = Label(g,
                                         width=60,
                                         text='~ run upload first ~')
        self.export_dbname_label.grid(row=row, column=1, sticky=W)

        row += 1

        Label(g, text='Save .ttl file as:').grid(row=row,
                                                 column=0,
                                                 rowspan=1,
                                                 sticky=E,
                                                 padx=20,
                                                 pady=5)

        self.save_filename_var = StringVar()
        save_filename = Entry(g, width=60, textvariable=self.save_filename_var)
        self.save_filename_var.set("exported_onto")
        save_filename.grid(row=row, column=1, sticky=W)

        g.pack(expand=1, padx=20, fill=X, side=TOP)

        self.run_download_button = Button(f,
                                          text="Download ontology",
                                          bg='#dd99ff',
                                          command=self.on_download_button)
        self.run_download_button.pack(expand=1, fill=BOTH, padx=50, pady=5)
        self.run_download_button["state"] = DISABLED

        self.download_status_label = Label(f,
                                           text='No download performed',
                                           justify='left')
        self.download_status_label.pack(side=LEFT)

        return (f, 'Export ontology')

    def get_conn_details(self):
        conn_details = {
            'endpoint': self.server_url_var.get(),
            'username': '******',
            'password': '******',
            'schemafile': self.schema_file_var.get(),
            'dbname': self.server_dbname_var.get(),
            'createdb': self.server_db_create_var.get(),
            'dropdb': self.server_db_drop_var.get(),
        }
        return conn_details

    def on_upload_button(self):
        self.set_upload_status("Upload in progress ...")
        self.app.set_connection_details(self.get_conn_details())
        error = self.app.upload_triples(
            self.triples_list, progress_callback=self.set_upload_status)
        if error:
            messagebox.showinfo('Upload error', error)
            self.set_upload_status("Upload error")
        else:
            self.set_upload_status("Upload success")
            self.run_download_button["state"] = NORMAL
            self.export_dbname_label["text"] = self.server_dbname_var.get()
            self.tab.select(3)

    def set_upload_status(self, text):
        self.upload_status_label["text"] = str(text)

    def set_download_status(self, text):
        self.download_status_label["text"] = str(text)

    def on_download_button(self):
        save_as_fnm = self.save_filename_var.get()
        if not save_as_fnm:
            messagebox.showinfo('Please specify a filename!', error)
            self.set_download_status('Incorrect fields')

        self.set_download_status("Download in progress ...")
        self.app.set_connection_details(self.get_conn_details())
        error = self.app.download_ontology(
            save_as_fnm, progress_callback=self.set_download_status)
        if error:
            messagebox.showinfo('Download error', error)
            self.set_download_status("Download error")
        else:
            self.set_download_status("Download success")

    def on_tab_changed(self, ev):
        # print('on_tab_changed:')
        # print(ev)
        self.updateUI()
예제 #14
0
        height=tc1.winfo_reqheight(),
        width=tc1.winfo_reqwidth())

def on_click(event):
    clicked_tab = nb1.tk.call(nb1._w, "identify", "tab", event.x, event.y)
    if clicked_tab == 0:
        clicked_tab = 'one'
    if clicked_tab == 1:
        clicked_tab = 'two'
    if clicked_tab == 2:
        clicked_tab = 'three'

    lbl1['text'] = 'Tab '+clicked_tab+' was clicked'

nb1 = Notebook(root, style='green.TNotebook')
nb1.bind("<<NotebookTabChanged>>", tab_changed)
nb1.grid(row=0, column=0)
nb1.enable_traversal()

lbl1 = Label(root, text='ready')
lbl1.grid(row=5, column=0)
nb1.bind('<Button-1>', on_click)

# first page
page1 = Frame(root, background='red', height=70*mult)

enabler = Button(page1, text='Enable Tab two\n Test it out',
                 command=lambda: nb1.tab(1, state='normal'))
enabler.pack(ipadx=5, ipady=5)

nb1.add(page1, text='one', underline=0, padding=2)
class AppLauncher:
   def __init__(self):
      self.__root = Tk()
      
      self.__notebook = Notebook()
      
      if user32:
         self.__notebook.bind("<Map>", self._maximizeUnderWindows)
   
   @property
   def root(self):
      return self.__root
   
   def run(self, entry, baseTabLoader = BaseTabLoader()):
      self.__configurationFiles = self._createConfigurationInstances()
      
      self._loadConfigurationFiles()
      self._upgradeConfigurationFiles()
      
      Config["version"] = __version__
      
      self._createStyles()
      self._createLayouts()
      self._configureRoot()
      
      CommonUIComponents.init(**self._getCommonUIComponentsInitParams())
      SmartWidget.setFont()
      
      sys.path.append(path.dirname(path.dirname(path.abspath(entry))))
      
      baseTabLoader.load(self.__notebook, Config.INSTANCE.json, Storage.INSTANCE.json)
      
      self.__notebook.place(relwidth = 1, relheight = 1)
      
      Global.appLauncher = self
      
      self.__root.mainloop()
   
   def _configureRoot(self):
      self.__root.geometry(f"{self.__root.winfo_screenwidth()}x{self.__root.winfo_screenheight()}")
      
      #
      # There's a bug under Linux: if height == False, window contents
      # aren't centered vertically. Moreover, the app must be maximized
      # under Windows, otherwise vertical scrollbars don't scroll content
      # to the end.
      #
      self.__root.resizable(False, True)
      self.__root.title(Config["title"])
      self.__root.protocol("WM_DELETE_WINDOW", self._onDeleteWindow)
   
   def _createConfigurationInstances(self):
      _ = self
      
      return {"config": Config(), "storage": Storage()}
   
   def _createStyles(self):
      font = Config["widgetFont"]
      
      self.__root.style = Style()
      self.__root.style.configure(".", font = font)
      self.__root.style.configure("TButton", padding = [12, 7])
      self.__root.style.configure("TNotebook.Tab", padding = [13, 7])
      self.__root.style.configure("Horizontal.TScale", sliderthickness = 25)
      self.__root.style.configure("Horizontal.TScrollbar", arrowsize = 25)
      self.__root.style.configure("Vertical.TScrollbar", arrowsize = 25)
      self.__root.style.configure("TSpinbox", arrowsize = 30)
      
      self.__root.option_add('*TCombobox*Listbox.font', font)
      
      colors = {
         "Cyan": "cyan",
         "LGreen": "lightgreen",
         "Pink": "pink",
         "Yellow": "yellow"
      }
      
      styles = {
         "": "Frame",
         "Labeled": "Labelframe"
      }
      
      for style in styles.items():
         for color in colors.items():
            self.__root.style.configure(f"{color[0]}.T{style[0]}Container.TBaseContainer.T{style[1]}", background = color[1])
   
   def _createLayouts(self):
      name = "Scrollbar"
      
      for orient in ("Horizontal", "Vertical"):
         self.__root.style.layout(f"{orient}.T{name}.T{name}", self.__root.style.layout(f"{orient}.T{name}"))
   
   def _getCommonUIComponentsInitParams(self):
      _ = self
      
      return dict()
   
   def _loadConfigurationFiles(self):
      for configurationFile in self.__configurationFiles.values():
         configurationFile.load()
   
   def _maximizeUnderWindows(self, _):
      _ = self
      
      user32.ShowWindow(user32.GetForegroundWindow(), 3)
   
   def _onDeleteWindow(self):
      for name in self.__notebook.tabs():
         self.__notebook.nametowidget(name).onDeleteWindow()
      
      for configurationFile in self.__configurationFiles.values():
         configurationFile.dump()
      
      self.__root.destroy()
   
   def _upgradeConfigurationFiles(self):
      for configurationFile in self.__configurationFiles.values():
         configurationFile.upgrade(Config.INSTANCE.json.get("version", "1.6.7"))
예제 #16
0
    def __init__(self, *args, **kwargs):
        '''
node_name:   The name of this node. Usually set by ModelNode.__setattr__ automatically.
figure_meta: Meta information of figure.
The rest parameters are passed to PanedWindow.__init__.
'''
        node_name = kwargs.pop('node_name', '')
        super().__init__(node_name=node_name)

        self.__selected_curve = (None, None)

        figure_meta = None if 'figure_meta' not in kwargs \
            else kwargs.pop('figure_meta')
        kwargs['orient'] = 'horizontal'

        paned_window = PanedWindow(*args, **kwargs)

        paned_window.config(sashwidth=4, sashrelief='groove', bg='forestgreen')

        #        figureTabsStyle = Style()
        #        figureTabsStyle.configure('Figure.TNotebook', tabposition='sw')
        #        figureTabs    = Notebook(paned_window, style='Figure.TNotebook')
        figureTabs = Notebook(paned_window)

        self.figureTabs = figureTabs
        figureTabs.bind('<<NotebookTabChanged>>', self._on_tab_change)
        self.lock_attribute('figureTabs')

        if figure_meta:
            self.make_figures(figure_meta)

        self.lock_elements()

        paned_window.add(figureTabs, stretch='always')

        listPan = PanedWindow(paned_window, orient='vertical')
        listPan.config(sashwidth=4, sashrelief='groove', bg='forestgreen')
        paned_window.add(listPan, stretch='never')

        listFrm = Frame(listPan)
        listPan.add(listFrm, stretch='always')
        Label(listFrm, text='Curves', bg='#b5d6b0').pack(side='top', fill='x')
        self.__list = ScrolledList(listFrm, relief='groove')
        self.__list.list_config(width=20)
        self.__list.list_click_callback = self._on_list_click
        self.__list.pack(fill='both', expand='yes')

        listFrm = Frame(listPan)
        listPan.add(listFrm, stretch='never')
        Label(listFrm, text='Indicators', bg='#b5d6b0').pack(side='top',
                                                             fill='x')
        self.__indicator_listbox = ScrolledList(listFrm, relief='groove')
        self.__indicator_listbox.list_config(width=20)
        self.__indicator_listbox.pack(fill='both', expand='yes')

        with self.attribute_lock:
            set_attributes(
                self,
                paned_window=paned_window,
                grid_group_observer=self.GridGroupObserver(self),
                axis_group_observer=self.AxisGroupObserver(self),
                clear_group_observer=self.ClearGroupObserver(self),
                label_group_observer=self.LabelGroupObserver(self),
                indicator_group_observer=self.IndicatorGroupObserver(self),
                data_figure_observer=self.DataFigureObserver(self),
                data_pool=[])
예제 #17
0
파일: layout.py 프로젝트: vospascal/pedal
    def __init__(self, *args, **kwargs):
        Tk.__init__(self, *args, **kwargs)
        self.activeTab = 0
        self.geometry("775x550")
        self.title("Pedalbox")
        # self.iconbitmap("assets/pedal.ico")
        self.serial_data = ''
        self.filter_data = ''

        # Main Container
        container = Frame(self, bg='white')
        container.pack(fill="both")
        tablayout = Notebook(container)

        ################################################################
        ## tab1
        tab1 = Frame(tablayout, bg='white')
        tab1.pack(fill="both")

        clutch_cluster = ClutchCluster(tab1, self)
        brake_cluster = BrakeCluster(tab1, self)
        throttle_cluster = ThrottleCluster(tab1, self)

        clutch_cluster.grid(row=0, column=0, padx=10, pady=10, sticky="nsew")
        brake_cluster.grid(row=0, column=1, padx=10, pady=10, sticky="nsew")
        throttle_cluster.grid(row=0, column=2, padx=10, pady=10, sticky="nsew")

        tab1.grid_columnconfigure(0, weight=1)
        tab1.grid_columnconfigure(1, weight=1)
        tab1.grid_columnconfigure(2, weight=1)

        tablayout.add(tab1, text="Clusters")

        ################################################################
        # tab2
        tab2 = Frame(tablayout, bg='white')
        tab2.pack(fill="both", expand=1)

        clutch = Clutch(tab2, self)
        brake = Brake(tab2, self)
        throttle = Throttle(tab2, self)

        clutch.grid(row=0, column=0, padx=10, pady=10, sticky="nsew")
        brake.grid(row=0, column=1, padx=10, pady=10, sticky="nsew")
        throttle.grid(row=0, column=2, padx=10, pady=10, sticky="nsew")

        tab2.grid_columnconfigure(0, weight=1)
        tab2.grid_columnconfigure(1, weight=1)
        tab2.grid_columnconfigure(2, weight=1)

        tablayout.add(tab2, text="Settings")
        tablayout.pack(fill="both", expand=1)

        ################################################################
        # tab3
        tab3 = Frame(tablayout, bg='white')
        tab3.pack(fill="both", expand=1)
        serial_port_settings = SerialPort(tab3, self)
        serial_port_settings.grid(row=0,
                                  column=0,
                                  padx=10,
                                  pady=10,
                                  sticky="nsew")
        tablayout.add(tab3, text="config")
        tablayout.pack(fill="both", expand=1)

        tablayout.bind("<<NotebookTabChanged>>",
                       lambda event: self.tab_changed(tablayout))

        connect_button = Button(
            self,
            text="connect serial port",
            command=lambda: serial_connect(self,
                                           get_connection_info()[1],
                                           get_connection_info()[0]))
        connect_button.pack()

        disconect_button = Button(self,
                                  text="disconect serial port",
                                  command=serial_disconect)
        disconect_button.pack()

        pub.subscribe(get_map_update_clutch, 'clutch_map_update')
        pub.subscribe(get_map_update_brake, 'brake_map_update')
        pub.subscribe(get_map_update_throttle, 'throttle_map_update')
예제 #18
0
class App:
    # need it for generate reports
    __ast = None
    __sym_table = None
    __sym_table_3d = None

    def __init__(self, ide):

        # setting title
        ide.title("TenorC @danii_mor")

        # setting window size
        width=700
        height=400
        screenwidth = ide.winfo_screenwidth()
        screenheight = ide.winfo_screenheight()
        alignstr = '%dx%d+%d+%d' % (width, height, (screenwidth - width) / 2, (screenheight - height) / 2)
        ide.geometry(alignstr)
        ide.resizable(width=True, height=True)

        # create menubar
        menubar = Menu(ide)

        # file menu
        filemenu = Menu(menubar, tearoff=0)
        filemenu.add_command(label="New", command=self.newFile)
        filemenu.add_command(label="Open", command=self.file_open)
        filemenu.add_command(label="Save", command=self.file_save)
        filemenu.add_command(label="Save as...", command=self.file_save_as)
        filemenu.add_command(label="Close", command=self.exitTab)

        filemenu.add_separator()

        filemenu.add_command(label="Exit", command=ide.quit)
        

        # edit menu
        editmenu = Menu(menubar, tearoff=0)
        editmenu.add_command(label="Cut", command=self.donothing)
        editmenu.add_command(label="Copy", command=self.copy_to_clipboard)
        editmenu.add_command(label="Paste", command=self.donothing)

        editmenu.add_separator()

        editmenu.add_command(label="Find", command=self.donothing)
        editmenu.add_command(label="Replace", command=self.donothing)


        # run menu
        runmenu = Menu(menubar, tearoff=0)
        runmenu.add_command(label="Execute Analysis", command=self.execute_current_tab_lef)
        runmenu.add_command(label="Show Intermediate Code", command=self.show3D)

        runmenu.add_separator()

        runmenu.add_command(label="Symbol Table", command=self.show_sym_table)
        runmenu.add_command(label="Error Report", command=self.show_error)
        runmenu.add_command(label="Abstract Syntax Tree", command=self.show_ast)
        runmenu.add_command(label="Grammar", command=self.show_grammar)

        runmenu.add_separator()
        
        runmenu.add_command(label="Debugging", command=self.execute_debug)


        # option menu
        #optionmenu = Menu(menubar, tearoff=0)
        #optionmenu.add_command(label="Theme...", command=self.donothing)
        #optionmenu.add_command(label="Line Numbers...", command=self.donothing)


        # help menu
        helpmenu = Menu(menubar, tearoff=0)
        helpmenu.add_command(label="Help", command=self.donothing)
        helpmenu.add_command(label="About...", command=self.show_info)
        

        # setting menu
        menubar.add_cascade(label="File", menu=filemenu)
        menubar.add_cascade(label="Edit", menu=editmenu)
        menubar.add_cascade(label="Run", menu=runmenu)
        menubar.add_cascade(label="Help", menu=helpmenu)
        ide.config(menu=menubar)

        # setting editor area
        self.tabs = Notebook(ide)
        f1 = Frame(self.tabs)
        self.tabs.add(f1, text="+")
        self.tabs.pack(side="top", fill="both", expand=True, padx=10, pady=0)

        self.tabs.bind("<<NotebookTabChanged>>", self.addTab)


        # setting terminal area
        self.terminal= Text(ide)
        ft = tkFont.Font(family="Lucinda Console", size=10)
        self.terminal["font"] = ft
        self.terminal["wrap"] = "word"
        self.terminal["fg"] = "white"
        self.terminal["bg"] = "black"
        self.terminal["insertbackground"] ="white"
        self.terminal["height"] = 5
        self.terminal["width"] = 5
        self.terminal.pack( side = "left", fill = "both", expand=True,  padx=10, pady=10)

        terminal_scroll = Scrollbar(ide)
        terminal_scroll["orient"] = "vertical"
        terminal_scroll["command"] = self.terminal.yview
        terminal_scroll.pack(side="right", fill="y")

        self.terminal.configure(yscrollcommand=terminal_scroll.set)
        self.terminal.bind("<Return>", self.execute_command)

    def copy_to_clipboard(self):
        selectedTab = self.tabs.index("current")
        currentTextArea = self.tabs.winfo_children()[selectedTab+1].textarea
        try:
            selected_text= currentTextArea.get("sel.first", "sel.last")
            currentTextArea.clipboard_append(selected_text)
        except:
            pass

    def show_grammar(self):
        if self.__sym_table:
            window = Toplevel()
            window['bg'] = 'black'
            productions = self.__sym_table.getGrammar()
            keys = list(productions.keys())
            keys.sort()
            grammar = Message(window)
            txt = ''
            for production in keys:
                txt += productions[production] + '\n' 
            grammar['fg'] = 'white'
            grammar['bg'] = 'black'
            grammar['text'] = txt
            grammar.pack(side='left')
    
    def show_error(self):
        if self.__sym_table:
            if self.__sym_table.error != '':
                window = Toplevel()
                window['bg'] = 'black'

                grammar = Message(window)
                grammar['fg'] = 'white'
                grammar['bg'] = 'black'
                grammar['text'] = self.__sym_table.error
                grammar.pack(side='left')
            else:
                window = Toplevel()
                window['bg'] = 'black'

                grammar = Message(window)
                grammar['fg'] = 'white'
                grammar['bg'] = 'black'
                grammar['text'] = 'Not Errors Found'
                grammar.pack(side='left')

    # TODO fix it
    def show_sym_table(self):
        if self.__sym_table:
            showTable(self.__sym_table)

    def show_ast(self):
        self.__ast.graph()
        showAST()

    codeGenerated = None
    def show3D(self):
        if self.codeGenerated != None:
            window = Toplevel()
            window['bg'] = 'black'

            grammar = Text(window)
            grammar['fg'] = 'white'
            grammar['bg'] = 'black'
            grammar.insert(1.0, self.codeGenerated)
            grammar.pack(side='left')

    def show_info(self):
        window = Toplevel()
        window['bg'] = 'black'

        grammar = Message(window)
        grammar['fg'] = 'white'
        grammar['bg'] = 'black'
        grammar['text'] = 'Augus intermediate code by Engr. Espino\nTenorC 1.23.2a Developed by @danii_mor\n 201314810'
        grammar.pack(side='left')

    def update_line_debugg(self, event= None):
        self.count["text"] = "Line: %s" % str(self.c+1)

        lines = self.codeGenerated.split('\n')

        # start execute line by self.c counter
        ply_left_3d = titus.parse()
        if self.c < len(lines):
            if "main:" not in lines[self.c]:
                line = "main:" + lines[self.c]
                result  = ply_left_3d(titus, line)
                if result:
                    ast = result[0]
                    ast.setType("LABEL")
                    ast.setValue("S")
                    ast.root = result[0]

                    if self.__sym_table_3d != None:
                        new_table =  {**self.__sym_table_3d.printTable(), **result[1].printTable()}
                        for sym_id in new_table:
                            sym = new_table[sym_id]
                            if sym != None:
                                if type(sym) == dict:
                                    continue
                                if sym.getValue() == None:
                                    try:
                                        new_table[sym_id] = self.__sym_table_3d.printTable()[sym_id]
                                    except:
                                        pass
                        self.__sym_table_3d.setTable({**self.__sym_table_3d.printTable(), **new_table})
                    else:
                        self.__sym_table_3d = result[1]
                        # define mode for syntax-tree know how to autoexecute
                        self.__sym_table_3d.setMode(1)

                    compute = [None, None]

                    # start execute
                    self.__sym_table_3d.terminal = self.terminal
                    compute = ast.start_execute(self.__sym_table_3d, "MAIN")
                    # lookup the last line
                    index = self.terminal.search(r'\n', "insert", backwards=True, regexp=True)
                    txt = self.terminal.get(str(index),'end-1c')
                    if txt == "":
                        index ="1.0"
                    else:
                        index = self.terminal.index("%s+1c" % index)
                    if compute[0]:
                        self.terminal.insert(str(float(index)+1), compute[0])
                        self.__sym_table_3d.cleanLog()
                    if compute[1]:
                        goto_line = 0
                        for l in lines:
                            if (compute[1]+":") in l:
                                break
                            goto_line = goto_line + 1
                        
                        self.c = goto_line - 1

            if self.__sym_table != None:
                if self.__sym_table.error != '':
                    # lookup the last line
                    index = self.terminal.search(r'\n', "insert", backwards=True, regexp=True)
                    txt = self.terminal.get(str(index),'end-1c')
                    if txt == "":
                        index ="1.0"
                    else:
                        index = self.terminal.index("%s+1c" % index)
                    self.terminal.insert(str(float(index)+1), "\nTenorC>> Error Report Generated\n")

            self.c = self.c + 1
            self.label_last_line["text"] = "Line: %s" % str(self.c+1)

    c = 0
    def execute_debug(self, event = None):
        self.__sym_table_3d = None

        self.c = 0
        # create debug player
        window = Toplevel()
        window['bg'] = 'black'

        label_count = Label(window, text="Execute Now:", 
                            borderwidth=0, width=10, bg = "black", fg = "white")
        label_count.grid(row=0, column=0, sticky="nsew", padx=1, pady=1)

        label_last = Label(window, text="Executed Before:", 
                            borderwidth=0, width=10, bg = "black", fg = "white")
        label_last.grid(row=0, column=2, sticky="nsew", padx=1, pady=1)

        self.label_last_line = Label(window, text="Line: 1", 
                            borderwidth=0, width=10, bg = "black", fg = "white")
        self.label_last_line.grid(row=1, column=0, sticky="nsew", padx=1, pady=1)

        execute = Button(window, text='>',
                                   command=self.update_line_debugg)
        execute.grid(row=1, column=1, sticky="nsew", padx=1, pady=1)

        self.count = Label(window, text="Line: 0", 
                            borderwidth=0, width=10, bg = "black", fg = "white")
        self.count.grid(row=1, column=2, sticky="nsew", padx=1, pady=1)

        window.grid_columnconfigure(0, weight=1)
        window.grid_columnconfigure(1, weight=1)
        window.grid_columnconfigure(2, weight=1)
        window.resizable(width=True, height=False)


        # get all txt from current tab
        selectedTab = self.tabs.index("current")
        currentTextArea = self.tabs.winfo_children()[selectedTab+1].textarea
        input = currentTextArea.get('1.0','end-1c')

        # new singleton symbol table
        self.__sym_table = table()

        # define mode for syntax-tree know how to autoexecute
        self.__sym_table.setMode(0)

        # start lex and sintactic analysis
        ply_left = tenorC.parse()

        self.__ast  = ply_left(tenorC, input, self.__sym_table)

        # TODO sintax error recover
        if self.__ast != None:
            self.__ast.execute(self.__sym_table)
            self.codeGenerated = self.__ast.get3D()

    def execute_current_tab_lef(self):
        # get all txt from current tab
        selectedTab = self.tabs.index("current")
        currentTextArea = self.tabs.winfo_children()[selectedTab+1].textarea
        input = currentTextArea.get('1.0','end-1c')

        # new singleton symbol table
        self.__sym_table = table()

        # define mode for syntax-tree know how to autoexecute
        self.__sym_table.setMode(0)

        # start lex and sintactic analysis
        ply_left = tenorC.parse()

        self.__ast  = ply_left(tenorC, input, self.__sym_table)

        # TODO sintax error recover
        if self.__ast != None:
            self.__ast.execute(self.__sym_table)
            self.codeGenerated = self.__ast.get3D()

            ## start executing

            ply_left_3d = titus.parse()
            result  = ply_left_3d(titus, self.codeGenerated)

            if result:
                ast_3D = result[0]
                ast_3D.setType("LABEL")
                ast_3D.setValue("S")
                ast_3D.root = True

                self.__sym_table_3d = result[1]

                # define mode for syntax-tree know how to autoexecute
                self.__sym_table_3d.setMode(1)

                goto_called = True
                start_from = "MAIN"
                compute = [None, None]
                while goto_called:
                    goto_called = False
                    self.__sym_table_3d.terminal = self.terminal
                    compute = ast_3D.start_execute(self.__sym_table_3d, start_from)
                    # lookup the last line
                    index = self.terminal.search(r'\n', "insert", backwards=True, regexp=True)
                    txt = self.terminal.get(str(index),'end-1c')
                    if txt == "":
                        index ="1.0"
                    else:
                        index = self.terminal.index("%s+1c" % index)
                    if compute[0]:
                        self.terminal.insert(str(float(index)+1), compute[0])
                        self.__sym_table_3d.cleanLog()
                    if compute[1]:
                        goto_called = True
                        start_from = compute[1]

        elif self.__sym_table.error != '':
            # lookup the last line
            index = self.terminal.search(r'\n', "insert", backwards=True, regexp=True)
            txt = self.terminal.get(str(index),'end-1c')
            if txt == "":
                index ="1.0"
            else:
                index = self.terminal.index("%s+1c" % index)
            self.terminal.insert(str(float(index)+1), "\nTenorC>> Error Report Generated\n")
    
    def execute_command(self, event):
        # lookup the last line
        index = self.terminal.search(r'\n', "insert", backwards=True, regexp=True)
        input = self.terminal.get(str(index),'end-1c')
        if input == "":
            index ="1.0"
        else:
            index = self.terminal.index("%s+1c" % index)
        input = self.terminal.get(index,'end-1c')
        # send the input to the calculate 
        self.__sym_table_3d.read_input.set(input)

    def newFile(self):
        lastindex = self.tabs.index("end")-1

        textarea = Editor(self.tabs)
        self.tabs.insert(lastindex, textarea, text="Tab" + str(lastindex+1))
        self.tabs.select(lastindex)

    def exitTab(self):
        result = self.save_if_modified()
        if result != None: #None => Aborted or Save cancelled, False => Discarded, True = Saved or Not modified
            selectedTab = self.tabs.index("current")
            currentTab = self.tabs.winfo_children()[selectedTab+1]
            
            self.tabs.select(self.tabs.winfo_children()[selectedTab])
            currentTab.destroy()

    def save_if_modified(self, event=None):
        selectedTab = self.tabs.index("current")
        currentTextArea = self.tabs.winfo_children()[selectedTab+1].textarea
        if currentTextArea.edit_modified(): #modified
            response = messagebox.askyesnocancel("Save?", "This document has been modified. Do you want to save changes?") #yes = True, no = False, cancel = None
            if response: #yes/save
                result = self.file_save()
                if result == "saved": #saved
                    return True
                else: #save cancelled
                    return None
            else:
                return response #None = cancel/abort, False = no/discard
        else: #not modified
            return True

    def file_open(self, event=None, filepath=None):
        if filepath == None:
            filepath = filedialog.askopenfilename()
        if filepath != None  and filepath != '':
            with open(filepath, encoding="utf-8") as f:
                fileContents = f.read()# Get all the text from file.           
            # Set current text to a new Tab file contents
            lastindex = self.tabs.index("end")-1

            textarea = Editor(self.tabs)
            self.tabs.insert(lastindex, textarea, text="Tab" + str(lastindex+1))
            self.tabs.select(lastindex)

            textarea.textarea.insert(1.0, fileContents)
            textarea.textarea.edit_modified(False)
            tab_tittle = os.path.basename(filepath)
            self.tabs.tab(lastindex, text = tab_tittle)

    def file_save(self, event=None):
        selectedTab = self.tabs.index("current")
        currentName = self.tabs.tab(selectedTab, "text")
        if 'Tab' in currentName:
            result = self.file_save_as()
        else:
            result = self.file_save_as(filepath='./' + currentName)
        return result

    def file_save_as(self, event=None, filepath=None):
        if filepath == None:
            filepath = filedialog.asksaveasfilename(filetypes=(('Text files', '*.txt'), ('C files', '*.mc'), ('All files', '*.*'))) #defaultextension='.txt'
        try:
            with open(filepath, 'wb') as f:
                selectedTab = self.tabs.index("current")
                currentTextArea = self.tabs.winfo_children()[selectedTab+1].textarea
                text = currentTextArea.get(1.0, "end-1c")
                f.write(bytes(text, 'UTF-8'))
                currentTextArea.edit_modified(False)
                tab_tittle = os.path.basename(filepath)
                self.tabs.tab(selectedTab, text = tab_tittle)
                return "saved"
        except FileNotFoundError:
            print('TenorC>> File Not Found Error')
            return "cancelled"

    def addTab(self, event):
        selectedTab = self.tabs.index("current")
        lastindex = self.tabs.index("end")-1

        if selectedTab == lastindex :
            textarea = Editor(self.tabs)
            self.tabs.insert(lastindex, textarea, text="Tab" + str(lastindex+1))
            self.tabs.select(lastindex)

    def donothing(self):
        print("clicked")
class ViewResults(Observer, View):
    """Takes care of the presentation of the Flow diagram."""
    def __init__(self, parent, col=0, row=0, root=None):
        super().__init__(parent,
                         col=col,
                         row=row,
                         sticky=NSEW,
                         scrollbars=False,
                         root=root)
        self._notebook = Notebook(self._frame, name="nb")
        self._notebook.columnconfigure(0, weight=1)
        self._notebook.rowconfigure(0, weight=1)
        self._notebook.config()
        self._notebook.grid(sticky=NSEW)
        self._notebook.grid(sticky=NSEW)
        self._tabs = []  # type: List[ImageTab]
        self._results = None
        self._parent = parent
        self.image_overlay = np.empty(shape=(0, 0, 0), dtype=np.uint8)

        # TODO: Work around below should be fixed; need to create a tab first and delete it, or background is old image in constant scale.
        name_init = "initialization_image"
        self.add_to_tab(np.zeros((1, 1, 3), dtype=np.uint8), name_init)
        self.RemoveTab(name_init)

        self.__temp_data_queue = Queue(
        )  # used for update function to store data in

        # add custom event handler to let updates be taken care of in tk main loop
        parent.root.bind("<<ViewResults.Update>>", self.__update)
        self._notebook.bind("<<NotebookTabChanged>>", self.__on_tabchange)

        self.__last_selected_tab = None

    def __on_tabchange(self, event):
        try:
            tab_index = self._notebook.index(self._notebook.select())
        except TclError as ex:
            return  # there are no tabs yet
        if self.__last_selected_tab is not None:
            self.__last_selected_tab.on_tab_deselect()
        self.__last_selected_tab = self._tabs[tab_index]
        self.__last_selected_tab.on_tab_selected()

    def RemoveTab(self, name):
        for tab in self._tabs:
            if name is tab.GetName():
                tab.destroy()
                self._tabs.remove(tab)

    def add_to_tab(self, npimage, name):
        if npimage is None:
            return

        # check if one exists; if so use that
        for tab in self._tabs:
            if tab.GetName() == name:
                tab.SetImage(npimage=npimage)
                return
        #create new tab one
        tab = ImageTab(name=name, notebook=self._notebook, parent=self)
        self._tabs.append(tab)
        self.add_to_tab(npimage=npimage, name=name)

    def __findAllImagesAndShow(self, flowblock_name):
        if self._results is None:
            return
        imageVars = self._results.FindAllOfType(ImageVar().name)
        for key, var in imageVars.items():
            name = key.split(".")[0]
            if name == flowblock_name:
                self.add_to_tab(var.value, name)

    def __draw_all_drawables_until(self, flowblock_name=None):
        '''
        Draws al drawable results to image_overlay. Images is as large as to fit all drawables.
        :param flowblock_name: draw until this block.
        :return:
        '''
        results = self.get_controller().results.get_result_dict(
        )  # type: Dict[str,Dict[str,Var]]
        self.image_overlay = np.empty(shape=(0, 0, 0), dtype=np.uint8)
        logging.debug("Starting drawing of drawables...")
        for key, value in results.items():
            for key2, value2 in value.items():
                if type(value2) == list:
                    for value3 in value2:
                        self.image_overlay = value3.draw(self.image_overlay)
                else:
                    self.image_overlay = value2.draw(self.image_overlay)
        logging.debug("Finished drawing of drawables.")

    def __update(self, event):
        self._results = self.get_controller().results.get_results_for_block()
        try:
            flowblock_name = self.__temp_data_queue.get_nowait(
            )["flowblock_name"]
        except Empty:
            flowblock_name = None
        if not flowblock_name is None:
            # redraw al drawables
            self.__draw_all_drawables_until(flowblock_name)
            # a flowblock has just updated, go and show all containing images
            self.__findAllImagesAndShow(flowblock_name)

    def Update(self, *args, **kwargs):
        self.__temp_data_queue.put_nowait(
            {"flowblock_name": kwargs.get("flowblock_name", None)})
        self._parent.root.event_generate("<<ViewResults.Update>>")