You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

app.py 8.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. # -*- coding: utf-8 -*-
  2. """
  3. Created on Fri Sep 4 11:36:24 2020
  4. @author: Igor Beloschapkin
  5. """
  6. import tkinter
  7. import tkinter.font
  8. import tkinter.filedialog
  9. import tkinter.messagebox
  10. import subprocess
  11. import configparser
  12. import os
  13. # TODO Eventuell updatefunktion über git pull mit einbauen!
  14. __version__ = 0.41
  15. class PythonBCIgui:
  16. def __init__(self, master):
  17. # Einstellung der Button Größe
  18. textH = 4
  19. textW = 20
  20. def makeBtn(self, text, bg, command):
  21. self.button = tkinter.Button(frame, text=text, bg=bg, command=command)
  22. self.button.config( height = textH, width = textW )
  23. self.button['font'] = tkinter.font.Font(family='Helvetica', size=16, weight='bold')
  24. return self.button
  25. frame = tkinter.Frame(master)
  26. frame.pack()
  27. # label generation
  28. headerText = config['SETTINGS']['paradigm'] + ' BCI'
  29. self.Lparadigm = tkinter.Label(frame, text = headerText, height = 4, width = 20)
  30. self.Lparadigm['font'] = tkinter.font.Font(family='Helvetica', size=16, weight='bold')
  31. self.Lparadigm.pack()
  32. # button generation
  33. self.BtacFilter = makeBtn(self, "Filter", "pink", self.btn_tacFilter)
  34. self.BtacCal = makeBtn(self, "Kalibrierung", "lightgreen", self.btn_tacCal)
  35. self.BvisCal = makeBtn(self, "Kalibrierung", "lightgreen", self.btn_visCal)
  36. self.Bp300 = makeBtn(self, "P300 Klassifizierung", "orange", self.btn_p300)
  37. self.BtacFree = makeBtn(self, "Freies Buchstabieren", "lightblue", self.btn_tacFree)
  38. self.BvisFree = makeBtn(self, "Freies Buchstabieren", "lightblue", self.btn_visFree)
  39. self.pack_layout()
  40. # FILTER ###################################
  41. def btn_tacFilter(self):
  42. subprocess.Popen(config['PATH']['tactilebcifilter'] + r'\TactileBCIFilter.exe')
  43. # KALIBRIERUNGEN ###########################
  44. def btn_tacCal(self):
  45. subprocess.Popen([config['PATH']['bci2000'] + r'\prog\Operator.exe', '--OnConnect', '-LOAD PARAMETERFILE TactileCalibration.prm'])
  46. # TODO Throw error if else
  47. subprocess.Popen([config['PATH']['bci2000'] + r'\prog\gUSBampSource.exe', '127.0.0.1'])
  48. subprocess.Popen([config['PATH']['bci2000'] + r'\prog\P3SignalProcessing.exe', '127.0.0.1'])
  49. subprocess.Popen([config['PATH']['bci2000'] + r'\prog\P3Speller.exe', '127.0.0.1'])
  50. # TODO Lock einführen und bei Returnwert Lock öffnen mit tkinter.Button.config(state = tkinter.DISABLED)
  51. def btn_visCal(self):
  52. subprocess.Popen([config['PATH']['bci2000'] + r'\prog\Operator.exe', '--OnConnect', '-LOAD PARAMETERFILE gUSBampVisualCalibration.prm'])
  53. subprocess.Popen([config['PATH']['bci2000'] + r'\prog\gUSBampSource.exe', '127.0.0.1'])
  54. subprocess.Popen([config['PATH']['bci2000'] + r'\prog\P3SignalProcessing.exe', '127.0.0.1'])
  55. subprocess.Popen([config['PATH']['bci2000'] + r'\prog\P3Speller.exe', '127.0.0.1'])
  56. # P300 Classifier #########################
  57. def btn_p300(self):
  58. subprocess.Popen(config['PATH']['bci2000'] + r'\tools\P300Classifier\P300Classifier.exe')
  59. # FREESPELL ###############################
  60. def btn_tacFree(self):
  61. subprocess.Popen([config['PATH']['bci2000'] + r'\prog\Operator.exe', '--OnConnect', '-LOAD PARAMETERFILE TactileFree.prm'])
  62. # TODO throw error if else
  63. subprocess.Popen([config['PATH']['bci2000'] + r'\prog\gUSBampSource.exe', '127.0.0.1'])
  64. subprocess.Popen([config['PATH']['bci2000'] + r'\prog\P3SignalProcessing.exe', '127.0.0.1'])
  65. subprocess.Popen([config['PATH']['bci2000'] + r'\prog\P3Speller.exe', '127.0.0.1'])
  66. def btn_visFree(self):
  67. subprocess.Popen([config['PATH']['bci2000'] + r'\prog\Operator.exe', '--OnConnect', '-LOAD PARAMETERFILE gUSBampVisualFree.prm'])
  68. subprocess.Popen([config['PATH']['bci2000'] + r'\prog\gUSBampSource.exe', '127.0.0.1'])
  69. subprocess.Popen([config['PATH']['bci2000'] + r'\prog\P3SignalProcessing.exe', '127.0.0.1'])
  70. subprocess.Popen([config['PATH']['bci2000'] + r'\prog\P3Speller.exe', '127.0.0.1'])
  71. # This Function packs all the Buttons into the Layout
  72. def pack_layout(self):
  73. if config['SETTINGS']['paradigm'] == 'Tactile':
  74. self.BtacFilter.pack()
  75. self.BtacCal.pack()
  76. self.Bp300.pack()
  77. self.BtacFree.pack()
  78. elif config['SETTINGS']['paradigm'] == 'Visual':
  79. self.BvisCal.pack()
  80. self.Bp300.pack()
  81. self.BvisFree.pack()
  82. # This Function removes all the Buttons from the Layout
  83. def unpack_layout(self):
  84. # Add ALL your Buttons here
  85. self.BtacFilter.pack_forget()
  86. self.BtacCal.pack_forget()
  87. self.BvisCal.pack_forget()
  88. self.Bp300.pack_forget()
  89. self.BtacFree.pack_forget()
  90. self.BvisFree.pack_forget()
  91. # set paths
  92. pathOrigin = os.path.dirname(os.path.realpath(__file__)) # set pathOrigin to directory of this file
  93. os.chdir(pathOrigin)
  94. config = configparser.ConfigParser()
  95. configPath = pathOrigin + '/config.ini'
  96. config.read(configPath)
  97. # This Function sets the Paradigm to 'Visual'
  98. def setVisual():
  99. if config['SETTINGS']['paradigm'] == 'Visual':
  100. return
  101. else:
  102. config['SETTINGS']['paradigm'] = 'Visual'
  103. config.write(open(configPath,'w'))
  104. app.Lparadigm.config(text = config['SETTINGS']['paradigm'] + ' BCI')
  105. app.unpack_layout()
  106. app.pack_layout()
  107. # This Function sets the Paradigm to 'Tactile'
  108. def setTactile():
  109. if config['SETTINGS']['paradigm'] == 'Tactile':
  110. return
  111. else:
  112. config['SETTINGS']['paradigm'] = 'Tactile'
  113. config.write(open(configPath,'w'))
  114. app.Lparadigm.config(text = config['SETTINGS']['paradigm'] + ' BCI')
  115. app.unpack_layout()
  116. app.pack_layout()
  117. # This Function sets the BCI2000 Path
  118. def setPathBci2000():
  119. tkinter.messagebox.showinfo('Konfiguration', 'Bitte wählen Sie nun den BCI2000 Ordner aus, in dem sich die Ordner "batch", "data", "parms", "prog" und "tools" befinden.')
  120. tmpPath = tkinter.filedialog.askdirectory()
  121. if not tmpPath:
  122. pass
  123. else:
  124. config['PATH']['bci2000'] = tmpPath
  125. config.write(open(configPath,'w'))
  126. # This Function sets the TactileBCIFilter Path
  127. def setPathTactileBCIFilter():
  128. tkinter.messagebox.showinfo('Konfiguration', 'Bitte wählen Sie nun den Ordner aus, in dem sich die TactileBCIfilter.exe befindet.')
  129. tmpPath = tkinter.filedialog.askdirectory()
  130. if not tmpPath:
  131. pass
  132. else:
  133. config['PATH']['tactilebcifilter'] = tmpPath
  134. config.write(open(configPath,'w'))
  135. # This Function resets the config
  136. def setConfigDefault():
  137. config['PATH']['tactilebcifilter'] = r'C:/Users/bci/Desktop/tactilebcifilter/release'
  138. config['PATH']['bci2000'] = r'C:/BCI2000/BCI2000 v3.6.beta.R5570/BCI2000.x64'
  139. # config['PATH']['tactilebcifilter'] = r'C:\Users\EEG-Gruppe\Desktop\Arduino\Qt Tactile BCI Filter App\Executable'
  140. # config['PATH']['bci2000'] = r'C:\Users\EEG-Gruppe\Desktop\BCI Paket\Paradigmen\Tactile\BCI2000\BCI2000-06-13\BCI2000src'
  141. config['SETTINGS']['paradigm'] = r'Visual'
  142. config['SETTINGS']['hardware'] = r'gUSBamp' # TODO Add gNautilus parameters
  143. config.write(open(configPath,'w'))
  144. app.Lparadigm.config(text = config['SETTINGS']['paradigm'] + ' BCI')
  145. app.unpack_layout()
  146. app.pack_layout()
  147. def on_closing():
  148. #self.global_close(root)
  149. root.destroy()
  150. # root.quit()
  151. root = tkinter.Tk()
  152. root.title('PythonBCIgui v' + str(__version__))
  153. root.protocol("WM_DELETE_WINDOW", on_closing)
  154. leistenMenu = tkinter.Menu(root)
  155. fileMenu = tkinter.Menu(leistenMenu)
  156. leistenMenu.add_cascade(label="Datei", menu=fileMenu)
  157. fileMenu.add_command(label="Einstellungen Zurücksetzen", command=setConfigDefault)
  158. fileMenu.add_command(label="Beenden", command=on_closing)
  159. paradigmMenu = tkinter.Menu(leistenMenu)
  160. leistenMenu.add_cascade(label="Paradigmen", menu=paradigmMenu)
  161. paradigmMenu.add_command(label="Visual", command=setVisual)
  162. paradigmMenu.add_separator()
  163. paradigmMenu.add_command(label="Tactile", command=setTactile)
  164. pathMenu = tkinter.Menu(leistenMenu)
  165. leistenMenu.add_cascade(label="Pfade", menu=pathMenu)
  166. pathMenu.add_command(label="BCI2000", command=setPathBci2000)
  167. pathMenu.add_separator()
  168. pathMenu.add_command(label="TactileBCIFilter", command=setPathTactileBCIFilter)
  169. root.config(menu = leistenMenu)
  170. app = PythonBCIgui(root)
  171. root.mainloop()
  172. #root.destroy() # optional;