pythonbcigui/app.py

264 lines
11 KiB
Python
Raw Normal View History

2020-09-04 12:16:57 +02:00
# -*- coding: utf-8 -*-
"""
Created on Fri Sep 4 11:36:24 2020
2020-09-04 14:02:12 +02:00
@author: Igor Beloschapkin
2020-09-04 12:16:57 +02:00
"""
2020-09-07 10:26:00 +02:00
import tkinter
2020-09-07 15:25:16 +02:00
import tkinter.font
import tkinter.filedialog
2020-09-04 14:02:12 +02:00
import subprocess
2020-09-04 15:06:04 +02:00
import configparser
2020-09-07 18:23:05 +02:00
import os
2020-09-04 12:16:57 +02:00
# own code:
# from questionnaire import quest
2020-09-04 14:48:10 +02:00
# TODO Eventuell updatefunktion über git pull mit einbauen!
2020-09-06 18:25:47 +02:00
__version__ = 0.3
2020-09-07 15:25:16 +02:00
class PythonBCIgui:
2020-09-04 12:16:57 +02:00
def __init__(self, master):
2020-09-07 15:25:16 +02:00
# Einstellung der Button Größe
2020-09-04 14:02:12 +02:00
textH = 4
2020-09-04 15:27:03 +02:00
textHsmall = 2
2020-09-04 14:02:12 +02:00
textW = 20
2020-09-07 18:23:05 +02:00
2020-09-07 15:25:16 +02:00
def makeBtn(self, text, bg, command):
2020-09-07 10:26:00 +02:00
self.button = tkinter.Button(frame, text=text, bg=bg, command=command)
2020-09-04 12:16:57 +02:00
self.button.config( height = textH, width = textW )
2020-09-07 10:26:00 +02:00
self.button['font'] = tkinter.font.Font(family='Helvetica', size=16, weight='bold')
2020-09-04 12:16:57 +02:00
return self.button
2020-09-07 15:25:16 +02:00
def makeBtnSmall(self, text, bg, command):
2020-09-07 10:26:00 +02:00
self.button = tkinter.Button(frame, text=text, bg=bg, command=command)
2020-09-04 12:16:57 +02:00
self.button.config( height = textHsmall, width = textW )
2020-09-07 10:26:00 +02:00
self.button['font'] = tkinter.font.Font(family='Helvetica', size=16, weight='bold')
2020-09-04 13:06:21 +02:00
return self.button
2020-09-07 10:26:00 +02:00
frame = tkinter.Frame(master)
2020-09-04 13:06:21 +02:00
frame.pack()
2020-09-04 12:16:57 +02:00
2020-09-05 13:06:46 +02:00
# label generation
2020-09-07 15:25:16 +02:00
headerText = config['SETTINGS']['paradigm'] + ' BCI'
2020-09-07 10:26:00 +02:00
self.Lparadigm = tkinter.Label(frame, text = headerText, height = 4, width = 20)
self.Lparadigm['font'] = tkinter.font.Font(family='Helvetica', size=16, weight='bold')
2020-09-05 13:06:46 +02:00
self.Lparadigm.pack()
2020-09-04 12:16:57 +02:00
# button generation
2020-09-07 15:25:16 +02:00
self.BtacFilter = makeBtn(self, "Filter", "pink", self.btn_tacFilter)
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)
2020-09-07 18:23:05 +02:00
2020-09-07 15:25:16 +02:00
# self.Bquest = makeBtnSmall(self, "Fragebogen", "green", self.btn_quest, TOP)
2020-09-04 12:16:57 +02:00
frame.rowconfigure((0,1), weight=1) # make buttons stretch when
frame.columnconfigure((0,2), weight=1) # when window is resized
2020-09-04 14:02:12 +02:00
# TODO Hilfestellung nach jedem Button aufploppen lassen:
# Was tun? Wo klicken? Welche File wo laden?
2020-09-04 13:06:21 +02:00
2020-09-07 15:25:16 +02:00
self.pack_layout()
2020-09-04 12:16:57 +02:00
# 1. FILTER ##################################
2020-09-07 15:25:16 +02:00
def btn_tacFilter(self):
2020-09-04 12:16:57 +02:00
print('Starte TactileBCIFilter.exe')
2020-09-08 10:35:01 +02:00
subprocess.Popen(config['PATH']['tactilebcifilter'] + r'\TactileBCIFilter.exe')
2020-09-04 12:16:57 +02:00
# 2. KALIBIERUNGEN ###########################
def btn_tacCal(self):
2020-09-04 14:02:12 +02:00
print('starte taktile Kalibrierung')
2020-09-04 15:59:50 +02:00
subprocess.Popen([config['PATH']['bci2000'] + r'\prog\Operator.exe', '--OnConnect', '-LOAD PARAMETERFILE TactileCalibration.prm'])
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'])
2020-09-07 15:25:16 +02:00
# TODO Lock einführen und bei Returnwert Lock öffnen mit tkinter.Button.config(state = tkinter.DISABLED)
2020-09-05 12:00:37 +02:00
def btn_visCal(self):
print('starte visuelle Kalibrierung')
subprocess.Popen([config['PATH']['bci2000'] + r'\prog\Operator.exe', '--OnConnect', '-LOAD PARAMETERFILE gUSBamp_visual_copySpeller.prm'])
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'])
2020-09-04 12:16:57 +02:00
# 3. P300 Classifier #########################
def btn_p300(self):
2020-09-04 14:02:12 +02:00
print('Starte P300Classifier.exe')
2020-09-04 15:59:50 +02:00
subprocess.Popen(config['PATH']['bci2000'] + r'\tools\P300Classifier\P300Classifier.exe')
2020-09-04 12:16:57 +02:00
2020-09-04 14:48:10 +02:00
# 4. COPYSPELL ###########################
2020-09-04 12:16:57 +02:00
def btn_tacCopy(self):
2020-09-05 12:00:37 +02:00
print('Starte taktilen Speller')
2020-09-04 15:59:50 +02:00
subprocess.Popen([config['PATH']['bci2000'] + r'\prog\Operator.exe', '--OnConnect', '-LOAD PARAMETERFILE TactileCopy.prm'])
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'])
2020-09-05 12:00:37 +02:00
def btn_visCopy(self):
print('Starte visuellen Speller')
subprocess.Popen([config['PATH']['bci2000'] + r'\prog\Operator.exe', '--OnConnect', '-LOAD PARAMETERFILE gUSBamp_visual_freeSpeller.prm'])
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'])
2020-09-04 14:48:10 +02:00
# 5. WHEELCHAIR SIMULATOR ###########################
def btn_tacSimul(self):
print('Starte Wheelchair Simulator')
2020-09-08 10:35:01 +02:00
subprocess.Popen(config['PATH']['wheelchairsimulator'] + r'\Wheels_Occlusion_AutoLog.exe')
subprocess.Popen([config['PATH']['bci2000'] + r'\prog\Operator.exe', '--OnConnect', '-LOAD PARAMETERFILE TactileDrive.prm'])
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'])
2020-09-04 12:16:57 +02:00
# QUESTIONNAIRE PROMPT ###########################
2020-09-05 12:00:37 +02:00
# def btn_quest(self):
2020-09-04 14:48:10 +02:00
#root.destroy()
2020-09-05 12:00:37 +02:00
# self.startQuestions(self.paradigmText)
2020-09-04 12:16:57 +02:00
2020-09-04 14:02:12 +02:00
# def startQuestions(self, para):
2020-09-04 14:48:10 +02:00
# print('Starte Fragebogen')
# q = quest(para)
# q.qSatisfaction()
# q.qExhaustion()
# q.qSubjControl()
# q.qCtrlChange()
# q.save()
2020-09-07 18:23:05 +02:00
2020-09-07 15:25:16 +02:00
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()
2020-09-07 18:23:05 +02:00
2020-09-07 15:25:16 +02:00
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()
2020-09-05 12:00:37 +02:00
2020-09-04 12:16:57 +02:00
def global_close(self, window):
2020-09-04 14:02:12 +02:00
print('Beenden')
2020-09-04 13:06:21 +02:00
window.destroy()
2020-09-07 18:23:05 +02:00
# set paths
pathOrigin = os.path.dirname(os.path.realpath(__file__)) # set pathOrigin to directory of this file
os.chdir(pathOrigin)
2020-09-04 15:27:03 +02:00
config = configparser.ConfigParser()
2020-09-07 18:23:05 +02:00
configPath = pathOrigin + '/config.ini'
config.read(configPath)
2020-09-07 15:25:16 +02:00
def setVisual():
config['SETTINGS']['paradigm'] = 'Visual'
2020-09-07 18:23:05 +02:00
config.write(open(configPath,'w'))
2020-09-07 15:25:16 +02:00
app.Lparadigm.config(text = config['SETTINGS']['paradigm'] + ' BCI')
app.unpack_layout()
app.pack_layout()
def setTactile():
config['SETTINGS']['paradigm'] = 'Tactile'
2020-09-07 18:23:05 +02:00
config.write(open(configPath,'w'))
2020-09-07 15:25:16 +02:00
app.Lparadigm.config(text = config['SETTINGS']['paradigm'] + ' BCI')
app.unpack_layout()
app.pack_layout()
2020-09-07 10:26:00 +02:00
root = tkinter.Tk()
2020-09-07 15:25:16 +02:00
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
2020-09-07 18:23:05 +02:00
config.write(open(configPath,'w'))
2020-09-07 15:25:16 +02:00
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
2020-09-07 18:23:05 +02:00
config.write(open(configPath,'w'))
2020-09-07 15:25:16 +02:00
2020-09-08 10:35:01 +02:00
def setPathWheelchair():
tkinter.messagebox.showinfo('Konfiguration', 'Bitte wählen Sie nun den Ordner aus, in dem sich die Wheels_Occlusion_AutoLog.exe befindet.')
tmpPath = tkinter.filedialog.askdirectory()
if not tmpPath:
pass
else:
config['PATH']['wheelchairsimulator'] = tmpPath
config.write(open(configPath,'w'))
2020-09-07 15:25:16 +02:00
def setConfigDefault():
2020-09-07 18:23:05 +02:00
# TODO Pfade von Wolfgang einbauen
2020-09-07 15:25:16 +02:00
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'
2020-09-08 10:35:01 +02:00
config['PATH']['wheelchairsimulator'] = r'C:\Users\bci\Desktop\Wheelchair' # TODO
2020-09-07 15:25:16 +02:00
config['SETTINGS']['paradigm'] = r'Visual'
config['SETTINGS']['hardware'] = r'gUSBamp'
2020-09-07 18:23:05 +02:00
config.write(open(configPath,'w'))
2020-09-07 15:25:16 +02:00
app.Lparadigm.config(text = config['SETTINGS']['paradigm'] + ' BCI')
app.unpack_layout()
app.pack_layout()
2020-09-04 12:16:57 +02:00
2020-09-04 13:06:21 +02:00
def on_closing():
#self.global_close(root)
2020-09-04 14:02:12 +02:00
print('Beenden')
2020-09-04 13:06:21 +02:00
root.destroy()
2020-09-07 15:25:16 +02:00
# root.quit()
2020-09-05 12:00:37 +02:00
2020-09-04 12:16:57 +02:00
root.protocol("WM_DELETE_WINDOW", on_closing)
2020-09-07 15:25:16 +02:00
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)
2020-09-08 10:35:01 +02:00
pathMenu.add_separator()
pathMenu.add_command(label="Wheelchair Simulator", command=setPathWheelchair)
2020-09-07 15:25:16 +02:00
root.config(menu = leistenMenu)
app = PythonBCIgui(root)
2020-09-04 12:16:57 +02:00
root.mainloop()
2020-09-05 12:00:37 +02:00
#root.destroy() # optional;
2020-09-07 15:25:16 +02:00
2020-09-07 18:23:05 +02:00
# TODO Remove prints before deployment