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