class LabeledVerticalScale(Frame):
    """
    LabeledVerticalScale - Supporting Frame of vertical slider with labels
    """
    def __init__(self, parent, text="", value=0.0, slider_bind_func=None):
        Frame.__init__(self, parent)

        self.main_bg = parent['bg']
        self.config(bg=self.main_bg)
        self.slider_events = ["<ButtonRelease-1>", "<ButtonRelease-3>"]

        self.label = Label(self, text=text)
        self.label.grid(row=0, column=0, padx=5, pady=3, sticky='s')
        self.slider = Scale(self,
                            from_=1,
                            to=0,
                            orient=VERTICAL,
                            resolution=0.01,
                            length=200,
                            width=18)
        self.slider.grid(row=1, column=0, padx=5, pady=5, sticky='n')
        if slider_bind_func is not None:
            for event in self.slider_events:
                self.slider.bind(event, slider_bind_func)
            self.slider.set(value)
        self.label.config(bg=self.slider['bg'])

    def get(self):
        return self.slider.get()
Exemple #2
0
    def ShowClock(self):
        self.SetServerTimeOffset()
        clockwindow = tix.Toplevel()

        clockwindow.resizable(0,0)
        tix.Label(clockwindow, text="현재 보인아이 시간").pack()
        clocklabel = Label(clockwindow, text="00:00:00", font=("TkDefaultFont", 50, "bold"))
        clocklabel.pack(expand=YES, fill=BOTH)
        clockwindow.update_idletasks()
        fontscale = Scale(clockwindow,label="글자크기",from_=10, to=200, orient=HORIZONTAL, resolution=10)
        fontscale.pack(fill=Y,anchor=S)
        fontscale.set(50)
        fontscale.bind("<ButtonRelease-1>",lambda x: self.UpdateStandaloneClock(clocklabel, fontscale))
        clocklabel.after(100, self.UpdateBoiniClock(clocklabel))
Exemple #3
0
 def __init__(self, modelProc, tick):
     self.modelProc = modelProc
     self.tick = tick
     self.queue = modelProc.getQueue()
     # ----------------- Model parameters -----------------
     # Waiting time between two events
     self.refreshRate = DEFAULT_REFRESH_RATE
     # Elapsed time (in number of ticks)
     self.count = 0
     # ------------------------ GUI -----------------------
     # Main window
     self.window = Tk()
     self.window.title("Model Rendering")
     self.window.configure(bg=BG_COLOR)
     self.window.protocol("WM_DELETE_WINDOW", self.onClosing)
     # Main pane
     mainPane = PanedWindow(self.window, orient=HORIZONTAL, bg=BG_COLOR)
     mainPane.pack(side=TOP, expand=Y, fill=BOTH, pady=5, padx=5)
     # Canvas frame
     canvasFrame = LabelFrame(mainPane, text="Rendering", padx=10, pady=10, bg=BG_COLOR)
     mainPane.add(canvasFrame)
     self.canvas = Canvas(canvasFrame, width=CANVAS_X, height=CANVAS_Y, background="white")
     self.canvas.pack()
     # Parameters frame
     paramFrame = LabelFrame(mainPane, text="Simulation parameters",\
     padx=20, pady=20, bg=BG_COLOR)
     mainPane.add(paramFrame)
     # ===> Refresh rate slider
     self.stepVar = DoubleVar(paramFrame, value=DEFAULT_REFRESH_RATE)
     slider = Scale(paramFrame, from_=0, to_=0.5, resolution=0.001, length=350, orient=VERTICAL,\
     variable=self.stepVar, label="# Refresh rate", bg=BG_COLOR, bd=1)
     slider.bind("<ButtonRelease-1>", self.updateRate)
     slider.grid(row=1, column=1)
     # ===> Elapsed time
     self.timeLabel = Label(paramFrame, text="# Elapsed time (hours) :\n0", bg=BG_COLOR)
     self.timeLabel.grid(row=3, column=1)
     # Rows and columns configuration
     paramFrame.grid_columnconfigure(0, weight=1)
     paramFrame.grid_columnconfigure(1, weight=2)
     paramFrame.grid_columnconfigure(2, weight=1)
     paramFrame.grid_rowconfigure(0, weight=1)
     paramFrame.grid_rowconfigure(2, weight=2)
     paramFrame.grid_rowconfigure(4, weight=2)
Exemple #4
0
    def create_buttons(self, parent, create_sliders):

        self.jso = Button(parent,
                          text="Import from .json",
                          command=self.import_json)
        self.jso.grid(row=0, column=0, sticky="w")
        self.sav = Button(parent,
                          text="Import from .sav",
                          command=self.import_sav)
        self.sav.grid(row=0, column=1, sticky="w")

        self.scales = []

        # create sliders
        if create_sliders:
            self.jso.grid_configure(row=0, column=0)
            self.sav.grid_configure(row=1, column=0)
            resources = [
                'minerals', 'energy', 'physics', 'society', 'engineering'
            ]
            colors = ["red", "yellow", "blue", "green", "orange"]
            for i in range(len(resources)):
                var = DoubleVar()
                var.set(500)
                callback = lambda event, tag=i: self.weight_update(event, tag)
                b = Scale(parent,
                          from_=1,
                          to=1000,
                          variable=var,
                          length=135,
                          orient='horizontal',
                          troughcolor=colors[i],
                          resolution=1,
                          label=resources[i],
                          showvalue=0)
                b.grid(row=2 + i, column=0, sticky="w")
                b.bind('<ButtonRelease-1>',
                       self.redraw)  # redraw when user release scale
                self.scales.append(var)
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]])
Exemple #6
0
class Gui:
    """
    This class is built to let the user have a better interaction with
    game.
    inputs =>
    root = Tk() => an object which inherits the traits of Tkinter class
    agent = an object which inherit the traits of mctsagent class.

    """

    agent_type = {1: "UCT", 2: "RAVE", 3: "LAST-GOOD-REPLY", 4: "POOLRAVE", 5: "DECISIVE-MOVE", 6: "UCB1-TUNED"}

    AGENTS = {"UCT": UctMctsAgent,
              "RAVE": RaveMctsAgent,
              "LAST-GOOD-REPLY": LGRMctsAgent,
              "POOLRAVE": PoolRaveMctsAgent,
              "DECISIVE-MOVE": DecisiveMoveMctsAgent,
              "UCB1-TUNED": UCB1TunedMctsAgent}

    def __init__(self, root, agent_name='UCT'):
        self.root = root
        self.root.geometry('1366x690+0+0')
        self.agent_name = agent_name
        try:
            self.agent = self.AGENTS[agent_name]()
        except KeyError:
            print("Unknown agent defaulting to basic")
            self.agent_name = "uct"
            self.agent = self.AGENTS[agent_name]()
        self.game = GameState(8)
        self.agent.set_gamestate(self.game)
        self.time = 1
        self.root.configure(bg='#363636')
        self.colors = {'white': '#ffffff',
                       'milk': '#e9e5e5',
                       'red': '#9c0101',
                       'orange': '#ee7600',
                       'yellow': '#f4da03',
                       'green': '#00ee76',
                       'cyan': '#02adfd',
                       'blue': '#0261fd',
                       'purple': '#9c02fd',
                       'gray1': '#958989',
                       'gray2': '#3e3e3e',
                       'black': '#000000'}
        global BG
        BG = self.colors['gray2']
        self.last_move = None
        self.frame_board = Frame(self.root)  # main frame for the play board
        self.canvas = Canvas(self.frame_board, bg=BG)
        self.scroll_y = ttk.Scrollbar(self.frame_board, orient=VERTICAL)
        self.scroll_x = ttk.Scrollbar(self.frame_board, orient=HORIZONTAL)

        # the notebook frame which holds the left panel frames

        self.notebook = ttk.Notebook(self.frame_board, width=350)
        self.panel_game = Frame(self.notebook, highlightbackground=self.colors['white'])
        self.developers = Frame(self.notebook, highlightbackground=self.colors['white'])

        # Registering variables for:

        self.game_size_value = IntVar()  # size of the board
        self.game_time_value = IntVar()  # time of CPU player
        self.game_turn_value = IntVar()  # defines whose turn is it

        self.switch_agent_value = IntVar()  # defines which agent to play against
        self.switch_agent_value.set(1)

        self.game_turn_value.set(1)
        self.turn = {1: 'white', 2: 'black'}

        self.game_size = Scale(self.panel_game)
        self.game_time = Scale(self.panel_game)
        self.game_turn = Scale(self.panel_game)
        self.generate = Button(self.panel_game)
        self.reset_board = Button(self.panel_game)

        self.switch_agent = Scale(self.panel_game)
        self.agent_show = Label(self.panel_game, font=('Calibri', 14, 'bold'), fg='white', justify=LEFT,
                                bg=BG, text='Agent Policy: ' + self.agent_name + '\n')

        self.hex_board = []
        # Holds the IDs of hexagons in the main board for implementing the click and play functions
        self.game_size_value.set(8)
        self.game_time_value.set(1)
        self.size = self.game_size_value.get()
        self.time = self.game_time_value.get()
        self.board = self.game.board
        self.board = int_(self.board).tolist()
        self.gameboard2hexagons(self.board)  # building the game board
        self.logo = PhotoImage(file='image/hex.png')
        self.uut_logo = PhotoImage(file='image/uut_2.png')
        self.generate_black_edge()
        self.generate_white_edge()

        # Frame_content

        self.frame_board.configure(bg=BG, width=1366, height=760)
        self.frame_board.pack(fill=BOTH)
        self.notebook.add(self.panel_game, text='       Game       ')
        self.notebook.add(self.developers, text='    Developers    ')
        self.notebook.pack(side=LEFT, fill=Y)
        self.canvas.configure(width=980, bg=BG, cursor='hand2')
        self.canvas.pack(side=LEFT, fill=Y)
        self.canvas.configure(yscrollcommand=self.scroll_y.set)
        self.scroll_y.configure(command=self.canvas.yview)
        self.scroll_x.configure(command=self.canvas.xview)
        self.scroll_y.place(x=387, y=482)
        self.scroll_x.place(x=370, y=500)

        # Frame_left_panel

        """
        the left panel notebook ---->   Game

        """
        self.panel_game.configure(bg=BG)
        Label(self.panel_game, text='Board size',
              font=('Calibri', 14, 'bold'),
              foreground='white', bg=BG, pady=10).pack(fill=X, side=TOP)  # label ---> Board size
        self.game_size.configure(from_=3, to=20, tickinterval=1, bg=BG, fg='white',
                                 orient=HORIZONTAL, variable=self.game_size_value)
        self.game_size.pack(side=TOP, fill=X)
        Label(self.panel_game, text='Time',
              font=('Calibri', 14, 'bold'),
              foreground='white', bg=BG, pady=10).pack(side=TOP, fill=X)  # label ---> Time
        self.game_time.configure(from_=1, to=20, tickinterval=1, bg=BG, fg='white',
                                 orient=HORIZONTAL, variable=self.game_time_value)
        self.game_time.pack(side=TOP, fill=X)
        Label(self.panel_game, text='Player',
              font=('Calibri', 14, 'bold'),
              foreground='white', bg=BG, pady=10).pack(side=TOP, fill=X)  # label ---> Turn
        self.game_turn.configure(from_=1, to=2, tickinterval=1, bg=BG, fg='white',
                                 orient=HORIZONTAL, variable=self.game_turn_value)
        self.game_turn.pack(side=TOP)
        Label(self.panel_game, text='   ',
              font=('Calibri', 14, 'bold'),
              foreground='white', bg=BG).pack(side=TOP, fill=X)

        #  ################################## AGENT CONTROLS #############################

        self.agent_show.pack(fill=X, side=TOP)
        self.switch_agent.configure(from_=1, to=len(self.agent_type), tickinterval=1, bg=BG, fg='white',
                                    orient=HORIZONTAL, variable=self.switch_agent_value, )
        self.switch_agent.pack(side=TOP, fill=X)

        #  ################################## MOVE LABELS ################################
        self.move_label = Label(self.panel_game, font=('Calibri', 15, 'bold'), height=5, fg='white', justify=LEFT,
                                bg=BG, text='PLAY : CLICK A CELL ON GAME BOARD \nMCTS BOT: CLICK GENERATE')
        self.move_label.pack(side=TOP, fill=X)

        self.reset_board.configure(text='Reset Board', pady=10,
                                   cursor='hand2', width=22,
                                   font=('Calibri', 12, 'bold'))
        self.reset_board.pack(side=LEFT)
        self.generate.configure(text='Generate', pady=10,
                                cursor='hand2', width=22,
                                font=('Calibri', 12, 'bold'))
        self.generate.pack(side=LEFT)

        """
        the left panel notebook ---> Developers

        """
        self.developers.configure(bg=BG)
        Label(self.developers,
              text='HEXPY',
              font=('Calibri', 18, 'bold'),
              foreground='white', bg=BG, pady=5).pack(side=TOP, fill=X)
        Label(self.developers,
              text='DEVELOPED BY:\n'
                   + 'Masoud Masoumi Moghadam\n\n'
                   + 'SUPERVISED BY:\n'
                   + 'Dr.Pourmahmoud Aghababa\n'
                   + 'Dr.Bagherzadeh\n\n'
                   + 'SPECIAL THANKS TO:\n'
                   + 'Nemat Rahmani\n',
              font=('Calibri', 16, 'bold'), justify=LEFT,
              foreground='white', bg=BG, pady=10).pack(side=TOP, fill=X)
        Label(self.developers, image=self.uut_logo, bg=BG).pack(side=TOP, fill=X)
        Label(self.developers, text='Summer 2016',
              font=('Calibri', 17, 'bold'), wraplength=350, justify=LEFT,
              foreground='white', bg=BG, pady=30).pack(side=TOP, fill=X)

        # Binding Actions

        """
        Binding triggers for the actions defined in the class.

        """
        self.canvas.bind('<1>', self.click2play)
        self.game_size.bind('<ButtonRelease>', self.set_size)
        self.game_time.bind('<ButtonRelease>', self.set_time)
        self.generate.bind('<ButtonRelease>', self.click_to_bot_play)
        self.reset_board.bind('<ButtonRelease>', self.reset)
        self.switch_agent.bind('<ButtonRelease>', self.set_agent)

    @staticmethod
    def top_left_hexagon():
        """
        Returns the points which the first hexagon has to be created based on.

        """
        return [[85, 50], [105, 65], [105, 90], [85, 105], [65, 90], [65, 65]]

    def hexagon(self, points, color):
        """
        Creates a hexagon by getting a list of points and their assigned colors
        according to the game board
        """
        if color is 0:
            hx = self.canvas.create_polygon(points[0], points[1], points[2],
                                            points[3], points[4], points[5],
                                            fill=self.colors['gray1'], outline='black', width=2, activefill='cyan')
        elif color is 1:
            hx = self.canvas.create_polygon(points[0], points[1], points[2],
                                            points[3], points[4], points[5],
                                            fill=self.colors['yellow'], outline='black', width=2, activefill='cyan')
        elif color is 2:
            hx = self.canvas.create_polygon(points[0], points[1], points[2],
                                            points[3], points[4], points[5],
                                            fill=self.colors['red'], outline='black', width=2, activefill='cyan')
        elif color is 3:
            hx = self.canvas.create_polygon(points[0], points[1], points[2],
                                            points[3], points[4], points[5],
                                            fill=self.colors['black'], outline='black', width=2)
        else:
            hx = self.canvas.create_polygon(points[0], points[1], points[2],
                                            points[3], points[4], points[5],
                                            fill=self.colors['white'], outline='black', width=2)
        return hx

    def generate_row(self, points, colors):
        """
        By getting a list of points as the starting point of each row and a list of
        colors as the dedicated color for each item in row, it generates a row of
        hexagons by calling hexagon functions multiple times.
        """
        x_offset = 40
        row = []
        temp_array = []
        for i in range(len(colors)):
            for point in points:
                temp_points_x = point[0] + x_offset * i
                temp_points_y = point[1]
                temp_array.append([temp_points_x, temp_points_y])
            if colors[i] is 0:
                hx = self.hexagon(temp_array, 0)
            elif colors[i] is 1:
                hx = self.hexagon(temp_array, 4)
            else:
                hx = self.hexagon(temp_array, 3)
            row.append(hx)
            temp_array = []
        return row

    def gameboard2hexagons(self, array):
        """
        Simply gets the game_board and generates the hexagons by their dedicated colors.
        """
        initial_offset = 20
        y_offset = 40
        temp = []
        for i in range(len(array)):
            points = self.top_left_hexagon()
            for point in points:
                point[0] += initial_offset * i
                point[1] += y_offset * i
                temp.append([point[0], point[1]])
            row = self.generate_row(temp, self.board[i])
            temp.clear()
            self.hex_board.append(row)

    def generate_white_edge(self):
        """
        Generates the white zones in the left and right of the board.

        """
        init_points = self.top_left_hexagon()
        for pt in init_points:
            pt[0] -= 40
        for pt in init_points:
            pt[0] -= 20
            pt[1] -= 40
        label_x, label_y = 0, 0
        init_offset = 20
        y_offset = 40
        temp_list = []
        for i in range(len(self.board)):
            for pt in range(len(init_points)):
                init_points[pt][0] += init_offset
                init_points[pt][1] += y_offset
                label_x += init_points[pt][0]
                label_y += init_points[pt][1]
            label_x /= 6
            label_y /= 6
            self.hexagon(init_points, 4)
            self.canvas.create_text(label_x, label_y, fill=self.colors['black'], font="Times 20 bold",
                                    text=chr(ord('A') + i))
            label_x, label_y = 0, 0
            for j in init_points:
                temp_list.append([j[0] + (len(self.board) + 1) * 40, j[1]])
            self.hexagon(temp_list, 4)
            temp_list.clear()

    def generate_black_edge(self):
        """
        Generates the black zones in the top and bottom of the board.

        """
        init_points = self.top_left_hexagon()
        label_x, label_y = 0, 0
        temp_list = []
        for pt in init_points:
            pt[0] -= 60
            pt[1] -= 40
        for t in range(len(init_points)):
            init_points[t][0] += 40
            label_x += init_points[t][0]
            label_y += init_points[t][1]
        label_x /= 6
        label_y /= 6
        for i in range(len(self.board)):
            self.hexagon(init_points, 3)
            self.canvas.create_text(label_x, label_y, fill=self.colors['white'], font="Times 20 bold", text=i + 1)
            label_x, label_y = 0, 0
            for pt in init_points:
                temp_list.append([pt[0] + (len(self.board) + 1) * 20, pt[1] + (len(self.board) + 1) * 40])
            self.hexagon(temp_list, 3)
            temp_list.clear()
            for j in range(len(init_points)):
                init_points[j][0] += 40
                label_x += init_points[j][0]
                label_y += init_points[j][1]
            label_x /= 6
            label_y /= 6

    def click2play(self, event):
        """
        Whenever any of the hexagons in the board is clicked, depending
        on the player turns, it changes the color of hexagon to the player
        assigned color.

        """
        if self.winner() == 'none':
            x = self.canvas.canvasx(event.x)
            y = self.canvas.canvasy(event.y)
            idd = self.canvas.find_overlapping(x, y, x, y)
            idd = list(idd)
            if len(idd) is not 0:
                clicked_cell = idd[0]
                if any([clicked_cell in x for x in self.hex_board]):
                    coordinated_cell = clicked_cell - self.hex_board[0][0]
                    col = (coordinated_cell % self.size)
                    turn = self.turn[self.game_turn_value.get()]
                    if coordinated_cell % self.size == 0:
                        row = int(coordinated_cell / self.size)
                    else:
                        row = int(coordinated_cell / self.size)
                        cell = str(chr(65 + row)) + str(col + 1)
                        self.move_label.configure(text=str(turn) + ' played ' + cell, justify=LEFT, height=5)
                    if self.board[row][col] == 0:
                        self.board[row][col] = self.game_turn_value.get()
                        if self.game_turn_value.get() == 1:
                            self.game_turn_value.set(2)
                        else:
                            self.game_turn_value.set(1)
                    self.refresh()
                    y = row
                    x = col
                    if turn[0].lower() == 'w':
                        self.last_move = (x, y)
                        if self.game.turn() == GameMeta.PLAYERS["white"]:
                            self.game.play((x, y))
                            self.agent.move((x, y))
                            if self.winner() != 'none':
                                messagebox.showinfo(" GAME OVER", " Wow, You won! \n Winner is %s" % self.winner())
                            return
                        else:
                            self.game.place_white((x, y))
                            self.agent.set_gamestate(self.game)
                            if self.winner() != 'none':
                                messagebox.showinfo(" GAME OVER", " Wow, You won! \n Winner is %s" % self.winner())
                            return
                    elif turn[0].lower() == 'b':
                        self.last_move = (x, y)
                        if self.game.turn() == GameMeta.PLAYERS["black"]:
                            self.game.play((x, y))
                            self.agent.move((x, y))
                            if self.winner() != 'none':
                                messagebox.showinfo(" GAME OVER", " Wow, You won! \n Winner is %s" % self.winner())
                            return
                        else:
                            self.game.place_black((x, y))
                            self.agent.set_gamestate(self.game)
                            if self.winner() != 'none':
                                messagebox.showinfo(" GAME OVER", " Wow, You won! \n Winner is %s" % self.winner())
                            return
        else:
            messagebox.showinfo(" GAME OVER ", " The game is already over! Winner is %s" % self.winner())

    def set_size(self, event):
        """
        It changes the board size and reset the whole game.

        """
        self.canvas.delete('all')
        self.size = self.game_size_value.get()
        self.game = GameState(self.size)
        self.agent.set_gamestate(self.game)
        self.board = self.game.board
        self.board = int_(self.board).tolist()
        self.last_move = None
        self.move_label.config(text='PLAY : CLICK A CELL ON GAME BOARD \nMCTS BOT: CLICK GENERATE', justify='left',
                               height=5)
        self.refresh()

    def set_time(self, event) -> None:
        """
        It changes the time for CPU player to think and generate a move.

        """
        self.time = self.game_time_value.get()
        print('The CPU time = ', self.time, ' seconds')

    def set_agent(self, event) -> None:
        """
        It changes the time for CPU player to think and generate a move.

        """
        agent_num = self.switch_agent_value.get()
        self.agent_name = self.agent_type[agent_num]
        self.agent = self.AGENTS[self.agent_name](self.game)
        self.agent_show.config(font=('Calibri', 14, 'bold'), justify=LEFT,
                               text='Agent Policy: ' + self.agent_name + '\n')

    def winner(self) -> str:
        """
        Return the winner of the current game (black or white), none if undecided.

        """
        if self.game.winner == GameMeta.PLAYERS["white"]:
            return "white"
        elif self.game.winner == GameMeta.PLAYERS["black"]:
            return "black"
        else:
            return "none"

    def click_to_bot_play(self, event):
        """
        By pushing the generate button, It produces an appropriate move
        by using monte carlo tree search algorithm for the player which
        turn is his/hers! .

        """
        if self.winner() == 'none':
            self.agent.search(self.time)
            num_rollouts, node_count, run_time = self.agent.statistics()
            move = self.agent.best_move()  # the move is tuple like (3, 1)
            self.game.play(move)
            self.agent.move(move)
            row, col = move  # Relating the 'move' tuple with index of self.board
            self.board[col][row] = self.game_turn_value.get()
            if self.game_turn_value.get() == 1:  # change the turn of players
                self.game_turn_value.set(2)
            else:
                self.game_turn_value.set(1)
            self.refresh()
            player = self.turn[self.game_turn_value.get()]
            cell = chr(ord('A') + move[1]) + str(move[0] + 1)
            self.move_label.config(font=('Calibri', 15, 'bold'), justify='left',
                                   text=str(num_rollouts) + ' Game Simulations ' + '\n'
                                                          + 'In ' + str(run_time) + ' seconds ' + '\n'
                                                          + 'Node Count : ' + str(node_count) + '\n'
                                                          + player + ' played at ' + cell, height=5)
            print('move = ', cell)
            if self.winner() != 'none':
                messagebox.showinfo(" GAME OVER", " Oops!\n You lost! \n Winner is %s" % self.winner())
        else:
            messagebox.showinfo(" GAME OVER", " The game is already over! Winner is %s" % self.winner())

    def refresh(self):
        """
        Delete the whole world and recreate it again

        """
        self.canvas.delete('all')
        self.hex_board.clear()
        self.gameboard2hexagons(self.board)
        self.generate_black_edge()
        self.generate_white_edge()

    def reset(self, event):
        """
        By clicking on the Reset button game board would be cleared
        for a new game

        """
        self.game = GameState(self.game.size)
        self.agent.set_gamestate(self.game)
        self.set_size(event)
        self.last_move = None
        self.game_turn_value.set(1)
        self.move_label.config(text='PLAY : CLICK A CELL ON GAME BOARD \nMCTS BOT: CLICK GENERATE', justify='left',
                               height=5)
Exemple #7
0
class ControlAppGUI:
    def __init__(self, master):
        self.master = master
        # GUI layout setup
        self.menu = Menu(self.master)

        self.master.config(menu=self.menu)
        master.grid_rowconfigure(0, weight=1)
        master.grid_columnconfigure(0, weight=1)
        filemenu = Menu(self.menu)
        self.menu.add_cascade(label="File", menu=filemenu)
        filemenu.add_command(label="New", command=self.NewFile)
        openmenu = Menu(self.menu)
        openmenu.add_command(label="Gcode", command=self.OpenGcodeFile)
        openmenu.add_command(label="CSV", command=self.OpenCsvFile)
        savemenu = Menu(self.menu)
        savemenu.add_command(label="Gcode", command=self.SaveGcodeFile)
        savemenu.add_command(label="CSV", command=self.SaveCsvFile)
        filemenu.add_cascade(label='Open...', menu=openmenu, underline=0)
        filemenu.add_cascade(label="Save...", menu=savemenu, underline=0)
        #filemenu.add_command(label="Reload current file", command=None)
        filemenu.add_command(label="Set color", command=self.AskColor)
        filemenu.add_separator()

        def updatePortList():
            ports = serial.serial_ports()
            self.portCombo['values'] = ports
            if len(ports) > 0:
                self.portCombo.current(0)

        filemenu.add_command(label="Refresh port list", command=updatePortList)
        filemenu.add_command(label="Exit", command=self.Quit)

        editmenu = Menu(self.menu)
        self.menu.add_cascade(label="Edit", menu=editmenu)
        editmenu.add_command(label="Settings", command=self.Settings)

        helpmenu = Menu(self.menu)
        self.menu.add_cascade(label="Help", menu=helpmenu)
        helpmenu.add_command(label="About...", command=self.About)
        master.title("Embroiderino frontend")

        self.controls = ttk.Notebook(master)
        tab1 = Frame(self.controls)
        tab2 = Frame(self.controls)
        self.controls.add(tab1, text="Machine control")
        self.controls.add(tab2, text="Path manipulation")
        self.controls.grid(row=0, column=1, sticky=N)
        self.controls.grid_rowconfigure(0, weight=1)
        self.controls.grid_columnconfigure(0, weight=1)

        # MACHINE TAB
        ports = serial.serial_ports()
        self.portCombo = ttk.Combobox(tab1, values=ports)
        if len(ports) > 0:
            self.portCombo.current(0)
        self.portCombo.grid(row=1, column=0)
        self.baudCombo = ttk.Combobox(tab1,
                                      state='readonly',
                                      values=("115200", "9600"),
                                      width=10)
        self.baudCombo.current(0)
        self.baudCombo.grid(row=1, column=1)
        self.connectButton = Button(tab1,
                                    text="Connect",
                                    command=self.ToggleConnect,
                                    width=10)
        self.connectButton.grid(row=1, column=2)

        self.startButton = Button(tab1,
                                  text="Start job",
                                  command=self.ToggleStart,
                                  state=DISABLED)
        self.startButton.grid(row=2, column=1)
        self.homeButton = Button(tab1,
                                 text="Home machine",
                                 command=lambda: serial.queue_command("G28\n"),
                                 state=DISABLED)
        self.homeButton.grid(row=2, column=0)

        testNavigation = Frame(tab1)
        leftButton = Button(
            testNavigation,
            text="<",
            command=lambda: serial.queue_command("G91\nG0 X-2\nG90\n"),
            state=DISABLED)
        leftButton.grid(row=1, column=0)
        rightButton = Button(
            testNavigation,
            text=">",
            command=lambda: serial.queue_command("G91\nG0 X2\nG90\n"),
            state=DISABLED)
        rightButton.grid(row=1, column=2)
        upButton = Button(
            testNavigation,
            text="/\\",
            command=lambda: serial.queue_command("G91\nG0 Y2\nG90\n"),
            state=DISABLED)
        upButton.grid(row=0, column=1)
        downButton = Button(
            testNavigation,
            text="\\/",
            command=lambda: serial.queue_command("G91\nG0 Y-2\nG90\n"),
            state=DISABLED)
        downButton.grid(row=2, column=1)
        testNavigation.grid(row=3, column=0)
        self.navigationButtons = [
            leftButton, rightButton, upButton, downButton
        ]

        self.testButton = Button(tab1,
                                 text="Test border path",
                                 command=self.TestBorder,
                                 state=DISABLED)
        self.testButton.grid(row=3, column=1)

        self.gotoButton = Button(tab1,
                                 text="Go to",
                                 command=self.GoTo,
                                 state=DISABLED,
                                 relief=RAISED)
        self.gotoButton.grid(row=3, column=2)

        self.stopButton = Button(tab1,
                                 text="STOP",
                                 command=self.StopAll,
                                 state=DISABLED)
        self.stopButton.grid(row=4, column=0)

        self.pauseOnToolChange = IntVar()
        self.pauseOnTrim = IntVar()
        self.toolChangeCheck = Checkbutton(tab1,
                                           variable=self.pauseOnToolChange,
                                           onvalue=1,
                                           offvalue=0,
                                           text="Pause on tool change")
        self.toolChangeCheck.grid(row=4, column=1)
        self.toolChangeCheck.select()
        self.trimCheck = Checkbutton(tab1,
                                     variable=self.pauseOnTrim,
                                     onvalue=1,
                                     offvalue=0,
                                     text="Pause on trim")
        self.trimCheck.grid(row=4, column=2)
        self.trimCheck.select()

        progressFrame = Frame(tab1)
        Label(progressFrame, text="Tool changes: ", bd=1).grid(row=0,
                                                               column=0,
                                                               pady=(10, 1))
        self.toolChangesLabel = Label(progressFrame,
                                      text="0/0",
                                      bd=1,
                                      relief=SUNKEN)
        self.toolChangesLabel.grid(row=1, column=0)

        Label(progressFrame, text="Tool points: ", bd=1).grid(row=0,
                                                              column=2,
                                                              pady=(10, 1))
        self.toolPointsLabel = Label(progressFrame,
                                     text="0/0",
                                     bd=1,
                                     relief=SUNKEN)
        self.toolPointsLabel.grid(row=1, column=2)

        Label(progressFrame, text="Estimated endtime: ",
              bd=1).grid(row=0, column=4, pady=(10, 1))
        self.timeLabel = Label(progressFrame, text="0/0", bd=1, relief=SUNKEN)
        self.timeLabel.grid(row=1, column=4)
        progressFrame.grid(row=5, column=0, columnspan=3)

        colorsFrame = Frame(tab1, bd=1)
        colorsFrame.grid(row=6, column=0, columnspan=3, pady=(10, 1))
        Label(colorsFrame, text="Current color: ", bd=1).pack(side=LEFT)
        self.currentColorIndicator = Label(colorsFrame,
                                           text="    ",
                                           relief=RAISED,
                                           bd=1)
        self.currentColorIndicator.pack(side=LEFT, padx=(1, 40))
        Label(colorsFrame, text="Next color: ", bd=1).pack(side=LEFT, padx=2)
        self.nextColorIndicator = Label(colorsFrame,
                                        text="    ",
                                        relief=RAISED,
                                        bd=1)
        self.nextColorIndicator.pack(side=LEFT)

        Label(tab1, text="SPM speed limit: ", bd=1).grid(row=7, column=0)
        self.speedSlider = Scale(tab1,
                                 from_=80,
                                 to=800,
                                 command=None,
                                 orient=HORIZONTAL,
                                 length=200)
        self.speedSlider.set(400)
        self.speedSlider.bind(
            "<ButtonRelease-1>", lambda _: serial.queue_command(
                "M222 S%d\n" % self.speedSlider.get(), priority=-1))
        self.speedSlider.grid(row=7, column=1, columnspan=2)

        # PATH TAB
        tab2.grid_columnconfigure(0, weight=1)
        Label(tab2, text="Display progress: ", bd=1).grid(row=0)
        self.slider = Scale(tab2,
                            from_=0,
                            to=0,
                            command=self.UpdatePath,
                            orient=HORIZONTAL,
                            length=300)
        self.slider.grid(row=1)

        toolbar = Frame(tab2, bd=1, relief=RAISED)
        toolbar.grid(row=2)
        self.panButton = Button(toolbar,
                                relief=RAISED,
                                command=self.TogglePan,
                                text="Move path")
        self.panButton.pack(side=LEFT, padx=2, pady=2)

        self.rotateButton = Button(toolbar,
                                   relief=RAISED,
                                   command=self.ToggleRotate,
                                   text="Rotate path")
        self.rotateButton.pack(side=LEFT, padx=2, pady=2)

        self.mirrorButton = Button(toolbar,
                                   relief=RAISED,
                                   command=self.ToggleMirror,
                                   text="Mirror path")
        self.mirrorButton.pack(side=LEFT, padx=2, pady=2)

        self.scaleButton = Button(toolbar,
                                  relief=RAISED,
                                  command=self.ToggleScale,
                                  text="Scale path")
        self.scaleButton.pack(side=LEFT, padx=2, pady=2)

        # CANVAS
        canvasFrame = Frame(master)
        canvasFrame.grid(row=0, column=0, sticky='NWES')
        self.canvas = ResizingCanvas(canvasFrame,
                                     width=400,
                                     height=400,
                                     bg="white",
                                     highlightthickness=0)
        self.canvas.bind("<B1-Motion>", self.CanvasDrag)
        self.canvas.bind("<Button-1>", self.CanvasClick)
        self.canvas.bind("<ButtonRelease-1>", self.CanvasRelease)
        self.canvas.pack(expand=YES, anchor=N + W)

        #STATUS BAR
        self.status = Label(master,
                            text="Not connected",
                            bd=1,
                            relief=SUNKEN,
                            anchor=W)
        self.status.grid(row=2, columnspan=2, sticky='WE')

        # PROGRAM VARIABLES
        self.SETTINGSFNAME = "settings.pickle"
        self.commands = []
        self.transform = (0, 0)
        self.isConnected = False
        self.isJobRunning = False
        self.isJobPaused = False
        self.lastSendCommandIndex = -1
        self.lastMove = None
        self.currentColor = 'black'
        self.currentToolChange = 0
        self.toolChangesTotal = 0
        self.currentToolPoint = 0
        self.toolPointsTotal = 0
        self.distancesList = []
        self.distanceTraveled = 0
        self.positionResponseRegex = re.compile(
            "X:(\-?\d+\.\d+),Y:(\-?\d+\.\d+)")
        self.machineSetups = {}
        self.currentSetupName = None
        self.workAreaSize = [100, 100]
        self.workAreaOrigin = [0, 0]

        # LOAD SOME SETTIGS
        self.loadSettings()
        self.canvas.setArea(self.workAreaSize[0], self.workAreaSize[1])
        self.canvas.setOrigin(self.workAreaOrigin[0], self.workAreaOrigin[1])

    # UI LOGIC
    def Quit(self):
        if messagebox.askyesno('Confirm', 'Really quit?'):
            self.master.quit()
            return True
        return False

    def AskColor(self):
        color = colorchooser.askcolor(title="Colour Chooser")

    def NewFile(self):
        if self.isJobRunning:
            return
        self.toolChangesTotal = 0
        self.toolPointsTotal = 0
        self.distancesList = []
        self.lastSendCommandIndex = -1
        self.lastMove = None
        self.commands = []
        self.canvas.clear()
        self.slider.config(to=0)

    def OpenGcodeFile(self):
        if self.isJobRunning:
            return
        with filedialog.askopenfile(filetypes=(("Machine G-code",
                                                "*.gcode"), )) as f:
            self.commands = load_gcode_file(f)
            self.FinishLoading()

    def SaveGcodeFile(self):
        if not self.commands:
            return
        with filedialog.asksaveasfile(filetypes=(("Machine G-code",
                                                  "*.gcode"), ),
                                      defaultextension='.gcode') as f:
            save_gcode_file(f, self.commands)

    def OpenCsvFile(self):
        if self.isJobRunning:
            return
        with filedialog.askopenfile(filetypes=(("Comma separated values",
                                                "*.csv"), )) as f:
            self.commands = load_csv_file(f)
            self.FinishLoading()

    def SaveCsvFile(self):
        pass

    def FinishLoading(self):
        points_count = len(self.commands)
        # file loaded
        if points_count > 2:
            self.testButton.config(state=NORMAL)
            self.startButton.config(state=NORMAL)
            # prepare color indicators
            self.currentColorIndicator.configure(background=self.currentColor)
            self.currentColorIndicator.configure(background=None)
            # center loaded path
            rectangle = toolpath_border_points(self.commands)
            rwidth = rectangle[2][0] - rectangle[0][0]
            rheight = rectangle[2][1] - rectangle[0][1]
            center = (rectangle[2][0] - (rwidth) / 2,
                      rectangle[2][1] - (rheight) / 2)
            transform = (self.workAreaSize[0] / 2 - center[0] +
                         self.workAreaOrigin[0], self.workAreaSize[1] / 2 -
                         center[1] + self.workAreaOrigin[1])
            self.commands = translate_toolpath(self.commands, transform)
            # check if  design is bigger than available workarea
            if (rwidth > self.workAreaSize[0]
                    or rheight > self.workAreaSize[1]):
                messagebox.showinfo(
                    'Size Warning!',
                    "Looks like this design is bigger than available work area."
                )

        self.slider.config(to=points_count)
        self.slider.set(points_count)
        self.toolPointsTotal, self.toolChangesTotal, self.distancesList = toolpath_info(
            self.commands)
        self.toolPointsLabel.config(
            text="%d/%d" % (self.currentToolPoint, self.toolPointsTotal))
        self.toolChangesLabel.config(
            text="%d/%d" % (self.currentToolChange, self.toolChangesTotal))
        self.UpdateTimeEstLabel()
        self.canvas.draw_toolpath(self.commands)

    def About(self):
        #self.PausePopup()
        messagebox.showinfo(
            'About this software',
            'This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or any later version.\n\nThis program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more details.\n\nWritten in 2018 by markol.'
        )

    def Settings(self):
        tl = Toplevel(root)
        tl.title("Global settings")

        frame = Frame(tl)
        frame.grid()

        machineFrame = LabelFrame(frame,
                                  text="Machine hoop workarea (mm)",
                                  relief=RIDGE)
        machineFrame.grid()
        Label(machineFrame, text="width ").grid(row=0, column=0, sticky=N)
        workareaWidth = Entry(machineFrame, text="1")
        workareaWidth.grid(row=0, column=1)
        Label(machineFrame, text="height ").grid(row=2, column=0, sticky=N)
        workareaHeight = Entry(machineFrame, text="2")
        workareaHeight.grid(row=2, column=1)
        hoopFrame = LabelFrame(frame,
                               text="Machine hoop origin (mm)",
                               relief=RIDGE)
        hoopFrame.grid()
        Label(hoopFrame, text="X ").grid(row=0, column=0, sticky=N)
        workareaOriginX = Entry(hoopFrame, text="3")
        workareaOriginX.grid(row=0, column=1)
        Label(hoopFrame, text="Y ").grid(row=2, column=0, sticky=N)
        workareaOriginY = Entry(hoopFrame, text="4")
        workareaOriginY.grid(row=2, column=1)
        Label(hoopFrame, text="Setup name ").grid(row=3, column=0, sticky=N)
        setupName = Entry(hoopFrame, text="Setup1")
        setupName.grid(row=3, column=1)

        def setupSelected(event=None):
            if event:
                selectedSetupName = setupsCombo.get()
            else:
                selectedSetupName = self.currentSetupName

            workareaWidth.delete(0, END)
            workareaWidth.insert(
                0,
                str(self.machineSetups[selectedSetupName]["workAreaSize"][0]))
            workareaHeight.delete(0, END)
            workareaHeight.insert(
                0,
                str(self.machineSetups[selectedSetupName]["workAreaSize"][1]))
            workareaOriginX.delete(0, END)
            workareaOriginX.insert(
                0,
                str(self.machineSetups[selectedSetupName]["workAreaOrigin"]
                    [0]))
            workareaOriginY.delete(0, END)
            workareaOriginY.insert(
                0,
                str(self.machineSetups[selectedSetupName]["workAreaOrigin"]
                    [1]))
            setupName.delete(0, END)
            setupName.insert(0, selectedSetupName)

        setupSelected()

        setupsCombo = ttk.Combobox(frame,
                                   values=list(self.machineSetups.keys()),
                                   state="readonly")
        setupsCombo.grid(row=2, column=0)
        setupsCombo.current(setupsCombo['values'].index(self.currentSetupName))
        setupsCombo.bind("<<ComboboxSelected>>", setupSelected)

        def addSettings():
            newSetupName = setupName.get()

            if newSetupName in self.machineSetups.keys():
                if not messagebox.askyesno(
                        "Machine setup exists",
                        "Machine setup with this name exists. Overwrite?"):
                    return
            newSetup = {
                "workAreaSize":
                (int(workareaWidth.get()), int(workareaHeight.get())),
                "workAreaOrigin":
                (int(workareaOriginX.get()), int(workareaOriginY.get()))
            }
            self.machineSetups[newSetupName] = newSetup
            setupsCombo['values'] = list(self.machineSetups.keys())

        Button(frame, relief=RAISED, command=addSettings,
               text="Add setup").grid(row=2, column=1)

        def removeSetup():
            self.machineSetups.pop(setupsCombo.get(), None)
            options = list(self.machineSetups.keys())
            setupsCombo['values'] = options
            if len(options) > 0:
                self.currentSetupName = list(self.machineSetups.keys())[0]
                setupsCombo.current(0)
                setupSelected(1)

        Button(frame, relief=RAISED, command=removeSetup,
               text="Remove setup").grid(row=2, column=2)

        def saveSettings():
            try:
                if len(setupsCombo.get()) > 0:
                    self.workAreaSize = (int(workareaWidth.get()),
                                         int(workareaHeight.get()))
                    self.workAreaOrigin = (int(workareaOriginX.get()),
                                           int(workareaOriginY.get()))
                    self.currentSetupName = setupsCombo.get()
            except:
                messagebox.showerror(
                    "Invalid numeric values",
                    "Please provide correct workarea values!")
                return

            self.canvas.setArea(self.workAreaSize[0], self.workAreaSize[1])
            self.canvas.setOrigin(self.workAreaOrigin[0],
                                  self.workAreaOrigin[1])
            self.storeSettings()
            TmpDim = namedtuple('TmpDim', 'width height')
            tmp = TmpDim(self.canvas.width, self.canvas.height)
            self.canvas.on_resize(tmp)

        Button(frame, text="Save", command=saveSettings,
               width=10).grid(row=3, column=3)
        Button(frame, text="Close", command=lambda: tl.destroy(),
               width=10).grid(row=3, column=2)

    def loadSettings(self):
        try:
            with open(self.SETTINGSFNAME, "rb") as f:
                data = pickle.load(f)
            self.machineSetups = data["machineSetups"]
            self.currentSetupName = data["currentSetupName"]
            self.workAreaSize = self.machineSetups[
                self.currentSetupName]["workAreaSize"]
            self.workAreaOrigin = self.machineSetups[
                self.currentSetupName]["workAreaOrigin"]
        except Exception as e:
            print("Unable to restore program settings:", str(e))

    def storeSettings(self):
        with open(self.SETTINGSFNAME, "wb") as f:
            try:
                data = {
                    "machineSetups": self.machineSetups,
                    "currentSetupName": self.currentSetupName
                }
                pickle.dump(data, f)
            except Exception as e:
                print("Error while saving settings:", str(e))

    def ToggleConnect(self):
        if self.isConnected:
            serial.close_serial()
            self.connectButton.config(text="Connect")
            self.status.config(text="Not connected")
            self.homeButton.config(state=DISABLED)
            self.stopButton.config(state=DISABLED)
            self.gotoButton.config(state=DISABLED)
            self.SetNavButtonsState(False)
            self.isConnected = False
        else:
            if serial.open_serial(self.portCombo.get(), self.baudCombo.get()):
                self.connectButton.config(text="Disconnect")
                self.status.config(text="Connected")
                self.homeButton.config(state=NORMAL)
                self.stopButton.config(state=NORMAL)
                self.gotoButton.config(state=NORMAL)
                self.SetNavButtonsState(True)
                self.isConnected = True
                self.GetPositionTimerTaks()

    def TestBorder(self):
        rectangle = toolpath_border_points(self.commands)
        for point in rectangle:
            serial.queue_command("G0 X%f Y%f F5000\n" % point)

    def ToggleStart(self):
        if self.isJobPaused:
            serial.queue.clear()
            self.startButton.config(text="Resume job")
            self.status.config(text="Job paused")
        else:
            self.startButton.config(text="Pause job")
            self.status.config(text="Job in progress")
            startInstructionIndex = self.lastSendCommandIndex + 1
            # job launch
            if not self.isJobRunning:
                self.canvas.clear()
                startInstructionIndex = 0
                self.start = time.time()
                serial.queue_command("G0 F15000\n")

            self.isJobRunning = True
            self.QueueCommandsBlock(startInstructionIndex)

        self.isJobPaused = not self.isJobPaused

    def QueueCommandsBlock(self, startInstructionIndex):
        commandsCount = len(self.commands)

        def progressCallback(instruction_index):
            ''' after every move G0 or G1 or G28 command being sent, this callback is executed '''
            point = self.commands[instruction_index]
            if self.lastMove:
                coord = (self.lastMove[1], self.lastMove[2], point[1],
                         point[2])
                color = self.currentColor
                # set color for jump move
                if "G0" == point[0] or "G28" == point[0]:
                    color = "snow2"
                else:
                    self.currentToolPoint += 1
                    self.toolPointsLabel.config(
                        text="%d/%d" %
                        (self.currentToolPoint, self.toolPointsTotal))
                    # calculate distance for material usage
                    self.distanceTraveled += math.hypot(
                        coord[0] - coord[2], coord[1] - coord[3])
                # draw new line on canvas
                line = self.canvas.create_line(self.canvas.calc_coords(coord),
                                               fill=color)
                self.canvas.lift(self.canvas.pointer, line)
                self.UpdateTimeEstLabel()
            # store next start point and instruction index
            self.lastSendCommandIndex = instruction_index
            self.lastMove = point

            # update status bar
            if self.currentToolPoint % 10 == 0:
                progress = instruction_index / commandsCount * 100
                self.status.config(text="Job in progress %.1f%%" % progress)

        def progressPauseCallback(instruction_index, trim=False):
            ''' this callback pauses the job '''
            point = self.commands[instruction_index]
            self.lastSendCommandIndex = instruction_index
            # pause on color change
            if not trim:
                self.currentColor = _from_rgb((point[1], point[2], point[3]))
                self.currentToolChange += 1
                self.currentColorIndicator.configure(
                    background=self.currentColor)
                self.toolChangesLabel.config(
                    text="%d/%d" %
                    (self.currentToolChange, self.toolChangesTotal))
                # pause enabled or not
                if self.pauseOnToolChange.get() == 1:
                    self.ToggleStart()
                    self.PausePopup(self.currentColor)
                else:
                    self.QueueCommandsBlock(self.lastSendCommandIndex + 1)
            # pause on trim
            else:
                # pause enabled or not
                if self.pauseOnTrim.get() == 1:
                    self.ToggleStart()
                    self.PausePopup(self.currentColor, trim)
                else:
                    self.QueueCommandsBlock(self.lastSendCommandIndex + 1)

        # all the commands until next tool change command, are queued at once
        # unsupported commands are ignored
        for i in range(startInstructionIndex, commandsCount):
            point = self.commands[i]
            # pause on color change
            if "M6" == point[0]:
                serial.queue_command(
                    "M6\n", lambda _, index=i: progressPauseCallback(index))
                self.nextColorIndicator.configure(
                    background=_from_rgb((point[1], point[2], point[3])))
                break
            # pause on trim
            elif "G12" == point[0]:
                # if next command is a color change, there is no need to pause now
                if i < commandsCount + 1 and self.commands[
                        i +
                        1][0] == "M6" and self.pauseOnToolChange.get() == 1:
                    serial.queue_command("G12\n")
                else:
                    serial.queue_command(
                        "G12\n",
                        lambda _, index=i: progressPauseCallback(index,
                                                                 trim=True))
                    break
            elif "G1" == point[0] or "G0" == point[0] or "G28" == point[0]:
                serial.queue_command(
                    "%s X%f Y%f\n" % (point[0], point[1], point[2]),
                    lambda _, index=i: progressCallback(index))
        # queue job finish callback
        if i + 1 >= commandsCount:
            serial.queue_command("M114\n", self.JobFinished)

    def SetNavButtonsState(self, enabled=False):
        newState = NORMAL if enabled else DISABLED
        for b in self.navigationButtons:
            b.config(state=newState)

    def TogglePan(self):
        self.rotateButton.config(relief=RAISED)
        self.scaleButton.config(relief=RAISED)
        if self.isJobRunning:
            return
        if self.panButton.config('relief')[-1] == SUNKEN:
            self.panButton.config(relief=RAISED)
        else:
            self.panButton.config(relief=SUNKEN)

    def ToggleRotate(self):
        self.panButton.config(relief=RAISED)
        self.scaleButton.config(relief=RAISED)
        if self.isJobRunning:
            return
        if self.rotateButton.config('relief')[-1] == SUNKEN:
            self.rotateButton.config(relief=RAISED)
        else:
            self.rotateButton.config(relief=SUNKEN)

    def ToggleMirror(self):
        self.panButton.config(relief=RAISED)
        self.rotateButton.config(relief=RAISED)
        self.scaleButton.config(relief=RAISED)
        if self.isJobRunning:
            return
        self.commands = reflect_toolpath(
            self.commands, self.workAreaSize[0] / 2 + self.workAreaOrigin[0])
        self.canvas.draw_toolpath(self.commands[0:int(self.slider.get())])

    def ToggleScale(self):
        self.panButton.config(relief=RAISED)
        self.rotateButton.config(relief=RAISED)
        self.mirrorButton.config(relief=RAISED)
        if self.isJobRunning:
            return
        if self.scaleButton.config('relief')[-1] == SUNKEN:
            self.scaleButton.config(relief=RAISED)
        else:
            self.scaleButton.config(relief=SUNKEN)

    def GoTo(self):
        if self.isJobRunning:
            return
        if self.gotoButton.config('relief')[-1] == SUNKEN:
            self.gotoButton.config(relief=RAISED)
        else:
            self.gotoButton.config(relief=SUNKEN)

    def StopAll(self):
        serial.queue.clear()
        self.JobFinished(False)
        self.status.config(text="Job stopped on user demand")

    def JobFinished(self, messagePopup=True):
        self.isJobRunning = False
        self.isJobPaused = False
        self.lastSendCommandIndex = -1
        self.lastMove = None
        self.distanceTraveled = 0
        self.currentToolChange = 0
        self.currentToolPoint = 0
        self.currentColor = 'black'
        self.toolPointsLabel.config(
            text="%d/%d" % (self.currentToolPoint, self.toolPointsTotal))
        self.toolChangesLabel.config(
            text="%d/%d" % (self.currentToolChange, self.toolChangesTotal))
        self.UpdateTimeEstLabel()
        self.startButton.config(text="Start job")
        self.status.config(text="Job finished")
        timeTaken = time.time() - self.start
        # non blocking popup messagebox
        if messagePopup:
            tl = Toplevel(root)
            # this pop-up is always on top and other windows are deactivated
            tl.attributes('-topmost', 'true')
            tl.title("Job finished")
            tl.grab_set()
            frame = Frame(tl)
            frame.grid()
            Label(frame,
                  text='Current job is finished and took %s.' %
                  time.strftime("%H hours, %M minutes, %S seconds",
                                time.gmtime(timeTaken))).grid(row=0,
                                                              column=0,
                                                              sticky=N)
            Button(frame, text="OK", command=lambda: tl.destroy(),
                   width=10).grid(row=1, column=0)

    def CanvasClick(self, event):
        if self.isJobRunning:
            return
        self.dragStart = [event.x, event.y]
        #self.transform = math.atan2(event.x, event.y)
        self.transform = 0
        # go to
        if self.gotoButton.config('relief')[-1] == SUNKEN:
            point = self.canvas.canvas_point_to_machine(self.dragStart)
            serial.queue_command("G0 X%f Y%f\n" % point)
        #print("Clicked at: ", self.dragStart)
    def CanvasRelease(self, event):
        if self.isJobRunning:
            return

        print("Applied transform", self.transform)

    def CanvasDrag(self, event):
        if self.isJobRunning:
            return
        vect = (self.dragStart[0] - event.x, self.dragStart[1] - event.y)
        # move event
        if self.panButton.config('relief')[-1] == SUNKEN:
            self.transform = self.canvas.canvas_vector_to_machine(vect)
            self.commands = translate_toolpath(self.commands, self.transform)
            self.canvas.draw_toolpath(self.commands[0:int(self.slider.get())])
            self.dragStart[0] = event.x
            self.dragStart[1] = event.y
        # rotate event
        if self.rotateButton.config('relief')[-1] == SUNKEN:
            angle = math.atan2(vect[0],
                               vect[1])  # atan2(y, x) or atan2(sin, cos)
            self.commands = rotate_toolpath(
                self.commands,
                (self.workAreaSize[0] / 2 + self.workAreaOrigin[0],
                 self.workAreaSize[1] / 2 + self.workAreaOrigin[1]),
                -(self.transform - angle))
            self.canvas.draw_toolpath(self.commands[0:int(self.slider.get())])
            self.transform = angle
        # scale event
        if self.scaleButton.config('relief')[-1] == SUNKEN:
            factor = math.sqrt((vect[0])**2 + (vect[1])**2) / 500
            f = factor - self.transform
            if vect[0] < 0:
                f = -f
            self.commands = scale_toolpath(self.commands, f)
            self.canvas.draw_toolpath(self.commands[0:int(self.slider.get())])
            self.transform = factor

    def UpdatePath(self, val):
        if self.isJobRunning:
            return
        self.canvas.draw_toolpath(self.commands[0:int(val)])

    def UpdateTimeEstLabel(self):
        # avg milimeters per second factor
        factor = 11.0
        time_to_toolchange = (self.distancesList[self.currentToolChange] -
                              self.distanceTraveled) / factor
        time_total = (self.distancesList[-1] - self.distanceTraveled) / factor
        self.timeLabel.config(text="%d m %d s/%d m %d s" %
                              (time_to_toolchange / 60, time_to_toolchange %
                               60, time_total / 60, time_total % 60))

    def GetPositionTimerTaks(self):
        if self.isConnected:

            def TimerCallback(response):
                response = self.positionResponseRegex.search(response)
                if response:
                    pos = (float(response.group(1)), float(response.group(2)))
                    self.canvas.move_pointer(pos)

            serial.queue_command("M114\n", TimerCallback, priority=-1)
            self.master.after(2000, self.GetPositionTimerTaks)

    def CleanUp(self):
        serial.close_serial()

    def PausePopup(self, newColor="black", trim=False):
        tl = Toplevel(root)
        tl.attributes('-topmost', 'true')
        tl.grab_set()

        tl.title("Tool change")
        msg = "change the tool for a next color"
        if trim:
            tl.title("Thread trim")
            msg = "cut the thread"

        frame = Frame(tl)
        frame.grid()

        canvas = Canvas(frame, width=64, height=64)
        canvas.grid(row=2, column=0)
        canvas.create_rectangle(0, 0, 65, 65, fill=newColor)
        msgbody = Label(
            frame,
            text=
            "There is the moment to %s. Resume the current job after change." %
            msg)
        msgbody.grid(row=1, column=0, sticky=N)

        okbttn = Button(frame,
                        text="OK",
                        command=lambda: tl.destroy(),
                        width=10)
        okbttn.grid(row=2, column=2)
Exemple #8
0
class ipGUI:
    def __init__(self, master):
        self.master = master
        self.master.minsize(width=800, height=600)

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

        # ***** Main Menu *****
        # *** file menu ***
        fileMenu = Menu(menu)
        menu.add_cascade(label='File', menu=fileMenu)
        fileMenu.add_command(label="Open", command=self.openImage)
        fileMenu.add_command(label="Load Blur Kernel", command=self.loadKernel)
        fileMenu.add_command(label="Save", command=self.saveImage)
        fileMenu.add_command(label="Exit", command=master.destroy)

        # *** edit menu ***
        editMenu = Menu(menu)
        menu.add_cascade(label='Space', menu=editMenu)
        editMenu.add_command(label="Histogram Equalization",
                             command=self.histWrap)
        editMenu.add_command(label="Gamma Correction",
                             command=self.gammaCorWrap)
        editMenu.add_command(label="Log Transform", command=self.logTranWrap)
        editMenu.add_command(label="Sharpen", command=self.sharpWrap)
        editMenu.add_command(label="Cartoonify", command=self.cartoonifyWrap)

        # *** blur menu ***
        blurMenu = Menu(editMenu)
        editMenu.add_cascade(label='Blur', menu=blurMenu)
        blurMenu.add_command(label="Box", command=self.boxBlurWrap)
        blurMenu.add_command(label="Gaussian", command=self.gaussianBlurWrap)
        blurMenu.add_command(label="Median", command=self.medianBlurWrap)

        # *** frequency filtering ***
        freqMenu = Menu(menu)
        menu.add_cascade(label='Frequency', menu=freqMenu)
        freqMenu.add_command(label="DFT", command=self.dftWrap)
        freqMenu.add_command(label="Load Mask", command=self.freqMaskWrap)

        # *** Mask Menu ***
        maskMenu = Menu(freqMenu)
        freqMenu.add_cascade(label='Create Mask', menu=maskMenu)
        maskMenu.add_command(label='Low Pass', command=self.lpmWrap)
        maskMenu.add_command(label='High Pass', command=self.hpmWrap)
        maskMenu.add_command(label='Band Pass', command=self.bppmWrap)
        maskMenu.add_command(label='Band Stop', command=self.bspmWrap)

        # *** frequency filtering ***
        restorationMenu = Menu(menu)
        menu.add_cascade(label='Restoration', menu=restorationMenu)
        restorationMenu.add_command(label="Full Inverse",
                                    command=self.fullInverseWrap)
        restorationMenu.add_command(label="Radially Limited Inverse",
                                    command=self.truncatedInverseWrap)
        restorationMenu.add_command(label="Approximate Weiner",
                                    command=self.approximateWeinerWrap)
        restorationMenu.add_command(label="Constrained LS",
                                    command=self.contrainedLSWrap)

        # ***** Toolbar *****
        toolbar = Frame(master, bg="grey")
        undoButton = Button(toolbar, text="Undo", command=self.undoFunc)
        undoButton.pack(side=LEFT)
        origButton = Button(toolbar, text="Original", command=self.origFunc)
        origButton.pack(side=LEFT)
        toolbar.pack(side=TOP, fill=X)

        # ***** Image Display Area *****
        self.frame = Frame(self.master)
        self.frame.pack()
        self.panel = Label(self.frame)
        self.panel.pack(padx=10, pady=10)
        self.img = None
        self.origImg = None
        self.prevImg = None

        # ***** Gamma Controls *****
        self.gammaFrame = Frame(self.master)
        self.gammaSlider = Scale(self.gammaFrame,
                                 from_=0.1,
                                 to=2,
                                 orient=HORIZONTAL,
                                 resolution=0.1)
        self.gammaSlider.pack(side=TOP)
        self.gammaExitButton = Button(self.gammaFrame,
                                      text="Exit",
                                      command=self.gammaFrame.pack_forget)
        self.gammaExitButton.pack(side=TOP)

        # ***** Box Blur Controls *****
        self.boxFrame = Frame(self.master)
        self.boxSlider = Scale(self.boxFrame, from_=1, to=5, orient=HORIZONTAL)
        self.boxSlider.pack(side=TOP)
        self.boxExitButton = Button(self.boxFrame,
                                    text="Exit",
                                    command=self.boxFrame.pack_forget)
        self.boxExitButton.pack(side=TOP)

        # ***** Truncated Inverse Controls *****
        self.truncatedInverseFrame = Frame(self.master)
        self.truncatedInverseSlider = Scale(self.truncatedInverseFrame,
                                            from_=-3,
                                            to=2,
                                            orient=HORIZONTAL,
                                            resolution=0.1)
        self.truncatedInverseSlider.pack(side=TOP)
        self.truncatedInverseExitButton = Button(
            self.truncatedInverseFrame,
            text="Exit",
            command=self.truncatedInverseFrame.pack_forget)
        self.truncatedInverseExitButton.pack(side=TOP)

        # ***** Weiner Controls *****
        self.weinerFrame = Frame(self.master)
        self.weinerSlider = Scale(self.weinerFrame,
                                  from_=-3,
                                  to=2,
                                  orient=HORIZONTAL,
                                  resolution=0.1)
        self.weinerSlider.pack(side=TOP)
        self.weinerExitButton = Button(self.weinerFrame,
                                       text="Exit",
                                       command=self.weinerFrame.pack_forget)
        self.weinerExitButton.pack(side=TOP)

        # ***** CLS Controls *****
        self.clsFrame = Frame(self.master)
        self.clsSlider = Scale(self.clsFrame,
                               from_=-3,
                               to=2,
                               orient=HORIZONTAL,
                               resolution=0.1)
        self.clsSlider.pack(side=TOP)
        self.clsExitButton = Button(self.clsFrame,
                                    text="Exit",
                                    command=self.clsFrame.pack_forget)
        self.clsExitButton.pack(side=TOP)

        # ***** DFT Display Area ******
        self.dftFrame = Frame(self.master)
        self.magPanel = Label(self.dftFrame)
        self.magPanel.pack(padx=10, pady=10, side=TOP)
        self.freqPanel = Label(self.dftFrame)
        self.freqPanel.pack(padx=10, pady=10, side=TOP)
        self.dftExitButton = Button(
            self.dftFrame,
            text="Exit",
            command=lambda: self.displayImg(np.array(self.img)))
        self.dftExitButton.pack(side=TOP, fill=X)

        # ***** Low Pass Mask Creation *****
        self.lpmFrame = Frame(self.master)
        self.lpmPanel = Label(self.lpmFrame)
        self.lpmPanel.pack(padx=10, pady=10, side=TOP)
        self.lpmSubButton = Button(self.lpmFrame, text="submit")
        self.lpmSubButton.pack(side=TOP)
        self.lpmExitButton = Button(
            self.lpmFrame,
            text="Exit",
            command=lambda: self.displayImg(np.array(self.img)))
        self.lpmExitButton.pack(side=TOP)
        self.lpmSlider = Scale(self.lpmFrame,
                               from_=1,
                               to=2,
                               orient=HORIZONTAL,
                               resolution=1)

        # ***** High Pass Mask Creation *****
        self.hpmFrame = Frame(self.master)
        self.hpmPanel = Label(self.hpmFrame)
        self.hpmPanel.pack(padx=10, pady=10, side=TOP)
        self.hpmSubButton = Button(self.hpmFrame, text="submit")
        self.hpmSubButton.pack(side=TOP)
        self.hpmExitButton = Button(
            self.hpmFrame,
            text="Exit",
            command=lambda: self.displayImg(np.array(self.img)))
        self.hpmExitButton.pack(side=TOP)
        self.hpmSlider = Scale(self.hpmFrame,
                               from_=1,
                               to=2,
                               orient=HORIZONTAL,
                               resolution=1)

        # ***** Band Pass Mask Creation *****
        self.bppmFrame = Frame(self.master)
        self.bppmPanel = Label(self.bppmFrame)
        self.bppmPanel.pack(padx=10, pady=10, side=TOP)
        self.bppmSubButton = Button(self.bppmFrame, text="submit")
        self.bppmSubButton.pack(side=TOP)
        self.bppmExitButton = Button(
            self.bppmFrame,
            text="Exit",
            command=lambda: self.displayImg(np.array(self.img)))
        self.bppmExitButton.pack(side=TOP)
        self.bppmSliderLow = Scale(self.bppmFrame,
                                   from_=1,
                                   to=2,
                                   orient=HORIZONTAL,
                                   resolution=1)
        self.bppmSliderHigh = Scale(self.bppmFrame,
                                    from_=1,
                                    to=2,
                                    orient=HORIZONTAL,
                                    resolution=1)

        # ***** Band Pass Mask Creation *****
        self.bspmFrame = Frame(self.master)
        self.bspmPanel = Label(self.bspmFrame)
        self.bspmPanel.pack(padx=10, pady=10, side=TOP)
        self.bspmSubButton = Button(self.bspmFrame, text="submit")
        self.bspmSubButton.pack(side=TOP)
        self.bspmExitButton = Button(
            self.bspmFrame,
            text="exit",
            command=lambda: self.displayImg(np.array(self.img)))
        self.bspmExitButton.pack(side=TOP)
        self.bspmSliderLow = Scale(self.bspmFrame,
                                   from_=1,
                                   to=2,
                                   orient=HORIZONTAL,
                                   resolution=1)
        self.bspmSliderHigh = Scale(self.bspmFrame,
                                    from_=1,
                                    to=2,
                                    orient=HORIZONTAL,
                                    resolution=1)

    def displayImg(self, img):
        # input image in RGB
        self.frame.pack()
        self.dftFrame.pack_forget()
        self.lpmFrame.pack_forget()
        self.hpmFrame.pack_forget()
        self.bppmFrame.pack_forget()
        self.bspmFrame.pack_forget()
        self.img = Image.fromarray(img)
        imgtk = ImageTk.PhotoImage(self.img)

        self.panel.configure(image=imgtk)
        self.panel.image = imgtk

    def openImage(self):
        # can change the image
        path = filedialog.askopenfilename()
        if len(path) > 0:
            imgRead = cv2.imread(path)
            if imgRead is not None:
                imgRead = cv2.cvtColor(imgRead, cv2.COLOR_BGR2RGB)
                self.origImg = Image.fromarray(imgRead)
                self.prevImg = Image.fromarray(imgRead)
                self.displayImg(imgRead)
            else:
                raise ValueError("Not a valid image")
        else:
            raise ValueError("Not a valid path")

    def loadKernel(self):
        path = filedialog.askopenfilename()
        if len(path) > 0:
            self.filter_kernel = np.mean(cv2.imread(path), axis=-1)
            self.filter_kernel = self.filter_kernel / np.sum(
                self.filter_kernel)
        else:
            raise ValueError("Not a valid path")

    def saveImage(self):
        if self.img is not None:
            toSave = filedialog.asksaveasfilename()
            self.img.save(toSave)
        else:
            messagebox.showerror(title="Save Error",
                                 message="No image to be saved!")

    def histWrap(self):
        img = np.array(self.img)
        self.prevImg = self.img
        imgNew = image_utils.histEqlFunc(img)
        self.displayImg(imgNew)

    # Gamma Correction
    def gammaCallback(self, event, img):
        gamma = self.gammaSlider.get()
        self.prevImg = self.img
        imgNew = image_utils.gammaCorFunc(img, 255.0 / (255.0**gamma), gamma)
        self.displayImg(imgNew)

    def truncatedInverseCallback(self, event, img):
        th = 10**self.truncatedInverseSlider.get()
        imgNew = self.truncatedInverseFilter(th)
        self.displayImg(imgNew)

    def weinerCallback(self, event, img):
        gamma = 10**self.weinerSlider.get()
        imgNew = self.weinerFilter(gamma)
        self.displayImg(imgNew)

    def clsCallback(self, event, img):
        K = 10**self.clsSlider.get()
        imgNew = self.clsFilter(K)
        self.displayImg(imgNew)

    def gammaCorWrap(self):
        img = np.array(self.img)
        self.gammaFrame.pack()
        self.gammaSlider.set(1.0)
        self.gammaSlider.bind(
            "<ButtonRelease-1>",
            lambda event, img=img: self.gammaCallback(event, img))

    def logTranWrap(self):
        img = np.array(self.img)
        self.prevImg = self.img
        imgNew = image_utils.logTranFunc(img, 255.0 / np.log10(256))
        self.displayImg(imgNew)

    def sharpWrap(self):
        # Sharpen Wrapper
        img = np.array(self.img)
        self.prevImg = self.img
        imgNew = image_utils.sharpFunc(img)
        self.displayImg(imgNew)

    def boxBlurWrap(self):
        # Box Blur Wrapper
        img = np.array(self.img)
        self.prevImg = self.img
        self.boxFrame.pack()
        self.boxSlider.set(1)
        self.boxSlider.bind("<ButtonRelease-1>",
                            lambda event, img=img: self.displayImg(
                                image_utils.boxBlurFunc(
                                    event, img, 2 * self.boxSlider.get() + 1)))

    def gaussianBlurWrap(self):
        # Gaussian Blur Wrapper
        img = np.array(self.img)
        self.prevImg = self.img
        imgNew = image_utils.gaussianBlurFunc(img)
        self.displayImg(imgNew)

    def medianBlurWrap(self):
        # Median Blur Wrapper
        img = np.array(self.img)
        self.prevImg = self.img
        imgNew = image_utils.medianBlurFunc(img)
        self.displayImg(imgNew)

    def cartoonifyWrap(self):
        img = np.array(self.img)
        self.prevImg = self.img
        imgNew = image_utils.cartoonifyFunc(img)
        self.displayImg(imgNew)

    def undoFunc(self):
        self.img = self.prevImg
        self.displayImg(np.array(self.img))

    def origFunc(self):
        self.prevImg = self.img
        self.img = self.origImg
        self.displayImg(np.array(self.img))

    def displayDFT(self, x_fft):
        m, n = x_fft.shape[:]
        self.frame.pack_forget()
        self.dftFrame.pack()

        x_mag = np.log10(np.absolute(x_fft)) * 255 / np.log10(m * n * 255)
        x_mag = Image.fromarray(x_mag)
        x_mag = x_mag.resize((min(256, m), min(int(256 * n / m), n)),
                             Image.ANTIALIAS)
        x_mag = ImageTk.PhotoImage(x_mag)

        x_freq = (np.angle(x_fft) % 360) * 255 / 360
        x_freq = Image.fromarray(x_freq)
        x_freq = x_freq.resize((min(256, m), min(int(256 * n / m), n)),
                               Image.ANTIALIAS)
        x_freq = ImageTk.PhotoImage(x_freq)

        self.magPanel.configure(image=x_mag)
        self.magPanel.image = x_mag

        self.freqPanel.configure(image=x_freq)
        self.freqPanel.image = x_freq

    def dftWrap(self):
        img = np.array(self.img)
        x = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
        x_outp_img = fft.fft2d_img(x)
        self.displayDFT(x_outp_img)

    def freqMaskWrap(self):
        m, n = np.array(self.img).shape[:2]
        lm, ln = np.log2(m), np.log2(m)
        dm, dn = int(2**np.ceil(lm)) + 1, int(2**np.ceil(ln)) + 1
        messagebox.showinfo(
            "Mask Size",
            "Mask Size should be (" + str(dm) + "," + str(dn) + ")")
        path = filedialog.askopenfilename()
        if len(path) > 0:
            maskRead = cv2.imread(path, 0)
            if (maskRead.shape != (dm, dn)):
                messagebox.showerror(
                    title="Shape Error",
                    message="Shape of mask and image don't match")
            else:
                self.prevImg = self.img
                self.display(image_utils.freqMask(np.array(self.img),
                                                  maskRead))
        else:
            raise ValueError("Not a valid path")

    def maskWrap(self):
        img = np.array(self.img)
        x = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
        x_outp_img = fft.fft2d_img(x)
        x_mag = image_utils.xMagCreate(x_outp_img)

        return x_outp_img, x_mag

    def maskFinal(self, x_outp_img):
        self.prevImg = self.img
        img = np.array(self.img)
        img = cv2.cvtColor(img, cv2.COLOR_RGB2HSV)
        m = len(img)
        res = fft.ifft2d_img(x_outp_img)
        res = np.array(res * 255 / np.max(res), dtype=np.uint8)
        res = np.array([[[img[i][j][0], img[i][j][1], res[i][j]]
                         for j in range(m)] for i in range(m)])
        res = cv2.cvtColor(res, cv2.COLOR_HSV2RGB)
        self.displayImg(res)

    def lpmCallBack(self, event, slider, x_outp_img):
        m = len(x_outp_img)
        m2 = int((m - 1) / 2)
        r = slider.get()
        x_outp_copy = np.copy(x_outp_img)

        nCircle = np.array([[(i - m2)**2 + (j - m2)**2 for j in range(m)]
                            for i in range(m)])
        nCircle = np.where(nCircle > r**2)
        x_outp_copy[nCircle] = 1

        x_mag = image_utils.xMagCreate(x_outp_copy)

        self.lpmPanel.configure(image=x_mag)
        self.lpmPanel.image = x_mag

    def lpmFinal(self, x_outp_img):
        mx = len(x_outp_img)
        m2 = int((mx - 1) / 2)
        r = self.lpmSlider.get()
        nCircle = np.array([[(i - m2)**2 + (j - m2)**2 for j in range(mx)]
                            for i in range(mx)])
        nCircle = np.where(nCircle > r**2)
        x_outp_img[nCircle] = 0

        self.maskFinal(x_outp_img)

    def lpmWrap(self):
        x_outp_img, x_mag = self.maskWrap()
        m = len(x_outp_img)

        self.lpmPanel.configure(image=x_mag)
        self.lpmPanel.image = x_mag

        self.lpmSlider.configure(to=int(np.ceil(m / 2)))
        self.lpmSlider.set(1)
        self.lpmSlider.pack(side=TOP)
        self.lpmSlider.bind(
            "<ButtonRelease-1>",
            lambda event, slider=self.lpmSlider, x_outp_img=x_outp_img: self.
            lpmCallBack(event, slider, x_outp_img))

        self.lpmSubButton.configure(
            command=lambda x_outp_img=x_outp_img: self.lpmFinal(x_outp_img))

        self.dftFrame.pack_forget()
        self.frame.pack_forget()
        self.hpmFrame.pack_forget()
        self.bppmFrame.pack_forget()
        self.bspmFrame.pack_forget()
        self.lpmFrame.pack()

    def hpmCallBack(self, event, slider, x_outp_img):
        mx = len(x_outp_img)
        m2 = int((mx - 1) / 2)
        r = slider.get()
        x_outp_copy = np.copy(x_outp_img)

        circle = np.array([[(i - m2)**2 + (j - m2)**2 for j in range(mx)]
                           for i in range(mx)])
        circle = np.where(circle <= r**2)
        x_outp_copy[circle] = 1

        x_mag = image_utils.xMagCreate(x_outp_copy)

        self.hpmPanel.configure(image=x_mag)
        self.hpmPanel.image = x_mag

    def hpmFinal(self, x_outp_img):
        mx = len(x_outp_img)
        m2 = int((mx - 1) / 2)
        r = self.hpmSlider.get()
        circle = np.array([[(i - m2)**2 + (j - m2)**2 for j in range(mx)]
                           for i in range(mx)])
        circle = np.where(circle <= r**2)
        x_outp_img[circle] = 0

        self.maskFinal(x_outp_img)

    def hpmWrap(self):
        x_outp_img, x_mag = self.maskWrap()
        m = len(x_outp_img)

        self.hpmPanel.configure(image=x_mag)
        self.hpmPanel.image = x_mag

        self.hpmSlider.configure(to=m // 2)
        self.hpmSlider.set(1)
        self.hpmSlider.pack(side=TOP)
        self.hpmSlider.bind(
            "<ButtonRelease-1>",
            lambda event, slider=self.hpmSlider, x_outp_img=x_outp_img: self.
            hpmCallBack(event, slider, x_outp_img))

        self.hpmSubButton.configure(
            command=lambda x_outp_img=x_outp_img: self.hpmFinal(x_outp_img))

        self.dftFrame.pack_forget()
        self.frame.pack_forget()
        self.lpmFrame.pack_forget()
        self.bppmFrame.pack_forget()
        self.bspmFrame.pack_forget()
        self.hpmFrame.pack()

    def bppmCallBack(self, event, x_outp_img):
        mx = len(x_outp_img)
        m2 = int((mx - 1) / 2)
        r1 = self.bppmSliderLow.get()
        r2 = self.bppmSliderHigh.get()
        assert (r1 <= r2)

        self.bppmSliderLow.configure(to=r2)
        self.bppmSliderHigh.configure(from_=r1)

        x_outp_copy = np.copy(x_outp_img)
        allVals = np.array([[(i - m2)**2 + (j - m2)**2 for j in range(mx)]
                            for i in range(mx)])
        nullVals = np.where(allVals < r1**2)
        x_outp_copy[nullVals] = 1
        nullVals = np.where(allVals > r2**2)
        x_outp_copy[nullVals] = 1

        x_mag = image_utils.xMagCreate(x_outp_copy)

        self.bppmPanel.configure(image=x_mag)
        self.bppmPanel.image = x_mag

    def bppmFinal(self, x_outp_img):
        mx = len(x_outp_img)
        m2 = int((mx - 1) / 2)
        r1 = self.bppmSliderLow.get()
        r2 = self.bppmSliderHigh.get()

        allVals = np.array([[(i - m2)**2 + (j - m2)**2 for j in range(mx)]
                            for i in range(mx)])
        nullVals = np.where(allVals < r1**2)
        x_outp_img[nullVals] = 0
        nullVals = np.where(allVals > r2**2)
        x_outp_img[nullVals] = 0

        self.maskFinal(x_outp_img)

    def bppmWrap(self):
        x_outp_img, x_mag = self.maskWrap()
        m = len(x_outp_img)

        self.bppmPanel.configure(image=x_mag)
        self.bppmPanel.image = x_mag

        self.bppmSliderHigh.configure(from_=1)
        self.bppmSliderHigh.configure(to=m // 2)
        self.bppmSliderHigh.set(m // 2)
        self.bppmSliderHigh.pack(side=TOP)
        self.bppmSliderHigh.bind("<ButtonRelease-1>",
                                 lambda event, x_outp_img=x_outp_img: self.
                                 bppmCallBack(event, x_outp_img))

        self.bppmSliderLow.configure(from_=1)
        self.bppmSliderLow.configure(to=m // 2)
        self.bppmSliderLow.set(1)
        self.bppmSliderLow.pack(side=TOP)
        self.bppmSliderLow.bind("<ButtonRelease-1>",
                                lambda event, x_outp_img=x_outp_img: self.
                                bppmCallBack(event, x_outp_img))

        self.bppmSubButton.configure(
            command=lambda x_outp_img=x_outp_img: self.bppmFinal(x_outp_img))

        self.dftFrame.pack_forget()
        self.frame.pack_forget()
        self.lpmFrame.pack_forget()
        self.hpmFrame.pack_forget()
        self.bspmFrame.pack_forget()
        self.bppmFrame.pack()

    def bspmCallBack(self, event, x_outp_img):
        mx = len(x_outp_img)
        m2 = int((mx - 1) / 2)
        r1 = self.bspmSliderLow.get()
        r2 = self.bspmSliderHigh.get()
        assert (r1 <= r2)

        self.bspmSliderLow.configure(to=r2)
        self.bspmSliderHigh.configure(from_=r1)

        x_outp_copy = np.copy(x_outp_img)
        allVals = np.array([[(i - m2)**2 + (j - m2)**2 for j in range(mx)]
                            for i in range(mx)])
        nullVals = np.where((allVals - r1**2) * (allVals - r2**2) < 0)
        x_outp_copy[nullVals] = 1

        x_mag = image_utils.xMagCreate(x_outp_copy)

        self.bspmPanel.configure(image=x_mag)
        self.bspmPanel.image = x_mag

    def bspmFinal(self, x_outp_img):
        mx = len(x_outp_img)
        m2 = int((mx - 1) / 2)
        r1 = self.bspmSliderLow.get()
        r2 = self.bspmSliderHigh.get()

        allVals = np.array([[(i - m2)**2 + (j - m2)**2 for j in range(mx)]
                            for i in range(mx)])
        nullVals = np.where((allVals - r1**2) * (allVals - r2**2) < 0)
        x_outp_img[nullVals] = 0

        self.maskFinal(x_outp_img)

    def bspmWrap(self):
        x_outp_img, x_mag = self.maskWrap()
        m = len(x_outp_img)

        self.bspmPanel.configure(image=x_mag)
        self.bspmPanel.image = x_mag

        self.bspmSliderHigh.configure(from_=1)
        self.bspmSliderHigh.configure(to=m // 2)
        self.bspmSliderHigh.set(m // 2)
        self.bspmSliderHigh.pack(side=TOP)
        self.bspmSliderHigh.bind("<ButtonRelease-1>",
                                 lambda event, x_outp_img=x_outp_img: self.
                                 bspmCallBack(event, x_outp_img))

        self.bspmSliderLow.configure(from_=1)
        self.bspmSliderLow.configure(to=m // 2)
        self.bspmSliderLow.set(1)
        self.bspmSliderLow.pack(side=TOP)
        self.bspmSliderLow.bind("<ButtonRelease-1>",
                                lambda event, x_outp_img=x_outp_img: self.
                                bspmCallBack(event, x_outp_img))

        self.bspmSubButton.configure(
            command=lambda x_outp_img=x_outp_img: self.bspmFinal(x_outp_img))

        self.dftFrame.pack_forget()
        self.frame.pack_forget()
        self.lpmFrame.pack_forget()
        self.hpmFrame.pack_forget()
        self.bppmFrame.pack_forget()
        self.bspmFrame.pack()

    def fullInverseWrap(self):
        img = np.array(self.img)
        self.prevImg = self.img
        imgNew = filtering.inverseFilter2D(img, self.filter_kernel)
        self.displayImg(imgNew)

    def truncatedInverseWrap(self):
        img = np.array(self.img)
        self.prevImg = self.img
        self.truncatedInverseFilter = filtering.getTruncatedInverseFilter2D(
            img, self.filter_kernel)
        self.truncatedInverseFrame.pack()
        self.truncatedInverseSlider.set(1.0)
        self.truncatedInverseSlider.bind(
            "<ButtonRelease-1>",
            lambda event, img=img: self.truncatedInverseCallback(event, img))

    def approximateWeinerWrap(self):
        img = np.array(self.img)
        self.prevImg = self.img
        self.weinerFilter = filtering.getApproximateWeinerFilter2D(
            img, self.filter_kernel)
        self.weinerFrame.pack()
        self.weinerSlider.set(1.0)
        self.weinerSlider.bind(
            "<ButtonRelease-1>",
            lambda event, img=img: self.weinerCallback(event, img))

    def contrainedLSWrap(self):  # TODO: implement
        img = np.array(self.img)
        self.prevImg = self.img
        self.clsFilter = filtering.getConstrainedLSFilter2D(
            img, self.filter_kernel)
        self.clsFrame.pack()
        self.clsSlider.set(1.0)
        self.clsSlider.bind(
            "<ButtonRelease-1>",
            lambda event, img=img: self.clsCallback(event, img))
class AuxMode(Frame):
    def __init__(self, root, parent):
        Frame.__init__(self, root, borderwidth=2, relief='groove', height=10)
        settings = parent.settings('aux_mode')
        self.parent = parent

        lbl_power = Label(self, text='Power:')
        lbl_power.grid(row=0, column=0, pady=2)
        self.cmb_power = ttk.Combobox(self, value=['Off', 'On'])
        self.cmb_power.grid(row=0, column=1, pady=2)
        self.cmb_power.set(settings['power'])
        self.cmb_power['state'] = 'readonly'
        self.cmb_power.bind('<<ComboboxSelected>>', self.set_power)

        lbl_aux_pin = Label(self, text='AUX pin:')
        lbl_aux_pin.grid(row=1, column=0, pady=2)
        self.cmb_aux_pin = ttk.Combobox(self, values=['AUX', 'CS'])
        self.cmb_aux_pin.grid(row=1, column=1, pady=2)
        self.cmb_aux_pin['state'] = 'readonly'
        self.cmb_aux_pin.set(settings['aux_pin'])
        self.cmb_aux_pin.bind('<<ComboboxSelected>>', self.select_aux_pin)

        lbl_aux = Label(self, text='AUX mode:')
        lbl_aux.grid(row=2, column=0, pady=2)
        self.cmb_aux_mode = ttk.Combobox(
            self, values=['Input', 'Output', 'Servo', 'PWM'])
        self.cmb_aux_mode.grid(row=2, column=1, pady=2)
        self.cmb_aux_mode['state'] = 'readonly'
        self.cmb_aux_mode.set(settings['mode'])
        self.cmb_aux_mode.bind('<<ComboboxSelected>>', self.select_aux_mode)

        self.aux_servo = Scale(self, from_=0, to=180, orient='horizontal')
        self.aux_servo.set(settings['servo'])
        self.aux_servo.bind('<ButtonRelease-1>', self.select_aux_mode)

        self.aux_pin_state = IntVar()
        self.aux_pin_state.set(settings['aux_state'])
        self.aux_pin_state.trace_add('write', self.select_aux_mode)

        self.aux_high = Radiobutton(self,
                                    text='HIGH',
                                    value=1,
                                    variable=self.aux_pin_state)
        self.aux_low = Radiobutton(self,
                                   text='LOW',
                                   value=0,
                                   variable=self.aux_pin_state)

        self.aux_pwm_lbl = Label(self, text='Frequency (KHz):')
        self.aux_pwm_freq = Entry(self)
        self.aux_pwm_freq.insert(0, settings['pwm_freq'])
        self.aux_pwm_freq.bind('<KeyRelease>', self.select_aux_mode)

        self.aux_pwm_duty_lbl = Label(self, text='Duty cycle (%):')
        self.aux_pwm_duty = Scale(self, from_=0, to=99, orient='horizontal')
        self.aux_pwm_duty.set(settings['pwm_duty'])
        self.aux_pwm_duty.bind('<ButtonRelease-1>', self.select_aux_mode)

    def __call__(self):
        return {
            'power': self.cmb_power.get(),
            'mode': self.cmb_aux_mode.get(),
            'aux_state': self.aux_pin_state.get(),
            'aux_pin': self.cmb_aux_pin.get(),
            'servo': self.aux_servo.get(),
            'pwm_freq': self.aux_pwm_freq.get(),
            'pwm_duty': self.aux_pwm_duty.get()
        }

    def select_aux_mode(self, e=None, a=None, b=None):

        for i, widget in enumerate(self.winfo_children()):
            if i > 5:
                widget.grid_forget()
        mode = self.cmb_aux_mode.get()

        # if self.parent.console.mode == 'HiZ': return
        if mode == 'Input':
            self.parent.console.aux('Input')

        if mode == 'Output':
            self.aux_high.grid(row=3, column=1)
            self.aux_low.grid(row=4, column=1)
            self.parent.console.aux('Output', self.aux_pin_state.get())

        if mode == 'Servo':
            self.aux_servo.grid(row=3, column=1)
            self.parent.console.servo(self.aux_servo.get())

        if mode == 'PWM':
            self.aux_pwm_lbl.grid(row=3, column=0)
            self.aux_pwm_freq.grid(row=3, column=1)
            self.aux_pwm_duty_lbl.grid(row=4, column=0)
            self.aux_pwm_duty.grid(row=4, column=1)
            self.parent.console.pwm(self.aux_pwm_freq.get(),
                                    self.aux_pwm_duty.get())

        if mode == 'CS':
            self.parent.console.cs()

        self.parent.settings('aux_mode', self())

    def select_aux_pin(self, e=None):
        self.parent.console.aux_pin(self.cmb_aux_pin.get())

    def set_power(self, e=None):
        self.parent.console.power(self.cmb_power.get())
        self.parent.settings('aux_mode', self())

    def disable(self):
        self.cmb_power['state'] = 'disabled'
        self.cmb_aux_mode['state'] = 'disabled'
        self.aux_high['state'] = 'disabled'
        self.aux_low['state'] = 'disabled'
        self.aux_servo['state'] = 'disabled'
        self.aux_pwm_freq['state'] = 'disabled'
        self.aux_pwm_duty['state'] = 'disabled'

    def enable(self):
        self.cmb_power['state'] = 'readonly'
        self.cmb_aux_mode['state'] = 'readonly'
        self.aux_high['state'] = 'normal'
        self.aux_low['state'] = 'normal'
        self.aux_servo['state'] = 'normal'
        self.aux_pwm_freq['state'] = 'normal'
        self.aux_pwm_duty['state'] = 'normal'
Exemple #10
0
def main():
    """
    основной метод - создание графического интерфейса TKinter
    :return:
    """
    global params
    window = Tk()
    window.title("Отражение в параболическом зеркале")
    window.geometry('500x400')
    canv = Frame(window)
    setup = LabelFrame(window, text='Настройки', width=450, height=150)
    c = Canvas(canv, width=450, height=230, bg='black')
    c.pack(side=TOP, padx=10)

    setup1 = Frame(setup)
    butFrame = Frame(setup1)

    scal = Scale(setup1,
                 orient=HORIZONTAL,
                 length=200,
                 from_=0.002,
                 to=0.01,
                 tickinterval=0.002,
                 resolution=0.002)
    scal.set(0.002)
    scal.pack(side=TOP, pady=(0, 10), padx=(10, 10))
    scal.bind("<ButtonRelease-1>",
              lambda event, draw_canv=c: redraw(event, draw_canv))

    Button(butFrame, text='Очистить', width=12,
           command=lambda event=None, draw_canv=c, flag=True: redraw(event, draw_canv,
                                                                     setarrow=flag)) \
        .pack(side=LEFT, padx=(10, 5), pady=(5, 10))
    Button(butFrame,
           text='Закрыть',
           width=12,
           command=lambda flag=0: sys.exit(flag)).pack(side=LEFT,
                                                       padx=(5, 10),
                                                       pady=(5, 10))

    butFrame.pack(side=TOP)

    setup1.pack(side=LEFT)

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

    canv.pack(side=TOP, pady=(10, 10))
    setup.pack(side=TOP, pady=(0, 10), padx=(25, 25))

    draw_parabola(c)

    window.bind('<Button-1>', press)
    window.bind('<ButtonRelease-1>',
                lambda event, draw_canv=c: release(event, draw_canv))
    window.mainloop()
class Application(tk.Frame):
    def __init__(self, master=None):
        super().__init__(master)
        self.master = master
        self.grid(padx=4, pady=0)

        self.window_width = 1850
        self.window_height = 900
        self._geom = '{x}x{y}+0+0'.format(x=self.window_width,
                                          y=self.window_height)
        self.master.geometry(self._geom)

        self.image_size = 450
        self.canvases = dict()
        self.scale_value = DoubleVar()

        self.create_window()
        self.create_widgets()

        #fullscreen
        #pad = 3
        #master.geometry("{0}x{1}+0+0".format(
        #    master.winfo_screenwidth()-pad, master.winfo_screenheight()-pad))
        #master.bind('<Escape>',self.toggle_geom)

    def create_widgets(self):
        self.create_buttons()
        #self.create_scroll_bar()
        self.create_canvases()
        self.create_parameters_box()
        self.create_progressbar()

        self.set_default_values()

    def create_buttons(self):
        #upload button
        self.upload_input_button = tk.Button(self,
                                             text="Wgraj obraz",
                                             command=self.upload_input_file,
                                             width=50,
                                             height=3,
                                             fg='white',
                                             bg='green')
        self.upload_input_button.grid(row=12, column=0, pady=15)
        #transform start button
        self.start_transform_button = tk.Button(self,
                                                text="Uruchom tomograf",
                                                command=start_radon_transform,
                                                width=50,
                                                height=3,
                                                fg='white',
                                                bg='green')
        self.start_transform_button.grid(row=13, column=0, pady=15)

    def create_window(self):
        self.frame = Frame(self.master,
                           width=self.window_width,
                           height=self.window_height)

    def upload_input_file(self):
        filename = filedialog.askopenfilename(filetypes=[('Image',
                                                          'jpg jpeg png gif')])
        if filename == "":
            return

        load_input_file(filename)
        img = Image.open(filename)
        self.set_image_on_canvas(img, ImageType.INPUT_IMAGE)

        self.reconstruction_progress['value'] = 0

    def set_image_on_canvas(self, img, image_type):
        canvas = self.canvases[image_type]
        if type(img) is np.ndarray:
            img = Image.frombytes('L', (img.shape[1], img.shape[0]),
                                  img.astype('b').tostring())
        img = img.resize((canvas.winfo_width(), canvas.winfo_height()),
                         Image.ANTIALIAS)
        self.canvases[image_type].image = ImageTk.PhotoImage(img)
        self.canvases[image_type].create_image(0,
                                               0,
                                               image=canvas.image,
                                               anchor=tk.NW)
        self.update()

    def create_canvases(self):
        x = 0
        for i in ImageType:
            self.canvases[i] = Canvas(self,
                                      width=self.image_size,
                                      height=self.image_size,
                                      bg='white')
            self.canvases[i].create_rectangle(2, 2, self.image_size,
                                              self.image_size)
            self.canvases[i].create_text(self.image_size // 2,
                                         self.image_size // 2,
                                         text=text_values[i])
            if i == ImageType.GRAPH:
                continue
                #self.canvases[i].grid(row=1, column=2, rowspan=15)
            else:
                self.canvases[i].grid(row=0, column=x)
                x += 1

    def create_scroll_bar(self):
        self.scale = Scale(self,
                           from_=0,
                           to_=150,
                           tickinterval=10,
                           length=self.image_size - 20,
                           variable=self.scale_value,
                           orient=tk.HORIZONTAL)
        self.scale.bind("<ButtonRelease-1>", method)
        self.scale.set(0)
        self.scale.grid(row=2, column=2)

    def create_parameters_box(self):
        default_font = ("Helvetica", 9)
        #error label
        self.error = tk.StringVar()
        tk.Label(self,
                 textvariable=self.error,
                 fg="red",
                 font=("Helvetica", 16)).grid(row=2)

        tk.Label(self, text="Liczba emiterów",
                 font=default_font).grid(row=3, sticky='w')
        self.detectors_number = tk.Entry(self, width=4, justify=tk.RIGHT)
        self.detectors_number.grid(row=3)

        tk.Label(self, text="Rozpiętość kątowa",
                 font=default_font).grid(row=4, sticky='w')
        self.emission_angle = tk.Entry(self, width=4, justify=tk.RIGHT)
        self.emission_angle.grid(row=4)

        tk.Label(self, text="Obrót tomografu",
                 font=default_font).grid(row=5, sticky='w')
        self.radon_angle = tk.Entry(self, width=4, justify=tk.RIGHT)
        self.radon_angle.grid(row=5)

        tk.Label(self, text="Krok", font=default_font).grid(row=6, sticky='w')
        self.step_angle = tk.Entry(self, width=4, justify=tk.RIGHT)
        self.step_angle.grid(row=6)

        self.sinogram_convolution = tkinter.IntVar(value=1)
        self.sinogram_convoltion_checkbox = tk.Checkbutton(
            self,
            text="Użyj splotu przy sinorgamie",
            variable=self.sinogram_convolution,
            command=self.update_options)
        self.sinogram_convoltion_checkbox.grid(row=7, sticky='w')

        self.use_parallel_rays = tkinter.IntVar(value=1)
        self.parallel_rays_checkbox = tk.Checkbutton(
            self,
            text="Użyj promieni równoległych",
            variable=self.use_parallel_rays,
            command=self.update_options)
        self.parallel_rays_checkbox.grid(row=8, sticky='w')

        self.use_fourier = tkinter.IntVar(value=1)
        self.fourier_checkbox = tk.Checkbutton(
            self,
            text="Użyj rekonstrukcji Fouriera",
            variable=self.use_fourier,
            command=self.update_options)
        self.fourier_checkbox.grid(row=9, sticky='w')

        self.use_convolution_at_end = tkinter.IntVar(value=1)
        self.convolution_end_checkbutton = tk.Checkbutton(
            self,
            text="Użyj splotu na wyjściu",
            variable=self.use_convolution_at_end,
            command=self.update_options)
        self.convolution_end_checkbutton.grid(row=10, sticky='w')

    def set_default_values(self):
        self.sinogram_convolution.set(1 if main.use_convolution_filter else 0)
        self.use_parallel_rays.set(1 if main.parallel_rays_mode else 0)
        self.use_convolution_at_end.set(
            1 if main.use_convolution_in_output else 0)
        self.use_fourier.set(1 if main.use_fourier_reconstruction else 0)

        self.detectors_number.insert(tk.END, main.n_detectors)
        self.radon_angle.insert(tk.END, main.radon_angle)
        self.emission_angle.insert(tk.END, main.emission_angle)
        self.step_angle.insert(tk.END, main.step_angle)

        self.reset_progressbar()

    def update_options(self):
        main.use_convolution_in_output = False if self.use_convolution_at_end.get(
        ) == 0 else True
        main.use_fourier_reconstruction = False if self.use_fourier.get(
        ) == 0 else True
        main.use_convolution_filter = False if self.sinogram_convolution.get(
        ) == 0 else True
        main.parallel_rays_mode = False if self.use_parallel_rays.get(
        ) == 0 else True

    def create_progressbar(self):
        self.reconstruction_progress = ttk.Progressbar(self,
                                                       orient="horizontal",
                                                       length=self.image_size,
                                                       mode="determinate")
        self.reconstruction_progress.grid(row=1, column=3, rowspan=2)

    def reset_progressbar(self):
        self.reconstruction_progress['value'] = 0
        ratio = main.radon_angle // main.step_angle * main.step_angle
        self.reconstruction_progress['maximum'] = ratio
Exemple #12
0
st.set('0')
ptscln.set('-1')
ptsclb = BooleanVar()  # 是否正在拖拽进度条
ptsclb.set(False)
liststatuscode = IntVar()
liststatuscode.set(0)

ptlb = Label(duf, text=mtt)  # 总时长显示,↓进度条
ptscl = Scale(duf,
              length=170,
              orient=HORIZONTAL,
              from_=0,
              to=0,
              showvalue=False,
              command=ptscl1)
ptscl.bind('<1>', ptscl0)
ptscl.bind('<ButtonRelease-1>', ptscl2)
listbutton = Button(duf, text='列表循环', command=liststatus)
prebutton = Button(duf, text='⏮', command=playlastmusic)
nextbutton = Button(duf, text='⏭', command=playnextmusic_)
ptlb.pack(side=LEFT)
ptscl.pack(side=LEFT)
prebutton.pack(side=LEFT)
listbutton.pack(side=LEFT)
nextbutton.pack(side=LEFT)
duf.pack(side=TOP)

# 第四区块(音乐列表)
lbrf = Frame(t)
lbrsb = Scrollbar(lbrf)  # 列表侧滚轮
lbrsb.pack(side=RIGHT, fill=Y)
class GraphicalInterface():
    def __init__(self, *args, **kwargs):
        threading.Thread.__init__(self)
        self.kwargs = kwargs
        self.enable_joysticks = True
        if 'enable_joysticks' in self.kwargs:
            self.enable_joysticks = self.kwargs['enable_joysticks']

        logging.getLogger("requests").setLevel(logging.WARNING)

        self.stop_robot = False
        self.logger = logging.getLogger('GUI')
        self.curr_image = None
        self.joint_states = []
        self.num_empty_commands = 0

        self.robot_ctrl = RobotController.getInstance(*args, **kwargs)
        self.logger.info('initializing robot...')
        self.robot_ctrl.init_robot()
        self.logger.info('robot successfully initilized')

        if 'robot_init_pos' in self.kwargs:
            self.logger.info('Sending robot to center.')
            self.robot_ctrl.send_robot_to_center(goal=kwargs['robot_init_pos'])
            self.logger.info('Robot centered.')

        np.set_printoptions(precision=2)

        self.image_size = (640, 360)
        if 'image_size' in self.kwargs:
            self.image_size = self.kwargs['image_size']

    def callback(self):
        self.parent.quit()

    def run(self):

        self.parent = tk.Tk()

        self.main_frame = Frame(self.parent)
        self.main_frame.pack()
        if self.enable_joysticks:
            self.create_widgets()

        self.robot_controller()

        # def signal_handler(sig, frame):
        #     self.logger.info('You pressed Ctrl+C')
        #     # cap.release()
        #     cv2.destroyAllWindows()
        #     self.logger.info("Stopping Robot...")
        #     self.stop_robot = True
        #     self.robot_ctrl.send_joint_command_to_robot([0, 0, 0, 0, 0, 0], use_thread=False)
        #     sys.exit(0)

        # signal.signal(signal.SIGINT, signal_handler)

        self.parent.mainloop()

    def robot_controller(self):
        self.curr_image = self.robot_ctrl.get_image_cv2()
        if self.curr_image is None:
            self.parent.after(10, self.robot_controller)
            return

        img = cv2.resize(self.curr_image, self.image_size)
        cv2.imshow('frame', img / 255.0)
        if cv2.waitKey(1) & 0xFF == ord('q'):
            return

        if self.stop_robot == True:
            return

        if self.enable_joysticks:
            x = -self.canvas.joystick_x
            y = -self.canvas.joystick_y
            v = (100 - abs(x)) * (y / 100) + y
            w = (100 - abs(y)) * (x / 100) + x
            x = (v - w) // 2
            y = (v + w) // 2
            command_to_send = [
                x, y,
                self.scale1.get(),
                self.scale2.get(),
                self.scale4.get(),
                self.scale3.get()
            ]

            self.robot_ctrl.send_joint_command_to_robot(command_to_send)
            # self.robot_ctrl.update_joint_states()

        self.parent.after(10, self.robot_controller)

    def create_widgets(self):
        self.main_frame.style = ttk.Style()
        self.main_frame.winfo_toplevel().title("Nabot Controls")
        self.main_frame.style.theme_use('default')
        self.main_frame.configure(background='black')

        def create_canvas():
            class Joystick(tk.Canvas):
                pass

            self.canvas = Joystick(self.main_frame, width=400, height=400)
            self.canvas.joystick_x = 0
            self.canvas.joystick_y = 0
            self.canvas.is_moving = False

            def paint(event):
                # self.canvas.create_rectangle(0, 0, 200, 200, fill='red')
                reset_canvas()
                self.canvas.create_oval(0,
                                        0,
                                        400,
                                        400,
                                        fill='black',
                                        outline='gray')
                x1, y1 = event.x - 75, event.y - 75
                x2, y2 = event.x + 75, event.y + 75
                self.canvas.create_oval(x1, y1, x2, y2, fill='blue')

                self.canvas.joystick_x = (event.x - 200) * 7 / 10
                self.canvas.joystick_y = (event.y - 200) * 7 / 10

                self.canvas.joystick_x = min(max(self.canvas.joystick_x, -100),
                                             100)
                self.canvas.joystick_y = min(max(self.canvas.joystick_y, -100),
                                             100)

            def reset(event):
                self.canvas.is_moving = False
                self.canvas.joystick_x = 0
                self.canvas.joystick_y = 0
                reset_canvas()
                logging.debug('move the robot, x:{} y:{}'.format(
                    self.canvas.joystick_x, self.canvas.joystick_y))

            def reset_canvas():
                self.canvas.create_rectangle(0, 0, 400, 400, fill='black')
                self.canvas.create_oval(0,
                                        0,
                                        400,
                                        400,
                                        fill='black',
                                        outline='gray')
                self.canvas.create_oval(125, 125, 275, 275, fill='gray')

            self.canvas.pack(side='left')

            # self.canvas.bind('<Button-1>', start)
            self.canvas.bind('<B1-Motion>', paint)
            self.canvas.bind('<ButtonRelease-1>', reset)
            reset_canvas()

            def scale1_command(val):
                val = self.scale1.get()

            def scale1_stop(event):
                self.scale1.set(0)

            self.scale1 = Scale(from_=100,
                                to=-100,
                                label='head',
                                command=scale1_command)
            self.scale1.bind('<ButtonRelease-1>', scale1_stop)
            self.scale1.pack(side='left')

            def scale2_command(val):
                val = self.scale2.get()

            def scale2_stop(event):
                self.scale2.set(0)

            self.scale2 = Scale(from_=100,
                                to=-100,
                                label='elbow',
                                command=scale2_command)
            self.scale2.bind('<ButtonRelease-1>', scale2_stop)
            self.scale2.pack(side='left')
            self.scale3 = Scale(from_=0,
                                to=100,
                                orient=HORIZONTAL,
                                label='Gripper')
            self.scale3.pack(side='top')

            def scale4_command(val):
                val = self.scale4.get()

            def scale4_stop(event):
                self.scale4.set(0)

            self.scale4 = Scale(from_=-100,
                                to=100,
                                orient=HORIZONTAL,
                                command=scale4_command,
                                label='wrist')
            self.scale4.bind('<ButtonRelease-1>', scale4_stop)
            self.scale4.pack(side='top')

        create_canvas()
class FilterFrame(Toplevel):
    def __init__(self, master=None):
        Toplevel.__init__(self, master=master)

        self.original_image = self.master.processed_image
        self.filtered_image = None

        self.negative_button = Button(master=self, text="Negative")
        self.black_white_button = Button(master=self, text="Black White")
        self.sepia_button = Button(master=self, text="Sepia")
        self.sepia_label = Label(self, text="Sepia")
        self.sepia_scale = Scale(self,
                                 from_=-200,
                                 to_=200,
                                 length=250,
                                 resolution=1,
                                 orient=HORIZONTAL)
        self.emboss_label = Label(self, text="Emboss")
        self.emboss_scale = Scale(self,
                                  from_=-200,
                                  to_=200,
                                  length=250,
                                  resolution=1,
                                  orient=HORIZONTAL)

        self.gaussian_blur_label = Label(self, text="Gaussian Blur")
        self.gaussian_blur_scale = Scale(self,
                                         from_=0,
                                         to_=10,
                                         length=250,
                                         resolution=1,
                                         orient=HORIZONTAL)

        # self.gaussian_blur_button = Button(master=self, text="Gaussian Blur")
        self.cancel_button = Button(master=self, text="Cancel")
        self.apply_button = Button(master=self, text="Apply")

        self.negative_button.bind("<ButtonRelease>",
                                  self.negative_button_released)
        self.black_white_button.bind("<ButtonRelease>",
                                     self.black_white_released)
        self.sepia_scale.bind("<ButtonRelease>", self.sepia_scale_released)
        self.emboss_scale.bind("<ButtonRelease>", self.emboss_scale_released)
        self.gaussian_blur_scale.bind("<ButtonRelease>",
                                      self.gaussian_blur_scale_released)
        # self.gaussian_blur_button.bind("<ButtonRelease>", self.gaussian_blur_button_released)
        self.apply_button.bind("<ButtonRelease>", self.apply_button_released)
        self.cancel_button.bind("<ButtonRelease>", self.cancel_button_released)

        self.negative_button.pack()
        self.black_white_button.pack()
        self.sepia_label.pack()
        self.sepia_scale.pack()
        self.emboss_label.pack()
        self.emboss_scale.pack()
        self.gaussian_blur_scale.pack()
        # self.gaussian_blur_button.pack()
        self.cancel_button.pack(side=RIGHT)
        self.apply_button.pack()

    def negative_button_released(self, event):
        self.negative()
        self.show_image()

    def black_white_released(self, event):
        self.black_white()
        self.show_image()

    def sepia_scale_released(self, event):
        self.sepia()
        self.show_image()

    def emboss_button_released(self, event):
        self.emboss()
        self.show_image()

    def emboss_scale_released(self, event):
        self.emboss()
        self.show_image()

    def gaussian_blur_scale_released(self, event):
        self.gaussian_blur()
        self.show_image()

    def apply_button_released(self, event):
        self.master.processed_image = self.filtered_image
        self.show_image()
        self.close()

    def cancel_button_released(self, event):
        self.master.image_viewer.show_image()
        self.close()

    def show_image(self):
        self.master.image_viewer.show_image(img=self.filtered_image)

    def negative(self):
        self.filtered_image = cv2.bitwise_not(self.original_image)

    def black_white(self):
        self.filtered_image = cv2.cvtColor(self.original_image,
                                           cv2.COLOR_BGR2GRAY)
        self.filtered_image = cv2.cvtColor(self.filtered_image,
                                           cv2.COLOR_GRAY2BGR)

    def sepia(self):
        kernel = np.array([[0.272, 0.534, 0.131], [0.349, 0.686, 0.168],
                           [0.393, 0.769, 0.189]])
        self.filtered_image = cv2.filter2D(self.original_image,
                                           -1,
                                           kernel,
                                           delta=self.sepia_scale.get())

    def emboss(self):
        kernel = np.array([[0, -1, -1], [1, 0, -1], [1, 1, 0]])

        self.filtered_image = cv2.filter2D(self.original_image,
                                           -1,
                                           kernel,
                                           delta=self.emboss_scale.get())

    def gaussian_blur(self):
        size = self.gaussian_blur_scale.get() * 10 + 1
        self.filtered_image = cv2.GaussianBlur(self.original_image,
                                               (size, size), 0)

    def close(self):
        self.destroy()
class AdjustFrame(Toplevel):
    def __init__(self, master=None):
        Toplevel.__init__(self, master=master)

        self.brightness_value = 0
        self.previous_brightness_value = 0

        self.original_image = self.master.processed_image
        self.processing_image = self.master.processed_image

        self.brightness_label = Label(self, text="Brightness")
        self.brightness_scale = Scale(self,
                                      from_=0,
                                      to_=2,
                                      length=250,
                                      resolution=0.1,
                                      orient=HORIZONTAL)
        self.r_label = Label(self, text="R")
        self.r_scale = Scale(self,
                             from_=-100,
                             to_=100,
                             length=250,
                             resolution=1,
                             orient=HORIZONTAL)
        self.g_label = Label(self, text="G")
        self.g_scale = Scale(self,
                             from_=-100,
                             to_=100,
                             length=250,
                             resolution=1,
                             orient=HORIZONTAL)
        self.b_label = Label(self, text="B")
        self.b_scale = Scale(self,
                             from_=-100,
                             to_=100,
                             length=250,
                             resolution=1,
                             orient=HORIZONTAL)
        self.apply_button = Button(self, text="Apply")
        self.cancel_button = Button(self, text="Cancel")

        self.brightness_scale.set(1)

        self.apply_button.bind("<ButtonRelease>", self.apply_button_released)
        self.brightness_scale.bind("<ButtonRelease>", self.show_button_release)
        self.r_scale.bind("<ButtonRelease>", self.show_button_release)
        self.g_scale.bind("<ButtonRelease>", self.show_button_release)
        self.b_scale.bind("<ButtonRelease>", self.show_button_release)
        self.cancel_button.bind("<ButtonRelease>", self.cancel_button_released)

        self.brightness_label.pack()
        self.brightness_scale.pack()
        self.r_label.pack()
        self.r_scale.pack()
        self.g_label.pack()
        self.g_scale.pack()
        self.b_label.pack()
        self.b_scale.pack()
        self.cancel_button.pack(side=RIGHT)
        self.apply_button.pack()

    def apply_button_released(self, event):
        self.master.processed_image = self.processing_image
        self.close()

    def show_button_release(self, event):
        self.processing_image = cv2.convertScaleAbs(
            self.original_image, alpha=self.brightness_scale.get())
        b, g, r = cv2.split(self.processing_image)

        for b_value in b:
            cv2.add(b_value, self.b_scale.get(), b_value)
        for g_value in g:
            cv2.add(g_value, self.g_scale.get(), g_value)
        for r_value in r:
            cv2.add(r_value, self.r_scale.get(), r_value)

        self.processing_image = cv2.merge((b, g, r))
        self.show_image(self.processing_image)

    def cancel_button_released(self, event):
        self.close()

    def show_image(self, img=None):
        self.master.image_viewer.show_image(img=img)

    def close(self):
        self.show_image()
        self.destroy()
class GradientKit(Frame):
    """
    Gradient Kit Frame - it manages gradient pattern.
    Gradient pattern allows modification of arrays.
    Parameters:
     - Minimum value gradient's radius: radius for max weakening of array's values
     - Maximum value gradient's radius: radius for max magnifying of array's values
    """
    def __init__(self, parent):
        Frame.__init__(self, parent, bd=1, relief=SUNKEN)
        self.root = parent.master

        self.main_bg = parent['bg']
        self.config(bg=self.main_bg)
        # basic array for faster response of changing pattern's parameters, but it takes 2x RAM!
        self.circle_basic_array = None
        self.array = None
        self.slider_events = ["<ButtonRelease-1>", "<ButtonRelease-3>"]

        # gradient menu
        self.generate_btn = Button(self,
                                   text="Make gradient",
                                   command=self.generate_gradient)
        self.generate_btn.grid(row=0, column=0, padx=5, pady=5, sticky='nw')
        self.show_btn = Button(self,
                               text="Show gradient",
                               command=self.show_array)
        self.show_btn.grid(row=0, column=1, padx=5, pady=5, sticky='nw')
        self.show_btn.grid_remove()
        self.clear_btn = Button(self,
                                text="Clear gradient",
                                command=self.clear_gradient,
                                bg='darkred',
                                fg='lightgray')
        self.clear_btn.grid(row=0, column=2, padx=5, pady=5, sticky='nw')
        self.clear_btn.grid_remove()

        # sliders - radius range 0-1 where 0 is exact middle of array and 1 is the most far corner
        self.min_value_radius = Scale(self,
                                      from_=0,
                                      to=1,
                                      resolution=0.01,
                                      length=275,
                                      orient=HORIZONTAL,
                                      label="Minimum value gradient's radius")
        self.min_value_radius.grid(row=1,
                                   column=0,
                                   padx=5,
                                   pady=5,
                                   columnspan=3)
        for event in self.slider_events:
            self.min_value_radius.bind(event, self.change_factor_event)
        self.max_value_radius = Scale(self,
                                      from_=0,
                                      to=1,
                                      resolution=0.01,
                                      length=275,
                                      orient=HORIZONTAL,
                                      label="Maximum value gradient's radius")
        self.max_value_radius.grid(row=2,
                                   column=0,
                                   padx=5,
                                   pady=5,
                                   columnspan=3)
        for event in self.slider_events:
            self.max_value_radius.bind(event, self.change_factor_event)
        self.max_value_radius.set(1)

    def change_factor_event(self, event):
        if self.array is not None:
            self.generate_gradient()

    def generate_gradient(self, refresh_map=True):
        if self.circle_basic_array is None \
                or shape(self.circle_basic_array)[0] != self.root.MAP_SIZE[0]\
                or shape(self.circle_basic_array)[1] != self.root.MAP_SIZE[1]:
            self.circle_basic_array = empty(self.root.MAP_SIZE, dtype=float)
            for i in range(self.root.MAP_SIZE[0] // 2):
                a = self.root.MAP_SIZE[0] // 2 - i
                for j in range(self.root.MAP_SIZE[1] // 2):
                    # old squared gradient formula: x = i if i < j else j
                    b = self.root.MAP_SIZE[1] // 2 - j
                    x = -sqrt(a * a + b * b)
                    self.circle_basic_array[i][j] = x
                    self.circle_basic_array[i][self.root.MAP_SIZE[1] - j -
                                               1] = x
                    self.circle_basic_array[self.root.MAP_SIZE[0] - i -
                                            1][j] = x
                    self.circle_basic_array[self.root.MAP_SIZE[0] - i -
                                            1][self.root.MAP_SIZE[1] - j -
                                               1] = x

        if self.max_value_radius.get() < self.min_value_radius.get():
            # allowing reversing gradient pattern (middle is suppressed instead of borders)
            self.array = 1 - self.circle_basic_array
        else:
            self.array = self.circle_basic_array.copy()

        # convert radius into array index
        x_of_border = int(self.root.MAP_SIZE[0] *
                          (1 - self.max_value_radius.get()) / 2)
        y_of_border = int(self.root.MAP_SIZE[1] *
                          (1 - self.max_value_radius.get()) / 2)
        self.array[self.array < self.array[x_of_border, y_of_border]] = \
            self.array[x_of_border, y_of_border]

        if self.max_value_radius.get() == self.min_value_radius.get():
            # in case of equal values, make sure indexes differ at least by 1 (pattern gets blank otherwise)
            x_of_border += 1
            y_of_border += 1
        else:
            x_of_border = int(self.root.MAP_SIZE[0] *
                              (1 - self.min_value_radius.get()) / 2)
            y_of_border = int(self.root.MAP_SIZE[1] *
                              (1 - self.min_value_radius.get()) / 2)

        self.array[self.array > self.array[x_of_border, y_of_border]] = \
            self.array[x_of_border, y_of_border]

        # normalize values to the range: 0-1
        if self.array.ptp():
            self.array = ((self.array - amin(self.array)) / self.array.ptp())

        if refresh_map:
            if self.root.img is None or self.root.displayed_frame is self:
                self.show_array()
            elif self.root.displayed_frame is self.root:
                self.root.display_map()

        self.show_btn.grid()
        self.clear_btn.grid()

    def show_array(self):
        # normalize values to 0-levels and rescale to 0-255 (grayscale)
        noise_map = (self.array *
                     self.root.levels).astype(int) / self.root.levels * 255
        self.root.img = ImageTk.PhotoImage(image=Image.fromarray(noise_map))
        self.root.canvas.itemconfig(self.root.map_img, image=self.root.img)
        self.root.displayed_frame = self

    def clear_gradient(self):
        self.show_btn.grid_remove()
        self.clear_btn.grid_remove()
        self.array = None
        self.root.display_map()
class Window(object):
    """"This class creates a GUI using the built in python libary tkinter"""

    def __init__(self, window):
        self.window = window

        self.check = False

        self.animateval = False

        titlel = Label(window, text="Evolutionary Spatial Games", height=3)
        titlel.grid(row=0, column=0, rowspan=2)

        self.cellularAutomata = Canvas(window, height=600, width=600, background="blue")
        self.cellularAutomata.grid(row=2, column=0, rowspan="20")

        l2 = Label(window, text="Payoff matrix:", width=16)
        l2.grid(row=3, column=1)

        l3 = Label(window, text="Cell size: ", width=16)
        l3.grid(row=6, column=1)

        l8 = Label(window, text="Moore Neighbourhood: ", width=22)
        l8.grid(row=7, column=1)

        l9 = Label(window, text="Von Nuemann Neighbourhood: ", width=26)
        l9.grid(row=8, column=1)

        l4 = Label(window, text="Initial Distribution: ", width=16)
        l4.grid(row=10, column=1)

        l9 = Label(window, text="Fixed boundary (A): ", width=26)
        l9.grid(row=11, column=1)

        l9 = Label(window, text="Reflective boundary:  ", width=26)
        l9.grid(row=12, column=1)

        l9 = Label(window, text="Periodic boundary: ", width=26)
        l9.grid(row=13, column=1)

        la = Label(window, text="Count (A|B|C): ", width=16)
        la.grid(row=16, column=1)

        l5 = Label(window, text="Iterations: ", width=16)
        l5.grid(row=17, column=1)

        b1 = Button(window, text="Draw", command=self.draw_command)
        b1.grid(row=19, column=1)

        self.b2 = Button(window, text="Start", command=self.begin_command)
        self.b2.grid(row=19, column=2)

        self.e1 = Scale(
            window, width=8, orient=HORIZONTAL, from_=2, to=3, label="Strategies"
        )
        self.e1.grid(row=0, column=1)

        self.e1.bind("<ButtonRelease-1>", self.change_entry)

        self.li = Label(window, text="B invades A: ", width=16)
        self.li.grid(row=14, column=1)

        self.ival = IntVar()
        self.iv = Checkbutton(window, variable=self.ival)
        self.iv.grid(row=14, column=2)

        self.ld = Label(window, text="Dynamic", width=16)
        self.ld.grid(row=15, column=1)

        self.dyval = IntVar()
        self.dyval.set(1)
        self.dy = Checkbutton(window, variable=self.dyval)
        self.dy.grid(row=15, column=2)

        self.e2 = IntVar()
        self.e2 = Entry(window, textvariable=self.e2, width=6)
        self.e2.grid(row=3, column=2)

        self.e3 = IntVar()
        self.e3 = Entry(window, textvariable=self.e3, width=6)
        self.e3.grid(row=3, column=3)

        self.e4 = IntVar()
        self.e4 = Entry(window, textvariable=self.e4, width=6)
        self.e4.grid(row=4, column=2)

        self.e5 = IntVar()
        self.e5 = Entry(window, textvariable=self.e5, width=6)
        self.e5.grid(row=4, column=3)

        self.cellsize = IntVar()
        self.cellsize.set(8)
        self.cellsize = Entry(window, textvariable=self.cellsize, width=6)
        self.cellsize.grid(row=6, column=2)

        self.p1 = DoubleVar()
        self.p1 = Entry(window, textvariable=self.p1, width=6)
        self.p1.grid(row=10, column=2)

        self.p2 = DoubleVar()
        self.p2 = Entry(window, textvariable=self.p2, width=6)
        self.p2.grid(row=10, column=3)

        self.neighbourE = IntVar()
        self.neighbourE.set(1)
        self.moore = Radiobutton(window, variable=self.neighbourE, value=1)
        self.moore.grid(row=7, column=2)

        self.nuemann = Radiobutton(window, variable=self.neighbourE, value=2)
        self.nuemann.grid(row=8, column=2)

        self.boundaryvar = IntVar()
        self.boundaryvar.set(2)
        self.fixed = Radiobutton(window, variable=self.boundaryvar, value=1)
        self.fixed.grid(row=11, column=2)

        self.reflective = Radiobutton(window, variable=self.boundaryvar, value=2)
        self.reflective.grid(row=12, column=2)

        self.periodic = Radiobutton(window, variable=self.boundaryvar, value=3)
        self.periodic.grid(row=13, column=2)

        self.a1 = Listbox(window, width=4, height=1)
        self.a1.grid(row=16, column=2)

        self.a2 = Listbox(window, width=4, height=1)
        self.a2.grid(row=16, column=3)

        self.i1 = Listbox(window, width=4, height=1)
        self.i1.grid(row=17, column=2)

    def draw_command(self):
        self.cellularAutomata.delete("all")
        self.count = 0
        self.i1.delete(0, END)
        self.i1.insert(END, self.count)
        try:
            self.b3.destroy()
            self.b2 = Button(window, text="Start", command=self.begin_command)
            self.b2.grid(row=19, column=2)
        except AttributeError:
            pass
        try:
            if self.e1.get() == 2:
                matrix = [
                    [self.e2.get(), self.e3.get()],
                    [self.e4.get(), self.e5.get()],
                ]
                self.SpatialGame = spatialGame(
                    600,
                    600,
                    self.cellsize.get(),
                    [self.p1.get(), self.p2.get()],
                    self.e1.get(),
                    matrix,
                    self.ival.get(),
                    self.neighbourE.get(),
                    self.boundaryvar.get(),
                    self.dyval.get(),
                )
            if self.e1.get() == 3:
                matrix = [
                    [self.e2.get(), self.e3.get(), self.e6.get()],
                    [self.e4.get(), self.e5.get(), self.e7.get()],
                    [self.e8.get(), self.e9.get(), self.e10.get()],
                ]
                self.SpatialGame = spatialGame(
                    600,
                    600,
                    self.cellsize.get(),
                    [self.p1.get(), self.p2.get(), self.p3.get()],
                    self.e1.get(),
                    matrix,
                    self.ival.get(),
                    self.neighbourE.get(),
                    self.boundaryvar.get(),
                    self.dyval.get(),
                )
            self.cells = self.SpatialGame.cells
            for x in range(0, self.SpatialGame.width):
                for y in range(0, self.SpatialGame.height):
                    if self.cells[x][y] == 2:
                        square_coords = (
                            x * self.SpatialGame.cell_size,
                            y * self.SpatialGame.cell_size,
                            x * self.SpatialGame.cell_size + self.SpatialGame.cell_size,
                            y * self.SpatialGame.cell_size + self.SpatialGame.cell_size,
                        )
                        self.cellularAutomata.create_rectangle(
                            square_coords, fill="red", outline="red"
                        )
                    if self.SpatialGame.cells[x][y] == 3:
                        square_coords = (
                            x * self.SpatialGame.cell_size,
                            y * self.SpatialGame.cell_size,
                            x * self.SpatialGame.cell_size + self.SpatialGame.cell_size,
                            y * self.SpatialGame.cell_size + self.SpatialGame.cell_size,
                        )
                        self.cellularAutomata.create_rectangle(
                            square_coords, fill="pink", outline="pink"
                        )
        except ValueError:
            self.cellularAutomata.create_text(
                300,
                300,
                fill="White",
                font="Times 20 bold",
                text="Your probability distribution must add to 1.",
            )

    def begin_command(self):
        self.animateval = True
        self.animate()

    def next(self):
        self.cellularAutomata.delete("all")
        self.SpatialGame.run_rules()
        self.cells = self.SpatialGame.cells
        self.count = self.count + 1
        self.i1.delete(0, END)
        self.i1.insert(END, self.count)
        self.b2.destroy()
        self.b3 = Button(window, text="Stop", command=self.stop_command)
        self.b3.grid(row=19, column=2)
        self.animateval = True
        for x in range(0, self.SpatialGame.width):
            for y in range(0, self.SpatialGame.height):
                if self.cells[x][y] == 2:
                    square_coords = (
                        x * self.SpatialGame.cell_size,
                        y * self.SpatialGame.cell_size,
                        x * self.SpatialGame.cell_size + self.SpatialGame.cell_size,
                        y * self.SpatialGame.cell_size + self.SpatialGame.cell_size,
                    )
                    self.cellularAutomata.create_rectangle(
                        square_coords, fill="red", outline="red"
                    )
                if self.cells[x][y] == 4:
                    square_coords = (
                        x * self.SpatialGame.cell_size,
                        y * self.SpatialGame.cell_size,
                        x * self.SpatialGame.cell_size + self.SpatialGame.cell_size,
                        y * self.SpatialGame.cell_size + self.SpatialGame.cell_size,
                    )
                    self.cellularAutomata.create_rectangle(
                        square_coords, fill="green", outline="green"
                    )
                if self.cells[x][y] == 5:
                    square_coords = (
                        x * self.SpatialGame.cell_size,
                        y * self.SpatialGame.cell_size,
                        x * self.SpatialGame.cell_size + self.SpatialGame.cell_size,
                        y * self.SpatialGame.cell_size + self.SpatialGame.cell_size,
                    )
                    self.cellularAutomata.create_rectangle(
                        square_coords, fill="yellow", outline="yellow"
                    )
                if self.cells[x][y] == 3:
                    square_coords = (
                        x * self.SpatialGame.cell_size,
                        y * self.SpatialGame.cell_size,
                        x * self.SpatialGame.cell_size + self.SpatialGame.cell_size,
                        y * self.SpatialGame.cell_size + self.SpatialGame.cell_size,
                    )
                    self.cellularAutomata.create_rectangle(
                        square_coords, fill="pink", outline="pink"
                    )
                if self.cells[x][y] == 6:
                    square_coords = (
                        x * self.SpatialGame.cell_size,
                        y * self.SpatialGame.cell_size,
                        x * self.SpatialGame.cell_size + self.SpatialGame.cell_size,
                        y * self.SpatialGame.cell_size + self.SpatialGame.cell_size,
                    )
                    self.cellularAutomata.create_rectangle(
                        square_coords, fill="purple", outline="purple"
                    )
        self.a1.delete(0, END)
        self.a1.insert(END, self.SpatialGame.stratA)
        self.a2.delete(0, END)
        self.a2.insert(END, self.SpatialGame.stratB)
        try:
            self.a3.delete(0, END)
            self.a3.insert(END, self.SpatialGame.stratC)
        except:
            pass

    def change_entry(self, event):
        if self.e1.get() == 3 and self.check == False:
            self.check = True
            self.e6 = IntVar()
            self.e6 = Entry(window, textvariable=self.e6, width=6)
            self.e6.grid(row=3, column=4)
            self.e7 = IntVar()
            self.e7 = Entry(window, textvariable=self.e7, width=6)
            self.e7.grid(row=4, column=4)
            self.e8 = IntVar()
            self.e8 = Entry(window, textvariable=self.e8, width=6)
            self.e8.grid(row=5, column=2)
            self.e9 = IntVar()
            self.e9 = Entry(window, textvariable=self.e9, width=6)
            self.e9.grid(row=5, column=3)
            self.e10 = IntVar()
            self.e10 = Entry(window, textvariable=self.e10, width=6)
            self.e10.grid(row=5, column=4)
            self.p3 = DoubleVar()
            self.p3 = Entry(window, textvariable=self.p3, width=6)
            self.p3.grid(row=10, column=4)
            self.li.destroy()
            self.iv.destroy()
            self.ival = IntVar()
            self.ival.set(0)
            self.a3 = Listbox(window, width=4, height=1)
            self.a3.grid(row=16, column=4)
        elif self.e1.get() == 2 and self.check == True:
            self.li = Label(window, text="B invades A: ", width=16)
            self.li.grid(row=14, column=1)
            self.ival = IntVar()
            self.iv = Checkbutton(window, variable=self.ival)
            self.iv.grid(row=14, column=2)
            self.check = False
            self.e6.destroy()
            self.e7.destroy()
            self.e8.destroy()
            self.e9.destroy()
            self.e10.destroy()
            self.p3.destroy()
            self.a3.destroy()

    def stop_command(self):
        self.animateval = False
        self.b3.destroy()
        self.b2 = Button(window, text="Start", command=self.begin_command)
        self.b2.grid(row=19, column=2)

    def animate(self):
        while self.animateval == True:
            self.next()
            self.window.update()
            time.sleep(0.5)
Exemple #18
0
    boton.place (relx=0.5, rely=0.32, anchor=CENTER)

    # Etiqueta que contiene la cantidad de iteraciones realizadas para el cálculo.
    etiqueta = Label (ventana, text = ('Iteraciones necesarias: ' + str (iteracionesTotales)))
    etiqueta.config (bg = 'white', font = ('Verdana', 15))
    etiqueta.place (relx=0.5, rely=0.37, anchor=CENTER)

    #Función que permite graficar a tiempo real. Esta ejecuta nuevamente la función Graficar para realizar nuevamente el cálculo.
    animation.FuncAnimation (fig, Graficar, interval = 1000)
    plt.close ()
 

# Se define el slider para el tamaño del lado.
barraL = Scale(ventana, from_=7, to=20, tickinterval=13, length=400, bg = 'White',
resolution=1, showvalue=True, orient='horizontal', label="Tamaño del Lado (Lx)", cursor = "hand1")
barraL.bind ("<ButtonRelease-1>",Graficar)
barraL.set(10)

barraL.place (relx=0.175, rely=0.05, anchor=CENTER)

# Se define el slider para el tiempo a evaluar.
barraTiempos = Scale(ventana, from_=1, to=5, tickinterval=4,length=400, bg = 'White',
resolution=0.5, showvalue=True, orient='horizontal', label="Tiempo (s)", cursor = "hand1")
barraTiempos.bind ("<ButtonRelease-1>",Graficar)
barraTiempos.set(3)

barraTiempos.place (relx=0.5, rely=0.05, anchor=CENTER)

# Se define el slider para el número de términos.
barraPresición = Scale(ventana, from_=0.001, to=1, tickinterval=0.999,length=400, bg = 'White',
resolution=0.001, showvalue=True, orient='horizontal', label="Presición", cursor = "hand1")
root.resizable(False, False)
root.wm_attributes("-topmost", 1)

# uses xrandr to get current output
currentOutput = str(
    popen('xrandr | grep " connected" | cut -f1 -d " " ').read()).strip()
print(currentOutput)


def setBrightness(event, limiter=0.2):
    _level = level.get(
    ) / 100  # scale returns value from 0 - 100 must be converted to decimal
    print(_level)

    # limits darkest setting to 20% to prevent user from completly blacking out moniter
    if _level <= limiter:
        _level = limiter

    system(f'xrandr --output {currentOutput} --brightness {_level}')


level = Scale(root, from_=100, to_=0)
level.set(
    float(
        popen("xrandr --verbose | awk '/Brightness/ { print $2; exit }'").read(
        )) * 100)  # sets scale slider to current brightness
level.bind("<ButtonRelease-1>", setBrightness)
level.pack()

root.mainloop()
Exemple #20
0
class HOPSFitsWindow(HOPSWidget):
    def __init__(self,
                 window,
                 input=None,
                 input_name=None,
                 input_options=None,
                 figsize=None,
                 show_nav=False,
                 show_controls=False,
                 show_axes=False,
                 subplots_adjust=None,
                 dwmax=8.0,
                 dhmax=8.0):

        widget = Frame(window.main_frame)

        self.show_axes = show_axes

        if figsize:
            try:
                wpcent, hpcent, wmax, hmax, ratio, = figsize
                wmax, hmax = dwmax, dhmax
                w = min(wpcent * window.log.plt2screen_w, wmax)
                h = min(hpcent * window.log.plt2screen_h, hmax)
                if h * ratio < w:
                    w = h * ratio
                else:
                    h = w / ratio
            except:
                w, h = figsize
            self.figure = matplotlib.figure.Figure(figsize=(w, h))
        else:
            self.figure = matplotlib.figure.Figure()
        self.figure.patch.set_facecolor('white')
        self.canvas = FigureCanvasTkAgg(self.figure, widget)

        self.ax = self.figure.add_subplot(111)
        self.ax.tick_params(axis='y', rotation=90)

        if not self.show_axes:
            self.ax.axis('off')
            self.figure.subplots_adjust(left=0.01,
                                        right=0.99,
                                        bottom=0.01,
                                        top=0.99)

        if subplots_adjust:
            self.figure.subplots_adjust(left=subplots_adjust[0],
                                        right=subplots_adjust[1],
                                        bottom=subplots_adjust[2],
                                        top=subplots_adjust[3])

        self.data = None
        self.mean = 0
        self.std = 0
        self.image = None
        self.sqrt_vmin = DoubleVar(widget, value=0)
        self.vmin = IntVar(widget, value=0)
        self.sqrt_vmax = DoubleVar(widget, value=10000)
        self.vmax = IntVar(widget, value=10000)
        self.gamma = DoubleVar(widget, value=0)
        self.flip = IntVar(widget, value=0)
        self.mirror = IntVar(widget, value=0)
        self.white_sky = IntVar(widget, value=0)

        if input_name:
            if len(input_name) > 50:
                split = [
                    input_name[i:i + 50]
                    for i in range(0, len(input_name), 50)
                ]
                input_name = '\n'.join(split)

        self.fits_name = StringVar(widget, value=input_name)
        self.fits_name_label = Label(widget, textvar=self.fits_name)

        # extra widgets

        control_frame = Frame(widget)
        self.control_frame = control_frame

        self.info_label = Label(
            control_frame,
            text=
            'Scroll up/down to zoom in/out. Click & drag to move the image.')

        self.mouse_data = StringVar(control_frame, value=' ')
        self.mouse_data_label = Label(control_frame, textvar=self.mouse_data)

        self.black_entry = Scale(control_frame,
                                 resolution=0.1,
                                 variable=self.sqrt_vmin,
                                 orient=HORIZONTAL,
                                 showvalue=False)
        self.black_entry.bind("<B1-Motion>", self.contrast)
        self.black_entry.bind("<ButtonRelease-1>", self.contrast)
        self.black_entry_label_0 = Label(control_frame,
                                         text='Minimum = ',
                                         anchor=E)
        self.black_entry_label = Label(control_frame,
                                       textvar=self.vmin,
                                       anchor=W)
        self.black_entry['from_'] = 1
        self.black_entry['to'] = 1000

        self.white_entry = Scale(control_frame,
                                 resolution=0.1,
                                 variable=self.sqrt_vmax,
                                 orient=HORIZONTAL,
                                 showvalue=False)
        self.white_entry.bind("<B1-Motion>", self.contrast)
        self.white_entry.bind("<ButtonRelease-1>", self.contrast)
        self.white_entry_label_0 = Label(control_frame,
                                         text='Maximum = ',
                                         anchor=E)
        self.white_entry_label = Label(control_frame,
                                       textvar=self.vmax,
                                       anchor=W)
        self.white_entry['from_'] = 1
        self.white_entry['to'] = 1000

        self.gamma_entry = Scale(control_frame,
                                 resolution=0.001,
                                 variable=self.gamma,
                                 orient=HORIZONTAL,
                                 showvalue=False)
        self.gamma_entry.bind("<B1-Motion>", self.contrast)
        self.gamma_entry.bind("<ButtonRelease-1>", self.contrast)
        self.gamma_entry_label_0 = Label(control_frame,
                                         text='Stretch factor = ',
                                         anchor=E)
        self.gamma_entry_label = Label(control_frame,
                                       textvar=self.gamma,
                                       anchor=W)
        self.gamma_entry['from_'] = 0
        self.gamma_entry['to'] = 1

        self.flip_button = Checkbutton(control_frame,
                                       text='Flip',
                                       variable=self.flip,
                                       command=self.flip_fov)
        self.mirror_button = Checkbutton(control_frame,
                                         text='Mirror',
                                         variable=self.mirror,
                                         command=self.mirror_fov)
        self.reverse_color_button = Checkbutton(control_frame,
                                                text='White Sky',
                                                variable=self.white_sky,
                                                command=self.reverse_color)
        self.reset_button = Button(control_frame,
                                   text='RESET',
                                   command=self.reset)

        self.info_label.grid(row=1, column=1, columnspan=4)
        self.mouse_data_label.grid(row=2, column=1, columnspan=4)
        self.black_entry_label_0.grid(row=3, column=1, columnspan=2)
        self.black_entry_label.grid(row=3, column=3)
        self.black_entry.grid(row=4,
                              column=1,
                              columnspan=4,
                              sticky=N + S + E + W)
        self.white_entry_label_0.grid(row=5, column=1, columnspan=2)
        self.white_entry_label.grid(row=5, column=3)
        self.white_entry.grid(row=6,
                              column=1,
                              columnspan=4,
                              sticky=N + S + E + W)
        self.gamma_entry_label_0.grid(row=7, column=1, columnspan=2)
        self.gamma_entry_label.grid(row=7, column=3)
        self.gamma_entry.grid(row=8,
                              column=1,
                              columnspan=4,
                              sticky=N + S + E + W)
        self.reset_button.grid(row=9, column=1)
        self.flip_button.grid(row=9, column=2)
        self.mirror_button.grid(row=9, column=3)
        self.reverse_color_button.grid(row=9, column=4)
        Label(control_frame, text=' ').grid(row=10, column=1, columnspan=4)

        self.picked = False

        if input:
            self.load_fits(input, input_name, input_options)

        self.canvas.get_tk_widget().pack(side=TOP)
        if show_nav:
            toolbar = NavigationToolbar2Tk(self.canvas, self.widget)
            toolbar.pack(side=BOTTOM)
        self.fits_name_label.pack()
        if show_controls:
            control_frame.pack()
            self.canvas.callbacks.connect('scroll_event', self.zoom)
            self.canvas.callbacks.connect('motion_notify_event', self.move)
            self.canvas.callbacks.connect('button_press_event', self.pick)
            self.canvas.callbacks.connect('button_release_event', self.pick)

        HOPSWidget.__init__(self, window, widget, 'FitsWindow')

    def load_fits(self, input, input_name=None, input_options=None, draw=True):
        if isinstance(input, str):
            fits = get_fits_data(input)
            input_name = os.path.split(input)[1]
        elif isinstance(input, pf.ImageHDU) or isinstance(
                input, pf.PrimaryHDU) or isinstance(input, pf.CompImageHDU):
            fits = [input]
        else:
            raise RuntimeError('Invalid input ', type(input))

        if input_name:
            if len(input_name) > 50:
                split = [
                    input_name[i:i + 50]
                    for i in range(0, len(input_name), 50)
                ]
                input_name = '\n'.join(split)

        self.fits_name.set(input_name)

        self.data = fits[0].data

        try:
            self.mean = fits[0].header[self.window.log.mean_key]
            self.std = fits[0].header[self.window.log.std_key]
        except:
            self.mean = np.median(fits[0].data)
            self.std = plc.mad(fits[0].data) * 1.5

        self.black_entry['from_'] = np.sqrt(max(0, np.min(self.data)))
        self.black_entry['to'] = np.sqrt(np.max(self.data))

        self.white_entry['from_'] = np.sqrt(max(0, np.min(self.data)))
        self.white_entry['to'] = np.sqrt(np.max(self.data))

        self.ax.cla()
        if not self.show_axes:
            self.ax.axis('off')
        self.ax.tick_params(axis='y', rotation=90)

        self.vmin.set(
            max(1, int(self.mean + self.window.log.frame_low_std * self.std)))
        self.vmax.set(
            max(1,
                int(self.mean + self.window.log.frame_upper_std * self.std)))
        self.gamma.set(0)

        if input_options:
            if input_options[0] != 'auto':
                self.vmin.set(input_options[0])
            if input_options[1] != 'auto':
                self.vmax.set(input_options[1])
            self.gamma.set(input_options[2])
            self.flip.set(input_options[3])
            self.mirror.set(input_options[4])
            self.white_sky.set(input_options[5])

        self.sqrt_vmin.set(np.sqrt(self.vmin.get()))
        self.sqrt_vmax.set(np.sqrt(self.vmax.get()))

        self.image = self.ax.imshow(self.data**(10**-self.gamma.get()),
                                    origin='lower',
                                    extent=(0, len(self.data[0]), 0,
                                            len(self.data)),
                                    cmap=Greys,
                                    vmin=self.vmin.get(),
                                    vmax=self.vmax.get())
        if self.white_sky.get():
            self.image.set_cmap(Greys)
        else:
            self.image.set_cmap(Greys_r)

        if self.flip.get():
            self.ax.set_ylim(len(self.data) + 5, 0)
        else:
            self.ax.set_ylim(0, len(self.data) + 5)

        if self.mirror.get():
            self.ax.set_xlim(len(self.data[0]) + 5, 0)
        else:
            self.ax.set_xlim(0, len(self.data[0]) + 5)

        if draw:
            self.draw()

    def reverse_color(self):
        if self.white_sky.get():
            self.image.set_cmap(Greys)
        else:
            self.image.set_cmap(Greys_r)

        self.draw()

    def flip_fov(self):
        lims = self.ax.get_ylim()
        if self.flip.get():
            self.ax.set_ylim(max(lims), min(lims))
        else:
            self.ax.set_ylim(min(lims), max(lims))
        self.draw()

    def mirror_fov(self):
        lims = self.ax.get_xlim()
        if self.mirror.get():
            self.ax.set_xlim(max(lims), min(lims))
        else:
            self.ax.set_xlim(min(lims), max(lims))
        self.draw()

    def contrast(self, event):

        if self.sqrt_vmin.get() >= self.sqrt_vmax.get():
            self.sqrt_vmin.set(self.sqrt_vmax.get() - 1)

        self.vmin.set(int(self.sqrt_vmin.get()**2))
        self.vmax.set(int(self.sqrt_vmax.get()**2))

        self.image.set_data(np.maximum(0, self.data)**(10**-self.gamma.get()))

        self.image.set_clim(self.vmin.get()**(10**-self.gamma.get()),
                            self.vmax.get()**(10**-self.gamma.get()))
        self.draw()

    def get_fov_options(self):
        return [
            self.vmin.get(),
            self.vmax.get(),
            self.gamma.get(),
            self.flip.get(),
            self.mirror.get(),
            self.white_sky.get()
        ]

    def pick(self, event):

        if isinstance(event, matplotlib.backend_bases.MouseEvent):

            if event.inaxes is None:
                pass

            elif event.name == 'button_press_event':

                self.picked = (event.xdata, event.ydata)

            elif event.name == 'button_release_event':

                self.picked = False

    def move(self, event):

        if isinstance(event, matplotlib.backend_bases.MouseEvent):

            if event.inaxes is None:
                pass

            elif event.name == 'motion_notify_event':

                try:
                    self.mouse_data.set(
                        'Mouse on: x={0:.2f}, y={1:.2f}, counts={2:.2f}'.
                        format(event.xdata, event.ydata,
                               self.data[int(event.ydata),
                                         int(event.xdata)]))
                except:
                    self.mouse_data.set(
                        'Mouse on: x={0:.2f}, y={1:.2f}, counts={2}'.format(
                            event.xdata, event.ydata, '-'))

                if self.picked:

                    dx = event.xdata - self.picked[0]
                    dy = event.ydata - self.picked[1]

                    self.ax.set_xlim(self.ax.get_xlim()[0] - dx,
                                     self.ax.get_xlim()[1] - dx)
                    self.ax.set_ylim(self.ax.get_ylim()[0] - dy,
                                     self.ax.get_ylim()[1] - dy)

                    self.draw()

    def zoom(self, event):

        if isinstance(event, matplotlib.backend_bases.MouseEvent):

            if event.inaxes is None:
                pass

            elif event.name == 'scroll_event':

                zoom_factor = 1.2
                scale_factor = 1.0

                if event.button == 'up':
                    scale_factor = 1 / zoom_factor
                elif event.button == 'down':
                    scale_factor = zoom_factor

                xdata = event.xdata
                ydata = event.ydata

                cur_xlim = self.ax.get_xlim()
                cur_ylim = self.ax.get_ylim()

                cur_xrange = (cur_xlim[1] - cur_xlim[0])
                cur_yrange = (cur_ylim[1] - cur_ylim[0])

                new_xrange = cur_xrange * scale_factor
                new_yrange = cur_yrange * scale_factor

                new_xmin = xdata - new_xrange * (xdata -
                                                 cur_xlim[0]) / cur_xrange
                new_ymin = ydata - new_yrange * (ydata -
                                                 cur_ylim[0]) / cur_yrange

                self.ax.set_xlim([new_xmin, new_xmin + new_xrange])
                self.ax.set_ylim([new_ymin, new_ymin + new_yrange])

                self.draw()

    def reset(self):

        self.ax.set_xlim(0, len(self.data[0]) + 5)
        self.ax.set_ylim(0, len(self.data) + 5)

        if self.flip.get():
            self.ax.set_ylim(self.ax.get_ylim()[1], self.ax.get_ylim()[0])

        if self.mirror.get():
            self.ax.set_xlim(self.ax.get_xlim()[1], self.ax.get_xlim()[0])

        self.vmin.set(
            max(1, int(self.mean + self.window.log.frame_low_std * self.std)))
        self.sqrt_vmin.set(np.sqrt(self.vmin.get()))
        self.vmax.set(
            max(1,
                int(self.mean + self.window.log.frame_upper_std * self.std)))
        self.sqrt_vmax.set(np.sqrt(self.vmax.get()))

        self.gamma.set(0)

        self.image.set_data(np.maximum(0, self.data)**(10**-self.gamma.get()))

        self.image.set_clim(self.vmin.get()**(10**-self.gamma.get()),
                            self.vmax.get()**(10**-self.gamma.get()))
        self.draw()

    def draw(self, update_level=1):
        self.canvas.draw()
        if update_level == 0:
            pass
        elif update_level == 1:
            self.window.update_idletasks()
        elif update_level == 2:
            self.window.update()

    def disable(self):
        for child in self.widget.winfo_children():
            try:
                child.configure(state='disable')
            except:
                pass

    def activate(self):
        for child in self.widget.winfo_children():
            try:
                child.configure(state='active')
            except:
                pass
Exemple #21
0
    def create_voices(self):
        voice_ids = ['1', '2', '3', '4']
        SCALES = OrderedDict([
                  ('pan_pos', {'min': -1, 'max': 1, 'start': 0.5, 'res': 0.001}),
                  ('volume', {'min': 0, 'max': 1, 'start': 0.666, 'res': 0.001}),
                  ('slide_duration_msecs', {'min': 0, 'max': 2000, 'start': 60, 'res': 1}),
                  ('slide_duration_prop', {'min': 0, 'max': 2, 'start': 0.666, 'res': 0.001}),
                  ('binaural_diff', {'min': 0, 'max': 66, 'start': 0.2, 'res': 0.01})
                ])

        for vid in voice_ids:
            counter = 0
            for sca in SCALES:
                name = 'voice_' + vid + '_' + sca
                setattr(self, 'min_' + name, SCALES[sca]['min'])
                setattr(self, 'max_' + name, SCALES[sca]['max'])
                this_sca = Scale(self, label=sca, orient=HORIZONTAL,
                                 from_=getattr(self, 'min_' + name),
                                 to=getattr(self, 'max_' + name),
                                 resolution=SCALES[sca]['res'])
                this_sca.enable = ('enable' in list(SCALES[sca].keys()) and
                                   SCALES[sca]['enable'] or None)
                this_sca.disable = ('disable' in list(SCALES[sca].keys()) and
                                    SCALES[sca]['disable'] or None)
                this_sca.grid(column=int(2 + int(vid)), row=counter, sticky=E + W)
                this_sca.bind("<ButtonRelease>", self.scale_handler)
                this_sca.ref = name
                counter += 1
        CHECK_BUTTONS = OrderedDict(
                 [('mute', False),
                  ('automate_binaural_diffs', True),
                  ('automate_note_duration_prop', True),
                  ('use_proportional_slide_duration', {'val': True, 'label': 'proportional slide'}),
                  ('automate_pan', True),
                  ('automate_wavetables', True)])
        for vid in voice_ids:
            counter = 0
            cb_frame = LabelFrame(self, text="Voice {0} - Automation".format(vid))
            setattr(self, 'voice_' + vid + '_cb_frame', cb_frame)
            for cb in CHECK_BUTTONS:
                options = CHECK_BUTTONS[cb]
                name = 'voice_' + vid + '_' + cb
                if isinstance(options, dict) and 'label' in list(options.keys()):
                    label = options['label']
                else:
                    label = cb[9:] if cb[:9] == 'automate_' else cb
                setattr(self, name, IntVar(
                    value=type(options) == dict and options['val'] or options))
                self.this_cb = Checkbutton(cb_frame, text=label, variable=getattr(self, name))
                self.this_cb.bind('<Button-1>', self.check_boxes_handler)
                self.this_cb.disable = None
                self.this_cb.grid(sticky=W, column=0, row=counter)
                self.this_cb.ref = name
                counter += 1
            # add trigger wavetable-button
            trigWavetableButton = Button(cb_frame, text='Next Wavetable')
            trigWavetableButton.bind('<Button-1>', self.trigger_waveform_handler)
            trigWavetableButton.ref = 'voice_' + vid + "_trigger_wavetable"
            trigWavetableButton.grid(row=counter)
            cb_frame.grid(column=int(vid) + 2, row=5, sticky=E + W + N, rowspan=8)
        for vid in voice_ids:
            generation_types = ["random", "random_harmonic", "harmonic"]
            partial_pools = ["even", "odd", "all"]
            prefix = 'voice_' + vid + '_'
            types_name = prefix + 'wavetable_generation_type'
            pools_name = prefix + 'partial_pool'
            setattr(self, types_name, StringVar())
            getattr(self, types_name).set("random")
            setattr(self, pools_name, StringVar())
            getattr(self, pools_name).set("all")
            target_frame = getattr(self, 'voice_' + vid + '_cb_frame')
            gen_typ_frame = LabelFrame(target_frame, text="type")
            gen_typ_frame.grid(row=len(target_frame.winfo_children()), sticky=W)
            for gen_t in generation_types:
                gen_t_entry = Radiobutton(gen_typ_frame, value=gen_t, text=gen_t, anchor=W,
                                          variable=getattr(self, types_name))
                gen_t_entry.bind('<ButtonRelease-1>', self.wt_handler)
                gen_t_entry.ref = types_name
                gen_t_entry.grid(row=len(gen_typ_frame.winfo_children()), sticky=W)
            pp_frame = LabelFrame(target_frame, text="harmonics")
            for pp in partial_pools:
                pp_entry = Radiobutton(pp_frame, value=pp, text=pp, anchor=W,
                                       variable=getattr(self, pools_name))
                pp_entry.bind('<ButtonRelease-1>', self.wt_handler)
                pp_entry.ref = pools_name
                pp_entry.grid(row=len(pp_frame.winfo_children()), sticky=E + W)
            this_num_partials = Scale(pp_frame, label='number of harmonics', orient=HORIZONTAL,
                                      from_=1, to=24, resolution=1)
            this_num_partials.ref = prefix + 'num_partials'
            this_num_partials.grid(column=0, row=len(pp_frame.winfo_children()), sticky=E + W)
            this_num_partials.bind("<ButtonRelease>", self.scale_handler)
            pp_frame.grid(row=len(target_frame.winfo_children()), sticky=E + W)
Exemple #22
0
class Application(Frame):
    def __init__(self, master=None):
        Frame.__init__(self, master)
        self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        self.send_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        self.sock.bind((host, port))
        self.grid()
        self.columnconfigure(0, minsize=100)
        self.columnconfigure(1, minsize=200)
        self.columnconfigure(2, minsize=200)
        self.columnconfigure(3, minsize=150)
        self.columnconfigure(4, minsize=150)
        self.columnconfigure(5, minsize=150)
        self.columnconfigure(6, minsize=150)
        self.create_widgets()
        self.settables = self.assemble_settables()
        self.gui_logger = logging.getLogger('gui')
        self.request_update()

    def create_widgets(self):
        self.create_monitor()
        self.create_check_buttons()
        self.create_ranges()
        self.create_scales()
        self.create_radio_buttons()
        self.create_voices()
        self.quitButton = Button(self, text='Quit', command=self.quit)
        self.quitButton.grid(columnspan=7, sticky=E + W)

    def assemble_settables(self):
        settables = self.winfo_children()
        for w in settables:
            settables += w.winfo_children()
        return [w for w in settables if w.__class__.__name__ in ['Scale', 'Checkbutton']]

    def create_radio_buttons(self):
        # Scale related
        entries = ['DIATONIC', 'HARMONIC', 'MELODIC', 'PENTATONIC', 'PENTA_MINOR',
                   'GREEK_CHROMATIC', 'GREEK_ENHARMONIC']
        self.scale = StringVar()
        self.scale.set('DIATONIC')
        self.rb_frame = Frame(self)
        for e in entries:
            rb = Radiobutton(self.rb_frame, value=e, text=e, anchor=W,
                             command=self.send_scale, variable=self.scale)
            rb.grid(row=len(self.rb_frame.winfo_children()), sticky=W)
        self.rb_frame.grid(column=1, row=len(self.grid_slaves(column=1)), rowspan=3)

    def create_monitor(self):
        self.monitor_frame = LabelFrame(self, text="Monitor and Transport")
        this_cycle = Scale(self.monitor_frame, label='cycle_pos', orient=HORIZONTAL,
                           from_=1, to=16, resolution=1)
        this_cycle.disable, this_cycle.enable = (None, None)
        this_cycle.ref = 'cycle_pos'
        this_cycle.grid(column=0, row=0, sticky=E + W)
        self.updateButton = Button(self.monitor_frame,
                                   text='Reload all Settings',
                                   command=self.request_update)
        self.updateButton.grid(row=1, sticky=E + W)
        self.ForceCaesuraButton = Button(self.monitor_frame,
                                         text='Force Caesura',
                                         command=self.force_caesura)
        self.ForceCaesuraButton.grid(row=2, sticky=E + W)
        self.saveBehaviourButton = Button(self.monitor_frame,
                                          text='Save current behaviour',
                                          command=self.request_saving_behaviour)
        self.saveBehaviourButton.grid(row=3, sticky=E + W)
        self.saveBehaviourNameEntry = Entry(self.monitor_frame)
        self.saveBehaviourNameEntry.grid(row=4, sticky=E + W)
        self.saveBehaviourNameEntry.bind('<KeyRelease>', self.request_saving_behaviour)
        self.selected_behaviour = StringVar()
        self.selected_behaviour.trace('w', self.new_behaviour_chosen)
        self.savedBehavioursMenu = OptionMenu(self.monitor_frame,
                                              self.selected_behaviour, None,)
        self.savedBehavioursMenu.grid(row=5, sticky=E + W)
        self.monitor_frame.grid(column=0, row=10, sticky=E + W)

    def request_update(self):
        self.send({'sys': 'update'})

    def request_saving_behaviour(self, event=None):
        """callback for save behaviour button and textentry"""
        if event and event.widget == self.saveBehaviourNameEntry:
            if event.keysym == 'Return':
                name = self.saveBehaviourNameEntry.get()
                self.saveBehaviourNameEntry.delete(0, len(name))
            else:
                return
        else:  # button was pressed
            name = self.saveBehaviourNameEntry.get()
        if name:
            self.send({'sys': ['save_behaviour', name]})

    def force_caesura(self):
        self.send({'force_caesura': True})

    def create_voices(self):
        voice_ids = ['1', '2', '3', '4']
        SCALES = OrderedDict([
                  ('pan_pos', {'min': -1, 'max': 1, 'start': 0.5, 'res': 0.001}),
                  ('volume', {'min': 0, 'max': 1, 'start': 0.666, 'res': 0.001}),
                  ('slide_duration_msecs', {'min': 0, 'max': 2000, 'start': 60, 'res': 1}),
                  ('slide_duration_prop', {'min': 0, 'max': 2, 'start': 0.666, 'res': 0.001}),
                  ('binaural_diff', {'min': 0, 'max': 66, 'start': 0.2, 'res': 0.01})
                ])

        for vid in voice_ids:
            counter = 0
            for sca in SCALES:
                name = 'voice_' + vid + '_' + sca
                setattr(self, 'min_' + name, SCALES[sca]['min'])
                setattr(self, 'max_' + name, SCALES[sca]['max'])
                this_sca = Scale(self, label=sca, orient=HORIZONTAL,
                                 from_=getattr(self, 'min_' + name),
                                 to=getattr(self, 'max_' + name),
                                 resolution=SCALES[sca]['res'])
                this_sca.enable = ('enable' in list(SCALES[sca].keys()) and
                                   SCALES[sca]['enable'] or None)
                this_sca.disable = ('disable' in list(SCALES[sca].keys()) and
                                    SCALES[sca]['disable'] or None)
                this_sca.grid(column=int(2 + int(vid)), row=counter, sticky=E + W)
                this_sca.bind("<ButtonRelease>", self.scale_handler)
                this_sca.ref = name
                counter += 1
        CHECK_BUTTONS = OrderedDict(
                 [('mute', False),
                  ('automate_binaural_diffs', True),
                  ('automate_note_duration_prop', True),
                  ('use_proportional_slide_duration', {'val': True, 'label': 'proportional slide'}),
                  ('automate_pan', True),
                  ('automate_wavetables', True)])
        for vid in voice_ids:
            counter = 0
            cb_frame = LabelFrame(self, text="Voice {0} - Automation".format(vid))
            setattr(self, 'voice_' + vid + '_cb_frame', cb_frame)
            for cb in CHECK_BUTTONS:
                options = CHECK_BUTTONS[cb]
                name = 'voice_' + vid + '_' + cb
                if isinstance(options, dict) and 'label' in list(options.keys()):
                    label = options['label']
                else:
                    label = cb[9:] if cb[:9] == 'automate_' else cb
                setattr(self, name, IntVar(
                    value=type(options) == dict and options['val'] or options))
                self.this_cb = Checkbutton(cb_frame, text=label, variable=getattr(self, name))
                self.this_cb.bind('<Button-1>', self.check_boxes_handler)
                self.this_cb.disable = None
                self.this_cb.grid(sticky=W, column=0, row=counter)
                self.this_cb.ref = name
                counter += 1
            # add trigger wavetable-button
            trigWavetableButton = Button(cb_frame, text='Next Wavetable')
            trigWavetableButton.bind('<Button-1>', self.trigger_waveform_handler)
            trigWavetableButton.ref = 'voice_' + vid + "_trigger_wavetable"
            trigWavetableButton.grid(row=counter)
            cb_frame.grid(column=int(vid) + 2, row=5, sticky=E + W + N, rowspan=8)
        for vid in voice_ids:
            generation_types = ["random", "random_harmonic", "harmonic"]
            partial_pools = ["even", "odd", "all"]
            prefix = 'voice_' + vid + '_'
            types_name = prefix + 'wavetable_generation_type'
            pools_name = prefix + 'partial_pool'
            setattr(self, types_name, StringVar())
            getattr(self, types_name).set("random")
            setattr(self, pools_name, StringVar())
            getattr(self, pools_name).set("all")
            target_frame = getattr(self, 'voice_' + vid + '_cb_frame')
            gen_typ_frame = LabelFrame(target_frame, text="type")
            gen_typ_frame.grid(row=len(target_frame.winfo_children()), sticky=W)
            for gen_t in generation_types:
                gen_t_entry = Radiobutton(gen_typ_frame, value=gen_t, text=gen_t, anchor=W,
                                          variable=getattr(self, types_name))
                gen_t_entry.bind('<ButtonRelease-1>', self.wt_handler)
                gen_t_entry.ref = types_name
                gen_t_entry.grid(row=len(gen_typ_frame.winfo_children()), sticky=W)
            pp_frame = LabelFrame(target_frame, text="harmonics")
            for pp in partial_pools:
                pp_entry = Radiobutton(pp_frame, value=pp, text=pp, anchor=W,
                                       variable=getattr(self, pools_name))
                pp_entry.bind('<ButtonRelease-1>', self.wt_handler)
                pp_entry.ref = pools_name
                pp_entry.grid(row=len(pp_frame.winfo_children()), sticky=E + W)
            this_num_partials = Scale(pp_frame, label='number of harmonics', orient=HORIZONTAL,
                                      from_=1, to=24, resolution=1)
            this_num_partials.ref = prefix + 'num_partials'
            this_num_partials.grid(column=0, row=len(pp_frame.winfo_children()), sticky=E + W)
            this_num_partials.bind("<ButtonRelease>", self.scale_handler)
            pp_frame.grid(row=len(target_frame.winfo_children()), sticky=E + W)

    def wt_handler(self, event):
        print(event.widget.tk)
        ref = event.widget.ref
        self.send({ref: getattr(self, ref).get()})

    def create_check_buttons(self):
        self.cb_frame = LabelFrame(self, text="Global Settings")
        for cb in CHECK_BUTTONS:
            label = cb
            target_parent = self.cb_frame
            if isinstance(CHECK_BUTTONS[cb], dict) and 'sub_frame' in list(CHECK_BUTTONS[cb].keys()):
                target_parent = getattr(self, CHECK_BUTTONS[cb]['sub_frame'])
            setattr(self, cb, IntVar(value=type(CHECK_BUTTONS[cb]) == dict and
                                     CHECK_BUTTONS[cb]['val'] or
                                     CHECK_BUTTONS[cb]))
            self.this_cb = Checkbutton(target_parent, text=label, variable=getattr(self, cb))
            self.this_cb.bind('<Button-1>', self.check_boxes_handler)
            self.this_cb.disable = (type(CHECK_BUTTONS[cb]) == dict and
                                    'disable' in list(CHECK_BUTTONS[cb].keys()))
            self.this_cb.grid(sticky=W, column=0, row=len(target_parent.winfo_children()))
            self.this_cb.ref = cb
        for but in GLOBAL_BUTTONS:
            label = but
            ele = GLOBAL_BUTTONS[but]
            this_but = Button(self.cb_frame, text=but)
            this_but.bind('<ButtonRelease-1>', getattr(self, ele['handler']))
            this_but.ref = but
            this_but.grid(sticky=W, column=0, row=len(self.cb_frame.winfo_children()))
        self.cb_frame.grid(column=0, row=0, rowspan=10, sticky=N)

    def new_behaviour_chosen(self, a, b, c):
        self.send({'sys': ['change_behaviour', self.selected_behaviour.get()]})

    def set_value(self, name, val):
        '''sets a widget to the specified value

        various different widget types need custom setting functionality'''

        direct = ['scale', 'wavetable_generation_type', 'partial_pool']
        if [x for x in direct if match("(voice_\d_|)" + x, name)]:
            self.gui_logger.info("setting: '{0}' to '{1}' in GUI".format(name, val))
            getattr(self, name).set(val)
            return
        if name == 'saved_behaviours' and len(val):
            self.savedBehavioursMenu.destroy()
            self.savedBehavioursMenu = OptionMenu(self.monitor_frame,
                                                  self.selected_behaviour, *sorted(val))
            self.savedBehavioursMenu.grid(row=5, sticky=E + W)
            return
        for w in self.settables:
            typ = w.__class__.__name__
            if w.ref == name:
                # print "setting '{0}' of type: '{1}' to: {2}".format(name, typ, val)
                if typ == 'Scale':
                    w.set(val)
                elif typ == "Checkbutton":
                    w.select() if val else w.deselect()

    def check_boxes_handler(self, event):
        '''handles checkbox events.

        shows and hides gui elements according to their enable/disable fields'''
        # print event.__dict__
        # print event.widget.__dict__
        ref = event.widget.ref
        val = not getattr(self, ref).get()  # because is read before the var is changed
        self.send({ref: val})
        # print ref, val
        # handle gui elements
        # enable/disable functionality temporarily(?) commented on:
        # Wed Aug 17 09:39:54 CEST 2011
#        if event.widget.disable:
#            for w in self.children.values():
#
#                # this try clause is for debugging, remove when stable
#                try:
#                    w.ref
#                    #print w.ref
#                except:
#                    pass
#                if (w.__class__.__name__ == 'Scale' and
#                    (w.disable or w.enable)):
#                    if w.disable == ref:
#                        if val:
#                            w.grid()
#                        else:
#                            w.grid_remove()
#                    elif w.enable == ref:
#                        if val:
#                            w.grid_remove()
#                        else:
#                            w.grid()
#                    #print w.disable, w.enable

    def create_scales(self):
        counter = 0
        for sca in SCALES:
            label = SCALES[sca]['label'] if 'label' in list(SCALES[sca].keys()) else sca
            setattr(self, 'min_' + sca, SCALES[sca]['min'])
            setattr(self, 'max_' + sca, SCALES[sca]['max'])
            self.this_scale = Scale(self, label=label, orient=HORIZONTAL,
                                    from_=getattr(self, 'min_' + sca),
                                    to=getattr(self, 'max_' + sca),
                                    resolution=SCALES[sca]['res'])
            self.this_scale.set(SCALES[sca]['start'])
            self.this_scale.enable = ('enable' in list(SCALES[sca].keys()) and
                                      SCALES[sca]['enable'] or None)
            self.this_scale.disable = ('disable' in list(SCALES[sca].keys()) and
                                       SCALES[sca]['disable'] or None)
            if 'pos' in list(SCALES[sca].keys()):
                pos = SCALES[sca]['pos']
                col = pos['c']
                row = pos['r']
            else:
                row = counter
                col = 1
                counter += 1
            self.this_scale.grid(column=col, row=row, sticky=E + W)
            self.this_scale.ref = sca
            self.this_scale.bind("<ButtonRelease>", self.scale_handler)

    def scale_handler(self, event):
        self.send({event.widget.ref: event.widget.get()})
        self.gui_logger.info("handling scale: {0}, with new value: {1}".format(
                  event.widget.ref, event.widget.get()))

    def trigger_waveform_handler(self, event):
        self.send({event.widget.ref: True})
        # print event.widget.ref, "- triggering wavetable"

    def send_scale(self):
        do = {'scale': self.scale.get()}
        self.send(do)

    def send(self, msg):
        self.gui_logger.info("sending: {0}".format(msg))
        self.send_sock.sendto(json.dumps(msg), (remote_host, send_port))

    def create_ranges(self):
        counter = 0
        for ran in RANGES:
            setattr(self, 'min_' + ran, RANGES[ran]['min'])
            setattr(self, 'max_' + ran, RANGES[ran]['max'])
            self.this_min_scale = Scale(self, label='min ' + ran, orient=HORIZONTAL,
                                        from_=getattr(self, 'min_' + ran),
                                        to=getattr(self, 'max_' + ran),
                                        resolution=RANGES[ran]['res'])
            self.this_max_scale = Scale(self, label='max ' + ran, orient=HORIZONTAL,
                                        from_=getattr(self, 'min_' + ran),
                                        to=getattr(self, 'max_' + ran),
                                        resolution=RANGES[ran]['res'])
            self.this_min_scale.set(RANGES[ran]['min_start'])
            self.this_max_scale.set(RANGES[ran]['max_start'])
            self.this_min_scale.enable = ('enable' in list(RANGES[ran].keys()) and
                                          RANGES[ran]['enable'] or None)
            self.this_min_scale.disable = ('disable' in list(RANGES[ran].keys()) and
                                           RANGES[ran]['disable'] or None)
            self.this_max_scale.enable = ('enable' in list(RANGES[ran].keys()) and
                                          RANGES[ran]['enable'] or None)
            self.this_max_scale.disable = ('disable' in list(RANGES[ran].keys()) and
                                           RANGES[ran]['disable'] or None)
            self.this_min_scale.grid(column=2, row=counter, sticky=E + W)
            self.this_max_scale.grid(column=2, row=counter + 1, sticky=E + W)
            self.this_min_scale.ref = 'min_' + ran
            self.this_max_scale.ref = 'max_' + ran
            self.this_min_scale.bind("<ButtonRelease>", self.scale_handler)
            self.this_max_scale.bind("<ButtonRelease>", self.scale_handler)
            counter += 2

    def socket_read_handler(self, file, mask):
        data_object = json.loads(file.recv(1024))
        do = list(data_object.items())[0]
        self.set_value(do[0], do[1])
Exemple #23
0
    def __init__(self,parent,base_fl,lecteur):
        self.police_titre=('Times', -20, 'bold')
        self.police_nombre=('Arial', -20, 'bold')
        self.parent=parent
        self.bfl=base_fl
        self.lecteur=lecteur
        self.mot1=""
        self.mot2=""
        self.titre_colonne1=Label(parent,text="Base de données",font=self.police_titre)
        self.titre_colonne1.grid(column=0,row=0)
        self.titre_colonne2=Entry(parent,width=15,font=self.police_titre)
        self.titre_colonne2.grid(column=1,row=0)
        self.titre_colonne2.insert(END,self.mot1)
        self.titre_colonne3=Entry(parent,width=15,font=self.police_titre)
        self.titre_colonne3.grid(column=2,row=0)
        self.titre_colonne3.insert(END,self.mot2)
        self.titre_colonne3.bind("<Return>",self.actualise_mot2)
        self.titre_colonne4=Label(parent,text="Poids de chaque base",font=self.police_titre)
        self.titre_colonne4.grid(column=3,row=0)
        self.titre_ligne=[]
        for k in range(self.bfl.n_base):
            tl=Label(parent,font=self.police_titre,text=self.bfl.bddl_brute[k].nom)
            tl.grid(column=0,row=k+1)
            tl.bind("<Enter>", lambda event, obj=self.bfl.bddl_brute[k]: self.actualise_info(event, obj))
            self.titre_ligne.append(tl)
        self.titre_derniere_ligne=Label(parent,font=self.police_titre,text="Cumul:")
        self.titre_derniere_ligne.grid(column=0,row=k+2)
        self.curseur=[]
        def enter(event,c):
            c.active=True
        def leave(event,c):
            c.active=False
        for k in range(self.bfl.n_base):
            c=Scale(parent, orient='horizontal', resolution=1/10**NB_DECIMALES,from_=0, to=1,
                    command=self.actualise_cumul)
            c.grid(column=3,row=k+1)
            #Remettre cette ligne pour une répartition équitable des lectures
            #c.set(1.0/self.bfl.n_base)
            #A CHANGER: valeurs initales des poids de chaque base
            dict_params={"Blog":0.21,"Twitter":0.21,"Journaux":0.04,"Livres":0.12,"Films":0.42}
            c.set(dict_params[self.bfl.bddl_brute[k].nom])
            c.val_mem=c.get()
            c.active=False
            c.bind("<Enter>", lambda event, obj=c: enter(event, obj))
            c.bind("<Leave>", lambda event, obj=c: leave(event, obj))
            self.curseur.append(c)
        self.cumul=Label(parent,font=self.police_nombre)
        self.cumul.grid(column=3,row=k+2)

        self.freqp1=Label(parent,font=self.police_nombre)
        self.freqp1.grid(column=1,row=k+2)

        self.freqp2=Label(parent,font=self.police_nombre)
        self.freqp2.grid(column=2,row=k+2)

        
        self.freq1=[]
        for k in range(self.bfl.n_base):
            f=Label(parent,font=self.police_nombre,text="#")
            f.grid(column=1,row=k+1)
            self.freq1.append(f)
            
        self.freq2=[]
        for k in range(self.bfl.n_base):
            f=Label(parent,font=self.police_nombre,text="#")
            f.grid(column=2,row=k+1)
            self.freq2.append(f)
        self.modifie_mot1("")
        self.modifie_mot2("")