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

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