def createControllerWindow(self):
		if not self.controller is None:
			self.controller.focus_force()
			return

		window = tk.Toplevel(self.root)
		window.title('Simple Switch Controller')
		window.geometry("%dx%d%+d%+d" % (600, 300, 250, 125))

		ttk.Button(window, text='A', command=lambda: UnitCommand.A().start(self.ser)).grid(row=5, column=11)
		ttk.Button(window, text='B', command=lambda: UnitCommand.B().start(self.ser)).grid(row=6, column=10)
		ttk.Button(window, text='X', command=lambda: UnitCommand.X().start(self.ser)).grid(row=4, column=10)
		ttk.Button(window, text='Y', command=lambda: UnitCommand.Y().start(self.ser)).grid(row=5, column=9)
		ttk.Button(window, text='L', command=lambda: UnitCommand.L().start(self.ser)).grid(row=1, column=1)
		ttk.Button(window, text='R', command=lambda: UnitCommand.R().start(self.ser)).grid(row=1, column=10)
		ttk.Button(window, text='ZL', command=lambda: UnitCommand.ZL().start(self.ser)).grid(row=0, column=1)
		ttk.Button(window, text='ZR', command=lambda: UnitCommand.ZR().start(self.ser)).grid(row=0, column=10)
		ttk.Button(window, text='MINUS', command=lambda: UnitCommand.MINUS().start(self.ser)).grid(row=3, column=3)
		ttk.Button(window, text='PLUS', command=lambda: UnitCommand.PLUS().start(self.ser)).grid(row=3, column=7)
		ttk.Button(window, text='LCLICK', command=lambda: UnitCommand.LCLICK().start(self.ser)).grid(row=4, column=1)
		ttk.Button(window, text='RCLICK', command=lambda: UnitCommand.RCLICK().start(self.ser)).grid(row=8, column=10)
		ttk.Button(window, text='HOME', command=lambda: UnitCommand.HOME().start(self.ser)).grid(row=4, column=6)
		ttk.Button(window, text='CAP', command=lambda: UnitCommand.CAPTURE().start(self.ser)).grid(row=4, column=4)
		ttk.Button(window, text='UP', command=lambda: self.unit_dir_commands[0].start(self.ser)).grid(row=6, column=1)
		ttk.Button(window, text='RIGHT', command=lambda: self.unit_dir_commands[1].start(self.ser)).grid(row=7, column=2)
		ttk.Button(window, text='DOWN', command=lambda: self.unit_dir_commands[2].start(self.ser)).grid(row=8, column=1)
		ttk.Button(window, text='LEFT', command=lambda: self.unit_dir_commands[3].start(self.ser)).grid(row=7, column=0)

		for child in window.winfo_children():
			child['width'] = 8

		ttk.Label(window, text='NOTE:').grid(row=9, column=0, columnspan=8, sticky='w', padx=10, pady=(20, 0))
		ttk.Label(window, text='Direction buttons are toggle switch.').grid(row=10, column=0, columnspan=8, sticky='w', padx=10, pady=3)
		ttk.Label(window, text='Key Arrangements are based on Switch Pro. Controller.').grid(row=11, column=0, columnspan=8, sticky='w', padx=10, pady=3)
		
		# enable Keyboard as controller
		self.keyboard = SwitchKeyboardController(self.keyPress)
		self.keyboard.listen()

		# bind focus
		window.bind("<FocusIn>", self.onFocusInController)
		window.bind("<FocusOut>", self.onFocusOutController)
		self.root.bind("<FocusIn>", self.onFocusInController)
		self.root.bind("<FocusOut>", self.onFocusOutController)

		window.protocol("WM_DELETE_WINDOW", self.closingController)
		self.controller = window
Exemple #2
0
    def createControllerWindow(self):
        if not self.controller is None:
            self.controller.focus_force()
            return

        window = ControllerGUI(self.root, self.ser)

        # enable Keyboard as controller
        if self.keyboard is None:
            self.keyboard = SwitchKeyboardController(self.keyPress)
            self.keyboard.listen()

        # bind focus
        if os.name == 'nt':
            window.bind("<FocusIn>", self.onFocusInController)
            window.bind("<FocusOut>", self.onFocusOutController)
            self.root.bind("<FocusIn>", self.onFocusInController)
            self.root.bind("<FocusOut>", self.onFocusOutController)

        window.protocol("WM_DELETE_WINDOW", self.closingController)
        self.controller = window
Exemple #3
0
	def activateKeyboard(self):
		if self.settings.is_use_keyboard.get() == True:
			# enable Keyboard as controller
			if self.keyboard is None:
				self.keyboard = SwitchKeyboardController(self.keyPress)
				self.keyboard.listen()
		
			# bind focus
			if os.name == 'nt':
				self.root.bind("<FocusIn>", self.onFocusInController)
				self.root.bind("<FocusOut>", self.onFocusOutController)

		else:
			if os.name == 'nt': # NOTE: Idk why but self.keyboard.stop() makes crash on Linux
				if not self.keyboard is None:
					# stop listening to keyboard events
					self.keyboard.stop()
					self.keyboard = None

				self.root.bind("<FocusIn>", lambda _: None)
				self.root.bind("<FocusOut>", lambda _: None)
Exemple #4
0
 def onFocusInController(self, event):
     # enable Keyboard as controller
     if self.keyboard is None:
         self.keyboard = SwitchKeyboardController(self.keyPress)
         self.keyboard.listen()
Exemple #5
0
class GUI:
    def __init__(self):
        # NOTE: I'm gonna rewrite this function because this is not a good coding style

        self.root = tk.Tk()
        self.root.title('Pokemon Controller')
        self.frame1 = ttk.Frame(self.root,
                                height=720,
                                width=1280,
                                relief='flat',
                                borderwidth=5)
        self.controller = None
        self.keyPress = None
        self.keyboard = None

        # label frames
        self.lf = ttk.Labelframe(self.frame1, text='Command', padding=5)
        self.serial_lf = ttk.Labelframe(self.frame1,
                                        text='Serial Settings',
                                        padding=5)
        self.camera_lf = ttk.Labelframe(self.frame1, text='Camera', padding=5)
        self.control_lf = ttk.Labelframe(self.frame1,
                                         text='Controller',
                                         padding=5)

        # frames
        self.camera_f1 = ttk.Frame(self.camera_lf, relief='flat')
        self.camera_f2 = ttk.Frame(self.camera_lf, relief='flat')

        # log area
        self.logArea = MyScrolledText(self.frame1, width=70)
        self.logArea.write = self.write
        sys.stdout = self.logArea

        # load settings file
        self.loadSettings()

        # camera settings
        self.label1 = ttk.Label(self.camera_f1, text='Camera ID:')
        self.cameraID = tk.IntVar()
        self.cameraID.set(int(self.settings['camera_id']))
        if os.name == 'nt':
            import clr
            clr.AddReference("../DirectShowLib/DirectShowLib-2005")
            from DirectShowLib import DsDevice, FilterCategory

            # Get names of detected camera devices
            captureDevices = DsDevice.GetDevicesOfCat(
                FilterCategory.VideoInputDevice)
            self.camera_dic = {
                device.Name: cam_id
                for cam_id, device in enumerate(captureDevices)
            }
            dev_num = len(self.camera_dic)

            if self.cameraID.get() > dev_num - 1:
                print('inappropriate camera ID! -> set to 0')
                self.cameraID.set(0)
                if dev_num == 0: print('No camera devices can be found.')

            # locate a combobox instead of an entry
            self.cameraName = tk.StringVar()
            self.label1['text'] = 'Camera: '
            self.camera_cb = ttk.Combobox(self.camera_f1,
                                          width=30,
                                          textvariable=self.cameraName,
                                          state="readonly")
            self.camera_cb['values'] = [
                device for device in self.camera_dic.keys()
            ]
            self.camera_cb.bind('<<ComboboxSelected>>', self.assignCamera)
            if not dev_num == 0:
                self.camera_cb.current(self.cameraID.get())
        else:
            self.entry1 = ttk.Entry(self.camera_f1,
                                    width=5,
                                    textvariable=self.cameraID)

        # open up a camera
        self.camera = Camera()
        self.openCamera()

        if os.name == 'nt':
            import clr
            clr.AddReference("../DirectShowLib/DirectShowLib-2005")
            from DirectShowLib import DsDevice, FilterCategory
        else:
            pass

        self.showPreview = tk.BooleanVar()
        self.cb1 = ttk.Checkbutton(self.camera_f1,
                                   padding=5,
                                   text='Show Realtime',
                                   onvalue=True,
                                   offvalue=False,
                                   variable=self.showPreview)
        self.showPreview.set(True)

        self.label2 = ttk.Label(self.serial_lf, text='COM Port:')
        self.comPort = tk.IntVar()
        self.comPort.set(int(self.settings['com_port']))
        self.entry2 = ttk.Entry(self.serial_lf,
                                width=5,
                                textvariable=self.comPort)
        self.preview = ttk.Label(self.camera_lf)

        # activate serial communication
        self.ser = Sender.Sender()
        self.activateSerial()

        self.v1 = tk.StringVar(value='Python')
        self.rb1 = ttk.Radiobutton(self.lf,
                                   text='Mcu',
                                   value='Mcu',
                                   variable=self.v1,
                                   command=self.setCommandCmbbox)
        self.rb2 = ttk.Radiobutton(self.lf,
                                   text='Python',
                                   value='Python',
                                   variable=self.v1,
                                   command=self.setCommandCmbbox)
        self.rb3 = ttk.Radiobutton(self.lf,
                                   text='Utility',
                                   value='Utility',
                                   variable=self.v1,
                                   command=self.setCommandCmbbox)

        self.reloadButton = ttk.Button(self.camera_f1,
                                       text='Reload Cam',
                                       command=self.openCamera)
        self.reloadComPort = ttk.Button(self.serial_lf,
                                        text='Reload Port',
                                        command=self.activateSerial)
        self.startButton = ttk.Button(self.lf,
                                      text='Start',
                                      command=self.startPlay)
        self.captureButton = ttk.Button(self.camera_f1,
                                        text='Capture',
                                        command=self.saveCapture)

        self.showSerial = tk.BooleanVar()
        self.showSerial.set(False)
        self.cb_show_ser = ttk.Checkbutton(
            self.serial_lf,
            padding=5,
            text='Show Serial',
            onvalue=True,
            offvalue=False,
            variable=self.showSerial,
            command=lambda: self.ser.setIsShowSerial(self.showSerial.get()))

        # simple controller
        self.simpleConButton = ttk.Button(self.control_lf,
                                          text='Controller',
                                          command=self.createControllerWindow)

        # fps
        self.label3 = ttk.Label(self.camera_f2, text='FPS:')
        self.fps = tk.StringVar()
        self.fps.set(str(self.settings['fps']))
        self.fps_cb = ttk.Combobox(self.camera_f2,
                                   textvariable=self.fps,
                                   width=2,
                                   state="readonly")
        self.fps_cb['values'] = [45, 30, 15]
        self.fps_cb.bind('<<ComboboxSelected>>', self.applyFps)
        self.fps_cb.current(self.fps_cb['values'].index(self.fps.get()))

        # special commands registration
        self.unit_dir_commands = [
            UnitCommand.UP(),
            UnitCommand.RIGHT(),
            UnitCommand.DOWN(),
            UnitCommand.LEFT(),
        ]

        self.mcu_name = tk.StringVar()
        self.mcu_cb = ttk.Combobox(self.lf,
                                   textvariable=self.mcu_name,
                                   state="readonly")
        self.mcu_cb['values'] = [name for name in McuCommand.commands.keys()]
        self.mcu_cb.bind('<<ComboboxSelected>>', self.assignMcuCommand)
        self.mcu_cb.current(0)

        self.py_name = tk.StringVar()
        self.py_cb = ttk.Combobox(self.lf,
                                  textvariable=self.py_name,
                                  state="readonly")
        self.py_cb['values'] = [name for name in PythonCommand.commands.keys()]
        self.py_cb.bind('<<ComboboxSelected>>', self.assignPythonCommand)
        self.py_cb.current(0)
        self.assignCommand()

        self.util_name = tk.StringVar()
        self.util_cb = ttk.Combobox(self.lf,
                                    textvariable=self.util_name,
                                    state="readonly")
        self.util_cb['values'] = [name for name in PythonCommand.utils.keys()]
        self.util_cb.bind('<<ComboboxSelected>>', self.assignUtilCommand)
        self.util_cb.current(0)

        self.partition1 = ttk.Label(self.camera_f1, text=' / ')
        self.partition2 = ttk.Label(self.camera_f1, text=' / ')

        self.frame1.grid(row=0, column=0, sticky='nwse')
        self.logArea.grid(row=0, column=7, rowspan=5, sticky='nwse')

        # camera
        self.camera_lf.grid(row=0, column=0, columnspan=3, sticky='nw')
        self.camera_f1.grid(row=0, column=0, sticky='nw')
        self.camera_f2.grid(row=2, column=0, sticky='nw', pady=(5, 0))
        self.preview.grid(row=1, column=0, columnspan=7, sticky='nw')
        self.label1.pack(side=tk.LEFT)
        if os.name == 'nt':
            self.camera_cb.pack(side=tk.LEFT, padx=5)
        else:
            self.entry1.pack(side=tk.LEFT, padx=5)
        self.reloadButton.pack(side=tk.LEFT)
        self.partition1.pack(side=tk.LEFT, padx=10)
        self.cb1.pack(side=tk.LEFT)
        self.partition2.pack(side=tk.LEFT, padx=10)
        self.captureButton.pack(side=tk.LEFT)
        self.label3.pack(side=tk.LEFT)
        self.fps_cb.pack(side=tk.LEFT, padx=5)

        # serial
        self.serial_lf.grid(row=1, column=0, sticky='nw')
        self.label2.grid(row=0, column=0, sticky='w')
        self.entry2.grid(row=0, column=1, sticky='w')
        self.reloadComPort.grid(row=0, column=2, padx=(5, 0), sticky='w')
        self.cb_show_ser.grid(row=1, column=0)

        # controller simulator
        self.control_lf.grid(row=1, column=1, sticky='ne')
        self.simpleConButton.grid(row=0, column=0)

        # commands selection
        self.lf.grid(row=1, column=2, rowspan=3, sticky='ne')
        self.rb1.grid(row=0, column=0, sticky='w')
        self.rb2.grid(row=1, column=0, sticky='w')
        self.rb3.grid(row=2, column=0, sticky='w')
        self.setCommandCmbbox()
        self.startButton.grid(row=3, column=2, sticky='e')

        for child in self.frame1.winfo_children():
            if not type(child) is ttk.Combobox:
                child.grid_configure(padx=5, pady=5)

        self.root.protocol("WM_DELETE_WINDOW", self.exit)
        self.doProcess()

    def openCamera(self):
        self.camera.openCamera(self.cameraID.get())
        self.settings['camera_id'] = self.cameraID.get()

    def assignCamera(self, event):
        if os.name == 'nt':
            self.cameraID.set(self.camera_dic[self.cameraName.get()])

    def loadSettings(self):
        self.settings = None
        if os.path.isfile(SETTING_PATH):
            self.settings = json.load(open(SETTING_PATH, 'r'))
        else:
            default = {"camera_id": 0, "com_port": 1, "fps": "45"}
            json.dump(default, open(SETTING_PATH, 'w'), indent=4)
            print('default settings file has been created')
            self.loadSettings()

    def startPlay(self):
        if self.cur_command is None:
            print('No commands have been assinged yet.')

        # set and init selected command
        self.assignCommand()

        print(self.startButton["text"] + ' ' + self.cur_command.getName())
        self.cur_command.start(self.ser, self.stopPlayPost)

        self.startButton["text"] = "Stop"
        self.startButton["command"] = self.stopPlay

    def assignCommand(self):
        if self.v1.get() == 'Mcu':
            name = self.mcu_name.get()
            self.cur_command = McuCommand.commands[name](name)
        elif self.v1.get() == 'Python' or self.v1.get() == 'Utility':
            name = self.py_name.get() if self.v1.get(
            ) == 'Python' else self.util_name.get()
            cmd_class = PythonCommand.commands[name] if self.v1.get(
            ) == 'Python' else PythonCommand.utils[name]

            if issubclass(cmd_class, PythonCommand.ImageProcPythonCommand):
                self.cur_command = cmd_class(name, self.camera)
            else:
                self.cur_command = cmd_class(name)

    def stopPlay(self):
        print(self.startButton["text"] + ' ' + self.cur_command.getName())
        self.startButton["state"] = "disabled"
        self.cur_command.end(self.ser)

    def stopPlayPost(self):
        self.startButton["text"] = "Start"
        self.startButton["command"] = self.startPlay
        self.startButton["state"] = "normal"

    def exit(self):
        if self.ser.isOpened():
            self.ser.closeSerial()
            print("serial disconnected")

        # stop listening to keyboard events
        if not self.keyboard is None:
            self.keyboard.stop()
            self.keyboard = None

        # save settings
        json.dump(self.settings, open(SETTING_PATH, 'w'), indent=4)

        self.camera.destroy()
        cv2.destroyAllWindows()
        self.root.destroy()

    def saveCapture(self):
        self.camera.saveCapture()

    def applyFps(self, event):
        print('changed FPS to: ' + self.fps.get() + ' [fps]')
        self.settings['fps'] = self.fps.get()

    def assignMcuCommand(self, event):
        print('changed to mcu command: ' + self.mcu_name.get())

    def assignPythonCommand(self, event):
        print('changed to python command: ' + self.py_name.get())

    def assignUtilCommand(self, event):
        print('changed to utility command: ' + self.util_name.get())

    def setCommandCmbbox(self):
        if self.v1.get() == 'Mcu':
            self.mcu_cb.grid(row=1, column=1, columnspan=2, padx=(10, 0))
            self.py_cb.grid_remove()
            self.util_cb.grid_remove()
            self.assignMcuCommand(None)
        elif self.v1.get() == 'Python':
            self.mcu_cb.grid_remove()
            self.py_cb.grid(row=1, column=1, columnspan=2, padx=(10, 0))
            self.util_cb.grid_remove()
            self.assignPythonCommand(None)
        elif self.v1.get() == 'Utility':
            self.mcu_cb.grid_remove()
            self.py_cb.grid_remove()
            self.util_cb.grid(row=1, column=1, columnspan=2, padx=(10, 0))
            self.assignUtilCommand(None)

    def activateSerial(self):
        if self.ser.isOpened():
            print('Port is already opened and being closed.')
            self.ser.closeSerial()
            self.keyPress = None
            self.activateSerial()
        else:
            if self.ser.openSerial(self.comPort.get()):
                self.settings['com_port'] = self.comPort.get()
                print('COM Port ' + str(self.comPort.get()) +
                      ' connected successfully')
                self.keyPress = KeyPress(self.ser)

    def createControllerWindow(self):
        if not self.controller is None:
            self.controller.focus_force()
            return

        window = ControllerGUI(self.root, self.ser)

        # enable Keyboard as controller
        if self.keyboard is None:
            self.keyboard = SwitchKeyboardController(self.keyPress)
            self.keyboard.listen()

        # bind focus
        if os.name == 'nt':
            window.bind("<FocusIn>", self.onFocusInController)
            window.bind("<FocusOut>", self.onFocusOutController)
            self.root.bind("<FocusIn>", self.onFocusInController)
            self.root.bind("<FocusOut>", self.onFocusOutController)

        window.protocol("WM_DELETE_WINDOW", self.closingController)
        self.controller = window

    def closingController(self):
        if os.name == 'nt':  # NOTE: Idk why but self.keyboard.stop() makes crash on Linux
            # stop listening to keyboard events
            if not self.keyboard is None:
                self.keyboard.stop()
                self.keyboard = None

                self.root.bind("<FocusIn>", lambda _: None)
                self.root.bind("<FocusOut>", lambda _: None)

        self.controller.destroy()
        self.controller = None

    def onFocusInController(self, event):
        # enable Keyboard as controller
        if self.keyboard is None:
            self.keyboard = SwitchKeyboardController(self.keyPress)
            self.keyboard.listen()

    def onFocusOutController(self, event):
        # stop listening to keyboard events
        if not self.keyboard is None:
            self.keyboard.stop()
            self.keyboard = None

    def doProcess(self):
        image_bgr = self.camera.readFrame()
        if self.showPreview.get() and image_bgr is not None:
            image_bgr = cv2.resize(image_bgr, (640, 360))
            image_rgb = cv2.cvtColor(image_bgr, cv2.COLOR_BGR2RGB)
            image_pil = Image.fromarray(image_rgb)
            image_tk = ImageTk.PhotoImage(image_pil)

            self.preview.im = image_tk
            self.preview['image'] = image_tk

        self.root.after((int)(16 * (60 / int(self.fps.get()))), self.doProcess)

    def write(self, str):
        self.logArea.insert(tk.END, str)
        time.sleep(0.0001)
        self.logArea.see(tk.END)
Exemple #6
0
class GUI:
	def __init__(self):
		# NOTE: I'm gonna rewrite this function because this is not a good coding style

		self.root = tk.Tk()
		self.root.title(NAME + ' ' + VERSION)
		self.frame1 = ttk.Frame(
			self.root,
			height=720,
			width=1280,
			relief='flat',
			borderwidth=5)
		self.controller = None
		self.keyPress = None
		self.keyboard = None

		# label frames
		self.lf = ttk.Labelframe(self.frame1, text='Command', padding=5)
		self.serial_lf = ttk.Labelframe(self.frame1, text='Serial Settings', padding=5)
		self.camera_lf = ttk.Labelframe(self.frame1, text='Camera', padding=5)
		self.control_lf = ttk.Labelframe(self.frame1, text='Controller', padding=5)

		# frames
		self.camera_f1 = ttk.Frame(self.camera_lf, relief='flat')
		self.camera_f2 = ttk.Frame(self.camera_lf, relief='flat')
		self.serial_f1 = ttk.Frame(self.serial_lf, relief='flat')
		self.serial_f2 = ttk.Frame(self.serial_lf, relief='flat')

		# log area
		self.logArea = MyScrolledText(self.frame1, width=70)
		self.logArea.write = self.write
		sys.stdout = self.logArea

		# load settings file
		self.loadSettings()

		# camera settings
		self.label1 = ttk.Label(self.camera_f1, text='Camera ID:')
		self.camera_entry = None
		if os.name == 'nt':
			try:
				self.locateCameraCmbbox()
			except:
				# Locate an entry instead whenever dll is not imported successfully
				self.camera_entry = ttk.Entry(self.camera_f1, width=5, textvariable=self.settings.camera_id)
		else:
			self.camera_entry = ttk.Entry(self.camera_f1, width=5, textvariable=self.settings.camera_id)

		# open up a camera
		self.camera = Camera()
		self.openCamera()

		self.cb1 = ttk.Checkbutton(
			self.camera_f1,
			padding=5,
			text='Show Realtime',
			onvalue=True,
			offvalue=False,
			variable=self.settings.is_show_realtime)

		self.label2 = ttk.Label(self.serial_f1, text='COM Port:')
		self.entry2 = ttk.Entry(self.serial_f1, width=5, textvariable=self.settings.com_port)
		self.preview = CaptureArea(self.camera, self.settings.fps.get(), self.settings.is_show_realtime, self.camera_lf)

		# activate serial communication
		self.ser = Sender.Sender(self.settings.is_show_serial)
		self.activateSerial()

		self.v1 = tk.StringVar(value='Python')
		self.rb1 = ttk.Radiobutton(self.lf, text='Mcu', value='Mcu', variable=self.v1, command=self.setCommandCmbbox)
		self.rb2 = ttk.Radiobutton(self.lf, text='Python', value='Python', variable=self.v1, command=self.setCommandCmbbox)
		self.reloadCommandButton = ttk.Button(self.lf, text='Reload', command=self.reloadCommands)

		self.reloadButton = ttk.Button(self.camera_f1, text='Reload Cam', command=self.openCamera)
		self.reloadComPort = ttk.Button(self.serial_f1, text='Reload Port', command=self.activateSerial)
		self.startButton = ttk.Button(self.lf, text='Start', command=self.startPlay)
		self.captureButton = ttk.Button(self.camera_f1, text='Capture', command=self.preview.saveCapture)

		self.cb_show_ser = ttk.Checkbutton(
			self.serial_f2,
			padding=5,
			text='Show Serial',
			onvalue=True,
			offvalue=False,
			variable=self.settings.is_show_serial)

		# simple controller
		self.cb_use_keyboard = ttk.Checkbutton(
			self.control_lf, text='Use Keyboard',
			onvalue=True, offvalue=False, variable=self.settings.is_use_keyboard,
			command=self.activateKeyboard)
		self.activateKeyboard()
		self.simpleConButton = ttk.Button(self.control_lf, text='Controller', command=self.createControllerWindow)

		# fps
		self.label3 = ttk.Label(self.camera_f2, text='FPS:')
		self.fps_cb = ttk.Combobox(self.camera_f2, textvariable=self.settings.fps, width=2, state="readonly")
		self.fps_cb['values'] = [45, 30, 15]
		self.fps_cb.bind('<<ComboboxSelected>>', self.applyFps)
		self.fps_cb.current(self.fps_cb['values'].index(self.settings.fps.get()))

		# commands
		self.mcu_name = tk.StringVar()
		self.mcu_cb = ttk.Combobox(self.lf, textvariable=self.mcu_name, state="readonly")
		self.py_name = tk.StringVar()
		self.py_cb = ttk.Combobox(self.lf, textvariable=self.py_name, state="readonly")
		self.loadCommands()

		self.partition1 = ttk.Label(self.camera_f1, text=' / ')
		self.partition2 = ttk.Label(self.camera_f1, text=' / ')

		self.frame1.grid(row=0,column=0,sticky='nwse')
		self.logArea.grid(row=0,column=7,rowspan=5, sticky='nwse')

		# camera
		self.camera_lf.grid(row=0,column=0,columnspan=3, sticky='nw')
		self.camera_f1.grid(row=0,column=0, sticky='nw')
		self.camera_f2.grid(row=2,column=0, sticky='nw', pady=(5, 0))
		self.preview.grid(row=1,column=0,columnspan=7, sticky='nw')
		self.label1.pack(side=tk.LEFT)
		self.camera_entry.pack(side=tk.LEFT, padx=5)

		self.reloadButton.pack(side=tk.LEFT)
		self.partition1.pack(side=tk.LEFT, padx=10)
		self.cb1.pack(side=tk.LEFT)
		self.partition2.pack(side=tk.LEFT, padx=10)
		self.captureButton.pack(side=tk.LEFT)
		self.label3.pack(side=tk.LEFT)
		self.fps_cb.pack(side=tk.LEFT, padx=5)

		# serial
		self.serial_lf.grid(row=1,column=0, sticky='nw')
		self.serial_f1.grid(row=0,column=0, sticky='nw')
		self.serial_f2.grid(row=1,column=0, sticky='nw', pady=(5, 0))
		self.label2.pack(side=tk.LEFT)
		self.entry2.pack(side=tk.LEFT, padx=5)
		self.reloadComPort.pack(side=tk.LEFT)
		self.cb_show_ser.pack(side=tk.LEFT)

		# controller simulator
		self.control_lf.grid(row=1, column=1, sticky='ne')
		self.cb_use_keyboard.grid(row=0, column=0)
		self.simpleConButton.grid(row=1, column=0, pady=(5,0))

		# commands selection
		self.lf.grid(row=1,column=2, rowspan=3, sticky='ne')
		self.rb1.grid(row=0,column=0, sticky='w')
		self.rb2.grid(row=1,column=0, sticky='w')
		self.setCommandCmbbox()
		self.reloadCommandButton.grid(row=3,column=1, sticky='e', pady=(10, 0))
		self.startButton.grid(row=3,column=2, sticky='e', pady=(10, 0))

		for child in self.frame1.winfo_children():
			if not type(child) is ttk.Combobox:
				child.grid_configure(padx=5, pady=5)

		self.root.protocol("WM_DELETE_WINDOW", self.exit)
		self.preview.startCapture()

	def openCamera(self):
		self.camera.openCamera(self.settings.camera_id.get())
	
	def assignCamera(self, event):
		if os.name == 'nt':
			self.settings.camera_id.set(self.camera_dic[self.cameraName.get()])

	def loadSettings(self):
		self.settings = Settings.GuiSettings()
		self.settings.load()

	def startPlay(self):
		if self.cur_command is None:
			print('No commands have been assinged yet.')

		# set and init selected command
		self.assignCommand()

		print(self.startButton["text"] + ' ' + self.cur_command.NAME)
		self.cur_command.start(self.ser, self.stopPlayPost)

		self.startButton["text"] = "Stop"
		self.startButton["command"] = self.stopPlay
		self.reloadCommandButton["state"] = "disabled"

	def stopPlay(self):
		print(self.startButton["text"] + ' ' + self.cur_command.NAME)
		self.startButton["state"] = "disabled"
		self.cur_command.end(self.ser)

	def stopPlayPost(self):
		self.startButton["text"] = "Start"
		self.startButton["command"] = self.startPlay
		self.startButton["state"] = "normal"
		self.reloadCommandButton["state"] = "normal"

	def exit(self):
		if self.ser.isOpened():
			self.ser.closeSerial()
			print("serial disconnected")

		# stop listening to keyboard events
		if not self.keyboard is None:
			self.keyboard.stop()
			self.keyboard = None

		# save settings
		self.settings.save()

		self.camera.destroy()
		cv2.destroyAllWindows()
		self.root.destroy()

	def applyFps(self, event):
		print('changed FPS to: ' + self.settings.fps.get() + ' [fps]')
		self.preview.setFps(self.settings.fps.get())

	def setCommandCmbbox(self):
		if self.v1.get() == 'Mcu':
			self.mcu_cb.grid(row=0,column=1, columnspan=2, padx=(10, 0))
			self.py_cb.grid_remove()
		elif self.v1.get() == 'Python':
			self.mcu_cb.grid_remove()
			self.py_cb.grid(row=0,column=1, columnspan=2, padx=(10, 0))

	def locateCameraCmbbox(self):
		import clr
		clr.AddReference(r"..\DirectShowLib\DirectShowLib-2005")
		from DirectShowLib import DsDevice, FilterCategory

		# Get names of detected camera devices
		captureDevices = DsDevice.GetDevicesOfCat(FilterCategory.VideoInputDevice)
		self.camera_dic = {device.Name: cam_id for cam_id, device in enumerate(captureDevices)}
		self.camera_dic['Disable'] = max(list(self.camera_dic.values())) + 1
		dev_num = len(self.camera_dic)

		if self.settings.camera_id.get() > dev_num - 1:
			print('inappropriate camera ID! -> set to 0')
			self.settings.camera_id.set(0)
			if dev_num == 0: print('No camera devices can be found.')

		# locate a combobox instead of an entry
		self.cameraName = tk.StringVar()
		self.label1['text'] = 'Camera: '
		self.camera_entry = ttk.Combobox(self.camera_f1, width=30, textvariable=self.cameraName, state="readonly")
		self.camera_entry['values'] = [device for device in self.camera_dic.keys()]
		self.camera_entry.bind('<<ComboboxSelected>>', self.assignCamera)
		if not dev_num == 0:
			self.camera_entry.current(self.settings.camera_id.get())

	def activateSerial(self):
		if self.ser.isOpened():
			print('Port is already opened and being closed.')
			self.ser.closeSerial()
			self.keyPress = None
			self.activateSerial()
		else:
			if self.ser.openSerial(self.settings.com_port.get()):
				print('COM Port ' + str(self.settings.com_port.get()) + ' connected successfully')
				self.keyPress = KeyPress(self.ser)

	def createControllerWindow(self):
		if not self.controller is None:
			self.controller.focus_force()
			return

		window = ControllerGUI(self.root, self.ser)
		window.protocol("WM_DELETE_WINDOW", self.closingController)
		self.controller = window
	
	def activateKeyboard(self):
		if self.settings.is_use_keyboard.get() == True:
			# enable Keyboard as controller
			if self.keyboard is None:
				self.keyboard = SwitchKeyboardController(self.keyPress)
				self.keyboard.listen()
		
			# bind focus
			if os.name == 'nt':
				self.root.bind("<FocusIn>", self.onFocusInController)
				self.root.bind("<FocusOut>", self.onFocusOutController)

		else:
			if os.name == 'nt': # NOTE: Idk why but self.keyboard.stop() makes crash on Linux
				if not self.keyboard is None:
					# stop listening to keyboard events
					self.keyboard.stop()
					self.keyboard = None

				self.root.bind("<FocusIn>", lambda _: None)
				self.root.bind("<FocusOut>", lambda _: None)

	def closingController(self):
		self.controller.destroy()
		self.controller = None

	def onFocusInController(self, event):
		# enable Keyboard as controller
		if event.widget == self.root and self.keyboard is None:
			self.keyboard = SwitchKeyboardController(self.keyPress)
			self.keyboard.listen()

	def onFocusOutController(self, event):
		# stop listening to keyboard events
		if event.widget == self.root and not self.keyboard is None:
			self.keyboard.stop()
			self.keyboard = None

	def write(self, str):
		self.logArea.insert(tk.END, str)
		time.sleep(0.0001)
		self.logArea.see(tk.END)

	def loadCommands(self):
		self.py_loader = CommandLoader(util.ospath('Commands/PythonCommands'), PythonCommandBase.PythonCommand)
		self.mcu_loader = CommandLoader(util.ospath('Commands/McuCommands'), McuCommandBase.McuCommand)
		
		self.py_classes = self.py_loader.load()
		self.mcu_classes = self.mcu_loader.load()

		self.setCommandItems()
		self.assignCommand()
	
	def setCommandItems(self):
		self.py_cb['values'] = [c.NAME for c in self.py_classes]
		self.py_cb.current(0)
		self.mcu_cb['values'] = [c.NAME for c in self.mcu_classes]
		self.mcu_cb.current(0)

	def assignCommand(self):
		if self.v1.get() == 'Mcu':
			self.cur_command = self.mcu_classes[self.mcu_cb.current()]()
		elif self.v1.get() == 'Python':
			cmd_class = self.py_classes[self.py_cb.current()]

			if issubclass(cmd_class, PythonCommandBase.ImageProcPythonCommand):
				self.cur_command = cmd_class(self.camera)
			else:
				self.cur_command = cmd_class()

	def reloadCommands(self):
		if self.v1.get() == 'Mcu':
			visibledCb = self.mcu_cb
		elif self.v1.get() == 'Python':
			visibledCb = self.py_cb
		oldval = visibledCb.get()

		self.py_classes = self.py_loader.reload()
		self.mcu_classes = self.mcu_loader.reload()

		# Restore the command selecting state if possible
		self.setCommandItems()
		if(oldval in visibledCb['values']):
			visibledCb.set(oldval)
		self.assignCommand()
		print('Finished reloading command modules.')
class PokeControllerApp:
    def __init__(self, master=None):

        self._logger = getLogger(__name__)
        self._logger.addHandler(NullHandler())
        self._logger.setLevel(DEBUG)
        self._logger.propagate = True

        self.root = master
        self.root.title(NAME + ' ' + VERSION)
        # self.root.resizable(0, 0)
        self.controller = None
        self.poke_treeview = None
        self.keyPress = None
        self.keyboard = None
        '''
        ここから
        '''
        # build ui
        self.frame_1 = ttk.Frame(master)
        self.camera_lf = ttk.Labelframe(self.frame_1)
        self.label_1 = ttk.Label(self.camera_lf)
        self.label_1.config(anchor='center', text='Camera ID:')
        self.label_1.grid(padx='5', sticky='ew')
        self.camera_entry = ttk.Entry(self.camera_lf)
        self.camera_id = tk.IntVar()
        self.camera_entry.config(state='normal', textvariable=self.camera_id)
        self.camera_entry.grid(column='1', padx='5', row='0', sticky='ew')
        self.camera_entry.columnconfigure('1', uniform='0')
        self.reloadButton = ttk.Button(self.camera_lf)
        self.reloadButton.config(text='Reload Camera')
        self.reloadButton.grid(column='2', padx='5', row='0', sticky='ew')
        self.reloadButton.configure(command=self.openCamera)
        self.separator_1 = ttk.Separator(self.camera_lf)
        self.separator_1.config(orient='vertical')
        self.separator_1.grid(column='3', row='0', sticky='ns')
        self.cb1 = ttk.Checkbutton(self.camera_lf)
        self.is_show_realtime = tk.BooleanVar()
        self.cb1.config(text='Show Realtime', variable=self.is_show_realtime)
        self.cb1.grid(column='4', row='0')
        self.separator_2 = ttk.Separator(self.camera_lf)
        self.separator_2.config(orient='vertical')
        self.separator_2.grid(column='5', row='0', sticky='ns')
        self.captureButton = ttk.Button(self.camera_lf)
        self.captureButton.config(text='Capture')
        self.captureButton.grid(column='6', row='0')
        self.captureButton.configure(command=self.saveCapture)
        self.camera_f2 = ttk.Frame(self.camera_lf)
        self.label3 = ttk.Label(self.camera_f2)
        self.label3.config(text='FPS:')
        self.label3.grid(padx='5', sticky='ew')
        self.fps_cb = ttk.Combobox(self.camera_f2)
        self.fps = tk.StringVar()
        self.fps_cb.config(justify='right',
                           state='readonly',
                           textvariable=self.fps,
                           values=[60, 45, 30, 15, 5])
        self.fps_cb.config(width='5')
        self.fps_cb.grid(column='1', padx='10', row='0', sticky='ew')
        self.fps_cb.bind('<<ComboboxSelected>>', self.applyFps, add='')
        self.separator_3 = ttk.Separator(self.camera_f2)
        self.separator_3.config(orient='vertical')
        self.separator_3.grid(column='2', row='0', sticky='ns')
        self.show_size_label = ttk.Label(self.camera_f2)
        self.show_size_label.config(text='Show Size:')
        self.show_size_label.grid(column='3', padx='5', row='0', sticky='ew')
        self.show_size_cb = ttk.Combobox(self.camera_f2)
        self.show_size = tk.StringVar()
        self.show_size_cb.config(textvariable=self.show_size,
                                 state='readonly',
                                 values='640x360 1280x720 1920x1080')
        self.show_size_cb.grid(column='4', padx='10', row='0', sticky='ew')
        self.show_size_cb.bind('<<ComboboxSelected>>',
                               self.applyWindowSize,
                               add='')
        self.camera_f2.grid(column='0', columnspan='7', row='3', sticky='nsew')
        self.camera_name_l = ttk.Label(self.camera_lf)
        self.camera_name_l.config(anchor='center', text='Camera Name: ')
        self.camera_name_l.grid(column='0', padx='5', row='1', sticky='ew')
        self.Camera_Name = ttk.Combobox(self.camera_lf)
        self.camera_name_fromDLL = tk.StringVar()
        self.Camera_Name.config(state='normal',
                                textvariable=self.camera_name_fromDLL)
        self.Camera_Name.grid(column='1',
                              columnspan='6',
                              padx='5',
                              row='1',
                              sticky='ew')
        self.Camera_Name.bind('<<ComboboxSelected>>',
                              self.set_cameraid,
                              add='')
        self.frame_1_2 = ttk.Frame(self.camera_lf)
        self.frame_1_2.config(height='360', relief='groove', width='640')
        self.frame_1_2.grid(column='0', columnspan='7', row='2')
        self.camera_lf.config(height='200', text='Camera', width='200')
        self.camera_lf.grid(columnspan='3', padx='5', sticky='ew')
        self.serial_lf = ttk.Labelframe(self.frame_1)
        self.label2 = ttk.Label(self.serial_lf)
        self.label2.config(text='COM Port: ')
        self.label2.grid(padx='5', sticky='ew')
        self.label2.rowconfigure('0', uniform='None', weight='0')
        self.entry2 = ttk.Entry(self.serial_lf)
        self.com_port = tk.IntVar()
        self.entry2.config(textvariable=self.com_port, width='5')
        self.entry2.grid(column='1', padx='5', row='0', sticky='ew')
        self.entry2.rowconfigure('0', uniform='None', weight='0')
        self.reloadComPort = ttk.Button(self.serial_lf)
        self.reloadComPort.config(text='Reload Port')
        self.reloadComPort.grid(column='2', row='0')
        self.reloadComPort.rowconfigure('0', uniform='None', weight='0')
        self.reloadComPort.configure(command=self.activateSerial)
        self.separator_4 = ttk.Separator(self.serial_lf)
        self.separator_4.config(orient='vertical')
        self.separator_4.grid(column='3', padx='5', row='0', sticky='ns')
        self.separator_4.rowconfigure('0', uniform='None', weight='0')
        self.separator_4.columnconfigure('3', uniform='None', weight='0')
        self.checkbutton_2 = ttk.Checkbutton(self.serial_lf)
        self.is_show_serial = tk.BooleanVar()
        self.checkbutton_2.config(text='Show Serial',
                                  variable=self.is_show_serial)
        self.checkbutton_2.grid(column='4',
                                columnspan='2',
                                padx='5',
                                row='0',
                                sticky='ew')
        self.checkbutton_2.rowconfigure('0', uniform='None', weight='0')
        self.serial_lf.config(text='Serial Settings')
        self.serial_lf.grid(column='0',
                            columnspan='2',
                            padx='5',
                            row='1',
                            sticky='nsew')
        self.control_lf = ttk.Labelframe(self.frame_1)
        self.cb_use_keyboard = ttk.Checkbutton(self.control_lf)
        self.cb_left_stick_mouse = ttk.Checkbutton(self.control_lf)
        self.cb_right_stick_mouse = ttk.Checkbutton(self.control_lf)
        self.is_use_keyboard = tk.BooleanVar()
        self.camera_lf.is_use_left_stick_mouse = tk.BooleanVar()
        self.camera_lf.is_use_right_stick_mouse = tk.BooleanVar()
        self.cb_use_keyboard.config(text='Use Keyboard',
                                    variable=self.is_use_keyboard)
        self.cb_use_keyboard.grid(column='0', padx='10', pady='5', sticky='ew')
        self.cb_use_keyboard.rowconfigure('0', weight='1')
        self.cb_use_keyboard.columnconfigure('0', weight='1')
        self.cb_use_keyboard.configure(command=self.activateKeyboard)
        self.cb_left_stick_mouse.config(
            text='Use LStick Mouse',
            variable=self.camera_lf.is_use_left_stick_mouse)
        self.cb_left_stick_mouse.grid(column='1',
                                      row='0',
                                      padx='10',
                                      pady='5',
                                      sticky='ew')
        self.cb_left_stick_mouse.rowconfigure('0', weight='1')
        self.cb_left_stick_mouse.columnconfigure('0', weight='1')
        self.cb_left_stick_mouse.configure(
            command=self.activate_Left_stick_mouse)
        self.cb_right_stick_mouse.config(
            text='Use RStick Mouse',
            variable=self.camera_lf.is_use_right_stick_mouse)
        self.cb_right_stick_mouse.grid(column='1',
                                       row='1',
                                       padx='10',
                                       pady='5',
                                       sticky='ew')
        self.cb_right_stick_mouse.rowconfigure('0', weight='1')
        self.cb_right_stick_mouse.columnconfigure('0', weight='1')
        self.cb_right_stick_mouse.configure(
            command=self.activate_Right_stick_mouse)
        self.simpleConButton = ttk.Button(self.control_lf)
        self.simpleConButton.config(text='Controller')
        self.simpleConButton.grid(column='0',
                                  padx='10',
                                  pady='5',
                                  row='1',
                                  sticky='ew')
        self.simpleConButton.rowconfigure('1', weight='1')
        self.simpleConButton.columnconfigure('0', weight='1')
        self.simpleConButton.configure(command=self.createControllerWindow)
        self.control_lf.config(height='200', text='Controller')
        # self.control_lf.grid(column='0', padx='5', row='2', sticky='nsew')
        self.control_lf.grid(column='0',
                             padx='5',
                             row='2',
                             columnspan='2',
                             sticky='nsew')
        # self.Poke_statistic_lf = ttk.Labelframe(self.frame_1)
        # self.OpenPokeButton = ttk.Button(self.Poke_statistic_lf)
        # self.OpenPokeButton.config(text='技統計')
        # self.OpenPokeButton.grid(padx='10', pady='10', sticky='nsew')
        # self.OpenPokeButton.rowconfigure('0', pad='0', uniform='1', weight='1')
        # self.OpenPokeButton.columnconfigure('0', pad='0', uniform='1', weight='1')
        # self.OpenPokeButton.configure(command=self.createGetFromHomeWindow)
        # self.Poke_statistic_lf.config(height='200', text='PokemonHome連携', width='200')
        # self.Poke_statistic_lf.grid(column='1', padx='5', row='2', sticky='nsew')
        self.lf = ttk.Labelframe(self.frame_1)
        self.Command_nb = ttk.Notebook(self.lf)
        self.py_cb = ttk.Combobox(self.Command_nb)
        self.py_name = tk.StringVar()
        self.py_cb.config(state='readonly', textvariable=self.py_name)
        self.py_cb.pack(side='top')
        self.Command_nb.add(self.py_cb, padding='5', text='Python Command')
        self.mcu_cb = ttk.Combobox(self.Command_nb)
        self.mcu_name = tk.StringVar()
        self.mcu_cb.config(state='readonly', textvariable=self.mcu_name)
        self.mcu_cb.pack(side='top')
        self.Command_nb.add(self.mcu_cb, padding='5', text='Mcu Command')
        self.Command_nb.grid(column='0',
                             columnspan='2',
                             padx='5',
                             pady='5',
                             row='0',
                             sticky='ew')
        self.reloadCommandButton = ttk.Button(self.lf)
        self.reloadCommandButton.config(text='Reload')
        self.reloadCommandButton.grid(column='0',
                                      padx='5',
                                      pady='5',
                                      row='1',
                                      sticky='ew')
        self.reloadCommandButton.configure(command=self.reloadCommands)
        self.startButton = ttk.Button(self.lf)
        self.startButton.config(text='Start')
        self.startButton.grid(column='1',
                              padx='5',
                              pady='5',
                              row='1',
                              sticky='ew')
        self.startButton.configure(command=self.startPlay)
        self.lf.config(height='200', text='Command')
        self.lf.grid(column='2', padx='5', row='1', rowspan='2', sticky='nsew')
        self.log_scroll = ScrollbarHelper(self.frame_1, scrolltype='both')
        self.logArea = tk.Text(self.log_scroll.container)
        self.logArea.config(blockcursor='true',
                            height='10',
                            insertunfocussed='none',
                            maxundo='0')
        self.logArea.config(relief='flat',
                            state='disabled',
                            undo='false',
                            width='50')
        self.logArea.pack(expand='true', fill='both', side='top')
        self.log_scroll.add_child(self.logArea)
        self.log_scroll.config(borderwidth='1', padding='1', relief='sunken')
        # TODO - self.log_scroll: code for custom option 'usemousewheel' not implemented.
        self.log_scroll.grid(column='3',
                             padx='5',
                             pady='5',
                             row='0',
                             rowspan='3',
                             sticky='nsew')
        self.frame_1.config(height='720',
                            padding='5',
                            relief='flat',
                            width='1280')
        self.frame_1.pack(expand='true', fill='both', side='top')
        self.frame_1.columnconfigure('3', weight='1')
        '''
        ここまで
        '''

        # 仮置フレームを削除
        self.frame_1_2.destroy()

        # 標準出力をログにリダイレクト
        sys.stdout = StdoutRedirector(self.logArea)
        # load settings file
        self.loadSettings()
        # 各tk変数に設定値をセット(コピペ簡単のため)
        self.is_show_realtime.set(self.settings.is_show_realtime.get())
        self.is_show_serial.set(self.settings.is_show_serial.get())
        self.is_use_keyboard.set(self.settings.is_use_keyboard.get())
        self.fps.set(self.settings.fps.get())
        self.show_size.set(self.settings.show_size.get())
        self.com_port.set(self.settings.com_port.get())
        self.camera_id.set(self.settings.camera_id.get())
        # 各コンボボックスを現在の設定値に合わせて表示
        self.fps_cb.current(self.fps_cb['values'].index(self.fps.get()))
        self.show_size_cb.current(self.show_size_cb['values'].index(
            self.show_size.get()))

        if os.name == 'nt':
            try:
                self.locateCameraCmbbox()
                self.camera_entry.config(state='disable')
            except:
                # Locate an entry instead whenever dll is not imported successfully
                self.camera_name_fromDLL.set(
                    "An error occurred while displaying the camera names in NT environment."
                )
                self._logger.warning(
                    "An error occurred while displaying the camera names in NT environment."
                )
                self.Camera_Name.config(state='disable')
        else:
            self.camera_name_fromDLL.set(
                "Not nt environment so that cannot show Camera name.")
            self.Camera_Name.config(state='disable')
        # open up a camera
        self.camera = Camera(self.fps.get())
        self.openCamera()
        # activate serial communication
        self.ser = Sender.Sender(self.is_show_serial)
        self.activateSerial()
        self.activateKeyboard()
        self.preview = CaptureArea(
            self.camera, self.fps.get(), self.is_show_realtime, self.ser,
            self.camera_lf, *list(map(int,
                                      self.show_size.get().split("x"))))
        self.preview.config(cursor='crosshair')
        self.preview.grid(column='0',
                          columnspan='7',
                          row='2',
                          padx='5',
                          pady='5',
                          sticky=tk.NSEW)
        self.loadCommands()

        # Main widget
        self.mainwindow = self.frame_1

        self.root.protocol("WM_DELETE_WINDOW", self.exit)
        self.preview.startCapture()

        self.menu = PokeController_Menubar(self)
        self.root.config(menu=self.menu)

        # logging.debug(f'python version: {sys.version}')

    def openCamera(self):
        self.camera.openCamera(self.camera_id.get())

    def assignCamera(self, event):
        if os.name == 'nt':
            self.camera_name_fromDLL.set(self.camera_dic[self.camera_id.get()])

    def locateCameraCmbbox(self):
        import clr
        clr.AddReference(r"..\DirectShowLib\DirectShowLib-2005")
        from DirectShowLib import DsDevice, FilterCategory

        # Get names of detected camera devices
        captureDevices = DsDevice.GetDevicesOfCat(
            FilterCategory.VideoInputDevice)
        self.camera_dic = {
            cam_id: device.Name
            for cam_id, device in enumerate(captureDevices)
        }

        self.camera_dic[str(max(list(self.camera_dic.keys())) + 1)] = 'Disable'
        self.Camera_Name['values'] = [
            device for device in self.camera_dic.values()
        ]
        self._logger.debug(
            f"Camera list: {[device for device in self.camera_dic.values()]}")
        dev_num = len(self.camera_dic)

        if self.camera_id.get() > dev_num - 1:
            print('Inappropriate camera ID! -> set to 0')
            self._logger.debug('Inappropriate camera ID! -> set to 0')
            self.camera_id.set(0)
            if dev_num == 0:
                print('No camera devices can be found.')
                self._logger.debug('No camera devices can be found.')
        #
        self.camera_entry.bind('<KeyRelease>', self.assignCamera)
        self.Camera_Name.current(self.camera_id.get())

    def saveCapture(self):
        self.camera.saveCapture()

    def set_cameraid(self, event=None):
        keys = [
            k for k, v in self.camera_dic.items()
            if v == self.Camera_Name.get()
        ]
        if keys:
            ret = keys[0]
        else:
            ret = None
        self.camera_id.set(ret)

    def applyFps(self, event=None):
        print('changed FPS to: ' + self.fps.get() + ' [fps]')
        self.preview.setFps(self.fps.get())

    def applyWindowSize(self, event=None):
        width, height = map(int, self.show_size.get().split("x"))
        self.preview.setShowsize(height, width)

    def activateSerial(self):
        if self.ser.isOpened():
            print('Port is already opened and being closed.')
            self.ser.closeSerial()
            self.keyPress = None
            self.activateSerial()
        else:
            if self.ser.openSerial(self.com_port.get()):
                print('COM Port ' + str(self.com_port.get()) +
                      ' connected successfully')
                self._logger.debug('COM Port ' + str(self.com_port.get()) +
                                   ' connected successfully')
                self.keyPress = KeyPress(self.ser)

    def activateKeyboard(self):
        if self.is_use_keyboard.get():
            # enable Keyboard as controller
            if self.keyboard is None:
                self.keyboard = SwitchKeyboardController(self.keyPress)
                self.keyboard.listen()

            # bind focus
            if os.name == 'nt':
                self.root.bind("<FocusIn>", self.onFocusInController)
                self.root.bind("<FocusOut>", self.onFocusOutController)

        else:
            if os.name == 'nt':  # NOTE: Idk why but self.keyboard.stop() makes crash on Linux
                if self.keyboard is not None:
                    # stop listening to keyboard events
                    self.keyboard.stop()
                    self.keyboard = None

                self.root.bind("<FocusIn>", lambda _: None)
                self.root.bind("<FocusOut>", lambda _: None)

    def onFocusInController(self, event):
        # enable Keyboard as controller
        if event.widget == self.root and self.keyboard is None:
            self.keyboard = SwitchKeyboardController(self.keyPress)
            self.keyboard.listen()

    def onFocusOutController(self, event):
        # stop listening to keyboard events
        if event.widget == self.root and not self.keyboard is None:
            self.keyboard.stop()
            self.keyboard = None

    def createControllerWindow(self):
        if not self.controller is None:
            self.controller.focus_force()
            return

        window = ControllerGUI(self.root, self.ser)
        window.protocol("WM_DELETE_WINDOW", self.closingController)
        self.controller = window

    def activate_Left_stick_mouse(self):
        self.preview.ApplyLStickMouse()

    def activate_Right_stick_mouse(self):
        self.preview.ApplyRStickMouse()

    # def createGetFromHomeWindow(self):
    #     if self.poke_treeview is not None:
    #         self.poke_treeview.focus_force()
    #         return
    #
    #     window2 = GetFromHomeGUI(self.root, self.settings.season, self.settings.is_SingleBattle)
    #     window2.protocol("WM_DELETE_WINDOW", self.closingGetFromHome)
    #     self.poke_treeview = window2

    def loadCommands(self):
        self.py_loader = CommandLoader(
            util.ospath('Commands/PythonCommands'),
            PythonCommandBase.PythonCommand)  # コマンドの読み込み
        self.mcu_loader = CommandLoader(util.ospath('Commands/McuCommands'),
                                        McuCommandBase.McuCommand)
        self.py_classes = self.py_loader.load()
        self.mcu_classes = self.mcu_loader.load()
        self.setCommandItems()
        self.assignCommand()

    def setCommandItems(self):
        self.py_cb['values'] = [c.NAME for c in self.py_classes]
        self.py_cb.current(0)
        self.mcu_cb['values'] = [c.NAME for c in self.mcu_classes]
        self.mcu_cb.current(0)

    def assignCommand(self):
        # 選択されているコマンドを取得する
        self.mcu_cur_command = self.mcu_classes[
            self.mcu_cb.current()]()  # MCUコマンドについて

        # pythonコマンドは画像認識を使うかどうかで分岐している
        cmd_class = self.py_classes[self.py_cb.current()]
        if issubclass(cmd_class, PythonCommandBase.ImageProcPythonCommand):
            try:  # 画像認識の際に認識位置を表示する引数追加。互換性のため従来のはexceptに。
                self.py_cur_command = cmd_class(self.camera, self.preview)
            except TypeError:
                self.py_cur_command = cmd_class(self.camera)
            except:
                self.py_cur_command = cmd_class(self.camera)

        else:
            self.py_cur_command = cmd_class()

        if self.Command_nb.index(self.Command_nb.select()) == 0:
            self.cur_command = self.py_cur_command
        else:
            self.cur_command = self.mcu_cur_command

    def reloadCommands(self):
        # 表示しているタブを読み取って、どのコマンドを表示しているか取得、リロード後もそれが選択されるようにする
        oldval_mcu = self.mcu_cb.get()
        oldval_py = self.py_cb.get()

        self.py_classes = self.py_loader.reload()
        self.mcu_classes = self.mcu_loader.reload()

        # Restore the command selecting state if possible
        self.setCommandItems()
        if oldval_mcu in self.mcu_cb['values']:
            self.mcu_cb.set(oldval_mcu)
        if oldval_py in self.py_cb['values']:
            self.py_cb.set(oldval_py)
        self.assignCommand()
        print('Finished reloading command modules.')
        self._logger.info("Reloaded commands.")

    def startPlay(self):
        if self.cur_command is None:
            print('No commands have been assigned yet.')
            self._logger.info('No commands have been assigned yet.')

        # set and init selected command
        self.assignCommand()

        print(self.startButton["text"] + ' ' + self.cur_command.NAME)
        self._logger.info(self.startButton["text"] + ' ' +
                          self.cur_command.NAME)
        self.cur_command.start(self.ser, self.stopPlayPost)

        self.startButton["text"] = "Stop"
        self.startButton["command"] = self.stopPlay
        self.reloadCommandButton["state"] = "disabled"

    def stopPlay(self):
        print(self.startButton["text"] + ' ' + self.cur_command.NAME)
        self._logger.info(self.startButton["text"] + ' ' +
                          self.cur_command.NAME)
        self.startButton["state"] = "disabled"
        self.cur_command.end(self.ser)

    def stopPlayPost(self):
        self.startButton["text"] = "Start"
        self.startButton["command"] = self.startPlay
        self.startButton["state"] = "normal"
        self.reloadCommandButton["state"] = "normal"

    def run(self):
        self._logger.debug("Start Poke-Controller")
        self.mainwindow.mainloop()

    def exit(self):
        if self.ser.isOpened():
            self.ser.closeSerial()
            print("Serial disconnected")
            # self._logger.info("Serial disconnected")

        # stop listening to keyboard events
        if not self.keyboard is None:
            self.keyboard.stop()
            self.keyboard = None

        # save settings
        self.settings.is_show_realtime.set(self.is_show_realtime.get())
        self.settings.is_show_serial.set(self.is_show_serial.get())
        self.settings.is_use_keyboard.set(self.is_use_keyboard.get())
        self.settings.fps.set(self.fps.get())
        self.settings.show_size.set(self.show_size.get())
        self.settings.com_port.set(self.com_port.get())
        self.settings.camera_id.set(self.camera_id.get())

        self.settings.save()

        self.camera.destroy()
        cv2.destroyAllWindows()
        self._logger.debug("Stop Poke Controller")
        self.root.destroy()

    def closingController(self):
        self.controller.destroy()
        self.controller = None

    # def closingGetFromHome(self):
    #     self.poke_treeview.destroy()
    #     self.poke_treeview = None

    def loadSettings(self):
        self.settings = Settings.GuiSettings()
        self.settings.load()
class GUI:
	def __init__(self):
		# NOTE: I'm gonna rewrite this function because this is not a good coding style

		self.root = tk.Tk()
		self.root.title('Pokemon Controller')
		self.frame1 = ttk.Frame(
			self.root,
			height=720,
			width=1280,
			relief='flat',
			borderwidth=5)
		self.controller = None
		self.keyPress = None
		self.keyboard = None

		# label frames
		self.lf = ttk.Labelframe(self.frame1, text='Command', padding=5)
		self.serial_lf = ttk.Labelframe(self.frame1, text='Serial Settings', padding=5)
		self.camera_lf = ttk.Labelframe(self.frame1, text='Camera', padding=5)
		self.control_lf = ttk.Labelframe(self.frame1, text='Controller', padding=5)

		# frames
		self.camera_f1 = ttk.Frame(self.camera_lf, relief='flat')
		self.camera_f2 = ttk.Frame(self.camera_lf, relief='flat')

		# log area
		self.logArea = MyScrolledText(self.frame1, width=70)
		self.logArea.write = self.write
		sys.stdout = self.logArea

		# load settings file
		self.loadSettings()
			
		self.label1 = ttk.Label(self.camera_f1, text='Camera ID:')
		self.cameraID = tk.IntVar()
		self.cameraID.set(int(self.settings['camera_id']))
		self.entry1 = ttk.Entry(self.camera_f1, width=5, textvariable=self.cameraID)

		# open up a camera
		self.camera = Camera()
		self.openCamera()

		self.showPreview = tk.BooleanVar()
		self.cb1 = ttk.Checkbutton(
			self.camera_f1,
			padding=5,
			text='Show Realtime',
			onvalue=True,
			offvalue=False,
			variable=self.showPreview)
		self.showPreview.set(True)
		
		self.label2 = ttk.Label(self.serial_lf, text='COM Port:')
		self.comPort = tk.IntVar()
		self.comPort.set(int(self.settings['com_port']))
		self.entry2 = ttk.Entry(self.serial_lf, width=5, textvariable=self.comPort)
		self.preview = ttk.Label(self.camera_lf) 

		# activate serial communication
		self.ser = Sender.Sender()
		self.activateSerial()

		self.v1 = tk.StringVar(value='Python')
		self.rb1 = ttk.Radiobutton(self.lf, text='Mcu', value='Mcu', variable=self.v1, command=self.setCommandCmbbox)
		self.rb2 = ttk.Radiobutton(self.lf, text='Python', value='Python', variable=self.v1, command=self.setCommandCmbbox)
		self.rb3 = ttk.Radiobutton(self.lf, text='Utility', value='Utility', variable=self.v1, command=self.setCommandCmbbox)

		self.reloadButton = ttk.Button(self.camera_f1, text='Reload Cam', command=self.openCamera)
		self.reloadComPort = ttk.Button(self.serial_lf, text='Reload Port', command=self.activateSerial)
		self.startButton = ttk.Button(self.lf, text='Start', command=self.startPlay)
		self.captureButton = ttk.Button(self.camera_f1, text='Capture', command=self.saveCapture)

		self.showSerial = tk.BooleanVar()
		self.showSerial.set(False)
		self.cb_show_ser = ttk.Checkbutton(
			self.serial_lf,
			padding=5,
			text='Show Serial',
			onvalue=True,
			offvalue=False,
			variable=self.showSerial,
			command=lambda: self.ser.setIsShowSerial(self.showSerial.get()))

		# simple controller
		self.simpleConButton = ttk.Button(self.control_lf, text='Controller', command=self.createControllerWindow)

		# fps
		self.label3 = ttk.Label(self.camera_f2, text='FPS:')
		self.fps = tk.StringVar()
		self.fps.set(str(self.settings['fps']))
		self.fps_cb = ttk.Combobox(self.camera_f2, textvariable=self.fps, width=2, state="readonly")
		self.fps_cb['values'] = [45, 30, 15]
		self.fps_cb.bind('<<ComboboxSelected>>', self.applyFps)
		self.fps_cb.current(self.fps_cb['values'].index(self.fps.get()))

		# special commands registration
		self.unit_dir_commands = [
			UnitCommand.UP(),
			UnitCommand.RIGHT(),
			UnitCommand.DOWN(),
			UnitCommand.LEFT(),
		]

		self.mcu_name = tk.StringVar()
		self.mcu_cb = ttk.Combobox(self.lf, textvariable=self.mcu_name, state="readonly")
		self.mcu_cb['values'] = [name for name in McuCommand.commands.keys()]
		self.mcu_cb.bind('<<ComboboxSelected>>', self.assignMcuCommand)
		self.mcu_cb.current(0)

		self.py_name = tk.StringVar()
		self.py_cb = ttk.Combobox(self.lf, textvariable=self.py_name, state="readonly")
		self.py_cb['values'] = [name for name in PythonCommand.commands.keys()]
		self.py_cb.bind('<<ComboboxSelected>>', self.assignPythonCommand)
		self.py_cb.current(0)
		self.assignCommand()
	
		self.util_name = tk.StringVar()
		self.util_cb = ttk.Combobox(self.lf, textvariable=self.util_name, state="readonly")
		self.util_cb['values'] = [name for name in PythonCommand.utils.keys()]
		self.util_cb.bind('<<ComboboxSelected>>', self.assignUtilCommand)
		self.util_cb.current(0)

		self.partition1 = ttk.Label(self.camera_f1, text=' / ')
		self.partition2 = ttk.Label(self.camera_f1, text=' / ')

		self.frame1.grid(row=0,column=0,sticky='nwse')
		self.logArea.grid(row=0,column=7,rowspan=5, sticky='nwse')

		# camera
		self.camera_lf.grid(row=0,column=0,columnspan=3, sticky='nw')
		self.camera_f1.grid(row=0,column=0, sticky='nw')
		self.camera_f2.grid(row=2,column=0, sticky='nw', pady=(5, 0))
		self.preview.grid(row=1,column=0,columnspan=7, sticky='nw')
		self.label1.pack(side=tk.LEFT)
		self.entry1.pack(side=tk.LEFT, padx=5)
		self.reloadButton.pack(side=tk.LEFT)
		self.partition1.pack(side=tk.LEFT, padx=10)
		self.cb1.pack(side=tk.LEFT)
		self.partition2.pack(side=tk.LEFT, padx=10)
		self.captureButton.pack(side=tk.LEFT)
		self.label3.pack(side=tk.LEFT)
		self.fps_cb.pack(side=tk.LEFT, padx=5)

		# serial
		self.serial_lf.grid(row=1,column=0, sticky='nw')
		self.label2.grid(row=0,column=0, sticky='w')
		self.entry2.grid(row=0,column=1, sticky='w')
		self.reloadComPort.grid(row=0,column=2, padx=(5,0), sticky='w')
		self.cb_show_ser.grid(row=1, column=0)

		# controller simulator
		self.control_lf.grid(row=1, column=1, sticky='ne')
		self.simpleConButton.grid(row=0, column=0)

		# commands selection
		self.lf.grid(row=1,column=2, rowspan=3, sticky='ne')
		self.rb1.grid(row=0,column=0, sticky='w')
		self.rb2.grid(row=1,column=0, sticky='w')
		self.rb3.grid(row=2,column=0, sticky='w')
		self.setCommandCmbbox()
		self.startButton.grid(row=3,column=2, sticky='e')

		for child in self.frame1.winfo_children():
			if not type(child) is ttk.Combobox:
				child.grid_configure(padx=5, pady=5)

		self.root.iconbitmap('../infinite.ico')
		self.root.protocol("WM_DELETE_WINDOW", self.exit)
		self.root.after(100, self.doProcess)

	def openCamera(self):
		self.camera.openCamera(self.cameraID.get())
		self.settings['camera_id'] = self.cameraID.get()
	
	def loadSettings(self):
		self.settings = None
		if os.path.isfile(SETTING_PATH):
			self.settings = json.load(open(SETTING_PATH, 'r'))
		else:
			default = {
				"camera_id": 0,
				"com_port": 1,
				"fps": "45"
			}
			json.dump(default, open(SETTING_PATH, 'w'), indent=4)
			print('default settings file has been created')
			self.loadSettings()
	
	def startPlay(self):
		if self.cur_command is None:
			print('No commands have been assinged yet.')
		
		# set and init selected command
		self.assignCommand()

		print(self.startButton["text"] + ' ' + self.cur_command.getName())
		self.cur_command.start(self.ser, self.stopPlayPost)
		
		self.startButton["text"] = "Stop"
		self.startButton["command"] = self.stopPlay
	
	def assignCommand(self):
		if self.v1.get() == 'Mcu':
			name = self.mcu_name.get()
			self.cur_command = McuCommand.commands[name](name)
		elif self.v1.get() == 'Python' or self.v1.get() == 'Utility':
			name = self.py_name.get() if self.v1.get() == 'Python' else self.util_name.get()
			cmd_class = PythonCommand.commands[name] if self.v1.get() == 'Python' else PythonCommand.utils[name]

			if issubclass(cmd_class, PythonCommand.ImageProcPythonCommand):
				self.cur_command = cmd_class(name, self.camera)
			else:
				self.cur_command = cmd_class(name)
	
	def stopPlay(self):
		print(self.startButton["text"] + ' ' + self.cur_command.getName())
		self.startButton["state"] = "disabled"
		self.cur_command.end(self.ser)
	
	def stopPlayPost(self):
		self.startButton["text"] = "Start"
		self.startButton["command"] = self.startPlay
		self.startButton["state"] = "normal"
		
	def exit(self):
		if self.ser.isOpened():
			self.ser.closeSerial()
			print("serial disconnected")
		
		# stop listening to keyboard events
		if not self.keyboard is None:
			self.keyboard.stop()
			self.keyboard = None

		# save settings
		json.dump(self.settings, open(SETTING_PATH, 'w'), indent=4)

		self.root.destroy()
	
	def saveCapture(self):
		self.camera.saveCapture()
	
	def applyFps(self, event):
		print('changed FPS to: ' + self.fps.get() + ' [fps]')
		self.settings['fps'] = self.fps.get()

	def assignMcuCommand(self, event):
		print('changed to mcu command: ' + self.mcu_name.get())
	
	def assignPythonCommand(self, event):
		print('changed to python command: ' + self.py_name.get())
	
	def assignUtilCommand(self, event):
		print('changed to utility command: ' + self.util_name.get())

	def setCommandCmbbox(self):
		if self.v1.get() == 'Mcu':
			self.mcu_cb.grid(row=1,column=1, columnspan=2, padx=(10, 0))
			self.py_cb.grid_remove()
			self.util_cb.grid_remove()
			self.assignMcuCommand(None)
		elif self.v1.get() == 'Python':
			self.mcu_cb.grid_remove()
			self.py_cb.grid(row=1,column=1, columnspan=2, padx=(10, 0))
			self.util_cb.grid_remove()
			self.assignPythonCommand(None)
		elif self.v1.get() == 'Utility':
			self.mcu_cb.grid_remove()
			self.py_cb.grid_remove()
			self.util_cb.grid(row=1,column=1, columnspan=2, padx=(10, 0))
			self.assignUtilCommand(None)
	
	def activateSerial(self):
		try:
			if self.ser.isOpened():
				print('Port is already opened and being closed.')
				self.ser.closeSerial()
				self.keyPress = None
				self.activateSerial()
			else:
				self.ser.openSerial("COM"+str(self.comPort.get()))
				self.settings['com_port'] = self.comPort.get()
				print('COM Port ' + str(self.comPort.get()) + ' connected successfully')
				self.keyPress = KeyPress(self.ser)
		except IOError:
			print('COM Port: can\'t be established')

	def createControllerWindow(self):
		if not self.controller is None:
			self.controller.focus_force()
			return

		window = tk.Toplevel(self.root)
		window.title('Simple Switch Controller')
		window.geometry("%dx%d%+d%+d" % (600, 300, 250, 125))

		ttk.Button(window, text='A', command=lambda: UnitCommand.A().start(self.ser)).grid(row=5, column=11)
		ttk.Button(window, text='B', command=lambda: UnitCommand.B().start(self.ser)).grid(row=6, column=10)
		ttk.Button(window, text='X', command=lambda: UnitCommand.X().start(self.ser)).grid(row=4, column=10)
		ttk.Button(window, text='Y', command=lambda: UnitCommand.Y().start(self.ser)).grid(row=5, column=9)
		ttk.Button(window, text='L', command=lambda: UnitCommand.L().start(self.ser)).grid(row=1, column=1)
		ttk.Button(window, text='R', command=lambda: UnitCommand.R().start(self.ser)).grid(row=1, column=10)
		ttk.Button(window, text='ZL', command=lambda: UnitCommand.ZL().start(self.ser)).grid(row=0, column=1)
		ttk.Button(window, text='ZR', command=lambda: UnitCommand.ZR().start(self.ser)).grid(row=0, column=10)
		ttk.Button(window, text='MINUS', command=lambda: UnitCommand.MINUS().start(self.ser)).grid(row=3, column=3)
		ttk.Button(window, text='PLUS', command=lambda: UnitCommand.PLUS().start(self.ser)).grid(row=3, column=7)
		ttk.Button(window, text='LCLICK', command=lambda: UnitCommand.LCLICK().start(self.ser)).grid(row=4, column=1)
		ttk.Button(window, text='RCLICK', command=lambda: UnitCommand.RCLICK().start(self.ser)).grid(row=8, column=10)
		ttk.Button(window, text='HOME', command=lambda: UnitCommand.HOME().start(self.ser)).grid(row=4, column=6)
		ttk.Button(window, text='CAP', command=lambda: UnitCommand.CAPTURE().start(self.ser)).grid(row=4, column=4)
		ttk.Button(window, text='UP', command=lambda: self.unit_dir_commands[0].start(self.ser)).grid(row=6, column=1)
		ttk.Button(window, text='RIGHT', command=lambda: self.unit_dir_commands[1].start(self.ser)).grid(row=7, column=2)
		ttk.Button(window, text='DOWN', command=lambda: self.unit_dir_commands[2].start(self.ser)).grid(row=8, column=1)
		ttk.Button(window, text='LEFT', command=lambda: self.unit_dir_commands[3].start(self.ser)).grid(row=7, column=0)

		for child in window.winfo_children():
			child['width'] = 8

		ttk.Label(window, text='NOTE:').grid(row=9, column=0, columnspan=8, sticky='w', padx=10, pady=(20, 0))
		ttk.Label(window, text='Direction buttons are toggle switch.').grid(row=10, column=0, columnspan=8, sticky='w', padx=10, pady=3)
		ttk.Label(window, text='Key Arrangements are based on Switch Pro. Controller.').grid(row=11, column=0, columnspan=8, sticky='w', padx=10, pady=3)
		
		# enable Keyboard as controller
		self.keyboard = SwitchKeyboardController(self.keyPress)
		self.keyboard.listen()

		# bind focus
		window.bind("<FocusIn>", self.onFocusInController)
		window.bind("<FocusOut>", self.onFocusOutController)
		self.root.bind("<FocusIn>", self.onFocusInController)
		self.root.bind("<FocusOut>", self.onFocusOutController)

		window.protocol("WM_DELETE_WINDOW", self.closingController)
		self.controller = window
	
	def closingController(self):
		# stop listening to keyboard events
		if not self.keyboard is None:
			self.keyboard.stop()
			self.keyboard = None
		
		self.root.bind("<FocusIn>", lambda _: None)
		self.root.bind("<FocusOut>", lambda _: None)

		self.controller.destroy()
		self.controller = None
	
	def onFocusInController(self, event):
		# enable Keyboard as controller
		if self.keyboard is None:
			self.keyboard = SwitchKeyboardController(self.keyPress)
			self.keyboard.listen()
	
	def onFocusOutController(self, event):
		# stop listening to keyboard events
		if not self.keyboard is None:
			self.keyboard.stop()
			self.keyboard = None

	def doProcess(self):
		image_bgr = self.camera.readFrame()
		if self.showPreview.get() and image_bgr is not None:
			image_bgr = cv2.resize(image_bgr, (640, 360))
			image_rgb = cv2.cvtColor(image_bgr, cv2.COLOR_BGR2RGB) 
			image_pil = Image.fromarray(image_rgb) 
			image_tk  = ImageTk.PhotoImage(image_pil)
			
			self.preview.im = image_tk
			self.preview['image']=image_tk

		self.root.after((int)(16 * (60 / int(self.fps.get()))), self.doProcess)
	
	def write(self, str):
		self.logArea.insert(tk.END, str)
		time.sleep(0.0001)
		self.logArea.see(tk.END)