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
2020-09-04 14:48:10 +02:00
# TODO Eventuell updatefunktion über git pull mit einbauen!
2020-09-14 14:49:19 +02:00
__version__ = 0.41
2020-09-06 18:25:47 +02:00
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
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 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 )
2020-09-15 11:42:00 +02:00
self . BtacCal = makeBtn ( self , " Kalibrierung " , " lightgreen " , self . btn_tacCal )
2020-09-07 15:25:16 +02:00
self . BvisCal = makeBtn ( self , " Kalibrierung " , " lightgreen " , self . btn_visCal )
self . Bp300 = makeBtn ( self , " P300 Klassifizierung " , " orange " , self . btn_p300 )
2020-09-15 11:42:00 +02:00
self . BtacFree = makeBtn ( self , " Freies Buchstabieren " , " lightblue " , self . btn_tacFree )
2020-09-14 14:49:19 +02:00
self . BvisFree = makeBtn ( self , " Freies Buchstabieren " , " lightblue " , self . btn_visFree )
2020-09-07 15:25:16 +02:00
self . pack_layout ( )
2020-09-09 16:07:18 +02:00
# FILTER ###################################
2020-09-07 15:25:16 +02:00
def btn_tacFilter ( self ) :
2020-09-08 10:35:01 +02:00
subprocess . Popen ( config [ ' PATH ' ] [ ' tactilebcifilter ' ] + r ' \ TactileBCIFilter.exe ' )
2020-09-04 12:16:57 +02:00
2020-09-09 12:43:17 +02:00
# KALIBRIERUNGEN ###########################
2020-09-04 12:16:57 +02:00
def btn_tacCal ( self ) :
2020-09-15 11:42:00 +02:00
if config [ ' SETTINGS ' ] [ ' tactilemode ' ] == ' Motors ' :
subprocess . Popen ( [ config [ ' PATH ' ] [ ' bci2000 ' ] + r ' \ prog \ Operator.exe ' , ' --OnConnect ' , ' -LOAD PARAMETERFILE TactileCalibration.prm ' ] )
elif config [ ' SETTINGS ' ] [ ' tactilemode ' ] == ' Nested ' :
subprocess . Popen ( [ config [ ' PATH ' ] [ ' bci2000 ' ] + r ' \ prog \ Operator.exe ' , ' --OnConnect ' , ' -LOAD PARAMETERFILE TactileCalibrationNested.prm ' ] )
# TODO Throw error if else
2020-09-04 15:59:50 +02:00
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 ) :
2020-09-14 14:49:19 +02:00
subprocess . Popen ( [ config [ ' PATH ' ] [ ' bci2000 ' ] + r ' \ prog \ Operator.exe ' , ' --OnConnect ' , ' -LOAD PARAMETERFILE gUSBampVisualCalibration.prm ' ] )
2020-09-05 12:00:37 +02:00
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
2020-09-09 12:43:17 +02:00
# P300 Classifier #########################
2020-09-04 12:16:57 +02:00
def btn_p300 ( self ) :
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-09 16:07:18 +02:00
# FREESPELL ###############################
2020-09-14 14:49:19 +02:00
def btn_tacFree ( self ) :
2020-09-15 11:42:00 +02:00
if config [ ' SETTINGS ' ] [ ' tactilemode ' ] == ' Motors ' :
subprocess . Popen ( [ config [ ' PATH ' ] [ ' bci2000 ' ] + r ' \ prog \ Operator.exe ' , ' --OnConnect ' , ' -LOAD PARAMETERFILE TactileFree.prm ' ] )
elif config [ ' SETTINGS ' ] [ ' tactilemode ' ] == ' Nested ' :
subprocess . Popen ( [ config [ ' PATH ' ] [ ' bci2000 ' ] + r ' \ prog \ Operator.exe ' , ' --OnConnect ' , ' -LOAD PARAMETERFILE TactileFreeNested.prm ' ] )
# TODO throw error if else
2020-09-05 12:00:37 +02:00
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-14 14:49:19 +02:00
def btn_visFree ( self ) :
subprocess . Popen ( [ config [ ' PATH ' ] [ ' bci2000 ' ] + r ' \ prog \ Operator.exe ' , ' --OnConnect ' , ' -LOAD PARAMETERFILE gUSBampVisualFree.prm ' ] )
2020-09-08 10:35:01 +02:00
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
2020-09-09 12:43:17 +02:00
# This Function packs all the Buttons into the Layout
2020-09-07 15:25:16 +02:00
def pack_layout ( self ) :
if config [ ' SETTINGS ' ] [ ' paradigm ' ] == ' Tactile ' :
self . BtacFilter . pack ( )
self . BtacCal . pack ( )
2020-09-09 12:43:17 +02:00
self . Bp300 . pack ( )
2020-09-14 14:49:19 +02:00
self . BtacFree . pack ( )
2020-09-07 15:25:16 +02:00
elif config [ ' SETTINGS ' ] [ ' paradigm ' ] == ' Visual ' :
2020-09-09 12:43:17 +02:00
self . BvisCal . pack ( )
self . Bp300 . pack ( )
2020-09-14 14:49:19 +02:00
self . BvisFree . pack ( )
2020-09-07 18:23:05 +02:00
2020-09-09 12:43:17 +02:00
# This Function removes all the Buttons from the Layout
2020-09-07 15:25:16 +02:00
def unpack_layout ( self ) :
# Add ALL your Buttons here
self . BtacFilter . pack_forget ( )
self . BtacCal . pack_forget ( )
self . BvisCal . pack_forget ( )
self . Bp300 . pack_forget ( )
2020-09-14 14:49:19 +02:00
self . BtacFree . pack_forget ( )
self . BvisFree . pack_forget ( )
2020-09-05 12:00:37 +02:00
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-09 16:07:18 +02:00
# This Function sets the Paradigm to 'Visual'
2020-09-07 15:25:16 +02:00
def setVisual ( ) :
2020-09-09 12:43:17 +02:00
if config [ ' SETTINGS ' ] [ ' paradigm ' ] == ' Visual ' :
return
else :
config [ ' SETTINGS ' ] [ ' paradigm ' ] = ' Visual '
config . write ( open ( configPath , ' w ' ) )
app . Lparadigm . config ( text = config [ ' SETTINGS ' ] [ ' paradigm ' ] + ' BCI ' )
app . unpack_layout ( )
app . pack_layout ( )
2020-09-07 15:25:16 +02:00
2020-09-09 16:07:18 +02:00
# This Function sets the Paradigm to 'Tactile'
2020-09-07 15:25:16 +02:00
def setTactile ( ) :
2020-09-09 12:43:17 +02:00
if config [ ' SETTINGS ' ] [ ' paradigm ' ] == ' Tactile ' :
return
else :
config [ ' SETTINGS ' ] [ ' paradigm ' ] = ' Tactile '
config . write ( open ( configPath , ' w ' ) )
app . Lparadigm . config ( text = config [ ' SETTINGS ' ] [ ' paradigm ' ] + ' BCI ' )
app . unpack_layout ( )
app . pack_layout ( )
2020-09-07 15:25:16 +02:00
2020-09-15 11:42:00 +02:00
def setTactileModeMotors ( ) :
if config [ ' SETTINGS ' ] [ ' tactilemode ' ] == ' Motors ' :
return
else :
config [ ' SETTINGS ' ] [ ' tactilemode ' ] = ' Motors '
config . write ( open ( configPath , ' w ' ) )
def setTactileModeNested ( ) :
if config [ ' SETTINGS ' ] [ ' tactilemode ' ] == ' Nested ' :
return
else :
config [ ' SETTINGS ' ] [ ' tactilemode ' ] = ' Nested '
config . write ( open ( configPath , ' w ' ) )
2020-09-07 15:25:16 +02:00
2020-09-09 16:07:18 +02:00
# This Function sets the BCI2000 Path
2020-09-07 15:25:16 +02:00
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
2020-09-09 16:07:18 +02:00
# This Function sets the TactileBCIFilter Path
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-09 16:07:18 +02:00
# This Function resets the config
2020-09-07 15:25:16 +02:00
def setConfigDefault ( ) :
2020-09-08 11:02:12 +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'
config [ ' PATH ' ] [ ' tactilebcifilter ' ] = r ' C: \ Users \ EEG-Gruppe \ Desktop \ Arduino \ Qt Tactile BCI Filter App \ Executable '
config [ ' PATH ' ] [ ' bci2000 ' ] = r ' C: \ Users \ EEG-Gruppe \ Desktop \ BCI Paket \ Paradigmen \ Tactile \ BCI2000 \ BCI2000-06-13 \ BCI2000src '
2020-09-07 15:25:16 +02:00
config [ ' SETTINGS ' ] [ ' paradigm ' ] = r ' Visual '
2020-09-09 12:43:17 +02:00
config [ ' SETTINGS ' ] [ ' hardware ' ] = r ' gUSBamp ' # TODO Add gNautilus parameters
2020-09-15 11:42:00 +02:00
config [ ' SETTINGS ' ] [ ' tactilemode ' ] = r ' Motors '
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)
root . destroy ( )
2020-09-07 15:25:16 +02:00
# root.quit()
2020-09-05 12:00:37 +02:00
2020-09-15 11:42:00 +02:00
root = tkinter . Tk ( )
root . title ( ' PythonBCIgui v ' + str ( __version__ ) )
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-15 11:42:00 +02:00
tactileModeMenu = tkinter . Menu ( leistenMenu )
leistenMenu . add_cascade ( label = " Taktiler Modus " , menu = tactileModeMenu )
tactileModeMenu . add_command ( label = " Motoren " , command = setTactileModeMotors )
tactileModeMenu . add_command ( label = " Kategorien " , command = setTactileModeNested )
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;