diff --git a/app.py b/app.py index a94c66d..9036877 100644 --- a/app.py +++ b/app.py @@ -6,6 +6,8 @@ Created on Fri Sep 4 11:36:24 2020 """ import tkinter +import tkinter.font +import tkinter.filedialog import subprocess import configparser @@ -16,12 +18,11 @@ import configparser __version__ = 0.3 -class App: +class PythonBCIgui: def __init__(self, master): - self.paradigmText = tkinter.sys.argv[1] - # App.paradigmText = sys.argv[1] - # pathOrigin = os.path.dirname(os.path.realpath(__file__)) + #pathOrigin = os.path.dirname(os.path.realpath(__file__)) + #print(pathOrigin) # TODO current working directory auf root von dieser file setzen @@ -29,68 +30,56 @@ class App: # pathSave = "\\questions\\" + self.paradigmText # pathSave = os.getcwd() + pathSave - config.read('config.ini') - - # Einstellung der GUI Größe + # Einstellung der Button Größe textH = 4 textHsmall = 2 textW = 20 - - def makeBtn(self, text, bg, command, side): + + def makeBtn(self, text, bg, command): self.button = tkinter.Button(frame, text=text, bg=bg, command=command) self.button.config( height = textH, width = textW ) self.button['font'] = tkinter.font.Font(family='Helvetica', size=16, weight='bold') - self.button.pack(side=side) return self.button - def makeBtnSmall(self, text, bg, command, side): + def makeBtnSmall(self, text, bg, command): self.button = tkinter.Button(frame, text=text, bg=bg, command=command) self.button.config( height = textHsmall, width = textW ) self.button['font'] = tkinter.font.Font(family='Helvetica', size=16, weight='bold') - self.button.pack(side=side) return self.button frame = tkinter.Frame(master) frame.pack() # label generation - headerText = 'PythonBCIgui V' + str(__version__) + '\n\n' + self.paradigmText + ' BCI' + headerText = config['SETTINGS']['paradigm'] + ' BCI' self.Lparadigm = tkinter.Label(frame, text = headerText, height = 4, width = 20) self.Lparadigm['font'] = tkinter.font.Font(family='Helvetica', size=16, weight='bold') self.Lparadigm.pack() # button generation - if self.paradigmText == 'Tactile': - self.Bfilter = makeBtn(self, "1. Filter", "lightyellow", self.btn_filter, tkinter.TOP) - self.BtacCal = makeBtn(self, "2. Kalibrierung", "lightgreen", self.btn_tacCal, tkinter.TOP) - self.Bp300 = makeBtn(self, "3. P300 Klassifizierung", "orange", self.btn_p300, tkinter.TOP) - self.BtacCopy = makeBtn(self, "4. Freies Buchstabieren", "lightblue", self.btn_tacCopy, tkinter.TOP) - self.BtacSimul = makeBtn(self, "5. Rollstuhlsimulator", "pink", self.btn_tacSimul, tkinter.TOP) - elif self.paradigmText == 'Visual': - self.Bfilter = makeBtn(self, "1. Filter", "lightyellow", self.btn_filter, tkinter.TOP) - self.BvisCal = makeBtn(self, "2. Kalibrierung", "lightgreen", self.btn_visCal, tkinter.TOP) - self.Bp300 = makeBtn(self, "3. P300 Klassifizierung", "orange", self.btn_p300, tkinter.TOP) - self.BvisCopy = makeBtn(self, "4. Freies Buchstabieren", "lightblue", self.btn_visCopy, tkinter.TOP) - elif self.paradigmText == 'Test': # TODO Remove - self.Bfilter = makeBtn(self, "1. Filter", "lightyellow", self.btn_filter, tkinter.TOP) - self.BvisCal = makeBtn(self, "2. Kalibrierung", "lightgreen", self.btn_visCal, tkinter.TOP) - self.Bp300 = makeBtn(self, "3. P300 Klassifizierung", "orange", self.btn_p300, tkinter.TOP) - self.BvisCopy = makeBtn(self, "4. Freies Buchstabieren", "lightblue", self.btn_visCopy, tkinter.TOP) - self.Btest = makeBtnSmall(self, "TEST", "green", self.btn_test, tkinter.TOP) # TODO Remove - else: - print('Fehler: Bitte wählen Sie "Tactile" oder "Visual" als Argument') - raise ValueError + self.BtacFilter = makeBtn(self, "Filter", "pink", self.btn_tacFilter) - # self.Bquest = makeBtnSmall(self, "6. Fragebogen", "green", self.btn_quest, TOP) - self.BtacConfig = makeBtnSmall(self, "Konfiguration", "gray", self.btn_config, tkinter.TOP) + self.BtacCal = makeBtn(self, "Kalibrierung", "lightgreen", self.btn_tacCal) + self.BvisCal = makeBtn(self, "Kalibrierung", "lightgreen", self.btn_visCal) + + self.Bp300 = makeBtn(self, "P300 Klassifizierung", "orange", self.btn_p300) + + self.BtacCopy = makeBtn(self, "Freies Buchstabieren", "lightblue", self.btn_tacCopy) + self.BvisCopy = makeBtn(self, "Freies Buchstabieren", "lightblue", self.btn_visCopy) + + self.BtacSimul = makeBtn(self, "Rollstuhlsimulator", "lightyellow", self.btn_tacSimul) + + # self.Bquest = makeBtnSmall(self, "Fragebogen", "green", self.btn_quest, TOP) frame.rowconfigure((0,1), weight=1) # make buttons stretch when frame.columnconfigure((0,2), weight=1) # when window is resized # TODO Hilfestellung nach jedem Button aufploppen lassen: # Was tun? Wo klicken? Welche File wo laden? + self.pack_layout() + # 1. FILTER ################################## - def btn_filter(self): + def btn_tacFilter(self): print('Starte TactileBCIFilter.exe') subprocess.Popen(config['PATH']['tactilebcifilter'] + '\TactileBCIFilter.exe') @@ -101,7 +90,7 @@ class App: subprocess.Popen([config['PATH']['bci2000'] + r'\prog\gUSBampSource.exe', '127.0.0.1']) subprocess.Popen([config['PATH']['bci2000'] + r'\prog\P3SignalProcessing.exe', '127.0.0.1']) subprocess.Popen([config['PATH']['bci2000'] + r'\prog\P3Speller.exe', '127.0.0.1']) - # TODO Lock einführen und bei Returnwert Lock öffnen + # TODO Lock einführen und bei Returnwert Lock öffnen mit tkinter.Button.config(state = tkinter.DISABLED) def btn_visCal(self): print('starte visuelle Kalibrierung') subprocess.Popen([config['PATH']['bci2000'] + r'\prog\Operator.exe', '--OnConnect', '-LOAD PARAMETERFILE gUSBamp_visual_copySpeller.prm']) @@ -150,34 +139,116 @@ class App: # q.qSubjControl() # q.qCtrlChange() # q.save() - - # X. Settings ######################### - def btn_config(self): - print('Konfiguration') - 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.') - config['PATH']['bci2000'] = tkinter.filedialog.askdirectory() - tkinter.messagebox.showinfo('Konfiguration', 'Bitte wählen Sie nun den Ordner aus, in dem sich die TactileBCIfilter.exe befindet.') - config['PATH']['tactilebcifilter'] = tkinter.filedialog.askdirectory() - config.write(open('config.ini','w')) - # TODO Catch errors falls falsche Ordner gewählt wurden - - def btn_test(self): # TODO Remove - print('TEST') - print(self.paradigmText) + + def pack_layout(self): + # This Function packs all the Buttons into the Layout + if config['SETTINGS']['paradigm'] == 'Tactile': + self.BtacFilter.pack() + self.BtacCal.pack() + elif config['SETTINGS']['paradigm'] == 'Visual': + self.BvisCal.pack() + self.Bp300.pack() + if config['SETTINGS']['paradigm'] == 'Tactile': + self.BtacCopy.pack() + self.BtacSimul.pack() + elif config['SETTINGS']['paradigm'] == 'Visual': + self.BvisCopy.pack() + + def unpack_layout(self): + # This Function removes all the Buttons from the Layout + # Add ALL your Buttons here + self.BtacFilter.pack_forget() + self.BtacCal.pack_forget() + self.BvisCal.pack_forget() + self.Bp300.pack_forget() + self.BtacCopy.pack_forget() + self.BtacSimul.pack_forget() + self.BvisCopy.pack_forget() def global_close(self, window): print('Beenden') window.destroy() + config = configparser.ConfigParser() +config.read('config.ini') + +def setVisual(): + config['SETTINGS']['paradigm'] = 'Visual' + config.write(open('config.ini','w')) + app.Lparadigm.config(text = config['SETTINGS']['paradigm'] + ' BCI') + app.unpack_layout() + app.pack_layout() + +def setTactile(): + config['SETTINGS']['paradigm'] = 'Tactile' + config.write(open('config.ini','w')) + app.Lparadigm.config(text = config['SETTINGS']['paradigm'] + ' BCI') + app.unpack_layout() + app.pack_layout() + root = tkinter.Tk() +root.title('PythonBCIgui v' + str(__version__)) + +def setPathBci2000(): + 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.') + tmpPath = tkinter.filedialog.askdirectory() + if not tmpPath: + pass + else: + config['PATH']['bci2000'] = tmpPath + config.write(open('config.ini','w')) + +def setPathTactileBCIFilter(): + tkinter.messagebox.showinfo('Konfiguration', 'Bitte wählen Sie nun den Ordner aus, in dem sich die TactileBCIfilter.exe befindet.') + tmpPath = tkinter.filedialog.askdirectory() + if not tmpPath: + pass + else: + config['PATH']['tactilebcifilter'] = tmpPath + config.write(open('config.ini','w')) + +def setConfigDefault(): + config['PATH']['tactilebcifilter'] = r'C:/Users/bci/Desktop/Qt Filter Program/build-TactileBCIFilter-Desktop_Qt_5_15_0_MinGW_32_bit-Release/release' + config['PATH']['bci2000'] = r'C:/BCI2000/BCI2000 v3.6.beta.R5570/BCI2000.x64' + config['SETTINGS']['paradigm'] = r'Visual' + config['SETTINGS']['hardware'] = r'gUSBamp' + config.write(open('config.ini','w')) + app.Lparadigm.config(text = config['SETTINGS']['paradigm'] + ' BCI') + app.unpack_layout() + app.pack_layout() def on_closing(): #self.global_close(root) print('Beenden') root.destroy() + # root.quit() root.protocol("WM_DELETE_WINDOW", on_closing) -app = App(root) + +leistenMenu = tkinter.Menu(root) + +fileMenu = tkinter.Menu(leistenMenu) +leistenMenu.add_cascade(label="Datei", menu=fileMenu) +fileMenu.add_command(label="Einstellungen Zurücksetzen", command=setConfigDefault) +fileMenu.add_command(label="Beenden", command=on_closing) + +paradigmMenu = tkinter.Menu(leistenMenu) +leistenMenu.add_cascade(label="Paradigmen", menu=paradigmMenu) +paradigmMenu.add_command(label="Visual", command=setVisual) +paradigmMenu.add_separator() +paradigmMenu.add_command(label="Tactile", command=setTactile) + +pathMenu = tkinter.Menu(leistenMenu) +leistenMenu.add_cascade(label="Pfade", menu=pathMenu) +pathMenu.add_command(label="BCI2000", command=setPathBci2000) +pathMenu.add_separator() +pathMenu.add_command(label="TactileBCIFilter", command=setPathTactileBCIFilter) + +root.config(menu = leistenMenu) + +app = PythonBCIgui(root) root.mainloop() #root.destroy() # optional; + +# TODO Remove prints before deployment \ No newline at end of file diff --git a/config.ini b/config.ini index 75c935d..ffda7af 100644 --- a/config.ini +++ b/config.ini @@ -1,3 +1,7 @@ +[SETTINGS] +paradigm = Tactile +hardware = gUSBamp + [PATH] bci2000 = C:/BCI2000/BCI2000 v3.6.beta.R5570/BCI2000.x64 tactilebcifilter = C:/Users/bci/Desktop/Qt Filter Program/build-TactileBCIFilter-Desktop_Qt_5_15_0_MinGW_32_bit-Release/release