def _set_icon_from_execution_results(self, controller): node = self._controller.find_node_by_controller(controller) if not node: return img_index = self._get_icon_index_for(controller) # Always set the static icon self.SetItemImage(node, img_index) if self._animctrl: self._animctrl.Stop() self._animctrl.Animation.Destroy() self._animctrl.Destroy() self._animctrl = None self.DeleteItemWindow(node) if img_index in (RUNNING_IMAGE_INDEX, PAUSED_IMAGE_INDEX): from wx.adv import Animation, AnimationCtrl import os _BASE = os.path.join(os.path.dirname(__file__), '..', 'widgets') if img_index == RUNNING_IMAGE_INDEX: img = os.path.join(_BASE, 'robot-running.gif') else: img = os.path.join(_BASE, 'robot-pause.gif') ani = Animation(img) obj = self rect = (node.GetX() + 20, node.GetY()) # Overlaps robot icon self._animctrl = AnimationCtrl(obj, -1, ani, rect) """ self._animctrl.SetBackgroundColour(obj.GetBackgroundColour()) """ self._animctrl.SetBackgroundColour('white') self.SetItemWindow(node, self._animctrl, False) self._animctrl.Play() # Make visible the running or paused test self.EnsureVisible(node)
def initpanel2(self, event): self.panel2.DestroyChildren() # self.panel2.bacpic = wx.Image('confbac.jpg', wx.BITMAP_TYPE_JPEG, ).Scale(1100,295).ConvertToBitmap() # self.panel2.bk = wx.StaticBitmap(parent=self.panel2, bitmap=self.panel2.bacpic) self.tex = wx.TextCtrl(parent=self.panel2, size=(900, 500), style=wx.TE_MULTILINE | wx.STAY_ON_TOP | wx.TE_READONLY) font = wx.Font(16, wx.ROMAN, wx.NORMAL, wx.NORMAL) self.tex.SetFont(font) self.tex.SetMaxLength(20) self.panelpic_gif = os.path.join(KeyboardRecorderr0.PIC_PATH, 'anikey.gif') self.panelpic = wx.Image( os.path.join(KeyboardRecorderr0.PIC_PATH, 'key.png'), wx.BITMAP_TYPE_PNG).Scale(1005, 305).ConvertToBitmap() ani = Animation(self.panelpic_gif) self.keybdbk = AnimationCtrl(self.panel2, -1, ani) self.keybdbk.Play() self.tex.SetBackgroundColour('black') self.tex.SetForegroundColour('white') self.LEDinit() self.Sizer = wx.BoxSizer(wx.VERTICAL) self.Sizer.Add(self.tex, 0, wx.EXPAND) self.Sizer.Add(self.keybdbk, 1, wx.EXPAND) self.panel2.SetSizer(self.Sizer) self.panel2.Fit() self.temp = sys.stdout redir = RedirectText(self.tex) sys.stdout = redir self.keybdbk.Bind(wx.EVT_LEFT_DCLICK, self.StopAndStart)
def __init__( self, title, parent=None, style=wx.DEFAULT_DIALOG_STYLE): """ :param parent: Can be None, a frame or another dialog box. :type parent: wx.Window :param title: The title of the dialog. :type title: str :param style: The window style. :type style: int """ self.parent = parent wx.Dialog.__init__(self, parent, wx.ID_ANY, title, style=style) # Prevent closing of dialog self.Bind(wx.EVT_CLOSE, lambda event: None) with path(GuiV2.GSMatch2_Core.GUI, "loading_animation.gif") as loading_gif: ani = Animation(name=str(loading_gif)) ctrl = AnimationCtrl(self, -1, ani) ctrl.SetBackgroundColour(self.GetBackgroundColour()) if wx.Platform == "__WXMSW__": self.Fit() ctrl.Play()
class Animate(wx.Frame): def __init__(self, parent, id, title): wx.Frame.__init__(self, parent, -1, title) self.animation = AnimationCtrl(self) self.animation.LoadFile('ajax-bar-loader.gif') self.animation.Play() self.Show()
def Sortear(self, e): #se podria agregar la cantidad de ganadores con = sqlite3.connect("DatosSorteo00.db") cur = con.cursor() listanumerosusados = [] for row in cur.execute('SELECT * FROM concursantes00;'): print(row) listanumerosusados.append(row) con.close() b = randint(0, len(listanumerosusados) - 1) G = ("Ganador/a: \n" + str(listanumerosusados[b])) styles = DEFAULT_FRAME_STYLE & ~(CAPTION) f4 = Frame(None, -1, " GANADOR/A ", size=(500, 510)) p4 = self.p4 = Panel(f4) p4.SetBackgroundColour((100, 149, 237)) imagen = AnimationCtrl(p4) imagen.LoadFile('tenor.gif') imagen.Play() ganadora = StaticText(p4, -1, G, size=(60, 20), pos=(5, 400)) font = wx.Font(10, MODERN, SLANT, BOLD) ganadora.SetFont(font) f4.Show() return True
def __init__(self, parent, log): self.controls = [None, None, None, None, None] self.timeStart = None self.log = log wx.StatusBar.__init__(self, parent, -1) self.SetFieldsCount(len(self.controls)) self.controls[0] = wx.StaticText(self, label=self.TEXT_GENERAL, style=wx.ST_NO_AUTORESIZE) self.controls[1] = wx.StaticText(self, label=self.TEXT_INFO, style=wx.ST_NO_AUTORESIZE) self.controls[2] = Led(self, label=self.TEXT_GPS) self.controls[3] = wx.Gauge(self, -1, style=wx.GA_HORIZONTAL | wx.GA_SMOOTH) animation = Animation(get_resource('busy.gif')) busy = AnimationCtrl(self, anim=animation) busy.SetToolTip('Updating plot') self.controls[4] = busy self.controls[3].Hide() self.controls[4].Hide() self.SetStatusWidths([-1, -1, -1, -1, busy.GetSize()[0] * 4]) self.Bind(wx.EVT_SIZE, self.__on_size) wx.CallAfter(self.__on_size, None) self.Fit()
def _set_icon_from_execution_results(self, controller): node = self._controller.find_node_by_controller(controller) if not node: return img_index = self._get_icon_index_for(controller) # Always set the static icon self.SetItemImage(node, img_index) # print("DEBUG setIcon img_index=%d" % (img_index)) if wx.VERSION >= (3, 0, 3, '') and self._animctrl: self._animctrl.Stop() self._animctrl.Animation.Destroy() self._animctrl.Destroy() self._animctrl = None if wx.VERSION >= (3, 0, 3, '') and img_index in (RUNNING_IMAGE_INDEX, PAUSED_IMAGE_INDEX): from wx.adv import Animation, AnimationCtrl import os _BASE = os.path.join(os.path.dirname(__file__), '..', 'widgets') if img_index == RUNNING_IMAGE_INDEX: img = os.path.join(_BASE, 'robot-running.gif') else: img = os.path.join(_BASE, 'robot-pause.gif') ani = Animation(img) obj = self rect = (node.GetX() + 20, node.GetY()) # Overlaps robot icon self._animctrl = AnimationCtrl(obj, -1, ani, rect) self._animctrl.SetBackgroundColour(obj.GetBackgroundColour()) try: self.SetItemWindow(node, self._animctrl, False) except TypeError: # DEBUG In case wxPython devel not ready self.SetItemWindow(node, self._animctrl) self._animctrl.Play() # Make visible the running or paused test self.EnsureVisible(node)
def __do_layout(self): sizer_5 = wx.BoxSizer(wx.VERTICAL) sizer_6 = wx.BoxSizer(wx.VERTICAL) label_19 = wx.StaticText(self.panel_5, wx.ID_ANY, "Change Connections...") label_19.SetFont( wx.Font(16, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD, 0, "")) sizer_6.Add(label_19, 0, wx.ALIGN_CENTER | wx.ALL, 10) if False: # TODO: Get gifs working!! # https://stackoverflow.com/a/49403198 # https://github.com/wxWidgets/Phoenix/blob/master/demo/AnimationCtrl.py gif = AnimationCtrl(self.panel_5, wx.ID_ANY, size=(456, 448)) gif.LoadFile(f'images\\gifs\\connection0{self.pos + 1}.gif', animType=wx.adv.ANIMATION_TYPE_ANY) gif.SetBackgroundColour(self.GetBackgroundColour()) gif.Play() sizer_6.Add(gif, 1) # For now, use a static image... else: bitmap_1 = wx.StaticBitmap( self.panel_5, wx.ID_ANY, wx.Bitmap(f'images\\connection0{self.pos + 1}.jpg', wx.BITMAP_TYPE_ANY)) sizer_6.Add(bitmap_1, 0, 0, 0) sizer_6.Add(self.btn_continue, 0, wx.ALIGN_CENTER | wx.ALL, 10) self.panel_5.SetSizer(sizer_6) sizer_5.Add(self.panel_5, 1, wx.ALL | wx.EXPAND, 5) self.SetSizer(sizer_5) sizer_5.Fit(self) self.Layout()
def StopAndStart(self, evt): if KeyboardRecorderr0.start: KeyboardRecorderr0.start = 0 redir = RedirectText(self.tex) sys.stdout = redir print '\n> Recording restarted:-)' self.keybdbk.Destroy() ani = Animation(self.panelpic_gif) self.keybdbk = AnimationCtrl(self.panel2, -1, ani) self.keybdbk.Play() self.keybdbk.Bind(wx.EVT_LEFT_DCLICK, self.StopAndStart) self.Sizer.Add(self.keybdbk, 1, wx.EXPAND) self.panel2.SetSizer(self.Sizer) self.panel2.Fit() self.LEDinit() else: KeyboardRecorderr0.start = 1 print '\n> Recording stopped.' sys.stdout = self.temp self.keybdbk.Destroy() self.keybdbk = wx.StaticBitmap(parent=self.panel2, bitmap=self.panelpic) self.keybdbk.Bind(wx.EVT_LEFT_DCLICK, self.StopAndStart) self.Sizer.Add(self.keybdbk, 1, wx.EXPAND) self.panel2.SetSizer(self.Sizer) self.panel2.Fit() self.LEDinit()
def init(self, parent): """ Finishes initializing the editor by creating the underlying toolkit widget. """ self._animate = Animation(self.value) self.control = AnimationCtrl(parent, -1, self._animate) #self.control.SetUseWindowBackgroundColour() self.sync_value(self.factory.playing, 'playing', 'from') self.set_tooltip()
class _AnimatedGIFEditor(Editor): """ Editor that displays an animated GIF file. """ #--------------------------------------------------------------------------- # Trait definitions: #--------------------------------------------------------------------------- # Is the animated GIF file currently playing? playing = Bool(True) #--------------------------------------------------------------------------- # Finishes initializing the editor by creating the underlying toolkit # widget: #--------------------------------------------------------------------------- def init(self, parent): """ Finishes initializing the editor by creating the underlying toolkit widget. """ self._animate = Animation(self.value) self.control = AnimationCtrl(parent, -1, self._animate) #self.control.SetUseWindowBackgroundColour() self.sync_value(self.factory.playing, 'playing', 'from') self.set_tooltip() #--------------------------------------------------------------------------- # Updates the editor when the object trait changes external to the editor: #--------------------------------------------------------------------------- def update_editor(self): """ Updates the editor when the object trait changes externally to the editor. """ if not self.playing: self.control.Stop() self.control.LoadFile(self.value) self._file_loaded = True if self.playing: self.control.Play() #--------------------------------------------------------------------------- # Handles the editor 'playing' trait being changed: #--------------------------------------------------------------------------- def _playing_changed(self): if self._file_loaded: if self.playing: self.control.Play() else: self.control.Stop()
def __init__(self, parent, idx, size=(280, 200), style=wx.TRANSPARENT_WINDOW): """ Panel to simulate the camera view.""" wx.Panel.__init__(self, parent) sizer = wx.BoxSizer(wx.VERTICAL) self.animCtrl = AnimationCtrl(self, -1, Animation(gv.TPSGIP_PATH)) self.animCtrl.Stop() # stop the gif play first. sizer.Add(self.animCtrl) self.SetSizerAndFit(sizer) self.Show()
def __init__(self, parent, id, title): wx.Frame.__init__(self, parent, -1, title) self.animation = AnimationCtrl(self, pos=(300, 40), size=(50000, 5000), name="AnimationCtrl") self.animation.LoadFile( "/Users/glynellis/Desktop/Dissertation/gifs/face prototype blink.gif" ) self.animation.Play() self.animation.Center() self.Show()
def __init__(self, parent, log): self.log = log wx.Panel.__init__(self, parent, -1) sizer = wx.FlexGridSizer(cols=3, hgap=5, vgap=5) for name in GIFNames: ani = Animation(opj(name)) ctrl = AnimationCtrl(self, -1, ani) ctrl.SetBackgroundColour(self.GetBackgroundColour()) ctrl.Play() sizer.Add(ctrl, 0, wx.ALL, 10) border = wx.BoxSizer() border.Add(sizer, 1, wx.EXPAND | wx.ALL, 20) self.SetSizer(border)
def buidUISizer(self): """ Build the UI and the return the wx.sizer. """ sizer = wx.BoxSizer(wx.VERTICAL) self.ctrl = AnimationCtrl(self, -1, Animation(gv.TAGIF_PATH)) self.ctrl.Play() sizer.Add(self.ctrl, flag=wx.CENTER | wx.ALIGN_CENTER_HORIZONTAL, border=2) self.stTxt = wx.StaticText( self, -1, "Your computer has been taken over by YC's Trojan, we will release control in 10 sec" ) self.stTxt.SetBackgroundColour(wx.Colour('GREEN')) self.stTxt.SetFont(wx.Font(30, wx.SWISS, wx.NORMAL, wx.NORMAL)) sizer.Add(self.stTxt, flag=wx.ALIGN_CENTER, border=2) return sizer
def __init__(self, parent, title, thread): super(ConnectingDialog, self).__init__(parent, title = title, size = (350,120)) panel = wx.Panel(self) self.thread = thread self.animation = AnimationCtrl(panel) self.animation.LoadFile("load.gif") self.animation.Play() self.label = wx.StaticText(panel, label="Uploading to the server") hbox = wx.BoxSizer(wx.HORIZONTAL) hbox.Add(self.animation, 1, wx.ALL, 5) hbox.Add(self.label, 2, wx.TOP|wx.BOTTOM|wx.EXPAND|wx.ALIGN_CENTER, 25) panel.SetSizer(hbox) self.Bind(wx.EVT_CLOSE, self.onClose) wx.CallLater(100, self.update, 1, 0, self.label)
class ConnectingDialog(wx.Dialog): def __init__(self, parent, title, thread): super(ConnectingDialog, self).__init__(parent, title = title, size = (350,120)) panel = wx.Panel(self) self.thread = thread self.animation = AnimationCtrl(panel) self.animation.LoadFile("load.gif") self.animation.Play() self.label = wx.StaticText(panel, label="Uploading to the server") hbox = wx.BoxSizer(wx.HORIZONTAL) hbox.Add(self.animation, 1, wx.ALL, 5) hbox.Add(self.label, 2, wx.TOP|wx.BOTTOM|wx.EXPAND|wx.ALIGN_CENTER, 25) panel.SetSizer(hbox) self.Bind(wx.EVT_CLOSE, self.onClose) wx.CallLater(100, self.update, 1, 0, self.label) def update(self, count, tick, label): if not self.thread.isAlive(): self.Destroy() return if tick >= 8: tick = 0 text = "Uploading to the server" + '.'*count label.SetLabel(text) if count > 4: count = 0 else: count+=1 wx.CallLater(100, self.update, count, tick+1, label) def onClose(self, event): if event.CanVeto(): event.Veto() return else: self.Destroy()
def __init__(self, parent=None): """ :param parent: Can be None, a frame or another dialog box. :type parent: wx.Window """ wx.Dialog.__init__(self, parent, style=0) with path(GuiV2.GSMatch2_Core.GUI, "loading_animation.gif") as loading_gif: ani = Animation(name=str(loading_gif)) sizer = wx.BoxSizer(wx.VERTICAL) ctrl = AnimationCtrl(self, -1, ani) ctrl.SetBackgroundColour(self.GetBackgroundColour()) sizer.Add(ctrl, 1, wx.EXPAND, 0) self.SetSizer(sizer) ctrl.Play() if wx.Platform == "__WXMSW__": self.Fit() self.CenterOnScreen()
def __init__(self, parent, id): wx.Frame.__init__(self, parent, id, size=(400, 200), style=0) panel = wx.Panel(self) self.LoadingText = wx.StaticText(panel, label="Loading...", pos=(335, 20)) self.LoadingText.SetForegroundColour('white') sizer = wx.BoxSizer(wx.VERTICAL) anim = Animation('123.gif') ctrl = AnimationCtrl(self, id, anim) #ctrl.Play() sizer.Add(ctrl) self.SetSizerAndFit(sizer)
class PanelCameraView(wx.Panel): """ Panel play a gif image to simulation the camera view when train pass.""" def __init__(self, parent, idx, size=(280, 200), style=wx.TRANSPARENT_WINDOW): """ Panel to simulate the camera view.""" wx.Panel.__init__(self, parent) sizer = wx.BoxSizer(wx.VERTICAL) self.animCtrl = AnimationCtrl(self, -1, Animation(gv.TPSGIP_PATH)) self.animCtrl.Stop() # stop the gif play first. sizer.Add(self.animCtrl) self.SetSizerAndFit(sizer) self.Show() #--PanelCameraView------------------------------------------------------------- def setPlay(self, plagFlag): """ Set the gif play or stop""" if plagFlag: self.animCtrl.Play() else: self.animCtrl.Stop()
def __init__(self, parent, title: str, gui: 'ChatbotGUI'): # init parent wx.Frame.__init__(self, parent, -1, title=title) # a reference to the chatbot GUI self.gui = gui # grid for splitting the screen into two parts, the gif and I/O elements self.grid = wx.BoxSizer(wx.HORIZONTAL) # user & AI message history self.user_message_history = [] self.ai_message_history = [] # panel for all of the I/O elements self.io_panel = wx.Panel(self) # the sizer for the panel I/O elements self.io_sizer = wx.BoxSizer(wx.VERTICAL) # chat bot animation asset self.chatbot_gif = Animation('talking.gif') # animation controller for the chat bot gif self.chatbot_control = AnimationCtrl(self, -1, self.chatbot_gif) # # I/O elements # # input chat self.input_chat = wx.TextCtrl(self.io_panel, size=wx.Size(200, 200), style=wx.TE_READONLY | wx.TE_MULTILINE) # input chat label self.input_chat_label = wx.StaticText(self.io_panel, label="Chat with AI:") # input chat text box self.input_box = wx.TextCtrl(self.io_panel, style=wx.TE_PROCESS_ENTER, size=wx.Size(200, 20)) # input chat enter button self.chat_button = wx.Button(self.io_panel, label="Send") # input chat label self.output_chat_label = wx.StaticText(self.io_panel, label="AI Responses:") # output chat self.output_chat = wx.TextCtrl(self.io_panel, size=wx.Size(200, 200), style=wx.TE_READONLY | wx.TE_MULTILINE) # start AI gif button self.start_gif = wx.Button(self.io_panel, label="Start GIF", size=wx.Size(200, 100)) # stop gif button self.stop_gif = wx.Button(self.io_panel, label="Stop GIF", size=wx.Size(200, 100)) # # Add and size elements # # add elements to the I/O sizer self.io_sizer.Add(self.input_chat, 0, wx.EXPAND | wx.ALL, 5) self.io_sizer.Add(self.input_chat_label, 0, wx.EXPAND | wx.LEFT | wx.TOP, 5) self.io_sizer.Add(self.input_box, 0, wx.EXPAND | wx.ALL, 5) self.io_sizer.Add(self.chat_button, 0, wx.EXPAND | wx.ALL, 5) self.io_sizer.Add(self.output_chat_label, 0, wx.EXPAND | wx.LEFT | wx.TOP, 5) self.io_sizer.Add(self.output_chat, 0, wx.EXPAND | wx.ALL, 5) self.io_sizer.Add(self.start_gif, 0, wx.EXPAND | wx.ALL, 5) self.io_sizer.Add(self.stop_gif, 0, wx.EXPAND | wx.ALL, 5) # add elements to the main grid sizer self.grid.Add(self.io_panel, 0, wx.EXPAND | wx.ALL) self.grid.Add(self.chatbot_control) # size and fit the sizers self.io_panel.SetSizerAndFit(self.io_sizer) self.SetSizerAndFit(self.grid) # # Bind buttons to functions # self.Bind(wx.EVT_TEXT_ENTER, self.on_send_press) self.Bind(wx.EVT_BUTTON, self.on_send_press, self.chat_button) self.Bind(wx.EVT_BUTTON, self.start_animation, self.start_gif) self.Bind(wx.EVT_BUTTON, self.stop_animation, self.stop_gif)
class Main(wx.Frame): def __init__(self, parent, title: str, gui: 'ChatbotGUI'): # init parent wx.Frame.__init__(self, parent, -1, title=title) # a reference to the chatbot GUI self.gui = gui # grid for splitting the screen into two parts, the gif and I/O elements self.grid = wx.BoxSizer(wx.HORIZONTAL) # user & AI message history self.user_message_history = [] self.ai_message_history = [] # panel for all of the I/O elements self.io_panel = wx.Panel(self) # the sizer for the panel I/O elements self.io_sizer = wx.BoxSizer(wx.VERTICAL) # chat bot animation asset self.chatbot_gif = Animation('talking.gif') # animation controller for the chat bot gif self.chatbot_control = AnimationCtrl(self, -1, self.chatbot_gif) # # I/O elements # # input chat self.input_chat = wx.TextCtrl(self.io_panel, size=wx.Size(200, 200), style=wx.TE_READONLY | wx.TE_MULTILINE) # input chat label self.input_chat_label = wx.StaticText(self.io_panel, label="Chat with AI:") # input chat text box self.input_box = wx.TextCtrl(self.io_panel, style=wx.TE_PROCESS_ENTER, size=wx.Size(200, 20)) # input chat enter button self.chat_button = wx.Button(self.io_panel, label="Send") # input chat label self.output_chat_label = wx.StaticText(self.io_panel, label="AI Responses:") # output chat self.output_chat = wx.TextCtrl(self.io_panel, size=wx.Size(200, 200), style=wx.TE_READONLY | wx.TE_MULTILINE) # start AI gif button self.start_gif = wx.Button(self.io_panel, label="Start GIF", size=wx.Size(200, 100)) # stop gif button self.stop_gif = wx.Button(self.io_panel, label="Stop GIF", size=wx.Size(200, 100)) # # Add and size elements # # add elements to the I/O sizer self.io_sizer.Add(self.input_chat, 0, wx.EXPAND | wx.ALL, 5) self.io_sizer.Add(self.input_chat_label, 0, wx.EXPAND | wx.LEFT | wx.TOP, 5) self.io_sizer.Add(self.input_box, 0, wx.EXPAND | wx.ALL, 5) self.io_sizer.Add(self.chat_button, 0, wx.EXPAND | wx.ALL, 5) self.io_sizer.Add(self.output_chat_label, 0, wx.EXPAND | wx.LEFT | wx.TOP, 5) self.io_sizer.Add(self.output_chat, 0, wx.EXPAND | wx.ALL, 5) self.io_sizer.Add(self.start_gif, 0, wx.EXPAND | wx.ALL, 5) self.io_sizer.Add(self.stop_gif, 0, wx.EXPAND | wx.ALL, 5) # add elements to the main grid sizer self.grid.Add(self.io_panel, 0, wx.EXPAND | wx.ALL) self.grid.Add(self.chatbot_control) # size and fit the sizers self.io_panel.SetSizerAndFit(self.io_sizer) self.SetSizerAndFit(self.grid) # # Bind buttons to functions # self.Bind(wx.EVT_TEXT_ENTER, self.on_send_press) self.Bind(wx.EVT_BUTTON, self.on_send_press, self.chat_button) self.Bind(wx.EVT_BUTTON, self.start_animation, self.start_gif) self.Bind(wx.EVT_BUTTON, self.stop_animation, self.stop_gif) def start_animation(self, event): print(event) self.chatbot_control.Play() def stop_animation(self, event): self.chatbot_control.Stop() # updates the user and AI message histories def update_message_history(self): # variables to store the aggregated text user_text = "" ai_text = "" # aggregate user messages for message in self.user_message_history: user_text += "You> " + message + "\n" # aggregate ai messages for message in self.ai_message_history: ai_text += "AI> " + str(message) + "\n" # update the chats self.input_chat.SetValue(user_text) self.output_chat.SetValue(ai_text) # send a ai message def send_ai_message(self, text: str): # add the message to message history self.ai_message_history.insert(0, text) # update the message history self.update_message_history() # clears the user and AI chat history def clear_chat(self): self.user_message_history = [] self.ai_message_history = [] self.update_message_history() # function handling "send" button press def on_send_press(self, event): # read the text box text = self.input_box.GetValue() if text == "": return # clear the text box self.input_box.SetValue("") # add the message to message history self.user_message_history.insert(0, text) # update the message history self.update_message_history() # call the message handler function for the ChatBot GUI self.gui.call_on_message(text)
class FrameGesto1 (wx.Frame): def __init__(self, parent): wx.Frame.__init__(self, parent, id=wx.ID_ANY, title=u"Captura de señales para el gesto 1", pos=wx.DefaultPosition, size=wx.Size(1400, 700), style=wx.DEFAULT_FRAME_STYLE | wx.TAB_TRAVERSAL) self.SetSizeHintsSz(wx.DefaultSize, wx.DefaultSize) bSizer4 = wx.BoxSizer(wx.VERTICAL) self.m_staticText2 = wx.StaticText( self, wx.ID_ANY, u"Captura de señales para el primer gesto \n", wx.DefaultPosition, wx.Size(700, -1), 0) self.m_staticText2.Wrap(-1) self.m_staticText2.SetFont( wx.Font(34, 70, 90, 90, False, wx.EmptyString)) bSizer4.Add(self.m_staticText2, 0, wx.ALIGN_CENTER_HORIZONTAL, 10) bSizer49 = wx.BoxSizer(wx.VERTICAL) bSizer50 = wx.BoxSizer(wx.HORIZONTAL) bSizer50.SetMinSize(wx.Size(700, -1)) self.m_staticText30 = wx.StaticText( self, wx.ID_ANY, u"Para iniciar el experimento por favor observe \n ", wx.DefaultPosition, wx.Size(1000, -1), 0) self.m_staticText30.Wrap(-1) self.m_staticText30.SetFont( wx.Font(17, 70, 90, 90, False, wx.EmptyString)) bSizer50.Add(self.m_staticText30, 0, wx.ALL, 5) bSizer52 = wx.BoxSizer(wx.VERTICAL) bSizer52.SetMinSize(wx.Size(90, -1)) self.m_button32 = wx.Button( self, wx.ID_ANY, u"Inicio", wx.Point(-1, -1), wx.Size(150, -1), 0) self.m_button32.SetFont(wx.Font(25, 70, 90, 90, False, wx.EmptyString)) bSizer52.Add(self.m_button32, 0, wx.TOP, 10) bSizer50.Add(bSizer52, 1, 0, 5) self.m_animCtrl1 = AnimationCtrl(self, pos=( 40, 40), size=(24, 24), name="AnimationCtrl") self.m_animCtrl1.LoadFile(u"/Users/macfabian/Desktop/manos.gif") self.m_animCtrl1.Play() self.m_animCtrl1.SetMinSize(wx.Size(200, -1)) bSizer50.Add(self.m_animCtrl1, 0, wx.ALIGN_CENTER, 5) bSizer49.Add(bSizer50, 1, 0, 5) bSizer51 = wx.BoxSizer(wx.VERTICAL) self.m_staticText31 = wx.StaticText( self, wx.ID_ANY, u"Señal EMG", wx.DefaultPosition, wx.DefaultSize, 0) self.m_staticText31.Wrap(-1) self.m_staticText31.SetFont( wx.Font(18, 70, 90, 90, False, wx.EmptyString)) bSizer51.Add(self.m_staticText31, 0, wx.ALL, 5) self.figure = Figure(figsize=(1, 2), dpi=80) self.axes = self.figure.add_subplot(111) t = np.arange(0.0, 3.0, 0.01) s = np.sin(2 * np.pi * t) self.axes.plot(t, s) self.canvas = FigureCanvas(self, -1, self.figure) bSizerEMG = wx.BoxSizer(wx.VERTICAL) bSizerEMG.Add(self.canvas, 1, wx.TOP | wx.LEFT | wx.EXPAND) bSizer49.Add(bSizerEMG, 1, wx.EXPAND, 5) bSizer49.Add(bSizer51, 1, wx.EXPAND, 5) bSizer53 = wx.BoxSizer(wx.VERTICAL) self.m_staticText32 = wx.StaticText( self, wx.ID_ANY, u"Señal EEG", wx.DefaultPosition, wx.DefaultSize, 0) self.m_staticText32.Wrap(-1) self.m_staticText32.SetFont( wx.Font(18, 70, 90, 90, False, wx.EmptyString)) self.figure = Figure(figsize=(1, 2), dpi=80) self.axes = self.figure.add_subplot(111) t = np.arange(0.0, 3.0, 0.01) s = np.sin(2 * np.pi * t) self.axes.plot(t, s) self.canvas = FigureCanvas(self, -1, self.figure) bSizerEEG = wx.BoxSizer(wx.VERTICAL) bSizerEEG.Add(self.canvas, 1, wx.TOP | wx.LEFT | wx.EXPAND) bSizer49.Add(bSizerEEG, 1, wx.EXPAND, 5) bSizer53.Add(self.m_staticText32, 0, wx.ALL, 5) bSizer49.Add(bSizer53, 1, wx.EXPAND, 5) bSizer8 = wx.BoxSizer(wx.HORIZONTAL) self.m_staticText33 = wx.StaticText( self, wx.ID_ANY, u"Tiempo:", wx.DefaultPosition, wx.Size(550, -1), 0) self.m_staticText33.Wrap(-1) self.m_staticText33.SetFont( wx.Font(18, 70, 90, 90, False, wx.EmptyString)) bSizer8.Add(self.m_staticText33, 0, wx.ALL, 5) pos = wx.DefaultPosition size = wx.DefaultSize style = gizmos.LED_ALIGN_CENTER self.led = gizmos.LEDNumberCtrl(self, -1, pos, size, style) self.led.SetBackgroundColour("white") self.led.SetForegroundColour("black") bSizerTimmer = wx.BoxSizer(wx.VERTICAL) bSizerTimmer.Add(self.led, 1, wx.TOP | wx.LEFT | wx.EXPAND) bSizer49.Add(bSizerTimmer, 1, wx.EXPAND, 5) self.button_siguiente = wx.Button( self, wx.ID_ANY, u"Aceptar", wx.DefaultPosition, wx.Size(150, -1), 0) self.button_siguiente.SetFont( wx.Font(18, 70, 90, 90, False, wx.EmptyString)) bSizer8.Add(self.button_siguiente, 0, wx.ALL, 5) self.button_salir = wx.Button( self, wx.ID_ANY, u"Salir", wx.DefaultPosition, wx.Size(150, -1), 0) self.button_salir.SetFont( wx.Font(18, 70, 90, 90, False, wx.EmptyString)) bSizer8.Add(self.button_salir, 0, wx.ALL, 5) bSizer49.Add(bSizer8, 0, wx.TOP, 1) bSizer4.Add(bSizer49, 1, wx.EXPAND, 5) self.SetSizer(bSizer4) self.Layout() self.Centre(wx.BOTH) # Connect Events self.m_button32.Bind(wx.EVT_BUTTON, self.OnClickInicio) self.button_siguiente.Bind(wx.EVT_BUTTON, self.OnClickConcentimiento) self.button_salir.Bind(wx.EVT_BUTTON, self.OnClickSalir) def __del__(self): pass # Virtual event handlers, overide them in your derived class def OnClickConcentimiento(self, event): event.Skip() def OnClickSalir(self, event): self.Close() def OnClickInicio(self, event): global i i = 0 self.led.SetValue("0:00") self.OnTimer(None, e=10) def OnTimer(self, event, e): global i global c c = e print("entro On Timmer c") print(c) print("ojo i") print(i) if(i < c): print("entro if") print(i) i += 1 self.timer = wx.Timer(self, -1) self.timer.Start(1000) self.Bind(wx.EVT_TIMER, self.TimerGo) else: print("stop") self.timer.Stop() def TimerGo(self, event): global s global m global t global c s = int(s) m = int(m) if(s < 59): s += 1 elif(s == 59): s = 0 if(m < 59): m += 1 elif(m == 59): m = 0 if (int(s) < 10): s = str(0) + str(s) if(int(s) > 9): s = str(s) t = str(m) + ":" + str(s) print("Timmer") print(t) self.led.SetValue(t) self.OnTimer(None , c)
def __init__(self, parent, log): self.log = log wx.Panel.__init__(self, parent, -1) sizer = wx.FlexGridSizer(cols=3, hgap=5, vgap=5) for name in GIFNames: # There are a few usage patterns for creating the control and the # animation object. They're more-or-less equivalent, but if you have # non-standard needs in your application then one pattern may make # more sense for you to use. if False: # If you need a separate animation object then you can have the # control create one for you. ctrl = AnimationCtrl(self) ani = ctrl.CreateAnimation() ani.LoadFile(opj(name)) ctrl.SetAnimation(ani) elif False: # if you need to have the animation object before the control is # created, then you can do it like this: ani = AnimationCtrl.CreateCompatibleAnimation() ani.LoadFile(opj(name)) ctrl = AnimationCtrl(self, -1, ani) else: # Or you can keep it simple and just have the control make and # use its own animation object internally. ctrl = AnimationCtrl(self) ctrl.LoadFile(opj(name)) ctrl.SetBackgroundColour(self.GetBackgroundColour()) ctrl.Play() sizer.Add(ctrl, 0, wx.ALL, 10) if UseNative and 'wxGTK' in wx.PlatformInfo: # See comment in updateBestSizes below wx.CallAfter(self.updateBestSizes) border = wx.BoxSizer() border.Add(sizer, 1, wx.EXPAND | wx.ALL, 20) self.SetSizer(border)
def __init__(self, parent): wx.Frame.__init__(self, parent, id=wx.ID_ANY, title=u"Captura de señales para el gesto 1", pos=wx.DefaultPosition, size=wx.Size(1400, 700), style=wx.DEFAULT_FRAME_STYLE | wx.TAB_TRAVERSAL) self.SetSizeHintsSz(wx.DefaultSize, wx.DefaultSize) bSizer4 = wx.BoxSizer(wx.VERTICAL) self.m_staticText2 = wx.StaticText( self, wx.ID_ANY, u"Captura de señales para el primer gesto \n", wx.DefaultPosition, wx.Size(700, -1), 0) self.m_staticText2.Wrap(-1) self.m_staticText2.SetFont( wx.Font(34, 70, 90, 90, False, wx.EmptyString)) bSizer4.Add(self.m_staticText2, 0, wx.ALIGN_CENTER_HORIZONTAL, 10) bSizer49 = wx.BoxSizer(wx.VERTICAL) bSizer50 = wx.BoxSizer(wx.HORIZONTAL) bSizer50.SetMinSize(wx.Size(700, -1)) self.m_staticText30 = wx.StaticText( self, wx.ID_ANY, u"Para iniciar el experimento por favor observe \n ", wx.DefaultPosition, wx.Size(1000, -1), 0) self.m_staticText30.Wrap(-1) self.m_staticText30.SetFont( wx.Font(17, 70, 90, 90, False, wx.EmptyString)) bSizer50.Add(self.m_staticText30, 0, wx.ALL, 5) bSizer52 = wx.BoxSizer(wx.VERTICAL) bSizer52.SetMinSize(wx.Size(90, -1)) self.m_button32 = wx.Button( self, wx.ID_ANY, u"Inicio", wx.Point(-1, -1), wx.Size(150, -1), 0) self.m_button32.SetFont(wx.Font(25, 70, 90, 90, False, wx.EmptyString)) bSizer52.Add(self.m_button32, 0, wx.TOP, 10) bSizer50.Add(bSizer52, 1, 0, 5) self.m_animCtrl1 = AnimationCtrl(self, pos=( 40, 40), size=(24, 24), name="AnimationCtrl") self.m_animCtrl1.LoadFile(u"/Users/macfabian/Desktop/manos.gif") self.m_animCtrl1.Play() self.m_animCtrl1.SetMinSize(wx.Size(200, -1)) bSizer50.Add(self.m_animCtrl1, 0, wx.ALIGN_CENTER, 5) bSizer49.Add(bSizer50, 1, 0, 5) bSizer51 = wx.BoxSizer(wx.VERTICAL) self.m_staticText31 = wx.StaticText( self, wx.ID_ANY, u"Señal EMG", wx.DefaultPosition, wx.DefaultSize, 0) self.m_staticText31.Wrap(-1) self.m_staticText31.SetFont( wx.Font(18, 70, 90, 90, False, wx.EmptyString)) bSizer51.Add(self.m_staticText31, 0, wx.ALL, 5) self.figure = Figure(figsize=(1, 2), dpi=80) self.axes = self.figure.add_subplot(111) t = np.arange(0.0, 3.0, 0.01) s = np.sin(2 * np.pi * t) self.axes.plot(t, s) self.canvas = FigureCanvas(self, -1, self.figure) bSizerEMG = wx.BoxSizer(wx.VERTICAL) bSizerEMG.Add(self.canvas, 1, wx.TOP | wx.LEFT | wx.EXPAND) bSizer49.Add(bSizerEMG, 1, wx.EXPAND, 5) bSizer49.Add(bSizer51, 1, wx.EXPAND, 5) bSizer53 = wx.BoxSizer(wx.VERTICAL) self.m_staticText32 = wx.StaticText( self, wx.ID_ANY, u"Señal EEG", wx.DefaultPosition, wx.DefaultSize, 0) self.m_staticText32.Wrap(-1) self.m_staticText32.SetFont( wx.Font(18, 70, 90, 90, False, wx.EmptyString)) self.figure = Figure(figsize=(1, 2), dpi=80) self.axes = self.figure.add_subplot(111) t = np.arange(0.0, 3.0, 0.01) s = np.sin(2 * np.pi * t) self.axes.plot(t, s) self.canvas = FigureCanvas(self, -1, self.figure) bSizerEEG = wx.BoxSizer(wx.VERTICAL) bSizerEEG.Add(self.canvas, 1, wx.TOP | wx.LEFT | wx.EXPAND) bSizer49.Add(bSizerEEG, 1, wx.EXPAND, 5) bSizer53.Add(self.m_staticText32, 0, wx.ALL, 5) bSizer49.Add(bSizer53, 1, wx.EXPAND, 5) bSizer8 = wx.BoxSizer(wx.HORIZONTAL) self.m_staticText33 = wx.StaticText( self, wx.ID_ANY, u"Tiempo:", wx.DefaultPosition, wx.Size(550, -1), 0) self.m_staticText33.Wrap(-1) self.m_staticText33.SetFont( wx.Font(18, 70, 90, 90, False, wx.EmptyString)) bSizer8.Add(self.m_staticText33, 0, wx.ALL, 5) pos = wx.DefaultPosition size = wx.DefaultSize style = gizmos.LED_ALIGN_CENTER self.led = gizmos.LEDNumberCtrl(self, -1, pos, size, style) self.led.SetBackgroundColour("white") self.led.SetForegroundColour("black") bSizerTimmer = wx.BoxSizer(wx.VERTICAL) bSizerTimmer.Add(self.led, 1, wx.TOP | wx.LEFT | wx.EXPAND) bSizer49.Add(bSizerTimmer, 1, wx.EXPAND, 5) self.button_siguiente = wx.Button( self, wx.ID_ANY, u"Aceptar", wx.DefaultPosition, wx.Size(150, -1), 0) self.button_siguiente.SetFont( wx.Font(18, 70, 90, 90, False, wx.EmptyString)) bSizer8.Add(self.button_siguiente, 0, wx.ALL, 5) self.button_salir = wx.Button( self, wx.ID_ANY, u"Salir", wx.DefaultPosition, wx.Size(150, -1), 0) self.button_salir.SetFont( wx.Font(18, 70, 90, 90, False, wx.EmptyString)) bSizer8.Add(self.button_salir, 0, wx.ALL, 5) bSizer49.Add(bSizer8, 0, wx.TOP, 1) bSizer4.Add(bSizer49, 1, wx.EXPAND, 5) self.SetSizer(bSizer4) self.Layout() self.Centre(wx.BOTH) # Connect Events self.m_button32.Bind(wx.EVT_BUTTON, self.OnClickInicio) self.button_siguiente.Bind(wx.EVT_BUTTON, self.OnClickConcentimiento) self.button_salir.Bind(wx.EVT_BUTTON, self.OnClickSalir)
def __init__(self, parent, title: str, gui: 'ChatbotGUI', gif_path: str, show_timestamp: bool = False): # init parent wx.Frame.__init__(self, parent, -1, title=title) # a reference to the chatbot GUI self.gui = gui # keeps track of the show_timestamp self.show_timestamp = show_timestamp # grid for splitting the screen into two parts, the gif and I/O elements self.grid = wx.BoxSizer(wx.HORIZONTAL) # user & AI message history self.user_message_history = [] self.ai_message_history = [] # panel for all of the I/O elements self.io_panel = wx.Panel(self) # the sizer for the panel I/O elements self.io_sizer = wx.BoxSizer(wx.VERTICAL) # chat bot animation asset self.chatbot_gif = Animation(gif_path) # animation controller for the chat bot gif self.chatbot_control = AnimationCtrl(self, -1, self.chatbot_gif) # # I/O elements # # input chat label self.input_chat_top_label = wx.StaticText(self.io_panel, label="History:") # Your chat history self.input_chat = wx.TextCtrl(self.io_panel, size=wx.Size(400, 290), style=wx.TE_READONLY | wx.TE_MULTILINE) # input chat label self.input_chat_label = wx.StaticText(self.io_panel, label="Input:") # input chat text box self.input_box = wx.TextCtrl(self.io_panel, style=wx.TE_PROCESS_ENTER, size=wx.Size(400, 20)) # input chat enter button self.chat_button = wx.Button(self.io_panel, label="Input text to Funbot!") # input chat label self.output_chat_label = wx.StaticText(self.io_panel, label="Chatlog:") # AI chat History self.output_chat = wx.TextCtrl(self.io_panel, size=wx.Size(400, 290), style=wx.TE_READONLY | wx.TE_MULTILINE) # ai status label self.ai_status_label = wx.StaticText(self.io_panel, label="Status:") # ai status box self.status_box = wx.TextCtrl(self.io_panel, style=wx.TE_READONLY) # # Add and size elements # # add elements to the I/O sizer self.io_sizer.Add(self.input_chat_top_label, 0, wx.EXPAND | wx.LEFT | wx.TOP, 5) self.io_sizer.Add(self.input_chat, 0, wx.EXPAND | wx.ALL, 5) self.io_sizer.Add(self.input_chat_label, 0, wx.EXPAND | wx.LEFT | wx.TOP, 5) self.io_sizer.Add(self.input_box, 0, wx.EXPAND | wx.ALL, 5) self.io_sizer.Add(self.chat_button, 0, wx.EXPAND | wx.ALL, 5) self.io_sizer.Add(self.output_chat_label, 0, wx.EXPAND | wx.LEFT | wx.TOP, 5) self.io_sizer.Add(self.output_chat, 0, wx.EXPAND | wx.ALL, 5) self.io_sizer.Add(self.ai_status_label, 0, wx.EXPAND | wx.LEFT | wx.TOP, 5) self.io_sizer.Add(self.status_box, 0, wx.EXPAND | wx.ALL, 5) # add elements to the main grid sizer self.grid.Add(self.io_panel, 0, wx.EXPAND | wx.ALL) self.grid.Add(self.chatbot_control) # size and fit the sizers self.io_panel.SetSizerAndFit(self.io_sizer) self.SetSizerAndFit(self.grid) # # Bind buttons to functions # self.Bind(wx.EVT_TEXT_ENTER, self.on_send_press) self.Bind(wx.EVT_BUTTON, self.on_send_press, self.chat_button) # bind the event handler for commands evt_command(self, self.on_command)
class Main(wx.Frame): def __init__(self, parent, title: str, gui: 'ChatbotGUI', gif_path: str, show_timestamp: bool = False): # init parent wx.Frame.__init__(self, parent, -1, title=title) # a reference to the chatbot GUI self.gui = gui # keeps track of the show_timestamp self.show_timestamp = show_timestamp # grid for splitting the screen into two parts, the gif and I/O elements self.grid = wx.BoxSizer(wx.HORIZONTAL) # user & AI message history self.user_message_history = [] self.ai_message_history = [] # panel for all of the I/O elements self.io_panel = wx.Panel(self) # the sizer for the panel I/O elements self.io_sizer = wx.BoxSizer(wx.VERTICAL) # chat bot animation asset self.chatbot_gif = Animation(gif_path) # animation controller for the chat bot gif self.chatbot_control = AnimationCtrl(self, -1, self.chatbot_gif) # # I/O elements # # input chat label self.input_chat_top_label = wx.StaticText(self.io_panel, label="History:") # Your chat history self.input_chat = wx.TextCtrl(self.io_panel, size=wx.Size(400, 290), style=wx.TE_READONLY | wx.TE_MULTILINE) # input chat label self.input_chat_label = wx.StaticText(self.io_panel, label="Input:") # input chat text box self.input_box = wx.TextCtrl(self.io_panel, style=wx.TE_PROCESS_ENTER, size=wx.Size(400, 20)) # input chat enter button self.chat_button = wx.Button(self.io_panel, label="Input text to Funbot!") # input chat label self.output_chat_label = wx.StaticText(self.io_panel, label="Chatlog:") # AI chat History self.output_chat = wx.TextCtrl(self.io_panel, size=wx.Size(400, 290), style=wx.TE_READONLY | wx.TE_MULTILINE) # ai status label self.ai_status_label = wx.StaticText(self.io_panel, label="Status:") # ai status box self.status_box = wx.TextCtrl(self.io_panel, style=wx.TE_READONLY) # # Add and size elements # # add elements to the I/O sizer self.io_sizer.Add(self.input_chat_top_label, 0, wx.EXPAND | wx.LEFT | wx.TOP, 5) self.io_sizer.Add(self.input_chat, 0, wx.EXPAND | wx.ALL, 5) self.io_sizer.Add(self.input_chat_label, 0, wx.EXPAND | wx.LEFT | wx.TOP, 5) self.io_sizer.Add(self.input_box, 0, wx.EXPAND | wx.ALL, 5) self.io_sizer.Add(self.chat_button, 0, wx.EXPAND | wx.ALL, 5) self.io_sizer.Add(self.output_chat_label, 0, wx.EXPAND | wx.LEFT | wx.TOP, 5) self.io_sizer.Add(self.output_chat, 0, wx.EXPAND | wx.ALL, 5) self.io_sizer.Add(self.ai_status_label, 0, wx.EXPAND | wx.LEFT | wx.TOP, 5) self.io_sizer.Add(self.status_box, 0, wx.EXPAND | wx.ALL, 5) # add elements to the main grid sizer self.grid.Add(self.io_panel, 0, wx.EXPAND | wx.ALL) self.grid.Add(self.chatbot_control) # size and fit the sizers self.io_panel.SetSizerAndFit(self.io_sizer) self.SetSizerAndFit(self.grid) # # Bind buttons to functions # self.Bind(wx.EVT_TEXT_ENTER, self.on_send_press) self.Bind(wx.EVT_BUTTON, self.on_send_press, self.chat_button) # bind the event handler for commands evt_command(self, self.on_command) # function for handling command events def on_command(self, event: CommandEvent): # process send command if event.task == "send": # send ai message to chat self.send_ai_message(event.data) # process gif commands if event.task == "gif": # start gif and set status to speaking if event.data == "start": self.status_box.SetValue("Speaking...") self.start_animation() # stop gif and set status to waiting else: self.status_box.SetValue("Waiting...") self.stop_animation() # process thinking commands if event.task == "thinking": # set status to thinking if event.data == "start": self.status_box.SetValue("Thinking...") # set status to waiting else: self.stop_animation("Waiting...") def start_animation(self, event=None): self.chatbot_control.Play() def stop_animation(self, event=None): self.chatbot_control.Stop() # updates the user and AI message histories def update_message_history(self): # variables to store the aggregated text user_text = "" ai_text = "" # aggregate user messages for message in self.user_message_history: user_text += message + "\n" # aggregate ai messages for message in self.ai_message_history: ai_text += str(message) + "\n" # update the chats self.input_chat.SetValue(user_text) self.output_chat.SetValue(ai_text) # send a ai message def send_ai_message(self, text: str): # add the message to message history self.ai_message_history.insert( 0, self.get_timestamp() + "AI> " + str(text)) # update the message history self.update_message_history() # clears the user and AI chat history def clear_chat(self): self.user_message_history = [] self.ai_message_history = [] self.update_message_history() # closes program def exit_bot(self): self.Close() # function handling "send" button press def on_send_press(self, event): # read the text box text = self.input_box.GetValue() if text == "": return # clear the text box self.input_box.SetValue("") # add the message to message history self.user_message_history.insert(0, self.get_timestamp() + "You> " + text) # update the message history self.update_message_history() # call the message handler function for the ChatBot GUI self.gui.call_on_message(text) # returns time stamp def get_timestamp(self) -> str: if self.show_timestamp: return "[" + time.strftime("%H:%M:%S", time.localtime()) + "] " else: return ""
class Tree(treemixin.DragAndDrop, customtreectrl.CustomTreeCtrl): _RESOURCES_NODE_LABEL = 'External Resources' def __init__(self, parent, action_registerer, settings=None): from ..controller.ui.treecontroller import TreeController self._checkboxes_for_tests = False self._test_selection_controller = \ self._create_test_selection_controller() self._controller = TreeController( self, action_registerer, settings=settings, test_selection=self._test_selection_controller) treemixin.DragAndDrop.__init__(self, parent, **_TREE_ARGS) self._controller.register_tree_actions() self._bind_tree_events() self._images = TreeImageList() self._animctrl = None self._silent_mode = False self.SetImageList(self._images) self.label_editor = TreeLabelEditListener(self, action_registerer) self._controller.bind_keys() self._subscribe_to_messages() self._popup_creator = PopupCreator() self._dragging = False self._clear_tree_data() self._editor = None self._execution_results = None self._resources = [] """ self.SetBackgroundColour('white') # TODO get background color from def """ self._menu = wx.Menu() self._menu.Append(wx.ID_CLOSE, item="&Close", helpString="Closes panel") self._mb = wx.MenuBar() self._mb.Append(self._menu, "Menu") self.GetParent().SetMenuBar(self._mb) # print(f"DEBUG: Tree tried to add menu to {self.GetParent().__repr__()}") if not hasattr(self, 'OnCancelEdit'): self.OnCancelEdit = self._on_cancel_edit def _create_test_selection_controller(self): from ..controller.ui.treecontroller import TestSelectionController tsc = TestSelectionController() PUBLISHER.subscribe(tsc.clear_all, RideOpenSuite) PUBLISHER.subscribe(tsc.clear_all, RideNewProject) return tsc def _on_cancel_edit(self, item): le = customtreectrl.TreeEvent(customtreectrl.wxEVT_TREE_END_LABEL_EDIT, self.GetId()) le._item = item le.SetEventObject(self) le._label = "" le._editCancelled = True self.GetEventHandler().ProcessEvent(le) def _bind_tree_events(self): self.Bind(wx.EVT_LEFT_DCLICK, self.OnDoubleClick) self.Bind(wx.EVT_TREE_SEL_CHANGED, self.OnSelChanged) self.Bind(wx.EVT_TREE_ITEM_EXPANDING, self.OnTreeItemExpanding) self.Bind(wx.EVT_TREE_ITEM_RIGHT_CLICK, self.OnRightClick) self.Bind(wx.EVT_TREE_ITEM_ACTIVATED, self.OnItemActivated) self.Bind(customtreectrl.EVT_TREE_ITEM_CHECKED, self.OnTreeItemChecked) self.Bind(wx.EVT_TREE_ITEM_COLLAPSING, self.OnTreeItemCollapsing) self.Bind(wx.EVT_CLOSE, self.OnClose) def OnDoubleClick(self, event): item, pos = self.HitTest(self.ScreenToClient(wx.GetMousePosition())) if item: handler = self._controller.get_handler(item) handler.double_clicked() event.Skip() def set_editor(self, editor): self._editor = editor def StartDragging(self): self._dragging = True treemixin.DragAndDrop.StartDragging(self) def OnEndDrag(self, event): self._dragging = False treemixin.DragAndDrop.OnEndDrag(self, event) def register_context_menu_hook(self, callable): self._popup_creator.add_hook(callable) def unregister_context_menu_hook(self, callable): self._popup_creator.remove_hook(callable) def _subscribe_to_messages(self): subscriptions = [ (self._item_changed, RideItem), (self._resource_added, RideOpenResource), (self._select_resource, RideSelectResource), (self._suite_added, RideSuiteAdded), (self._keyword_added, RideUserKeywordAdded), (self._test_added, RideTestCaseAdded), (self._variable_added, RideVariableAdded), (self._leaf_item_removed, RideUserKeywordRemoved), (self._leaf_item_removed, RideTestCaseRemoved), (self._leaf_item_removed, RideVariableRemoved), (self._datafile_removed, RideDataFileRemoved), (self._datafile_set, RideDataFileSet), (self._data_dirty, RideDataChangedToDirty), (self._data_undirty, RideDataDirtyCleared), (self._variable_moved_up, RideVariableMovedUp), (self._variable_moved_down, RideVariableMovedDown), (self._variable_updated, RideVariableUpdated), (self._filename_changed, RideFileNameChanged), (self._testing_started, RideTestExecutionStarted), (self._test_result, RideTestRunning), (self._test_result, RideTestPaused), (self._test_result, RideTestPassed), (self._test_result, RideTestFailed), (self._handle_import_setting_message, RideImportSetting), (self._mark_excludes, RideExcludesChanged), (self._mark_excludes, RideIncludesChanged), ] for listener, topic in subscriptions: PUBLISHER.subscribe(listener, topic) def _mark_excludes(self, message): tree = self._controller.find_node_by_controller(message.old_controller) self._render_datafile(self.GetItemParent(tree), message.new_controller) self._remove_datafile_node(tree) def _set_item_excluded(self, node): self.SetItemTextColour(node, wx.TheColourDatabase.Find("GRAY")) self.SetItemItalic(node, True) self.SetItemText(node, "%s (excluded)" % self.GetItemText(node)) def _handle_import_setting_message(self, message): if message.is_resource(): self._set_resource_color( message.import_controller.get_imported_controller()) self._set_resource_color( message.import_controller.get_previous_imported_controller()) def _set_resource_color(self, resource_controller): if not resource_controller: return node = self._controller.find_node_by_controller(resource_controller) if node: self.SetItemTextColour( node, self._get_resource_text_color(resource_controller)) def _get_resource_text_color(self, resource_controller): if resource_controller.is_used(): return self.GetDefaultAttributes().colFg else: return wx.LIGHT_GREY def _testing_started(self, message): self._for_all_drawn_tests( self._root, lambda t: self.SetItemImage(t, ROBOT_IMAGE_INDEX)) self._execution_results = message.results self._images.set_execution_results(message.results) def _test_result(self, message): from ..controller.macrocontrollers import TestCaseController test: TestCaseController = message.item if not test: # test object will be None when running with DataDriver return if isinstance(message, RideTestPassed): test.run_passed = True elif isinstance(message, RideTestFailed): test.run_passed = False else: test.run_passed = None wx.CallAfter(self._set_icon_from_execution_results, message.item) def _set_icon_from_execution_results(self, controller): node = self._controller.find_node_by_controller(controller) if not node: return img_index = self._get_icon_index_for(controller) # Always set the static icon self.SetItemImage(node, img_index) if self._animctrl: self._animctrl.Stop() self._animctrl.Animation.Destroy() self._animctrl.Destroy() self._animctrl = None self.DeleteItemWindow(node) if img_index in (RUNNING_IMAGE_INDEX, PAUSED_IMAGE_INDEX): from wx.adv import Animation, AnimationCtrl import os _BASE = os.path.join(os.path.dirname(__file__), '..', 'widgets') if img_index == RUNNING_IMAGE_INDEX: img = os.path.join(_BASE, 'robot-running.gif') else: img = os.path.join(_BASE, 'robot-pause.gif') ani = Animation(img) obj = self rect = (node.GetX() + 20, node.GetY()) # Overlaps robot icon self._animctrl = AnimationCtrl(obj, -1, ani, rect) """ self._animctrl.SetBackgroundColour(obj.GetBackgroundColour()) """ self._animctrl.SetBackgroundColour('white') self.SetItemWindow(node, self._animctrl, False) self._animctrl.Play() # Make visible the running or paused test self.EnsureVisible(node) def _get_icon_index_for(self, controller): if not self._execution_results: return ROBOT_IMAGE_INDEX if self._execution_results.is_paused(controller): return PAUSED_IMAGE_INDEX if self._execution_results.is_running(controller): return RUNNING_IMAGE_INDEX if self._execution_results.has_passed(controller): return PASSED_IMAGE_INDEX if self._execution_results.has_failed(controller): return FAILED_IMAGE_INDEX return ROBOT_IMAGE_INDEX def populate(self, model): self._clear_tree_data() self._populate_model(model) self._refresh_view() self.SetFocus() # Needed for keyboard shortcuts def _clear_tree_data(self): self.DeleteAllItems() self._root = self.AddRoot('') self._resource_root = self._create_resource_root() self._datafile_nodes = [] self._resources = [] self._controller.clear_history() def _create_resource_root(self): return self._create_node(self._root, self._RESOURCES_NODE_LABEL, self._images.directory) def _populate_model(self, model): handler = ResourceRootHandler(model, self, self._resource_root, self._controller.settings) self.SetPyData(self._resource_root, handler) if model.data: self._render_datafile(self._root, model.data, 0) for res in model.external_resources: if not res.parent: self._render_datafile(self._resource_root, res) def _resource_added(self, message): ctrl = message.datafile if self._controller.find_node_by_controller(ctrl): return parent = None if ctrl.parent: parent = self._get_dir_node(ctrl.parent) else: parent = self._resource_root self._render_datafile(parent, ctrl) def _get_dir_node(self, ctrl): if ctrl is None: return self._root dir_node = self._get_datafile_node(ctrl.data) if dir_node is None: parent = self._get_dir_node(ctrl.parent) self._render_datafile(parent, ctrl) dir_node = self._get_datafile_node(ctrl.data) return dir_node def _select_resource(self, message): self.select_controller_node(message.item) def select_controller_node(self, controller): self.SelectItem(self._controller.find_node_by_controller(controller)) def _suite_added(self, message): self.add_datafile(message.parent, message.suite) def _refresh_view(self): self.Refresh() # print(f"DEBUG: Called Tree._refresh_view {self.GetParent().GetClassName()}") if self._resource_root: self.Expand(self._resource_root) if self._datafile_nodes: self._expand_and_render_children(self._datafile_nodes[0]) wx.CallAfter(self.SelectItem, self._datafile_nodes[0]) def _render_datafile(self, parent_node, controller, index=None): node = self._create_node_with_handler(parent_node, controller, index) if not node: return None if controller.dirty: self._controller.mark_node_dirty(node) self._datafile_nodes.append(node) self.SetItemHasChildren(node, True) for child in controller.children: self._render_datafile(node, child) return node def _normalize(self, path): return os.path.normcase(os.path.normpath(os.path.abspath(path))) def _create_node_with_handler(self, parent_node, controller, index=None): from ..controller.filecontrollers import ResourceFileController if IS_WINDOWS and isinstance(controller, ResourceFileController): resourcefile = self._normalize(controller.filename) pname = parent_node.GetText() self._resources.append((pname, resourcefile)) if IS_WINDOWS: count = 0 for (p, r) in self._resources: if (p, r) == (pname, resourcefile): count += 1 if count > 3: return None handler_class = action_handler_class(controller) with_checkbox = (handler_class == TestCaseHandler and self._checkboxes_for_tests) node = self._create_node(parent_node, controller.display_name, self._images[controller], index, with_checkbox=with_checkbox) if isinstance(controller, ResourceFileController) and not controller.is_used(): self.SetItemTextColour(node, TREETEXTCOLOUR) # wxPython3 hack action_handler = handler_class(controller, self, node, self._controller.settings) self.SetPyData(node, action_handler) # if we have a TestCase node we have to make sure that # we retain the checked state if (handler_class == TestCaseHandler and self._checkboxes_for_tests) \ and self._test_selection_controller.is_test_selected(controller): self.CheckItem(node, True) if controller.is_excluded(): self._set_item_excluded(node) return node def set_checkboxes_for_tests(self): self._checkboxes_for_tests = True def _expand_and_render_children(self, node): assert node is not None self._render_children(node) self.Expand(node) def _render_children(self, node): handler = self._controller.get_handler(node) if not handler or not handler.can_be_rendered: return self._create_child_nodes(node, handler, lambda item: item.is_test_suite) handler.set_rendered() def _create_child_nodes(self, node, handler, predicate): for childitem in self._children_of(handler): index = self._get_insertion_index(node, predicate) self._create_node_with_handler(node, childitem, index) def _children_of(self, handler): return [v for v in handler.variables if v.has_data()] + \ list(handler.tests) + list(handler.keywords) def _create_node(self, parent_node, label, img, index=None, with_checkbox=False): node = self._wx_node(parent_node, index, label, with_checkbox) self.SetItemImage(node, img.normal, wx.TreeItemIcon_Normal) self.SetItemImage(node, img.expanded, wx.TreeItemIcon_Expanded) return node def _wx_node(self, parent_node, index, label, with_checkbox): ct_type = 1 if with_checkbox else 0 if index is not None: # blame wxPython for this ugliness if isinstance(index, int): return self.InsertItemByIndex(parent_node, index, label, ct_type=ct_type) else: return self.InsertItem(parent_node, index, label, ct_type=ct_type) return self.AppendItem(parent_node, label, ct_type=ct_type) def add_datafile(self, parent, suite): snode = self._render_datafile(self._get_datafile_node(parent.data), suite) self.SelectItem(snode) def add_test(self, parent_node, test): self._add_dataitem(parent_node, test, lambda item: item.is_user_keyword) def add_keyword(self, parent_node, kw): self._add_dataitem(parent_node, kw, lambda item: item.is_test_suite) def _add_dataitem(self, parent_node, dataitem, predicate): node = self._get_or_create_node(parent_node, dataitem, predicate) self._select(node) self._controller.mark_node_dirty(parent_node) def _get_or_create_node(self, parent_node, dataitem, predicate): if not self.IsExpanded(parent_node): self._expand_and_render_children(parent_node) return self._controller.find_node_with_label( parent_node, dataitem.display_name) index = self._get_insertion_index(parent_node, predicate) return self._create_node_with_handler(parent_node, dataitem, index) def _select(self, node): if node: wx.CallAfter(self.SelectItem, node) def _get_insertion_index(self, parent_node, predicate): if not predicate: return None item, cookie = self.GetFirstChild(parent_node) while item: if predicate(self._controller.get_handler(item)): index = self.GetPrevSibling(item) if not index: index = 0 return index item, cookie = self.GetNextChild(parent_node, cookie) return None def _keyword_added(self, message): self.add_keyword(self._get_datafile_node(self.get_selected_datafile()), message.item) def _variable_added(self, message): self._get_or_create_node( self._get_datafile_node(self.get_selected_datafile()), message.item, lambda item: not item.is_variable or item.index > message.index) def _leaf_item_removed(self, message): node = self._controller.find_node_by_controller(message.item) parent_node = self._get_datafile_node(message.datafile) # DEBUG The below call causes not calling delete_node # self._test_selection_controller.select(message.item, False) self._controller.mark_node_dirty(parent_node) self.delete_node(node) def _test_added(self, message): self.add_test(self._get_datafile_node(self.get_selected_datafile()), message.item) def _datafile_removed(self, message): dfnode = self._get_datafile_node(message.datafile.data) self._datafile_nodes.remove(dfnode) self.DeleteChildren(dfnode) self.Delete(dfnode) def _datafile_set(self, message): wx.CallAfter(self._refresh_datafile_when_file_set, message.item) def _filename_changed(self, message): df = message.datafile node = self._controller.find_node_by_controller(df) if not node: raise AssertionError('No node found with controller "%s"' % df) wx.CallAfter(self.SetItemText, node, df.display_name) def add_keyword_controller(self, controller): parent = self._get_datafile_node(self.get_selected_datafile()) self.add_keyword(parent, controller) def delete_node(self, node): if node is None: return parent = self.GetItemParent(node) self._controller.mark_node_dirty(parent) if self.IsSelected(node): self.Delete(node) wx.CallAfter(self.SelectItem, parent) def _data_dirty(self, message): self._controller.mark_controller_dirty(message.datafile) def _data_undirty(self, message): self.unset_dirty() def unset_dirty(self): for node in self._datafile_nodes: text = self.GetItemText(node) handler = self._controller.get_handler(node) if text.startswith('*') and not handler.controller.dirty: self.SetItemText(node, text[1:]) def select_node_by_data(self, controller): """Find and select the tree item associated with the given controller. Controller can be any of the controllers that are represented in the tree.""" parent_node = self._get_datafile_node(controller.datafile) if not parent_node: return None if not self.IsExpanded(parent_node): self._expand_and_render_children(parent_node) node = self._controller.find_node_by_controller(controller) if node != self.GetSelection(): self.SelectItem(node) return node def select_user_keyword_node(self, uk): parent_node = self._get_datafile_node(uk.parent.parent) if not parent_node: return if not self.IsExpanded(parent_node): self._expand_and_render_children(parent_node) node = self._controller.find_node_with_label(parent_node, utils.normalize(uk.name)) if node != self.GetSelection(): self.SelectItem(node) def _get_datafile_node(self, datafile): for node in self._datafile_nodes: if self._controller.get_handler(node).item == datafile: return node return None def get_selected_datafile(self): """Returns currently selected data file. If a test or user keyword node is selected, returns parent of that item.""" datafile = self._get_selected_datafile_node() if not datafile: return None return self._controller.get_handler(datafile).item def get_selected_datafile_controller(self): """Returns controller associated with currently active data file. If a test or user keyword node is selected, returns parent of that item.""" dfnode = self._get_selected_datafile_node() if dfnode: return self._controller.get_handler(dfnode).controller else: return None def _get_selected_datafile_node(self): node = self.GetSelection() if not node or node in (self._resource_root, self._root): return None while node not in self._datafile_nodes: node = self.GetItemParent(node) return node def get_selected_item(self): """Returns model object associated with currently selected tree node. """ selection = self.GetSelection() if not selection: return None handler = self._controller.get_handler(selection) return handler and handler.controller or None def tree_node_selected(self, node): # print(f"DEBUG: TreePlugin tree node selected {str(node)}") pass def move_up(self, node): prev = self.GetPrevSibling(node) if prev.IsOk(): self._switch_items(prev, node, node) def move_down(self, node): next = self.GetNextSibling(node) if next.IsOk(): self._switch_items(node, next, node) def _switch_items(self, first, second, currently_selected): """Changes the order of given items, first is expected to be directly above the second""" selection = self.GetItemData(currently_selected).controller controller = self._controller.get_handler(first).controller self.Delete(first) self._create_node_with_handler(self.GetItemParent(second), controller, second) self.select_node_by_data(selection) def _refresh_datafile_when_file_set(self, controller): # remove invalid cases selection when data file is changed in text editor self._test_selection_controller.remove_invalid_cases_selection( controller) # Prevent tab selections based on tree item selected events self._start_silent_mode() current = self.get_selected_datafile_controller() if not current: # If tree is not yet in use - do not expand anything. self._end_silent_mode() return item = self.GetSelection() current_txt = self.GetItemText(item) if item.IsOk() else '' # after refresh current and current_txt might have been changed node = self._refresh_datafile(controller) if node is None: # TODO: Find out why this sometimes happens return self._expand_and_render_children(node) if current == controller: select_item = self._controller.find_node_with_label( node, current_txt) if select_item is None: select_item = node wx.CallAfter(self.SelectItem, select_item) wx.CallAfter(self._end_silent_mode) else: self._end_silent_mode() def _uncheck_tests(self, controller): self._test_selection_controller.unselect_all(controller.tests) def _start_silent_mode(self): self._silent_mode = True def _end_silent_mode(self): self._silent_mode = False def refresh_datafile(self, controller, event): to_be_selected = self._get_pending_selection(event) new_node = self._refresh_datafile(controller) self._handle_pending_selection(to_be_selected, new_node) def _refresh_datafile(self, controller): orig_node = self._get_data_controller_node(controller) if orig_node is not None: insertion_index = self._get_datafile_index(orig_node) parent = self.GetItemParent(orig_node) self._remove_datafile_node(orig_node) return self._render_datafile(parent, controller, insertion_index) def _get_pending_selection(self, event): if hasattr(event, 'Item'): item = event.GetItem() event.Veto() elif hasattr(event, 'Position'): item, flags = self.HitTest(event.Position) if not self._click_on_item(item, flags): return else: return return self.GetItemText(item) def _get_data_controller_node(self, controller): for node in self._datafile_nodes: if self.GetItemData(node).controller == controller: return node return None def _click_on_item(self, item, flags): return item is not None and item.IsOk() and \ flags & wx.TREE_HITTEST_ONITEM def _get_datafile_index(self, node): insertion_index = self.GetPrevSibling(node) if not insertion_index: insertion_index = 0 return insertion_index def _remove_datafile_node(self, node): for child in self.GetItemChildren(node): if child in self._datafile_nodes: self._remove_datafile_node(child) self._datafile_nodes.remove(node) self.Delete(node) def _handle_pending_selection(self, to_be_selected, parent_node): if to_be_selected: self._expand_and_render_children(parent_node) select_item = self._controller.find_node_with_label( parent_node, to_be_selected) wx.CallAfter(self.SelectItem, select_item) def OnSelChanged(self, event): node = event.GetItem() if not node.IsOk() or self._dragging: event.Skip() return self._controller.add_to_history(node) handler = self._controller.get_handler(node) if handler and handler.item: self._update_data_file_namespace(node) RideTreeSelection(node=node, item=handler.controller, silent=self._silent_mode).publish() self.SetFocus() def _update_data_file_namespace(self, node): while True: if not node: return handler = self._controller.get_handler(node) if hasattr(handler.controller, 'get_namespace'): data_file_ns = handler.controller.get_namespace() if not data_file_ns: return cur_dir = handler.controller.directory if data_file_ns: data_file_ns.update_cur_dir_global_var(cur_dir) return else: node = node.GetParent() def OnTreeItemExpanding(self, event): node = event.GetItem() if node.IsOk(): self._render_children(node) # This exists because CustomTreeItem does not remove animations def OnTreeItemCollapsing(self, event): item = event.GetItem() self._hide_item(item) event.Skip() def _hide_item(self, item): for item in item.GetChildren(): itemwindow = item.GetWindow() if itemwindow: itemwindow.Hide() if self.ItemHasChildren(item): self._hide_item(item) def SelectAllTests(self, item: GenericTreeItem, selected=True): """ Select tests for execution :param item: The node of the graphical tree where the user triggered the action from :param selected: Whether we want to select or un-select for execution :return: Nothing """ test_controllers = self.retrieveTestCaseControllers(item) self._test_selection_controller.select_all(test_controllers, selected) def retrieveTestCaseControllers(self, item: GenericTreeItem): from ..controller.filecontrollers import TestDataDirectoryController, TestCaseFileController data = item.GetData() if isinstance(data, TestDataDirectoryHandler): item_controller: TestDataDirectoryController = data.tests.parent elif isinstance(data, TestCaseFileHandler): item_controller: TestCaseFileController = data.controller else: raise Exception("Unexpected type of handler: " + str(data)) test_controllers = item_controller.retrieve_test_controllers() return test_controllers def SelectTests(self, tests): self._test_selection_controller.select_all(tests) def ExpandAllSubNodes(self, item): self._expand_or_collapse_nodes(item, self.Expand) def CollapseAllSubNodes(self, item): self._expand_or_collapse_nodes(item, self.Collapse) def _expand_or_collapse_nodes(self, item, callback): if not self.HasAGWFlag(customtreectrl.TR_HIDE_ROOT) or \ item != self.GetRootItem(): callback(item) for child in item.GetChildren(): self._expand_or_collapse_nodes(child, callback) def _for_all_drawn_tests(self, item, func): if self._is_test_node(item): func(item) for child in item.GetChildren(): self._for_all_drawn_tests(child, func) def _is_test_node(self, node): return node.GetType() == 1 def DeselectTests(self, tests): self._test_selection_controller.unselect_all(tests) def SelectFailedTests(self, item): all_controllers = self.retrieveTestCaseControllers(item) test_controllers = filter(lambda ctrl: ctrl.run_passed == False, all_controllers) self._test_selection_controller.unselect_all(all_controllers) self._test_selection_controller.select_all(test_controllers) def SelectPassedTests(self, item): all_controllers = self.retrieveTestCaseControllers(item) test_controllers = filter(lambda ctrl: ctrl.run_passed == True, all_controllers) self._test_selection_controller.unselect_all(all_controllers) self._test_selection_controller.select_all(test_controllers) def OnClose(self, event): print("DEBUG: Tree OnClose hidding") self.Hide() def OnTreeItemChecked(self, event): node: GenericTreeItem = event.GetItem() handler: TestCaseHandler = self._controller.get_handler(node=node) self._test_selection_controller.select(handler.controller, node.IsChecked()) def OnItemActivated(self, event): node = event.GetItem() if self.IsExpanded(node): self.Collapse(node) elif self.ItemHasChildren(node): self._expand_and_render_children(node) def OnLeftArrow(self, event): node = self.GetSelection() if self.IsExpanded(node): self.Collapse(node) else: event.Skip() def OnRightClick(self, event): handler = None if hasattr(event, 'GetItem'): handler = self._controller.get_handler(event.GetItem()) if handler: if not self.IsExpanded(handler.node): self.Expand(handler.node) handler.show_popup() def OnNewTestCase(self, event): handler = self._controller.get_handler() if handler: handler.OnNewTestCase(event) def OnDrop(self, target, dragged): dragged = self._controller.get_handler(dragged) target = self._controller.get_handler(target) if target and target.accepts_drag(dragged): dragged.controller.execute(MoveTo(target.controller)) self.Refresh() # DEBUG Always refresh def IsValidDragItem(self, item): return self._controller.get_handler(item).is_draggable def OnMoveUp(self, event): handler = self._controller.get_handler() if handler.is_draggable: handler.OnMoveUp(event) def OnMoveDown(self, event): handler = self._controller.get_handler() if handler.is_draggable: handler.OnMoveDown(event) def _item_changed(self, message): controller = message.item node = self._controller.find_node_by_controller(controller) if node: self.SetItemText(node, message.item.name) if controller.dirty: self._controller.mark_node_dirty( self._get_datafile_node(controller.datafile)) def _variable_moved_up(self, message): if self._should_update_variable_positions(message): self._do_action_if_datafile_node_is_expanded(self.move_up, message) def _variable_moved_down(self, message): if self._should_update_variable_positions(message): self._do_action_if_datafile_node_is_expanded( self.move_down, message) def _should_update_variable_positions(self, message): return message.item != message.other and message.item.has_data() and \ message.other.has_data() def _do_action_if_datafile_node_is_expanded(self, action, data): if self.IsExpanded(self._get_datafile_node(data.item.datafile)): node = self._controller.find_node_by_controller(data.item) action(node) def _variable_updated(self, message): self._item_changed(message) def highlight(self, data, text): self.select_node_by_data(data) self._editor.highlight(text) def node_is_resource_file(self, node): return self._controller.get_handler(node).__class__ == \ ResourceFileHandler
class FrameGesto1(wx.Frame): def __init__(self, parent): wx.Frame.__init__(self, parent, id=wx.ID_ANY, title=u"Captura de señales para el gesto 1", pos=wx.DefaultPosition, size=wx.Size(1400, 1000), style=wx.DEFAULT_FRAME_STYLE | wx.TAB_TRAVERSAL) self.SetSizeHintsSz(wx.DefaultSize, wx.DefaultSize) bSizer4 = wx.BoxSizer(wx.VERTICAL) self.panel = wx.Panel(self) sizer = wx.BoxSizer(wx.VERTICAL) self.panel.SetSizer(sizer) self.m_staticText2 = wx.StaticText( self, wx.ID_ANY, u"Captura de señales para el primer gesto \n", wx.DefaultPosition, wx.Size(700, -1), 0) self.m_staticText2.Wrap(-1) self.m_staticText2.SetFont( wx.Font(34, 70, 90, 90, False, wx.EmptyString)) bSizer4.Add(self.m_staticText2, 0, wx.ALIGN_CENTER_HORIZONTAL, 10) bSizer49 = wx.BoxSizer(wx.VERTICAL) bSizer50 = wx.BoxSizer(wx.HORIZONTAL) bSizer50.SetMinSize(wx.Size(700, 50)) self.m_staticText30 = wx.StaticText( self, wx.ID_ANY, u"Para iniciar el experimento por favor observe \n ", wx.DefaultPosition, wx.Size(1000, -1), 0) self.m_staticText30.Wrap(-1) self.m_staticText30.SetFont( wx.Font(17, 70, 90, 90, False, wx.EmptyString)) bSizer50.Add(self.m_staticText30, 0, wx.ALL, 5) bSizer52 = wx.BoxSizer(wx.VERTICAL) bSizer52.SetMinSize(wx.Size(90, -1)) self.m_button32 = wx.Button(self, wx.ID_ANY, u"Inicio", wx.Point(-1, -1), wx.Size(150, -1), 0) self.m_button32.SetFont(wx.Font(25, 70, 90, 90, False, wx.EmptyString)) bSizer52.Add(self.m_button32, 0, wx.TOP, 10) bSizer50.Add(bSizer52, 1, 0, 5) self.m_animCtrl1 = AnimationCtrl(self, pos=(40, 40), size=(14, 14), name="AnimationCtrl") self.m_animCtrl1.LoadFile( r"C:\Users\crist\OneDrive\Escritorio\Universidad\LASER\Tesis\Open_BCI_and_MYO_UD\GUI_Adquisicion/manos.gif" ) self.m_animCtrl1.Play() self.m_animCtrl1.SetMinSize(wx.Size(200, -1)) bSizer50.Add(self.m_animCtrl1, 0, wx.ALIGN_CENTER, 5) bSizer49.Add(bSizer50, 1, 0, 5) bSizer51 = wx.BoxSizer(wx.VERTICAL) bSizer57 = wx.BoxSizer(wx.HORIZONTAL) # grafica EMG self.figureEMG = plt.figure(figsize=(1, 6), dpi=60) self.axes = [ self.figureEMG.add_subplot('81' + str(i)) for i in range(1, 9) ] self.n = 512 [(ax.set_ylim(ymin=-200, ymax=200)) for ax in self.axes] global graphs self.graphs = [ ax.plot(np.arange(self.n), np.zeros(self.n))[0] for ax in self.axes ] plt.ion() self.canvEMG = FigureCanvas(self, wx.ID_ANY, self.figureEMG) bSizer57.Add(self.canvEMG, 1, wx.TOP | wx.LEFT | wx.EXPAND) # grafica EEG self.figureEEG = plt.figure(figsize=(1, 6), dpi=60) self.axesEEG = [ self.figureEEG.add_subplot('81' + str(i)) for i in range(1, 9) ] [(ax.set_ylim([-150000, 150000])) for ax in self.axesEEG] self.m = 100 self.graphsEEG = [ ax.plot(np.arange(self.m), np.zeros(self.m))[0] for ax in self.axesEEG ] plt.ion() self.canvasEEG = FigureCanvas(self, -1, self.figureEEG) bSizer57.Add(self.canvasEEG, 1, wx.TOP | wx.LEFT | wx.EXPAND) bSizer51.Add(bSizer57, 1, wx.EXPAND, 5) bSizer49.Add(bSizer51, 1, wx.EXPAND, 5) bSizer53 = wx.BoxSizer(wx.HORIZONTAL) self.m_staticText31 = wx.StaticText(self, wx.ID_ANY, u"Señal EMG", wx.DefaultPosition, wx.Size(700, 30), 0) self.m_staticText31.Wrap(-1) self.m_staticText31.SetFont( wx.Font(18, 70, 90, 90, False, wx.EmptyString)) bSizer53.Add(self.m_staticText31, 0, wx.LEFT, 5) self.m_staticText32 = wx.StaticText(self, wx.ID_ANY, u"Señal EEG", wx.DefaultPosition, wx.Size(-1, 30), 0) self.m_staticText32.Wrap(-1) self.m_staticText32.SetFont( wx.Font(18, 70, 90, 90, False, wx.EmptyString)) bSizer53.Add(self.m_staticText32, 0, 0, 5) bSizer49.Add(bSizer53, 1, 0, 5) bSizer8 = wx.BoxSizer(wx.HORIZONTAL) self.m_staticText33 = wx.StaticText(self, wx.ID_ANY, u"Tiempo:", wx.DefaultPosition, wx.Size(550, -1), 0) self.m_staticText33.Wrap(-1) self.m_staticText33.SetFont( wx.Font(18, 70, 90, 90, False, wx.EmptyString)) bSizer8.Add(self.m_staticText33, 0, wx.ALL, 5) pos = wx.DefaultPosition size = wx.Size(1, 11) style = gizmos.LED_ALIGN_CENTER self.led = gizmos.LEDNumberCtrl(self, -1, pos, size, style) self.led.SetBackgroundColour("white") self.led.SetForegroundColour("black") bSizerTimmer = wx.BoxSizer(wx.VERTICAL) bSizerTimmer.Add(self.led, 1, wx.TOP | wx.LEFT | wx.EXPAND) bSizer49.Add(bSizerTimmer, 1, wx.EXPAND, 5) self.button_siguiente = wx.Button(self, wx.ID_ANY, u"Aceptar", wx.DefaultPosition, wx.Size(150, -1), 0) self.button_siguiente.SetFont( wx.Font(18, 70, 90, 90, False, wx.EmptyString)) bSizer8.Add(self.button_siguiente, 0, wx.ALL, 5) self.button_salir = wx.Button(self, wx.ID_ANY, u"Salir", wx.DefaultPosition, wx.Size(150, -1), 0) self.button_salir.SetFont( wx.Font(18, 70, 90, 90, False, wx.EmptyString)) bSizer8.Add(self.button_salir, 0, wx.ALL, 5) bSizer49.Add(bSizer8, 0, wx.TOP, 1) bSizer4.Add(bSizer49, 1, wx.EXPAND, 5) self.SetSizer(bSizer4) self.Layout() self.Centre(wx.BOTH) # Connect Events self.m_button32.Bind(wx.EVT_BUTTON, self.OnClickInicio) self.button_siguiente.Bind(wx.EVT_BUTTON, self.OnClickConcentimiento) self.button_salir.Bind(wx.EVT_BUTTON, self.OnClickSalir) # Arrancar conexion myo self.conexionMYO() def hiloMYOConexion(arg): hiloConexionMYO = threading.currentThread() while getattr(hiloConexionMYO, "do_run", True): print("working on %s" % arg) self.mainMYO() print("Stopping as you wish.") self.hiloConexionMYO = threading.Thread(target=hiloMYOConexion, args=("PLOT_EMG_MYO", )) self.hiloConexionMYO.setDaemon(True) self.hiloConexionMYO.start() # Arranca conexion UltraCortex self.datosEEG = [] self.start_board() def hiloPlotUltracortex(arg): hiloPlotUltracortex = threading.currentThread() while getattr(hiloPlotUltracortex, "do_run", True): print("working on %s" % arg) time.sleep(3) self.mainplotUltracortex() print("Stopping as you wish.") self.hiloPlotUltracortex = threading.Thread( target=hiloPlotUltracortex, args=("PLOT_EEG_ULTRACORTEX", )) self.hiloPlotUltracortex.setDaemon(True) self.hiloPlotUltracortex.start() def __del__(self): pass # Virtual event handlers, overide them in your derived class def OnClickInicio(self, event): self.GetSegundos(None) def OnClickConcentimiento(self, event): event.Skip() def OnClickSalir(self, event): self.Close() sys.exit() def GetSegundos(self, e): global segundos self.board.stop_stream() self.stopconexioUltracortexPlot = True self.hiloPlotUltracortex.do_run = False self.hiloPlotUltracortex.join() self.stopconexion = True self.hiloConexionMYO.do_run = False self.hiloConexionMYO.join() dlg = wx.TextEntryDialog(self.panel, 'Ingrese los segundos a grabar el gesto:', "Captura del gesto", "", style=wx.OK) dlg.ShowModal() segundos = int(dlg.GetValue()) def hiloRunTimmer(arg): hiloRunTimmer = threading.currentThread() while getattr(hiloRunTimmer, "do_run", True): print("working on %s" % arg) self.led.SetValue("00:00") self.OnTimer(None, e=segundos) print("Stopping as you wish.") self.hiloRunTimmer = threading.Thread(target=hiloRunTimmer, args=("RUN_Timmer", )) self.hiloRunTimmer.setDaemon(True) self.hiloRunTimmer.start() def hiloMYOSaved(arg): hiloMYOSaved = threading.currentThread() while getattr(hiloMYOSaved, "do_run", True): print("working on %s" % arg) self.mainSavedMYO() print("Stopping as you wish.") self.hiloMYOSaved = threading.Thread(target=hiloMYOSaved, args=("Saved_EMG_MYO", )) self.hiloMYOSaved.setDaemon(True) self.hiloMYOSaved.start() def hiloUltracortesConexion(arg): hiloUltracortesConexion = threading.currentThread() while getattr(hiloUltracortesConexion, "do_run", True): print("working on %s" % arg) self.mainULTRACORTEX() print("Stopping as you wish.") self.hiloUltracortesConexion = threading.Thread( target=hiloUltracortesConexion, args=("SAVE_EEG_ULTRACORTEX", )) self.hiloUltracortesConexion.setDaemon(True) self.hiloUltracortesConexion.start() dlg.Destroy() def OnTimer(self, event, e): print("OnTimmer Inicia") global i global c c = e if (i < c): i += 1 time.sleep(1) self.TimerGo(None) else: print("Termino Timer") self.board.stop_stream() self.stopconexioUltracortex = True self.hiloUltracortesConexion.do_run = False self.hiloUltracortesConexion.join() self.hiloRunTimmer.do_run = False self.stopsaved = True self.hiloMYOSaved.do_run = False self.hiloMYOSaved.join() def TimerGo(self, event): global s global m global t global c s = int(s) m = int(m) if (s < 59): s += 1 elif (s == 59): s = 0 if (m < 59): m += 1 elif (m == 59): m = 0 if (int(s) < 10): s = str(0) + str(s) if (int(s) > 9): s = str(s) t = str(m) + ":" + str(s) self.led.SetValue(t) self.OnTimer(None, c) def conexionMYO(self): print("Realizando Conexión MYO") myo.init() self.hub = myo.Hub() self.listener = EmgCollector(512) self.stopconexion = False self.stopsaved = False print("Conexión MYO Establecida") self.Crear_carpetaMYO() def mainMYO(self): global data_total data_total = [] with self.hub.run_in_background(self.listener.on_event): while True: self.plotMYO() time.sleep(0.1) if (self.stopconexion == True): break def mainSavedMYO(self): global fila fila = 0 with self.hub.run_in_background(self.listener.on_event): while True: self.SaveMYO() time.sleep(2.56) if (self.stopsaved == True): break def plotMYO(self): global graphs emg_data = self.listener.get_emg_data() emg_data = np.array([x[1] for x in emg_data]).T for g, data in zip(self.graphs, emg_data): if len(data) < self.n: data = np.concatenate([np.zeros(self.n - len(data)), data]) g.set_ydata(data) #plt.draw() def SaveMYO(self): global fila global data_total numMuestras = 512 emg_data = self.listener.get_emg_data() emg_data = [x[1] for x in emg_data] with open(os.path.join(carpetaEMG, "datos %d.csv" % j), 'a') as fp: # Guardar datos en el archivo csv for h in range(0, 512): for i in range(0, 8): fp.write(str(emg_data[h][i]) + ";") fp.write("\n") ########################################################################### # Ultracortex def start_board(self): global fila fila = 0 self.board = OpenBCICyton(port='COM8', daisy=False) self.stopconexioUltracortex = False self.stopconexioUltracortexPlot = False self.Crear_carpetaEEG() def mainULTRACORTEX(self): while (self.stopconexioUltracortex == False): self.board.start_stream(self.save_data) print("entro if") self.board.stop_stream() def mainplotUltracortex(self): while (self.stopconexioUltracortexPlot == False): time.sleep(0.1) self.board.start_stream(self.plot_eeg) print("entro if") self.board.stop_stream() def plot_eeg(self, sample): global datosEEG, bp_a, bp_b global graphsEEG self.datosEEG.append( [i * (SCALE_FACTOR) for i in sample.channels_data]) datosEEGplot = np.array(self.datosEEG).T # for o in range (8): # datosEEGplot[o] = signal.lfilter(bp_b, bp_a, datosEEGplot[o]) for g, data in zip(self.graphsEEG, datosEEGplot): if len(data) < self.m: data = np.concatenate([np.zeros(self.m - len(data)), data]) else: data = np.array(data[(len(data) - self.m):]) # dy = (max(data) - min(data))*0.7 # [(ax.set_ylim([min(data)-dy, max(data)+dy])) for ax in self.axesEEG] g.set_ydata(data) #plt.draw()>:V self.board.stop_stream() def save_data(self, sample): global fila global datosEEG, bp_a, bp_b self.datosEEG.append( [i * (SCALE_FACTOR) for i in sample.channels_data]) datosEEGplot = np.array(self.datosEEG).T with open(os.path.join(carpetaEEG, "datos %d.csv" % j), 'a') as fp: # Guardar datos en el archivo csv for i in range(0, 8): fp.write(str(self.datosEEG[fila][i]) + ";") fp.write("\n") fila += 1 def Crear_carpetaEEG(self): global carpetaEEG global j global fila fila = 0 Archivo = True j = 1 Tipo = "PruebaUltracortex" carpetaEEG = f"Base_Datos_{Tipo}" #Creacion de carpetas para guarda archivos si no existe if not os.path.exists(carpetaEEG): os.mkdir(carpetaEEG) while (Archivo == True ): # Se crea un archivo csv en caso de que no exista if os.path.isfile(carpetaEEG + "/datos %d.csv" % j): print('El archivo existe.') j += 1 else: with open(os.path.join(carpetaEEG, "datos %d.csv" % j), 'w') as fp: [fp.write('CH%d ;' % i) for i in range(1, 9)] fp.write("\n") print("Archivo Creado") Archivo = False def Crear_carpetaMYO(self): global carpetaEMG global j global fila fila = 0 Archivo = True j = 1 Tipo = "PruebaMYO" carpetaEMG = f"Base_Datos_{Tipo}" #Creacion de carpetas para guarda archivos si no existe if not os.path.exists(carpetaEMG): os.mkdir(carpetaEMG) while (Archivo == True ): # Se crea un archivo csv en caso de que no exista if os.path.isfile(carpetaEMG + "/datos %d.csv" % j): print('El archivo existe.') j += 1 else: with open(os.path.join(carpetaEMG, "datos %d.csv" % j), 'w') as fp: [fp.write('CH%d ;' % i) for i in range(1, 9)] fp.write("\n") print("Archivo Creado") Archivo = False
def __init__(self, parent): wx.Frame.__init__(self, parent, id=wx.ID_ANY, title=u"Captura de señales para el gesto 1", pos=wx.DefaultPosition, size=wx.Size(1400, 1000), style=wx.DEFAULT_FRAME_STYLE | wx.TAB_TRAVERSAL) self.SetSizeHintsSz(wx.DefaultSize, wx.DefaultSize) bSizer4 = wx.BoxSizer(wx.VERTICAL) self.panel = wx.Panel(self) sizer = wx.BoxSizer(wx.VERTICAL) self.panel.SetSizer(sizer) self.m_staticText2 = wx.StaticText( self, wx.ID_ANY, u"Captura de señales para el primer gesto \n", wx.DefaultPosition, wx.Size(700, -1), 0) self.m_staticText2.Wrap(-1) self.m_staticText2.SetFont( wx.Font(34, 70, 90, 90, False, wx.EmptyString)) bSizer4.Add(self.m_staticText2, 0, wx.ALIGN_CENTER_HORIZONTAL, 10) bSizer49 = wx.BoxSizer(wx.VERTICAL) bSizer50 = wx.BoxSizer(wx.HORIZONTAL) bSizer50.SetMinSize(wx.Size(700, 50)) self.m_staticText30 = wx.StaticText( self, wx.ID_ANY, u"Para iniciar el experimento por favor observe \n ", wx.DefaultPosition, wx.Size(1000, -1), 0) self.m_staticText30.Wrap(-1) self.m_staticText30.SetFont( wx.Font(17, 70, 90, 90, False, wx.EmptyString)) bSizer50.Add(self.m_staticText30, 0, wx.ALL, 5) bSizer52 = wx.BoxSizer(wx.VERTICAL) bSizer52.SetMinSize(wx.Size(90, -1)) self.m_button32 = wx.Button(self, wx.ID_ANY, u"Inicio", wx.Point(-1, -1), wx.Size(150, -1), 0) self.m_button32.SetFont(wx.Font(25, 70, 90, 90, False, wx.EmptyString)) bSizer52.Add(self.m_button32, 0, wx.TOP, 10) bSizer50.Add(bSizer52, 1, 0, 5) self.m_animCtrl1 = AnimationCtrl(self, pos=(40, 40), size=(14, 14), name="AnimationCtrl") self.m_animCtrl1.LoadFile( r"C:\Users\crist\OneDrive\Escritorio\Universidad\LASER\Tesis\Open_BCI_and_MYO_UD\GUI_Adquisicion/manos.gif" ) self.m_animCtrl1.Play() self.m_animCtrl1.SetMinSize(wx.Size(200, -1)) bSizer50.Add(self.m_animCtrl1, 0, wx.ALIGN_CENTER, 5) bSizer49.Add(bSizer50, 1, 0, 5) bSizer51 = wx.BoxSizer(wx.VERTICAL) bSizer57 = wx.BoxSizer(wx.HORIZONTAL) # grafica EMG self.figureEMG = plt.figure(figsize=(1, 6), dpi=60) self.axes = [ self.figureEMG.add_subplot('81' + str(i)) for i in range(1, 9) ] self.n = 512 [(ax.set_ylim(ymin=-200, ymax=200)) for ax in self.axes] global graphs self.graphs = [ ax.plot(np.arange(self.n), np.zeros(self.n))[0] for ax in self.axes ] plt.ion() self.canvEMG = FigureCanvas(self, wx.ID_ANY, self.figureEMG) bSizer57.Add(self.canvEMG, 1, wx.TOP | wx.LEFT | wx.EXPAND) # grafica EEG self.figureEEG = plt.figure(figsize=(1, 6), dpi=60) self.axesEEG = [ self.figureEEG.add_subplot('81' + str(i)) for i in range(1, 9) ] [(ax.set_ylim([-150000, 150000])) for ax in self.axesEEG] self.m = 100 self.graphsEEG = [ ax.plot(np.arange(self.m), np.zeros(self.m))[0] for ax in self.axesEEG ] plt.ion() self.canvasEEG = FigureCanvas(self, -1, self.figureEEG) bSizer57.Add(self.canvasEEG, 1, wx.TOP | wx.LEFT | wx.EXPAND) bSizer51.Add(bSizer57, 1, wx.EXPAND, 5) bSizer49.Add(bSizer51, 1, wx.EXPAND, 5) bSizer53 = wx.BoxSizer(wx.HORIZONTAL) self.m_staticText31 = wx.StaticText(self, wx.ID_ANY, u"Señal EMG", wx.DefaultPosition, wx.Size(700, 30), 0) self.m_staticText31.Wrap(-1) self.m_staticText31.SetFont( wx.Font(18, 70, 90, 90, False, wx.EmptyString)) bSizer53.Add(self.m_staticText31, 0, wx.LEFT, 5) self.m_staticText32 = wx.StaticText(self, wx.ID_ANY, u"Señal EEG", wx.DefaultPosition, wx.Size(-1, 30), 0) self.m_staticText32.Wrap(-1) self.m_staticText32.SetFont( wx.Font(18, 70, 90, 90, False, wx.EmptyString)) bSizer53.Add(self.m_staticText32, 0, 0, 5) bSizer49.Add(bSizer53, 1, 0, 5) bSizer8 = wx.BoxSizer(wx.HORIZONTAL) self.m_staticText33 = wx.StaticText(self, wx.ID_ANY, u"Tiempo:", wx.DefaultPosition, wx.Size(550, -1), 0) self.m_staticText33.Wrap(-1) self.m_staticText33.SetFont( wx.Font(18, 70, 90, 90, False, wx.EmptyString)) bSizer8.Add(self.m_staticText33, 0, wx.ALL, 5) pos = wx.DefaultPosition size = wx.Size(1, 11) style = gizmos.LED_ALIGN_CENTER self.led = gizmos.LEDNumberCtrl(self, -1, pos, size, style) self.led.SetBackgroundColour("white") self.led.SetForegroundColour("black") bSizerTimmer = wx.BoxSizer(wx.VERTICAL) bSizerTimmer.Add(self.led, 1, wx.TOP | wx.LEFT | wx.EXPAND) bSizer49.Add(bSizerTimmer, 1, wx.EXPAND, 5) self.button_siguiente = wx.Button(self, wx.ID_ANY, u"Aceptar", wx.DefaultPosition, wx.Size(150, -1), 0) self.button_siguiente.SetFont( wx.Font(18, 70, 90, 90, False, wx.EmptyString)) bSizer8.Add(self.button_siguiente, 0, wx.ALL, 5) self.button_salir = wx.Button(self, wx.ID_ANY, u"Salir", wx.DefaultPosition, wx.Size(150, -1), 0) self.button_salir.SetFont( wx.Font(18, 70, 90, 90, False, wx.EmptyString)) bSizer8.Add(self.button_salir, 0, wx.ALL, 5) bSizer49.Add(bSizer8, 0, wx.TOP, 1) bSizer4.Add(bSizer49, 1, wx.EXPAND, 5) self.SetSizer(bSizer4) self.Layout() self.Centre(wx.BOTH) # Connect Events self.m_button32.Bind(wx.EVT_BUTTON, self.OnClickInicio) self.button_siguiente.Bind(wx.EVT_BUTTON, self.OnClickConcentimiento) self.button_salir.Bind(wx.EVT_BUTTON, self.OnClickSalir) # Arrancar conexion myo self.conexionMYO() def hiloMYOConexion(arg): hiloConexionMYO = threading.currentThread() while getattr(hiloConexionMYO, "do_run", True): print("working on %s" % arg) self.mainMYO() print("Stopping as you wish.") self.hiloConexionMYO = threading.Thread(target=hiloMYOConexion, args=("PLOT_EMG_MYO", )) self.hiloConexionMYO.setDaemon(True) self.hiloConexionMYO.start() # Arranca conexion UltraCortex self.datosEEG = [] self.start_board() def hiloPlotUltracortex(arg): hiloPlotUltracortex = threading.currentThread() while getattr(hiloPlotUltracortex, "do_run", True): print("working on %s" % arg) time.sleep(3) self.mainplotUltracortex() print("Stopping as you wish.") self.hiloPlotUltracortex = threading.Thread( target=hiloPlotUltracortex, args=("PLOT_EEG_ULTRACORTEX", )) self.hiloPlotUltracortex.setDaemon(True) self.hiloPlotUltracortex.start()