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 9.9KB

4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  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 subprocess
  10. import configparser
  11. import os
  12. # TODO Eventuell updatefunktion über git pull mit einbauen!
  13. __version__ = 0.4
  14. class PythonBCIgui:
  15. def __init__(self, master):
  16. # Einstellung der Button Größe
  17. textH = 4
  18. textHsmall = 2
  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. def makeBtnSmall(self, text, bg, command):
  26. self.button = tkinter.Button(frame, text=text, bg=bg, command=command)
  27. self.button.config( height = textHsmall, width = textW )
  28. self.button['font'] = tkinter.font.Font(family='Helvetica', size=16, weight='bold')
  29. return self.button
  30. frame = tkinter.Frame(master)
  31. frame.pack()
  32. # label generation
  33. headerText = config['SETTINGS']['paradigm'] + ' BCI'
  34. self.Lparadigm = tkinter.Label(frame, text = headerText, height = 4, width = 20)
  35. self.Lparadigm['font'] = tkinter.font.Font(family='Helvetica', size=16, weight='bold')
  36. self.Lparadigm.pack()
  37. # button generation
  38. self.BtacFilter = makeBtn(self, "Filter", "pink", self.btn_tacFilter)
  39. self.BtacCal = makeBtn(self, "Kalibrierung", "lightgreen", self.btn_tacCal)
  40. self.BvisCal = makeBtn(self, "Kalibrierung", "lightgreen", self.btn_visCal)
  41. self.Bp300 = makeBtn(self, "P300 Klassifizierung", "orange", self.btn_p300)
  42. self.BtacCopy = makeBtn(self, "Freies Buchstabieren:\nTest", "lightblue", self.btn_tacCopy)
  43. self.BtacCopyNested = makeBtn(self, "Freies Buchstabieren:\nKategorien", "lightyellow", self.btn_tacCopyNested)
  44. self.BvisCopy = makeBtn(self, "Freies Buchstabieren", "lightblue", self.btn_visCopy)
  45. frame.rowconfigure((0,1), weight=1) # make buttons stretch when # TODO Remove
  46. frame.columnconfigure((0,2), weight=1) # when window is resized
  47. # TODO Hilfestellung nach jedem Button aufploppen lassen:
  48. # Was tun? Wo klicken? Welche File wo laden?
  49. self.pack_layout()
  50. # FILTER ##################################
  51. def btn_tacFilter(self):
  52. print('Starte TactileBCIFilter.exe')
  53. subprocess.Popen(config['PATH']['tactilebcifilter'] + r'\TactileBCIFilter.exe')
  54. # KALIBRIERUNGEN ###########################
  55. def btn_tacCal(self):
  56. print('starte taktile Kalibrierung')
  57. subprocess.Popen([config['PATH']['bci2000'] + r'\prog\Operator.exe', '--OnConnect', '-LOAD PARAMETERFILE TactileCalibration.prm'])
  58. subprocess.Popen([config['PATH']['bci2000'] + r'\prog\gUSBampSource.exe', '127.0.0.1'])
  59. subprocess.Popen([config['PATH']['bci2000'] + r'\prog\P3SignalProcessing.exe', '127.0.0.1'])
  60. subprocess.Popen([config['PATH']['bci2000'] + r'\prog\P3Speller.exe', '127.0.0.1'])
  61. # TODO Lock einführen und bei Returnwert Lock öffnen mit tkinter.Button.config(state = tkinter.DISABLED)
  62. def btn_visCal(self):
  63. print('starte visuelle Kalibrierung')
  64. subprocess.Popen([config['PATH']['bci2000'] + r'\prog\Operator.exe', '--OnConnect', '-LOAD PARAMETERFILE gUSBamp_visual_copySpeller.prm'])
  65. subprocess.Popen([config['PATH']['bci2000'] + r'\prog\gUSBampSource.exe', '127.0.0.1'])
  66. subprocess.Popen([config['PATH']['bci2000'] + r'\prog\P3SignalProcessing.exe', '127.0.0.1'])
  67. subprocess.Popen([config['PATH']['bci2000'] + r'\prog\P3Speller.exe', '127.0.0.1'])
  68. # P300 Classifier #########################
  69. def btn_p300(self):
  70. print('Starte P300Classifier.exe')
  71. subprocess.Popen(config['PATH']['bci2000'] + r'\tools\P300Classifier\P300Classifier.exe')
  72. # COPYSPELL ###########################
  73. def btn_tacCopy(self):
  74. print('Starte taktilen Speller')
  75. subprocess.Popen([config['PATH']['bci2000'] + r'\prog\Operator.exe', '--OnConnect', '-LOAD PARAMETERFILE TactileCopy.prm'])
  76. subprocess.Popen([config['PATH']['bci2000'] + r'\prog\gUSBampSource.exe', '127.0.0.1'])
  77. subprocess.Popen([config['PATH']['bci2000'] + r'\prog\P3SignalProcessing.exe', '127.0.0.1'])
  78. subprocess.Popen([config['PATH']['bci2000'] + r'\prog\P3Speller.exe', '127.0.0.1'])
  79. def btn_tacCopyNested(self):
  80. print('Starte taktilen Speller') # TODO Prints rausnehmen
  81. subprocess.Popen([config['PATH']['bci2000'] + r'\prog\Operator.exe', '--OnConnect', '-LOAD PARAMETERFILE TactileCopyNested.prm'])
  82. subprocess.Popen([config['PATH']['bci2000'] + r'\prog\gUSBampSource.exe', '127.0.0.1'])
  83. subprocess.Popen([config['PATH']['bci2000'] + r'\prog\P3SignalProcessing.exe', '127.0.0.1'])
  84. subprocess.Popen([config['PATH']['bci2000'] + r'\prog\P3Speller.exe', '127.0.0.1'])
  85. def btn_visCopy(self):
  86. print('Starte visuellen Speller')
  87. subprocess.Popen([config['PATH']['bci2000'] + r'\prog\Operator.exe', '--OnConnect', '-LOAD PARAMETERFILE gUSBamp_visual_freeSpeller.prm'])
  88. subprocess.Popen([config['PATH']['bci2000'] + r'\prog\gUSBampSource.exe', '127.0.0.1'])
  89. subprocess.Popen([config['PATH']['bci2000'] + r'\prog\P3SignalProcessing.exe', '127.0.0.1'])
  90. subprocess.Popen([config['PATH']['bci2000'] + r'\prog\P3Speller.exe', '127.0.0.1'])
  91. # This Function packs all the Buttons into the Layout
  92. def pack_layout(self):
  93. if config['SETTINGS']['paradigm'] == 'Tactile':
  94. self.BtacFilter.pack()
  95. self.BtacCal.pack()
  96. self.Bp300.pack()
  97. self.BtacCopy.pack()
  98. self.BtacCopyNested.pack()
  99. elif config['SETTINGS']['paradigm'] == 'Visual':
  100. self.BvisCal.pack()
  101. self.Bp300.pack()
  102. self.BvisCopy.pack()
  103. # This Function removes all the Buttons from the Layout
  104. def unpack_layout(self):
  105. # Add ALL your Buttons here
  106. self.BtacFilter.pack_forget()
  107. self.BtacCal.pack_forget()
  108. self.BvisCal.pack_forget()
  109. self.Bp300.pack_forget()
  110. self.BtacCopy.pack_forget()
  111. self.BtacCopyNested.pack_forget()
  112. self.BvisCopy.pack_forget()
  113. def global_close(self, window):
  114. print('Beenden')
  115. window.destroy()
  116. # set paths
  117. pathOrigin = os.path.dirname(os.path.realpath(__file__)) # set pathOrigin to directory of this file
  118. os.chdir(pathOrigin)
  119. config = configparser.ConfigParser()
  120. configPath = pathOrigin + '/config.ini'
  121. config.read(configPath)
  122. def setVisual():
  123. if config['SETTINGS']['paradigm'] == 'Visual':
  124. return
  125. else:
  126. config['SETTINGS']['paradigm'] = 'Visual'
  127. config.write(open(configPath,'w'))
  128. app.Lparadigm.config(text = config['SETTINGS']['paradigm'] + ' BCI')
  129. app.unpack_layout()
  130. app.pack_layout()
  131. def setTactile():
  132. if config['SETTINGS']['paradigm'] == 'Tactile':
  133. return
  134. else:
  135. config['SETTINGS']['paradigm'] = 'Tactile'
  136. config.write(open(configPath,'w'))
  137. app.Lparadigm.config(text = config['SETTINGS']['paradigm'] + ' BCI')
  138. app.unpack_layout()
  139. app.pack_layout()
  140. root = tkinter.Tk()
  141. root.title('PythonBCIgui v' + str(__version__))
  142. def setPathBci2000():
  143. tkinter.messagebox.showinfo('Konfiguration', 'Bitte wählen Sie nun den BCI2000 Ordner aus, in dem sich die Ordner "batch", "data", "icons", "parms", "prog" und "tools" befinden.')
  144. tmpPath = tkinter.filedialog.askdirectory()
  145. if not tmpPath:
  146. pass
  147. else:
  148. config['PATH']['bci2000'] = tmpPath
  149. config.write(open(configPath,'w'))
  150. def setPathTactileBCIFilter():
  151. tkinter.messagebox.showinfo('Konfiguration', 'Bitte wählen Sie nun den Ordner aus, in dem sich die TactileBCIfilter.exe befindet.')
  152. tmpPath = tkinter.filedialog.askdirectory()
  153. if not tmpPath:
  154. pass
  155. else:
  156. config['PATH']['tactilebcifilter'] = tmpPath
  157. config.write(open(configPath,'w'))
  158. def setConfigDefault():
  159. # config['PATH']['tactilebcifilter'] = r'C:/Users/bci/Desktop/Qt Filter Program/build-TactileBCIFilter-Desktop_Qt_5_15_0_MinGW_32_bit-Release/release'
  160. # config['PATH']['bci2000'] = r'C:/BCI2000/BCI2000 v3.6.beta.R5570/BCI2000.x64'
  161. config['PATH']['tactilebcifilter'] = r'C:\Users\EEG-Gruppe\Desktop\Arduino\Qt Tactile BCI Filter App\Executable'
  162. config['PATH']['bci2000'] = r'C:\Users\EEG-Gruppe\Desktop\BCI Paket\Paradigmen\Tactile\BCI2000\BCI2000-06-13\BCI2000src'
  163. config['SETTINGS']['paradigm'] = r'Visual'
  164. config['SETTINGS']['hardware'] = r'gUSBamp' # TODO Add gNautilus parameters
  165. config.write(open(configPath,'w'))
  166. app.Lparadigm.config(text = config['SETTINGS']['paradigm'] + ' BCI')
  167. app.unpack_layout()
  168. app.pack_layout()
  169. def on_closing():
  170. #self.global_close(root)
  171. print('Beenden')
  172. root.destroy()
  173. # root.quit()
  174. root.protocol("WM_DELETE_WINDOW", on_closing)
  175. leistenMenu = tkinter.Menu(root)
  176. fileMenu = tkinter.Menu(leistenMenu)
  177. leistenMenu.add_cascade(label="Datei", menu=fileMenu)
  178. fileMenu.add_command(label="Einstellungen Zurücksetzen", command=setConfigDefault)
  179. fileMenu.add_command(label="Beenden", command=on_closing)
  180. paradigmMenu = tkinter.Menu(leistenMenu)
  181. leistenMenu.add_cascade(label="Paradigmen", menu=paradigmMenu)
  182. paradigmMenu.add_command(label="Visual", command=setVisual)
  183. paradigmMenu.add_separator()
  184. paradigmMenu.add_command(label="Tactile", command=setTactile)
  185. pathMenu = tkinter.Menu(leistenMenu)
  186. leistenMenu.add_cascade(label="Pfade", menu=pathMenu)
  187. pathMenu.add_command(label="BCI2000", command=setPathBci2000)
  188. pathMenu.add_separator()
  189. pathMenu.add_command(label="TactileBCIFilter", command=setPathTactileBCIFilter)
  190. root.config(menu = leistenMenu)
  191. app = PythonBCIgui(root)
  192. root.mainloop()
  193. #root.destroy() # optional;
  194. # TODO Remove prints before deployment