Raspery-code
This commit is contained in:
commit
6a8ea069c7
327
UIController.py
Normal file
327
UIController.py
Normal file
@ -0,0 +1,327 @@
|
|||||||
|
'''--------------------------------------------------------------------------------------------------
|
||||||
|
Im Controller wird in der Init eine View erstellt und gestartet. Zudem wird der Acquisitionserver
|
||||||
|
gestartet, die shared Librarz geladen, die Konstanten Initialtisiert.
|
||||||
|
Mittels der Funktion Action Performed wird die jeweilige Reaktion auf die Benutyeraktion ausgeloest.
|
||||||
|
Hierfuer stehen die verschiedenen eigenen Funktionen die die Reaktion in der richtigen reihenfolge
|
||||||
|
an ein neu instanizieertes Modell weitergibt.
|
||||||
|
Zudem stehen einige Funktionen zur Informationsuebergabe an die View oder das Modell zur Verfuegung
|
||||||
|
'''
|
||||||
|
|
||||||
|
|
||||||
|
from UIModellVisuell import *
|
||||||
|
from UIModellTaktil import *
|
||||||
|
from UIModell import *
|
||||||
|
import UIViewTKinter as viewTkinter
|
||||||
|
from shutil import copyfile
|
||||||
|
import ctypes
|
||||||
|
import os
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class Controller():
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
'''--------------------------------------------------------------------------------------------------
|
||||||
|
In der Init wird die shared Library geladen, die View erstellt und geoeffnet und die verschiedenen
|
||||||
|
Konstanten gesetzt
|
||||||
|
'''
|
||||||
|
|
||||||
|
self.getSharedLibrary()
|
||||||
|
|
||||||
|
self.view = viewTkinter.View(self, self.dll.getDefaultPath())
|
||||||
|
self.modi = "visuellesBCI"
|
||||||
|
self.pathOVFile = self.dll.getPathOVFile()
|
||||||
|
self.pathSpatialCfg = self.dll.getSpatialCFGFile()
|
||||||
|
self.pathClassifierCfg = self.dll.getClassifierCFGFile()
|
||||||
|
self.infotext = ""
|
||||||
|
|
||||||
|
self.commands = {
|
||||||
|
"copySpelling": self.commandoCopySpelling,
|
||||||
|
"stop": self.commandStop,
|
||||||
|
"freeSpelling": self.commandFreeSpelling,
|
||||||
|
"test": self.test,
|
||||||
|
"wechsel": self.wechsel,
|
||||||
|
"speicherort": self.setDataset
|
||||||
|
}
|
||||||
|
|
||||||
|
self.nexts = {
|
||||||
|
"filterXdawn" : self.filterXdawn,
|
||||||
|
"filterClassic": self.filterClassic,
|
||||||
|
"save": self.speichern
|
||||||
|
}
|
||||||
|
|
||||||
|
self.pagesTaktil = {
|
||||||
|
"stop": "StartPage",
|
||||||
|
"copySpelling": "WorkingPageTaktil",
|
||||||
|
"freeSpelling": "WorkingPageTaktil",
|
||||||
|
"test": "WorkingPageTaktil"
|
||||||
|
}
|
||||||
|
self.pagesVisuell = {
|
||||||
|
"stop": "StartPage",
|
||||||
|
"copySpelling": "WorkingPageVisuell",
|
||||||
|
"freeSpelling": "WorkingPageVisuell",
|
||||||
|
"test": "WorkingPageVisuell"
|
||||||
|
}
|
||||||
|
self.acquisitionServer = Modell(self, self.dll)
|
||||||
|
self.acquisitionServer.start()
|
||||||
|
|
||||||
|
self.model = None
|
||||||
|
self.view.mainloop()
|
||||||
|
|
||||||
|
def getSharedLibrary(self):
|
||||||
|
'''--------------------------------------------------------------------------------------------------
|
||||||
|
Laedt die shared Library (diese muss sich im gleichen Ordner wie die ausfuehrunde Datei befinden)
|
||||||
|
und setzt die Eingabe und Rueckgabewerte.
|
||||||
|
'''
|
||||||
|
|
||||||
|
path = os.path.abspath(".")
|
||||||
|
path = path + "/dll.so"
|
||||||
|
self.dll = ctypes.CDLL(path)
|
||||||
|
|
||||||
|
self.dll.getCommandFreespellingTaktil.argtypes = []
|
||||||
|
self.dll.getCommandFreespellingTaktil.restype = ctypes.c_char_p
|
||||||
|
|
||||||
|
self.dll.getCommandFreespellingVisuell.argtypes = []
|
||||||
|
self.dll.getCommandFreespellingVisuell.restype = ctypes.c_char_p
|
||||||
|
|
||||||
|
self.dll.getCommandCopyspellingTaktil.argtypes = []
|
||||||
|
self.dll.getCommandCopyspellingTaktil.restype = ctypes.c_char_p
|
||||||
|
|
||||||
|
self.dll.getCommandCopyspellingVisuell.argtypes = []
|
||||||
|
self.dll.getCommandCopyspellingVisuell.restype = ctypes.c_char_p
|
||||||
|
|
||||||
|
self.dll.getCommandXDawn.argtypes = []
|
||||||
|
self.dll.getCommandXDawn.restype = ctypes.c_char_p
|
||||||
|
|
||||||
|
self.dll.getCommandClassifier.argtypes = []
|
||||||
|
self.dll.getCommandClassifier.restype = ctypes.c_char_p
|
||||||
|
|
||||||
|
self.dll.getDefaultPath.argtypes = []
|
||||||
|
self.dll.getDefaultPath.restype = ctypes.c_char_p
|
||||||
|
|
||||||
|
self.dll.getPathOVFile.argtypes = []
|
||||||
|
self.dll.getPathOVFile.restype = ctypes.c_char_p
|
||||||
|
|
||||||
|
self.dll.getSpatialCFGFile.argtypes = []
|
||||||
|
self.dll.getSpatialCFGFile.restype = ctypes.c_char_p
|
||||||
|
|
||||||
|
self.dll.getClassifierCFGFile.argtypes = []
|
||||||
|
self.dll.getClassifierCFGFile.restype = ctypes.c_char_p
|
||||||
|
|
||||||
|
self.dll.getCommandStartAquisitionServer.argtypes = []
|
||||||
|
self.dll.getCommandStartAquisitionServer.restype = ctypes.c_char_p
|
||||||
|
|
||||||
|
def actionPerformed(self, action):
|
||||||
|
'''--------------------------------------------------------------------------------------------------
|
||||||
|
Wird aufgerufen wenn ein Button in der Init gedrueckt wird zuerst wird kontrolliert ob die Seite
|
||||||
|
gewechselt werden muss, dann nach dem Buttonnamen die Funktion zugeordnert. Der Funktion zum
|
||||||
|
Buttomnamen wird in der Init festgelegt
|
||||||
|
'''
|
||||||
|
|
||||||
|
self.changePage(action)
|
||||||
|
func = self.commands.get(action)
|
||||||
|
if(func is not None):
|
||||||
|
func()
|
||||||
|
else:
|
||||||
|
print("Kommado existiert nicht")
|
||||||
|
|
||||||
|
|
||||||
|
def changePage(self,action):
|
||||||
|
'''--------------------------------------------------------------------------------------------------
|
||||||
|
Change Page ruft je nach Aktion und Modi die jeweilige Seite auf
|
||||||
|
'''
|
||||||
|
|
||||||
|
if(self.modi == "taktilesBCI"):
|
||||||
|
page = self.pagesTaktil.get(action)
|
||||||
|
elif(self.modi == "visuellesBCI"):
|
||||||
|
page = self.pagesVisuell.get(action)
|
||||||
|
if(page is not None):
|
||||||
|
self.view.changeFrame(page)
|
||||||
|
|
||||||
|
def wechsel(self):
|
||||||
|
'''--------------------------------------------------------------------------------------------------
|
||||||
|
Wechsel aendert den Modi. Dafuer wird zuerst der aktuelle Modi ueberprueft und dann auf den anderen
|
||||||
|
Modi gesetzt.
|
||||||
|
'''
|
||||||
|
|
||||||
|
self.resetInfo()
|
||||||
|
self.addInfoText("")
|
||||||
|
if(self.modi == "taktilesBCI"):
|
||||||
|
self.view.setChangeBtnText("Wechsel zu taktilen BCI")
|
||||||
|
self.view.setTitleText("visuelles BCI")
|
||||||
|
self.modi = "visuellesBCI"
|
||||||
|
elif(self.modi == "visuellesBCI"):
|
||||||
|
self.setTitle("taktiles BCI")
|
||||||
|
self.view.setChangeBtnText("Wechsel zu visuellen BCI")
|
||||||
|
self.modi = "taktilesBCI"
|
||||||
|
|
||||||
|
def speichern(self):
|
||||||
|
'''--------------------------------------------------------------------------------------------------
|
||||||
|
wird nach dem Classifier Training aufgerufen und speichert die erstellte .ov Datei und die
|
||||||
|
spatial.cfg, classifier.cgf-Dateine unter dem ausgewaehlten Ordnername.
|
||||||
|
(Ordnername wird zu Beginn des CopySpellings festgelegt)
|
||||||
|
'''
|
||||||
|
print("saveFile")
|
||||||
|
print(self.file)
|
||||||
|
os.mkdir(self.file)
|
||||||
|
copyfile(self.pathOVFile, (self.file + "/p300-xdawn-train.ov"))
|
||||||
|
copyfile(self.pathClassifierCfg, (self.file + "/p300-classifier.cfg"))
|
||||||
|
copyfile(self.pathSpatialCfg, (self.file + "/p300-spatial-filter.cfg"))
|
||||||
|
|
||||||
|
#copyfile(self.pathOVFile, self.file)
|
||||||
|
|
||||||
|
def setDataset(self):
|
||||||
|
'''--------------------------------------------------------------------------------------------------
|
||||||
|
Legt fest welches Datenset fuer das Freestelling genutzt wird
|
||||||
|
'''
|
||||||
|
|
||||||
|
file = self.view.openfiledialog()
|
||||||
|
print(file)
|
||||||
|
if not file:
|
||||||
|
print("nichts ausgewaehlt")
|
||||||
|
else:
|
||||||
|
if os.path.exists((file + "/p300-classifier.cfg")):
|
||||||
|
print("classifier kopiert")
|
||||||
|
copyfile((file + "/p300-classifier.cfg"), self.pathClassifierCfg)
|
||||||
|
if os.path.exists((file + "/p300-spatial-filter.cfg")):
|
||||||
|
print("spatialfilter kopiert")
|
||||||
|
copyfile((file + "/p300-spatial-filter.cfg"), self.pathSpatialCfg)
|
||||||
|
if os.path.exists((file + "/p300-xdawn-train.ov")):
|
||||||
|
print(".ov kopiert")
|
||||||
|
copyfile((file + "/p300-xdawn-train.ov"), self.pathOVFile)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def test(self):
|
||||||
|
'''--------------------------------------------------------------------------------------------------
|
||||||
|
Funktion zum testen von xDawn und ClassifierTraining
|
||||||
|
'''
|
||||||
|
self.file = self.view.savefiledialog()
|
||||||
|
if(self.modi == "taktilesBCI"):
|
||||||
|
self.model = ModellTaktil(self, dll=self.dll)
|
||||||
|
elif(self.modi == "visuellesBCI"):
|
||||||
|
self.model = ModellVisuell(self, dll=self.dll)
|
||||||
|
self.model.setFunktion(self.model.trainXDawn)
|
||||||
|
self.model.start()
|
||||||
|
|
||||||
|
def commandoCopySpelling(self):
|
||||||
|
self.view.savefiledialog()
|
||||||
|
|
||||||
|
|
||||||
|
def copyspelling(self, path):
|
||||||
|
'''--------------------------------------------------------------------------------------------------
|
||||||
|
Speichert den gewuenschte Pfad und erstellt anschliessend ein Model (als Thread) und fuehrt die
|
||||||
|
Funktion CopySpelling aus.
|
||||||
|
'''
|
||||||
|
self.file = path
|
||||||
|
if self.file is "-1":
|
||||||
|
self.view.changeFrame("StartPage")
|
||||||
|
else:
|
||||||
|
if(self.modi == "taktilesBCI"):
|
||||||
|
self.model = ModellTaktil(self, dll=self.dll)
|
||||||
|
elif(self.modi == "visuellesBCI"):
|
||||||
|
self.model = ModellVisuell(self, dll=self.dll)
|
||||||
|
self.model.setFunktion(self.model.startCopySpelling)
|
||||||
|
self.model.start()
|
||||||
|
|
||||||
|
def filterXdawn(self):
|
||||||
|
'''--------------------------------------------------------------------------------------------------
|
||||||
|
wird nach dem CopySpelling gestartet. Die Funktion erstellt ein Model (als Thread) und fuehrt die
|
||||||
|
Funktion trainXDawn aus.
|
||||||
|
'''
|
||||||
|
|
||||||
|
if(self.modi == "taktilesBCI"):
|
||||||
|
self.model = ModellTaktil(self, dll=self.dll)
|
||||||
|
elif(self.modi == "visuellesBCI"):
|
||||||
|
self.model = ModellVisuell(self, dll=self.dll)
|
||||||
|
self.model.setFunktion(self.model.trainXDawn)
|
||||||
|
self.model.start()
|
||||||
|
|
||||||
|
def filterClassic(self):
|
||||||
|
'''--------------------------------------------------------------------------------------------------
|
||||||
|
wird nach dem xDawn-Training gestartet. Die Funktion erstellt ein Model (als Thread) und fuehrt die
|
||||||
|
Funktion trainClassifier aus.
|
||||||
|
'''
|
||||||
|
|
||||||
|
if(self.modi == "taktilesBCI"):
|
||||||
|
self.model = ModellTaktil(self, dll=self.dll)
|
||||||
|
elif(self.modi == "visuellesBCI"):
|
||||||
|
self.model = ModellVisuell(self, dll=self.dll)
|
||||||
|
self.model.setFunktion(self.model.trainClassifier)
|
||||||
|
self.model.start()
|
||||||
|
|
||||||
|
def commandFreeSpelling(self):
|
||||||
|
'''--------------------------------------------------------------------------------------------------
|
||||||
|
startet nach Benutzeraktion das Freespelling: ie Funktion erstellt ein Model (als Thread) und fuehrt die
|
||||||
|
Funktion freespelling aus.
|
||||||
|
'''
|
||||||
|
print("freespelling")
|
||||||
|
if(self.modi == "taktilesBCI"):
|
||||||
|
self.model = ModellTaktil(self, dll=self.dll)
|
||||||
|
elif(self.modi == "visuellesBCI"):
|
||||||
|
self.model = ModellVisuell(self, dll=self.dll)
|
||||||
|
self.model.setFunktion(self.model.freeSpelling)
|
||||||
|
self.model.start()
|
||||||
|
|
||||||
|
|
||||||
|
def commandStop(self):
|
||||||
|
'''--------------------------------------------------------------------------------------------------
|
||||||
|
Wird nach Benutzeraktion aufgerufen und stopt, falls vorhanden, den ablaufenden Thread und schliesst
|
||||||
|
Openvibe
|
||||||
|
'''
|
||||||
|
if(self.model is not None):
|
||||||
|
self.addInfoText("Aktion: STOP-Befehl\n")
|
||||||
|
self.model.stop()
|
||||||
|
self.model.join()
|
||||||
|
self.model.killProzess()
|
||||||
|
self.mode = None
|
||||||
|
|
||||||
|
def stopAcquisitionServer(self):
|
||||||
|
'''--------------------------------------------------------------------------------------------------
|
||||||
|
Wird nur beim schliessen der GUI aufgerufen und stopt und schliesst den Acquisitionserver
|
||||||
|
'''
|
||||||
|
self.acquisitionServer.stop()
|
||||||
|
self.acquisitionServer.join()
|
||||||
|
self.acquisitionServer.killAcquisitionServer()
|
||||||
|
self.acquisitionServer = None
|
||||||
|
|
||||||
|
def stop(self, next=None):
|
||||||
|
'''--------------------------------------------------------------------------------------------------
|
||||||
|
Wird aus dem Modell nach Ablauf oder bei Fehler aufgerufen und stopt den aktuellen Thread.
|
||||||
|
Anschliessend wird je nach Prozess die naechste Funktion (XDawn-Training oder Classifier) aufgerufen
|
||||||
|
'''
|
||||||
|
print("Stop aus Modell")
|
||||||
|
self.model.stop()
|
||||||
|
self.model.join()
|
||||||
|
self.model.killProzess()
|
||||||
|
self.mode = None
|
||||||
|
if(next is not None):
|
||||||
|
func = self.nexts.get(next)
|
||||||
|
func()
|
||||||
|
|
||||||
|
|
||||||
|
def addInfoText(self,text):
|
||||||
|
'''--------------------------------------------------------------------------------------------------
|
||||||
|
Fuegt dem Infotext den Text hinzu und schreibt es in die Ausgabe
|
||||||
|
'''
|
||||||
|
self.infotext = self.infotext + text
|
||||||
|
self.view.setInfoText(self.infotext)
|
||||||
|
|
||||||
|
def resetInfo(self):
|
||||||
|
self.infotext = ""
|
||||||
|
|
||||||
|
def setTitle(self,text):
|
||||||
|
self.view.setTitleText(text)
|
||||||
|
|
||||||
|
def changeScreen(self, pageName):
|
||||||
|
self.view.changeFrame(pageName=pageName)
|
||||||
|
|
||||||
|
def getModi(self):
|
||||||
|
return self.modi
|
||||||
|
|
||||||
|
def getWindowSize(self):
|
||||||
|
return self.view.getWindowSize()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
BIN
UIController.pyc
Normal file
BIN
UIController.pyc
Normal file
Binary file not shown.
180
UIModell.py
Normal file
180
UIModell.py
Normal file
@ -0,0 +1,180 @@
|
|||||||
|
'''--------------------------------------------------------------------------------------------------
|
||||||
|
Das Model steuert stellt die Modi unabhaengigen Funktionen bereit
|
||||||
|
'''
|
||||||
|
|
||||||
|
from subprocess import *
|
||||||
|
from threading import Thread
|
||||||
|
import time
|
||||||
|
|
||||||
|
class Modell(Thread):
|
||||||
|
|
||||||
|
def __init__(self,c, dll):
|
||||||
|
Thread.__init__(self)
|
||||||
|
self.controller = c
|
||||||
|
self.dll = dll
|
||||||
|
self.aktiv= True
|
||||||
|
|
||||||
|
def setFunktion(self, func, args=None, kwargs=None):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def startCopySpelling(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def trainXDawn(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def trainClassifier(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def freeSpelling(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def stop(self):
|
||||||
|
'''--------------------------------------------------------------------------------------------------
|
||||||
|
Die Funktion stop stopt den ablaufenden Thread
|
||||||
|
'''
|
||||||
|
print("stop thread")
|
||||||
|
self.aktiv = False
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
'''--------------------------------------------------------------------------------------------------
|
||||||
|
Wird bei Thread.start() aus dem Controller aufgerufen und laeuft ab sobald der Thread destartet wurde
|
||||||
|
'''
|
||||||
|
print("start thread")
|
||||||
|
#self.aktiv = True
|
||||||
|
t = Thread(target=self.startAquisitionServer)
|
||||||
|
t.setDaemon(True)
|
||||||
|
t.start()
|
||||||
|
|
||||||
|
while self.aktiv:
|
||||||
|
time.sleep(0.1)
|
||||||
|
|
||||||
|
def killProzessParent(self):
|
||||||
|
'''--------------------------------------------------------------------------------------------------
|
||||||
|
schliesst OpenVibe-Designer
|
||||||
|
'''
|
||||||
|
print('Parent start killing')
|
||||||
|
pidOV = 0
|
||||||
|
items = []
|
||||||
|
|
||||||
|
prozesse = Popen(["ps", "-e"], stdout=PIPE).communicate()[0].strip()
|
||||||
|
zeilen = prozesse.split('\n')
|
||||||
|
for z in zeilen:
|
||||||
|
if(z.find("openvibe-design") != -1):
|
||||||
|
z = z.strip()
|
||||||
|
items = z.split(' ')
|
||||||
|
pidOV = items[0]
|
||||||
|
print(pidOV)
|
||||||
|
if pidOV is not 0:
|
||||||
|
#kill -TERM veranlasst dem Prozess sich selbst zu beenden (nicht erzwungen)
|
||||||
|
try:
|
||||||
|
Popen(["kill", "-TERM", str(pidOV)], stdout=PIPE).communicate()
|
||||||
|
except:
|
||||||
|
print("kein killing")
|
||||||
|
|
||||||
|
|
||||||
|
print("killed openvibe-designer")
|
||||||
|
|
||||||
|
def killAcquisitionServer(self):
|
||||||
|
'''--------------------------------------------------------------------------------------------------
|
||||||
|
schliesst den Acquisitionserver
|
||||||
|
'''
|
||||||
|
|
||||||
|
print('start killing AS')
|
||||||
|
pid = 0
|
||||||
|
items = []
|
||||||
|
|
||||||
|
prozesse = Popen(["ps", "-e"], stdout=PIPE).communicate()[0].strip()
|
||||||
|
zeilen = prozesse.split('\n')
|
||||||
|
for z in zeilen:
|
||||||
|
if(z.find("openvibe-acquis") != -1):
|
||||||
|
z = z.strip()
|
||||||
|
items = z.split(' ')
|
||||||
|
pid = items[0]
|
||||||
|
|
||||||
|
#kill -TERM veranlasst dem Prozess sich selbst zu beenden (nicht erzwungen)
|
||||||
|
Popen(["kill", "-TERM", str(pid)], stdout=PIPE).communicate()
|
||||||
|
|
||||||
|
|
||||||
|
print("killed openvibe-acquisitionserver")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def startAquisitionServer(self):
|
||||||
|
'''--------------------------------------------------------------------------------------------------
|
||||||
|
startet den Acquisitionserver und steuert die Benutzerausgabe
|
||||||
|
'''
|
||||||
|
|
||||||
|
print("start Aquisitionserver")
|
||||||
|
self.controller.resetInfo()
|
||||||
|
self.controller.addInfoText('Aquisitionserver -- Bitte starten sie den Server\n')
|
||||||
|
|
||||||
|
command = self.dll.getCommandStartAquisitionServer().split(" ")
|
||||||
|
process = Popen(command, stdout=PIPE, universal_newlines=True)
|
||||||
|
|
||||||
|
self.openVibeAktiv = True
|
||||||
|
while True:
|
||||||
|
output = process.stdout.readline()
|
||||||
|
print(output.strip())
|
||||||
|
x1 = output.find("Connection succeeded")
|
||||||
|
x2 = output.find("Now acquiring")
|
||||||
|
x3 = output.find("Stopping the acquisition")
|
||||||
|
x4 = output.find("Disconnecting")
|
||||||
|
init = output.find("Loading plugin: Fiddler")
|
||||||
|
y = output.find("Error")
|
||||||
|
if(x1 != -1):
|
||||||
|
self.controller.addInfoText('Aquisitionserver ist verbunden -- Bitte starten Sie den Server\n')
|
||||||
|
elif(x2 != -1 ):
|
||||||
|
self.controller.resetInfo()
|
||||||
|
self.controller.addInfoText("Aquisitionserver gestartet\n")
|
||||||
|
self.minimizeWindow("server")
|
||||||
|
elif(x3 != -1 ):
|
||||||
|
self.controller.addInfoText("AquisitionServer gestoppt -- Bitte starten Sie den Server\n")
|
||||||
|
self.positionWindow("server")
|
||||||
|
elif(x4 != -1 ):
|
||||||
|
self.controller.addInfoText("Verbindung vom Aquisitionserver getrennt!\n")
|
||||||
|
self.positionWindow("server")
|
||||||
|
elif(init != -1 ):
|
||||||
|
time.sleep(1)
|
||||||
|
self.positionWindow("server")
|
||||||
|
elif(y != -1 ):
|
||||||
|
self.controller.addInfoText("Fehler beim Auisitionserver aufgetaucht\n")
|
||||||
|
if not self.aktiv:
|
||||||
|
print("stop")
|
||||||
|
break
|
||||||
|
|
||||||
|
def positionWindow(self, name):
|
||||||
|
'''--------------------------------------------------------------------------------------------------
|
||||||
|
positioniert das Fenster auf der GUI
|
||||||
|
'''
|
||||||
|
print("calls positionWindow")
|
||||||
|
parameter = self.controller.getWindowSize()
|
||||||
|
positionX = int(parameter[0]+ int(parameter[3] * 0.05))
|
||||||
|
positionY = int(parameter[1]) + int(parameter[2]*0.08)
|
||||||
|
height = int(parameter[2])*0.55
|
||||||
|
width = int(parameter[3])*0.9
|
||||||
|
windowID = Popen(["xdotool", "search", "--onlyvisible", "--name", name], stdout=PIPE).communicate()[0].strip()
|
||||||
|
try:
|
||||||
|
print(int(windowID))
|
||||||
|
Popen(["xdotool", "windowsize", windowID, str(width), str(height)], stdout=PIPE).communicate()
|
||||||
|
Popen(["xdotool", "windowmove", windowID, str(positionX), str(positionY)], stdout=PIPE).communicate()
|
||||||
|
Popen(["xdotool", "windowactivate", windowID], stdout=PIPE).communicate()[0].strip()
|
||||||
|
except:
|
||||||
|
print("no window")
|
||||||
|
print(windowID)
|
||||||
|
self.controller.addInfoText("Fehler: kein Fenster gefunden!")
|
||||||
|
|
||||||
|
def minimizeWindow(self, name):
|
||||||
|
'''--------------------------------------------------------------------------------------------------
|
||||||
|
minimiert das Fenster
|
||||||
|
'''
|
||||||
|
windowID = Popen(["xdotool", "search", "--onlyvisible", "--name", name], stdout=PIPE).communicate()[0].strip()
|
||||||
|
try:
|
||||||
|
print(int(windowID))
|
||||||
|
Popen(["xdotool", "windowminimize", windowID], stdout=PIPE).communicate()
|
||||||
|
except:
|
||||||
|
print("no window")
|
||||||
|
print(windowID)
|
||||||
|
self.controller.addInfoText("Fehler: kein Fenster gefunden!")
|
||||||
|
|
||||||
|
|
BIN
UIModell.pyc
Normal file
BIN
UIModell.pyc
Normal file
Binary file not shown.
214
UIModellTaktil.py
Normal file
214
UIModellTaktil.py
Normal file
@ -0,0 +1,214 @@
|
|||||||
|
'''--------------------------------------------------------------------------------------------------
|
||||||
|
Das taktile Model steuert den Ablauf der aufrufe der Openvibe Funktionen fuer das taktile BCI
|
||||||
|
noch nicht implementiert da noch kein Programm dafuer
|
||||||
|
'''
|
||||||
|
|
||||||
|
from subprocess import *
|
||||||
|
from threading import Thread
|
||||||
|
import time
|
||||||
|
from UIModell import *
|
||||||
|
|
||||||
|
class ModellTaktil(Modell):
|
||||||
|
|
||||||
|
def __init__(self,c, dll):
|
||||||
|
Thread.__init__(self)
|
||||||
|
Modell.__init__(self, c, dll)
|
||||||
|
#self.dll = dll
|
||||||
|
self.aktiv= True
|
||||||
|
self.openVibeAktiv = False
|
||||||
|
|
||||||
|
def stop(self):
|
||||||
|
'''--------------------------------------------------------------------------------------------------
|
||||||
|
Die Funktion stop stopt den ablaufenden Thread
|
||||||
|
'''
|
||||||
|
print("stop thread")
|
||||||
|
self.aktiv = False
|
||||||
|
|
||||||
|
def setFunktion(self, func, args=None, kwargs=None):
|
||||||
|
'''--------------------------------------------------------------------------------------------------
|
||||||
|
Mittels dieser Funktion kann die im Thread ablaufende Funktion und deren Argumente eingestellt werden
|
||||||
|
'''
|
||||||
|
self.func = func
|
||||||
|
self.args = args or []
|
||||||
|
self.kwargs = kwargs or {}
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
'''--------------------------------------------------------------------------------------------------
|
||||||
|
Wird bei Thread.start() aus dem Controller aufgerufen und laeuft ab sobald der Thread destartet wurde
|
||||||
|
'''
|
||||||
|
print("start thread")
|
||||||
|
#self.aktiv = True
|
||||||
|
t = Thread(target=self.func, args=self.args, kwargs=self.kwargs)
|
||||||
|
t.setDaemon(True)
|
||||||
|
t.start()
|
||||||
|
|
||||||
|
while self.aktiv:
|
||||||
|
time.sleep(0.1)
|
||||||
|
|
||||||
|
|
||||||
|
def startCopySpelling(self):
|
||||||
|
'''--------------------------------------------------------------------------------------------------
|
||||||
|
Holt aus der shared Librarz die Befehle und startet das Copyspelling. Reagiert auf Error oder
|
||||||
|
beenden. Bei Beenden startet es das XDawnTraining, bei Error wird der Vorgang gestoppt.
|
||||||
|
'''
|
||||||
|
print("start copySpelling")
|
||||||
|
self.controller.resetInfo()
|
||||||
|
self.controller.addInfoText('Starten des gefuerten Buchstabierens -- ')
|
||||||
|
|
||||||
|
command = self.dll.getCommandCopyspellingVisuell().split(" ")
|
||||||
|
process = Popen(command, stdout=PIPE, universal_newlines=True)
|
||||||
|
|
||||||
|
self.openVibeAktiv = True
|
||||||
|
while True:
|
||||||
|
output = process.stdout.readline()
|
||||||
|
print(output.strip())
|
||||||
|
x = output.find("schlagwort?")
|
||||||
|
y = output.find("Error")
|
||||||
|
if(x != -1):
|
||||||
|
print("Training finished")
|
||||||
|
process.terminate()
|
||||||
|
self.controller.addInfoText('Buchstabieren beendet\n')
|
||||||
|
self.controller.stop("filterXdawn")
|
||||||
|
break
|
||||||
|
elif(y != -1 ):
|
||||||
|
print("Error occured")
|
||||||
|
self.controller.changeScreen("StartPage")
|
||||||
|
self.controller.addInfoText("Fehler beim Buchstabieren aufgetaucht\n")
|
||||||
|
process.terminate()
|
||||||
|
self.controller.stop()
|
||||||
|
break
|
||||||
|
if not self.aktiv:
|
||||||
|
print("stop")
|
||||||
|
break
|
||||||
|
|
||||||
|
|
||||||
|
self.controller.stop()
|
||||||
|
|
||||||
|
def trainXDawn(self):
|
||||||
|
'''--------------------------------------------------------------------------------------------------
|
||||||
|
Holt aus der shared Library die Befehle und startet das XDawnTraining. Reagiert auf Error oder
|
||||||
|
die Ausgabe das das Training beendet wurde. Bei Beenden startet es das ClassifierTraining, bei Error wird der Vorgang gestoppt.
|
||||||
|
'''
|
||||||
|
print("start training Xdawn")
|
||||||
|
self.controller.addInfoText('Starten des xDawn-Trainings -- ')
|
||||||
|
command = self.dll.getCommandXDawn().split(" ")
|
||||||
|
process = Popen(command, stdout=PIPE, universal_newlines=True)
|
||||||
|
|
||||||
|
self.openVibeAktiv = True
|
||||||
|
while self.aktiv:
|
||||||
|
output = process.stdout.readline()
|
||||||
|
print(output.strip())
|
||||||
|
x = output.find("Training finished and saved")
|
||||||
|
y = output.find("Error")
|
||||||
|
if(x != -1):
|
||||||
|
print("Training finished")
|
||||||
|
process.terminate()
|
||||||
|
self.controller.addInfoText('Training beendet\n')
|
||||||
|
self.controller.stop("filterClassic")
|
||||||
|
break
|
||||||
|
elif(y != -1 ):
|
||||||
|
print("Error occured")
|
||||||
|
self.controller.changeScreen("StartPage")
|
||||||
|
self.controller.addInfoText("Fehler beim XDawn Training aufgetaucht\n")
|
||||||
|
self.controller.stop()
|
||||||
|
process.terminate()
|
||||||
|
break
|
||||||
|
if not self.aktiv:
|
||||||
|
print("stop")
|
||||||
|
break
|
||||||
|
|
||||||
|
self.controller.stop()
|
||||||
|
|
||||||
|
#self.controller.filterClassic()
|
||||||
|
|
||||||
|
|
||||||
|
def trainClassifier(self):
|
||||||
|
'''--------------------------------------------------------------------------------------------------
|
||||||
|
Holt aus der shared Library die Befehle und startet das ClassifierTraining. Reagiert auf Error oder
|
||||||
|
die Ausgabe das das Training beendet wurde. Bei Beenden startet es das speichern der Daten, bei Error wird der Vorgang gestoppt.
|
||||||
|
'''
|
||||||
|
print("start training Classifier")
|
||||||
|
self.controller.addInfoText("Starten des Classifier-Trainings -- ")
|
||||||
|
|
||||||
|
command = self.dll.getCommandClassifier().split(" ")
|
||||||
|
process = Popen(command, stdout=PIPE, universal_newlines=True)
|
||||||
|
|
||||||
|
self.openVibeAktiv = True
|
||||||
|
counter = 0
|
||||||
|
while True:
|
||||||
|
output = process.stdout.readline()
|
||||||
|
print(output.strip())
|
||||||
|
x = output.find("aka Classifier trainer")
|
||||||
|
accuracy = output.find("Training set accuracy is")
|
||||||
|
y = output.find("Error")
|
||||||
|
if(x != -1):
|
||||||
|
counter = counter +1
|
||||||
|
#counter = 18
|
||||||
|
if(counter >= 17):
|
||||||
|
print("Training finished")
|
||||||
|
self.controller.addInfoText('Training beendet\n')
|
||||||
|
process.terminate()
|
||||||
|
self.controller.stop("save")
|
||||||
|
break
|
||||||
|
elif(y != -1 ):
|
||||||
|
print("Error occured")
|
||||||
|
self.controller.changeScreen("StartPage")
|
||||||
|
self.controller.addInfoText("Fehler beim Classifier Training aufgetaucht\n")
|
||||||
|
process.terminate()
|
||||||
|
break
|
||||||
|
elif(accuracy != -1):
|
||||||
|
print("ACCURACY" + output)
|
||||||
|
if not self.aktiv:
|
||||||
|
print("stop")
|
||||||
|
break
|
||||||
|
|
||||||
|
self.controller.changeScreen("StartPage")
|
||||||
|
self.controller.stop()
|
||||||
|
|
||||||
|
def freeSpelling(self):
|
||||||
|
'''--------------------------------------------------------------------------------------------------
|
||||||
|
Holt aus der shared Library die Befehle und startet das Freespelling. Reagiert auf Error oder
|
||||||
|
beenden. Daraufhin wird der Vorgang gestoppt.
|
||||||
|
'''
|
||||||
|
print("start freeSpelling")
|
||||||
|
self.controller.resetInfo()
|
||||||
|
self.controller.addInfoText('Starten des freien Buchstabierens -- ')
|
||||||
|
command = self.dll.getCommandFreespellingVisuell().split(" ")
|
||||||
|
process = Popen(command, stdout=PIPE, universal_newlines=True)
|
||||||
|
self.openVibeAktiv = True
|
||||||
|
while True:
|
||||||
|
output = process.stdout.readline()
|
||||||
|
print(output.strip())
|
||||||
|
y = output.find("Error")
|
||||||
|
x = output.find("Schlagwort")
|
||||||
|
if(x != -1):
|
||||||
|
print("End Spelling")
|
||||||
|
process.terminate()
|
||||||
|
self.controller.addInfoText('Buchstabieren beendet\n')
|
||||||
|
self.controller.changeScreen("StartPage")
|
||||||
|
self.controller.stop()
|
||||||
|
break
|
||||||
|
elif(y != -1 ):
|
||||||
|
print("Error occured")
|
||||||
|
self.controller.changeScreen("StartPage")
|
||||||
|
self.controller.addInfoText("Fehler beim Buchstabieren aufgetaucht\n")
|
||||||
|
process.terminate()
|
||||||
|
self.controller.stop()
|
||||||
|
break
|
||||||
|
if not self.aktiv:
|
||||||
|
print("stop")
|
||||||
|
break
|
||||||
|
|
||||||
|
self.controller.changeScreen("StartPage")
|
||||||
|
self.controller.stop()
|
||||||
|
|
||||||
|
def killProzess(self):
|
||||||
|
'''--------------------------------------------------------------------------------------------------
|
||||||
|
Ruft den Parent auf, dass Openvibe falls es noch laeuft geschlossen wird
|
||||||
|
'''
|
||||||
|
if(self.openVibeAktiv):
|
||||||
|
self.openVibeAktiv = False
|
||||||
|
self.killProzessParent()
|
||||||
|
|
||||||
|
|
||||||
|
|
BIN
UIModellTaktil.pyc
Normal file
BIN
UIModellTaktil.pyc
Normal file
Binary file not shown.
225
UIModellVisuell.py
Normal file
225
UIModellVisuell.py
Normal file
@ -0,0 +1,225 @@
|
|||||||
|
'''--------------------------------------------------------------------------------------------------
|
||||||
|
Das Visuelle Model steuert den Ablauf der aufrufe der Openvibe Funktionen fuer das visuelle BCI
|
||||||
|
'''
|
||||||
|
|
||||||
|
from subprocess import *
|
||||||
|
from threading import Thread
|
||||||
|
import time
|
||||||
|
|
||||||
|
from UIModell import Modell
|
||||||
|
|
||||||
|
class ModellVisuell(Modell):
|
||||||
|
|
||||||
|
def __init__(self,c, dll):
|
||||||
|
Thread.__init__(self)
|
||||||
|
Modell.__init__(self, c, dll)
|
||||||
|
self.aktiv= True
|
||||||
|
self.openVibeAktiv = False
|
||||||
|
|
||||||
|
def stop(self):
|
||||||
|
'''--------------------------------------------------------------------------------------------------
|
||||||
|
Die Funktion stop stopt den ablaufenden Thread
|
||||||
|
'''
|
||||||
|
print("stop thread")
|
||||||
|
self.aktiv = False
|
||||||
|
|
||||||
|
def setFunktion(self, func, args=None, kwargs=None):
|
||||||
|
'''--------------------------------------------------------------------------------------------------
|
||||||
|
Mittels dieser Funktion kann die im Thread ablaufende Funktion und deren Argumente eingestellt werden
|
||||||
|
'''
|
||||||
|
self.func = func
|
||||||
|
self.args = args or []
|
||||||
|
self.kwargs = kwargs or {}
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
'''--------------------------------------------------------------------------------------------------
|
||||||
|
Wird bei Thread.start() aus dem Controller aufgerufen und laeuft ab sobald der Thread destartet wurde
|
||||||
|
'''
|
||||||
|
print("start thread")
|
||||||
|
#self.aktiv = True
|
||||||
|
t = Thread(target=self.func, args=self.args, kwargs=self.kwargs)
|
||||||
|
t.setDaemon(True)
|
||||||
|
t.start()
|
||||||
|
|
||||||
|
while self.aktiv:
|
||||||
|
time.sleep(0.1)
|
||||||
|
|
||||||
|
|
||||||
|
def startCopySpelling(self):
|
||||||
|
'''--------------------------------------------------------------------------------------------------
|
||||||
|
Holt aus der shared Librarz die Befehle und startet das Copyspelling. Reagiert auf Error oder
|
||||||
|
beenden. Bei Beenden startet es das XDawnTraining, bei Error wird der Vorgang gestoppt.
|
||||||
|
Positioniert die visuelle Matrix.
|
||||||
|
'''
|
||||||
|
print("start copySpelling")
|
||||||
|
self.controller.resetInfo()
|
||||||
|
self.controller.addInfoText('Starten des gefuerhten Buchstabierens -- ')
|
||||||
|
command = self.dll.getCommandCopyspellingVisuell().split(" ")
|
||||||
|
process = Popen(command, stdout=PIPE, universal_newlines=True)
|
||||||
|
|
||||||
|
self.openVibeAktiv = True
|
||||||
|
while True:
|
||||||
|
output = process.stdout.readline()
|
||||||
|
print(output.strip())
|
||||||
|
x = output.find("Application terminated")
|
||||||
|
y = output.find("Error")
|
||||||
|
z = output.find("Initialization")
|
||||||
|
if(x != -1):
|
||||||
|
print("Training finished")
|
||||||
|
process.terminate()
|
||||||
|
self.controller.addInfoText('Buchstabieren beendet\n')
|
||||||
|
self.controller.stop("filterXdawn")
|
||||||
|
break
|
||||||
|
elif(y != -1 ):
|
||||||
|
print("Error occured")
|
||||||
|
self.controller.changeScreen("StartPage")
|
||||||
|
self.controller.addInfoText("Fehler beim Buchstabieren aufgetaucht\n")
|
||||||
|
process.terminate()
|
||||||
|
self.controller.stop()
|
||||||
|
break
|
||||||
|
elif(z != -1):
|
||||||
|
print("Initiation finisched")
|
||||||
|
time.sleep(1)
|
||||||
|
self.positionWindow("p300")
|
||||||
|
self.minimizeWindow("stimulator")
|
||||||
|
if not self.aktiv:
|
||||||
|
print("stop")
|
||||||
|
break
|
||||||
|
#self.controller.stop()
|
||||||
|
|
||||||
|
def trainXDawn(self):
|
||||||
|
'''--------------------------------------------------------------------------------------------------
|
||||||
|
Holt aus der shared Library die Befehle und startet das XDawnTraining. Reagiert auf Error oder
|
||||||
|
die Ausgabe das das Training beendet wurde. Bei Beenden startet es das ClassifierTraining, bei Error wird der Vorgang gestoppt.
|
||||||
|
'''
|
||||||
|
print("start training Xdawn")
|
||||||
|
self.controller.addInfoText('Starten des XDawn/Trainings -- ')
|
||||||
|
command = self.dll.getCommandXDawn().split(" ")
|
||||||
|
process = Popen(command, stdout=PIPE, universal_newlines=True)
|
||||||
|
|
||||||
|
self.openVibeAktiv = True
|
||||||
|
while self.aktiv:
|
||||||
|
output = process.stdout.readline()
|
||||||
|
print(output.strip())
|
||||||
|
x = output.find("Training finished and saved")
|
||||||
|
y = output.find("Error")
|
||||||
|
if(x != -1):
|
||||||
|
print("Training finished")
|
||||||
|
process.terminate()
|
||||||
|
self.controller.addInfoText('Beenden des Trainings\n')
|
||||||
|
self.controller.stop("filterClassic")
|
||||||
|
break
|
||||||
|
elif(y != -1 ):
|
||||||
|
print("Error occured")
|
||||||
|
self.controller.changeScreen("StartPage")
|
||||||
|
self.controller.addInfoText("Fehler beim XDawn Training aufgetaucht\n")
|
||||||
|
self.controller.stop()
|
||||||
|
process.terminate()
|
||||||
|
break
|
||||||
|
if not self.aktiv:
|
||||||
|
print("stop")
|
||||||
|
break
|
||||||
|
|
||||||
|
#self.controller.stop()
|
||||||
|
|
||||||
|
def trainClassifier(self):
|
||||||
|
'''--------------------------------------------------------------------------------------------------
|
||||||
|
Holt aus der shared Library die Befehle und startet das ClassifierTraining. Reagiert auf Error oder
|
||||||
|
die Ausgabe das das Training beendet wurde. Bei Beenden startet es das speichern der Daten, bei Error wird der Vorgang gestoppt.
|
||||||
|
'''
|
||||||
|
print("start training Classifier")
|
||||||
|
self.controller.addInfoText("Starten Classifier-Trainings -- ")
|
||||||
|
command = self.dll.getCommandClassifier().split(" ")
|
||||||
|
process = Popen(command, stdout=PIPE, universal_newlines=True)
|
||||||
|
|
||||||
|
self.openVibeAktiv = True
|
||||||
|
counter = 0
|
||||||
|
while True:
|
||||||
|
output = process.stdout.readline()
|
||||||
|
print(output.strip())
|
||||||
|
x = output.find("aka Classifier trainer")
|
||||||
|
accuracy = output.find("Training set accuracy is")
|
||||||
|
y = output.find("Error")
|
||||||
|
if(x != -1):
|
||||||
|
counter = counter +1
|
||||||
|
#counter = 18
|
||||||
|
if(counter >= 17):
|
||||||
|
print("Training finished")
|
||||||
|
self.controller.addInfoText('Beenden des Training\n')
|
||||||
|
process.terminate()
|
||||||
|
self.controller.stop("save")
|
||||||
|
break
|
||||||
|
elif(y != -1 ):
|
||||||
|
print("Error occured")
|
||||||
|
self.controller.changeScreen("StartPage")
|
||||||
|
self.controller.addInfoText("Fehler beim Classifier Training aufgetaucht\n")
|
||||||
|
process.terminate()
|
||||||
|
break
|
||||||
|
elif(accuracy != -1):
|
||||||
|
print("ACCURACY" + output)
|
||||||
|
if not self.aktiv:
|
||||||
|
print("stop")
|
||||||
|
break
|
||||||
|
|
||||||
|
self.controller.changeScreen("StartPage")
|
||||||
|
self.controller.stop()
|
||||||
|
|
||||||
|
def freeSpelling(self):
|
||||||
|
'''--------------------------------------------------------------------------------------------------
|
||||||
|
Holt aus der shared Library die Befehle und startet das Freespelling. Reagiert auf Error oder
|
||||||
|
beenden. Daraufhin wird der Vorgang gestoppt. Positioniert die visuelle Matrix.
|
||||||
|
'''
|
||||||
|
print("start freeSpelling")
|
||||||
|
self.controller.resetInfo()
|
||||||
|
self.controller.addInfoText('Starten des freien Buchstabierens -- ')
|
||||||
|
|
||||||
|
command = self.dll.getCommandFreespellingVisuell().split(" ")
|
||||||
|
process = Popen(command, stdout=PIPE, universal_newlines=True)
|
||||||
|
|
||||||
|
self.openVibeAktiv = True
|
||||||
|
while True:
|
||||||
|
output = process.stdout.readline()
|
||||||
|
print(output.strip())
|
||||||
|
y = output.find("Error")
|
||||||
|
x = output.find("Schlagwort")
|
||||||
|
z = output.find("Initialization")
|
||||||
|
if(x != -1):
|
||||||
|
print("End Spelling")
|
||||||
|
process.terminate()
|
||||||
|
self.controller.addInfoText('Buchstabieren beendet\n')
|
||||||
|
self.controller.changeScreen("StartPage")
|
||||||
|
self.controller.stop()
|
||||||
|
break
|
||||||
|
elif(y != -1 ):
|
||||||
|
print("Error occured")
|
||||||
|
self.controller.changeScreen("StartPage")
|
||||||
|
self.controller.addInfoText("Fehler beim Buchstabieren aufgetaucht\n")
|
||||||
|
process.terminate()
|
||||||
|
self.controller.stop()
|
||||||
|
break
|
||||||
|
elif(z != -1):
|
||||||
|
print("Initiation finisched")
|
||||||
|
time.sleep(1)
|
||||||
|
self.positionWindow("p300")
|
||||||
|
self.minimizeWindow("stimulator")
|
||||||
|
if not self.aktiv:
|
||||||
|
print("stop")
|
||||||
|
break
|
||||||
|
|
||||||
|
self.controller.changeScreen("StartPage")
|
||||||
|
self.controller.stop()
|
||||||
|
|
||||||
|
def killProzess(self):
|
||||||
|
'''--------------------------------------------------------------------------------------------------
|
||||||
|
Ruft den Parent auf, dass Openvibe falls es noch laeuft geschlossen wird
|
||||||
|
'''
|
||||||
|
if(self.openVibeAktiv):
|
||||||
|
self.openVibeAktiv = False
|
||||||
|
self.killProzessParent()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
BIN
UIModellVisuell.pyc
Normal file
BIN
UIModellVisuell.pyc
Normal file
Binary file not shown.
BIN
UIView.pyc
Normal file
BIN
UIView.pyc
Normal file
Binary file not shown.
267
UIViewTKinter.py
Normal file
267
UIViewTKinter.py
Normal file
@ -0,0 +1,267 @@
|
|||||||
|
'''--------------------------------------------------------------------------------------------------
|
||||||
|
Die View bildet die Oberflaeche ab.
|
||||||
|
Sie ist in 3 Sektoren Top, Main und ButtonFrame unterteilt. Der TopFrame beihnahltet die Taskleiste,
|
||||||
|
der Button Frame gibt Informationen raus. Im Main Frame sind die Buttons yu starten und stoppen der
|
||||||
|
Buchstabierungen. HIerfuer sind extra Seiten erstellt, die beliebig, je nach Situation ausgetauscht
|
||||||
|
werden koennen
|
||||||
|
'''
|
||||||
|
|
||||||
|
try:
|
||||||
|
from Tkinter import * #Fuer Python 2.7
|
||||||
|
import tkFileDialog as fd
|
||||||
|
except ImportError: #Fuer Python >3
|
||||||
|
from tkinter import *
|
||||||
|
from tkinter import filedialog as fd
|
||||||
|
|
||||||
|
from UIController import *
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class View(Tk):
|
||||||
|
def __init__(self, c, path_default, *args, **kwargs):
|
||||||
|
'''--------------------------------------------------------------------------------------------------
|
||||||
|
In der Init wird das Lazout gesetyt und die Funktionen yur erstellung der Frames aufgerufen,
|
||||||
|
zudem wird dem schliesen des Fensters sowie den anpassen der Groesse andere Funktionen hinterlegt
|
||||||
|
'''
|
||||||
|
Tk.__init__(self, *args, **kwargs)
|
||||||
|
self.controller = c
|
||||||
|
self.PATH_DEFAULT = path_default
|
||||||
|
self.title("Visuelles Buchstabieren")
|
||||||
|
self.h = 1000
|
||||||
|
self.w = 2000
|
||||||
|
self.geometry('{}x{}'.format(self.w,self.h))
|
||||||
|
self.faktor = [(0.073),(0.727), (0.2)]
|
||||||
|
#self.resizable(height=False, width= False)
|
||||||
|
self.layout = {
|
||||||
|
"background": "#00001E",
|
||||||
|
"backgroundBtn": "#1C86EE",
|
||||||
|
"fontColor": "#FFFFFF",
|
||||||
|
"backgroundBar": "#00002E",
|
||||||
|
"font": ('Calibri', 20, 'bold'),
|
||||||
|
"fontSmall": ('Calibri', 14, 'bold'),
|
||||||
|
"fontInfo": ('Calibri', 25)
|
||||||
|
}
|
||||||
|
|
||||||
|
self.createTopFrame()
|
||||||
|
self.createMainFrame()
|
||||||
|
self.createBottomFrame()
|
||||||
|
|
||||||
|
self.bind("<Configure>", self.adjustSize)
|
||||||
|
self.protocol("WM_DELETE_WINDOW", self.onClosing)
|
||||||
|
|
||||||
|
|
||||||
|
def changeFrame(self, pageName):
|
||||||
|
'''--------------------------------------------------------------------------------------------------
|
||||||
|
Setzt dem Frame passend zum pageName in den Vordergrund
|
||||||
|
'''
|
||||||
|
frame = self.frames[pageName]
|
||||||
|
frame.tkraise()
|
||||||
|
|
||||||
|
def adjustSize(self, event):
|
||||||
|
'''--------------------------------------------------------------------------------------------------
|
||||||
|
passt nach Faktoren die einyelnen Seitenteile der jeweiligen Frame Groesse an
|
||||||
|
'''
|
||||||
|
if(str(event.widget) =="."):
|
||||||
|
self.h = event.height
|
||||||
|
self.w = event.width
|
||||||
|
self.topFrame.configure(height=(self.h*self.faktor[0]), width=self.w)
|
||||||
|
self.mainFrame.configure(height=(self.h*self.faktor[1]), width=self.w)
|
||||||
|
self.bottomFrame.configure(height=(self.h*self.faktor[2]), width=self.w)
|
||||||
|
self.container.configure(height=(self.h*self.faktor[1]), width=self.w)
|
||||||
|
for f in self.frames:
|
||||||
|
self.frames[f].configure(height=(self.h*self.faktor[1]), width=self.w)
|
||||||
|
self.frames[f].adjustSize(height=(self.h*self.faktor[1]), width=self.w)
|
||||||
|
|
||||||
|
|
||||||
|
def onClosing(self):
|
||||||
|
'''--------------------------------------------------------------------------------------------------
|
||||||
|
Stoppt alle laufenden Threads und schliesst OpenVibe und den Aquisitionserver bevor sich das Fenster
|
||||||
|
schliesst
|
||||||
|
'''
|
||||||
|
print("closing")
|
||||||
|
self.controller.commandStop()
|
||||||
|
self.controller.stopAcquisitionServer()
|
||||||
|
print("destroy")
|
||||||
|
self.destroy()
|
||||||
|
|
||||||
|
|
||||||
|
def createTopFrame(self):
|
||||||
|
'''--------------------------------------------------------------------------------------------------
|
||||||
|
Erstellt die Buttons und Textfelder fuer die Taskleiste und positionier diese im Frame
|
||||||
|
'''
|
||||||
|
self.topFrame = Frame(self, bg=self.layout["backgroundBar"], height=50, width=500)
|
||||||
|
self.changeBtn = Button(self.topFrame, text="Wechsel zu taktilen BCI", command=lambda: self.controller.actionPerformed("wechsel"), height=3, width = 30, font=self.layout["fontSmall"], bg=self.layout["backgroundBtn"], fg=self.layout["fontColor"])
|
||||||
|
self.saveBtn = Button(self.topFrame, text="Auswaehlen der Datei", command=lambda: self.controller.actionPerformed("speicherort"), height=3, width = 30, font=self.layout["fontSmall"], bg=self.layout["backgroundBtn"], fg=self.layout["fontColor"])
|
||||||
|
#self.setBtn = Button(self.topFrame, text="Auswaehlen der Datei", command=lambda: self.controller.actionPerformed("setFile"), height=2, width = 25, font=self.layout["fontSmall"], bg=self.layout["backgroundBtn"], fg=self.layout["fontColor"])
|
||||||
|
self.toplabel = Label(self.topFrame, text="visuelles BCI", font=self.layout["font"], bg=self.layout["backgroundBar"], fg=self.layout["fontColor"], )
|
||||||
|
|
||||||
|
self.topFrame.grid(column=0, row=0)
|
||||||
|
self.topFrame.grid_propagate(0)
|
||||||
|
self.topFrame.pack_propagate(0)
|
||||||
|
|
||||||
|
self.changeBtn.grid(column=0, row=0, padx=10,pady=5)
|
||||||
|
self.saveBtn.grid(column=1, row=0, padx=10, pady=5)
|
||||||
|
#self.setBtn.grid(column=2, row=0, padx=10, pady=5)
|
||||||
|
self.toplabel.grid(column=2, row=0, padx=100, pady=2)
|
||||||
|
|
||||||
|
def createMainFrame(self):
|
||||||
|
'''--------------------------------------------------------------------------------------------------
|
||||||
|
Erstellt und postioniert einen Container als Platzhalter fuer die verschiedenen Seiten. Anscliessend
|
||||||
|
erstellt es die verschiedenen Seiten und speicher diese in eine Liste
|
||||||
|
'''
|
||||||
|
self.mainFrame = Frame(self, bg=self.layout["background"], height=250, width=500)
|
||||||
|
self.mainFrame.grid(column=0, row=1)
|
||||||
|
self.mainFrame.pack_propagate(0)
|
||||||
|
|
||||||
|
self.container = Frame(self.mainFrame, bg=self.layout["background"], height=250, width=500)
|
||||||
|
self.container.pack(side="top", fill="both", expand = True)
|
||||||
|
self.container.pack_propagate(0)
|
||||||
|
self.container.grid_propagate(0)
|
||||||
|
|
||||||
|
self.frames = {}
|
||||||
|
for F in (StartPage, WorkingPageTaktil, WorkingPageVisuell):
|
||||||
|
page_name = F.__name__
|
||||||
|
frame = F(parent=self.container, controller=self.controller, layout=self.layout)
|
||||||
|
self.frames[page_name] = frame
|
||||||
|
frame.grid(row=0, column=0, sticky="nsew")
|
||||||
|
|
||||||
|
self.changeFrame("StartPage")
|
||||||
|
|
||||||
|
def createBottomFrame(self):
|
||||||
|
'''--------------------------------------------------------------------------------------------------
|
||||||
|
Erstellt und positioniert ein Label fuer die ganzen Informationen
|
||||||
|
'''
|
||||||
|
self.bottomFrame = Frame(self, bg=self.layout["backgroundBar"], height=100, width=500)
|
||||||
|
self.bottomlabel = Label(self.bottomFrame, text="Hier stehen Infos\nGanz viele", justify='left', font=self.layout["fontInfo"], bg=self.layout["backgroundBar"], fg=self.layout["fontColor"])
|
||||||
|
|
||||||
|
self.bottomFrame.grid(column=0, row=2)
|
||||||
|
self.bottomFrame.pack_propagate(0)
|
||||||
|
self.bottomFrame.grid_propagate(0)
|
||||||
|
|
||||||
|
self.bottomlabel.grid(padx=5,pady=5)
|
||||||
|
|
||||||
|
def setInfoText(self, text):
|
||||||
|
self.bottomlabel['text'] = text
|
||||||
|
|
||||||
|
def setTitleText(self,text):
|
||||||
|
self.title(text)
|
||||||
|
self.toplabel["text"] = text
|
||||||
|
|
||||||
|
def setChangeBtnText(self,text):
|
||||||
|
self.changeBtn["text"] = text
|
||||||
|
|
||||||
|
def openfiledialog(self):
|
||||||
|
path = self.PATH_DEFAULT
|
||||||
|
#file = fd.askopenfilename(initialdir=path)
|
||||||
|
file = fd.askdirectory(initialdir=path)
|
||||||
|
return file
|
||||||
|
|
||||||
|
def savefiledialog(self):
|
||||||
|
self.dialog = Tk()
|
||||||
|
l = Label(self.dialog, text="Bitte geben Sie einen Speichernamen ein:")
|
||||||
|
eingabefeld = Entry(self.dialog)
|
||||||
|
okBtn = Button(self.dialog, text="OK", command=lambda:self.okBtn(eingabefeld.get()))
|
||||||
|
l.pack()
|
||||||
|
eingabefeld.pack()
|
||||||
|
okBtn.pack()
|
||||||
|
|
||||||
|
self.dialog.protocol("WM_DELETE_WINDOW", self.closeDialog)
|
||||||
|
self.dialog.mainloop()
|
||||||
|
|
||||||
|
def okBtn(self, text):
|
||||||
|
path = self.PATH_DEFAULT + "/" + text
|
||||||
|
print(path)
|
||||||
|
self.controller.copyspelling(path)
|
||||||
|
self.dialog.destroy()
|
||||||
|
|
||||||
|
def closeDialog(self):
|
||||||
|
self.controller.copyspelling("-1")
|
||||||
|
self.dialog.destroy()
|
||||||
|
|
||||||
|
def getWindowSize(self):
|
||||||
|
return [self.winfo_x(), self.winfo_y(), self.winfo_height(), self.winfo_width()]
|
||||||
|
|
||||||
|
|
||||||
|
class StartPage(Frame):
|
||||||
|
'''--------------------------------------------------------------------------------------------------
|
||||||
|
Bildet die Seite in der die Aktionen ausgesucht werden koennen. Beihaltet 2 Buttons einen zum starten
|
||||||
|
des freien Buchstabierens und einen yum starten des gefuerten Buchstabierens
|
||||||
|
'''
|
||||||
|
def __init__(self, parent, controller, layout):
|
||||||
|
self.layout = layout
|
||||||
|
|
||||||
|
Frame.__init__(self, parent, height=250, width=500, bg=self.layout["background"])
|
||||||
|
self.grid_propagate(0)
|
||||||
|
self.pack_propagate(0)
|
||||||
|
self.controller = controller
|
||||||
|
|
||||||
|
self.container = Frame(self, bg=self.layout["background"], height=250, width=500)
|
||||||
|
self.btnFrame = Frame(self.container, bg=self.layout["background"], height=250, width=250)
|
||||||
|
|
||||||
|
self.container.columnconfigure(0, weight=1) # Set weight to row and
|
||||||
|
self.container.rowconfigure(0, weight=1) # column where the widget is
|
||||||
|
self.container.grid_propagate(0)
|
||||||
|
self.container.pack_propagate(0)
|
||||||
|
|
||||||
|
self.container.pack()
|
||||||
|
self.btnFrame.grid()
|
||||||
|
|
||||||
|
testBtn = Button(self.btnFrame, text="gefuehrtes Buchstabieren", command=lambda: self.controller.actionPerformed("copySpelling"), height=6, width = 20, font=self.layout["font"], bg=self.layout["backgroundBtn"], fg=self.layout["fontColor"])
|
||||||
|
#testBtn = Button(self.btnFrame, text="copySpelling", command=lambda: self.controller.actionPerformed("test"), height=6, width = 20, font=self.layout["font"], bg=self.layout["backgroundBtn"], fg=self.layout["fontColor"])
|
||||||
|
testBtn.grid(row=0,column=0, padx=25,pady=25)
|
||||||
|
|
||||||
|
freeSpellingBtn = Button(self.btnFrame, text="freies Buchstabieren", command=lambda: self.controller.actionPerformed("freeSpelling"), height=6, width = 20, font=self.layout["font"], bg=self.layout["backgroundBtn"], fg=self.layout["fontColor"])
|
||||||
|
freeSpellingBtn.grid(row=0, column=1, padx=25,pady=25)
|
||||||
|
|
||||||
|
def adjustSize(self, height, width):
|
||||||
|
self.container.configure(height=height, width= width)
|
||||||
|
self.btnFrame.configure(height=(height*4)/5, width= width/2)
|
||||||
|
|
||||||
|
class WorkingPageTaktil(Frame):
|
||||||
|
'''--------------------------------------------------------------------------------------------------
|
||||||
|
Bildet die Seite nach Auswahl einer Aktion. Beihaltet einen mittig plazierten Buttons zum stoppen
|
||||||
|
des ablaufenden Vorgang
|
||||||
|
'''
|
||||||
|
def __init__(self, parent, controller, layout):
|
||||||
|
self.layout = layout
|
||||||
|
|
||||||
|
Frame.__init__(self, parent, height=250, width=500, bg=self.layout["background"])
|
||||||
|
self.controller = controller
|
||||||
|
|
||||||
|
|
||||||
|
self.columnconfigure(0, weight=1) # Set weight to row and
|
||||||
|
self.rowconfigure(0, weight=1) # column where the widget is
|
||||||
|
|
||||||
|
stopBtn = Button(self, text="stop", command=lambda: self.controller.actionPerformed("stop"), height=4, width = 15, font=self.layout["font"], bg=self.layout["backgroundBtn"], fg=self.layout["fontColor"])
|
||||||
|
stopBtn.grid()
|
||||||
|
|
||||||
|
def adjustSize(self, height, width):
|
||||||
|
pass
|
||||||
|
|
||||||
|
class WorkingPageVisuell(Frame):
|
||||||
|
'''--------------------------------------------------------------------------------------------------
|
||||||
|
Bildet die Seite nach Auswahl einer Aktion. Beihaltet einen mittig unten plazierten Buttons zum
|
||||||
|
stoppen des ablaufenden Vorgang
|
||||||
|
'''
|
||||||
|
def __init__(self, parent, controller, layout):
|
||||||
|
self.layout = layout
|
||||||
|
|
||||||
|
Frame.__init__(self, parent, height=250, width=500, bg=self.layout["background"])
|
||||||
|
self.controller = controller
|
||||||
|
self.grid_propagate(0)
|
||||||
|
self.pack_propagate(0)
|
||||||
|
|
||||||
|
self.windowFrame = Frame(self, height=200, width=500, bg=self.layout["background"])
|
||||||
|
self.windowFrame.grid(column=0, row=0)
|
||||||
|
|
||||||
|
self.buttonFrame = Frame(self, height=200, width=500, bg=self.layout["background"])
|
||||||
|
self.buttonFrame.grid(column=0, row=1)
|
||||||
|
self.buttonFrame.columnconfigure(0, weight=1) # Set weight to row and
|
||||||
|
self.buttonFrame.rowconfigure(0, weight=1) # column where the widget is
|
||||||
|
|
||||||
|
stopBtn = Button(self.buttonFrame, text="stop", command=lambda: self.controller.actionPerformed("stop"), height=1, width = 15, font=self.layout["font"], bg=self.layout["backgroundBtn"], fg=self.layout["fontColor"])
|
||||||
|
stopBtn.grid()
|
||||||
|
|
||||||
|
def adjustSize(self, height, width):
|
||||||
|
self.windowFrame.configure(height=(height*4)/5, width= width)
|
||||||
|
self.buttonFrame.configure(height=(height)/10, width= width)
|
BIN
UIViewTKinter.pyc
Normal file
BIN
UIViewTKinter.pyc
Normal file
Binary file not shown.
146
dll.cpp
Normal file
146
dll.cpp
Normal file
@ -0,0 +1,146 @@
|
|||||||
|
#include <iostream>
|
||||||
|
#include <cstring>
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
extern "C"{
|
||||||
|
|
||||||
|
string PATH_OV = "meta/dist/Release/openvibe-designer.sh";
|
||||||
|
string PATH_AquisitionServer = "meta/dist/Release/openvibe-acquisition-server.sh";
|
||||||
|
string PATH_FILES = "Projekte/OpenViBE_visual_BCI-master/openvibe_visual_bci/";
|
||||||
|
string pathOVFile = "Projekte/OpenViBE_visual_BCI-master/openvibe_visual_bci/signals/p300-xdawn-train2.ov";
|
||||||
|
string pathClassifierCFG = "Projekte/OpenViBE_visual_BCI-master/openvibe_visual_bci/cfg/p300-classifier.cfg";
|
||||||
|
string pathSpatialCFG = "Projekte/OpenViBE_visual_BCI-master/openvibe_visual_bci/cfg/p300-spatial-filter.cfg";
|
||||||
|
string PATH_DEFAULT = "Projekte/OpenViBE_visual_BCI-master/openvibe_visual_bci/datasets";
|
||||||
|
|
||||||
|
string fileCopySpellingTaktil = "p300-visual-1-acquisition.xml";
|
||||||
|
string fileCopySpellingVisuell = "p300-visual-1-acquisition.xml";
|
||||||
|
string fileXDawnTraining = "p300-visual-2-train-xDAWN.xml";
|
||||||
|
string fileClassifierTraining = "p300-visual-3-train-classifier.xml";
|
||||||
|
string filefreeSpellingTaktil = "p300-visual-4-online.xml";
|
||||||
|
string filefreeSpellingVisuell = "p300-visual-4-online.xml";
|
||||||
|
|
||||||
|
string command = "bash";
|
||||||
|
string nogui = "--no-gui";
|
||||||
|
string play = "--play";
|
||||||
|
|
||||||
|
|
||||||
|
char* getCommandPS(){
|
||||||
|
string s = "";
|
||||||
|
s = s.append("ps").append(" ").append("-e");
|
||||||
|
char char_array[s.length()+1];
|
||||||
|
strcpy(char_array, s.c_str());
|
||||||
|
char* s_convert = char_array;
|
||||||
|
return s_convert;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* getCommandFreespellingTaktil()
|
||||||
|
{
|
||||||
|
string s = "";
|
||||||
|
s = s.append(command).append(" ").append(PATH_OV).append(" ").append( play).append(" ").append(PATH_FILES).append(filefreeSpellingTaktil).append(" ").append(nogui);
|
||||||
|
char char_array[s.length()+1];
|
||||||
|
strcpy(char_array, s.c_str());
|
||||||
|
char* s_convert = char_array;
|
||||||
|
return s_convert;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* getCommandFreespellingVisuell()
|
||||||
|
{
|
||||||
|
string s = "";
|
||||||
|
s = s.append(command).append(" ").append(PATH_OV).append(" ").append( play).append(" ").append(PATH_FILES).append(filefreeSpellingVisuell).append(" ").append(nogui);
|
||||||
|
char char_array[s.length()+1];
|
||||||
|
strcpy(char_array, s.c_str());
|
||||||
|
char* s_convert = char_array;
|
||||||
|
return s_convert;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* getCommandCopyspellingTaktil()
|
||||||
|
{
|
||||||
|
string s = "";
|
||||||
|
s = s.append(command).append(" ").append(PATH_OV).append(" ").append( play).append(" ").append(PATH_FILES).append(fileCopySpellingTaktil).append(" ").append(nogui);
|
||||||
|
char char_array[s.length()+1];
|
||||||
|
strcpy(char_array, s.c_str());
|
||||||
|
char* s_convert = char_array;
|
||||||
|
return s_convert;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* getCommandCopyspellingVisuell()
|
||||||
|
{
|
||||||
|
string s = "";
|
||||||
|
s = s.append(command).append(" ").append(PATH_OV).append(" ").append( play).append(" ").append(PATH_FILES).append(fileCopySpellingVisuell).append(" ").append(nogui);
|
||||||
|
char char_array[s.length()+1];
|
||||||
|
strcpy(char_array, s.c_str());
|
||||||
|
char* s_convert = char_array;
|
||||||
|
return s_convert;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* getCommandXDawn()
|
||||||
|
{
|
||||||
|
string s = "";
|
||||||
|
s = s.append(command).append(" ").append(PATH_OV).append(" ").append( play).append(" ").append(PATH_FILES).append(fileXDawnTraining).append(" ").append(nogui);
|
||||||
|
char char_array[s.length()+1];
|
||||||
|
strcpy(char_array, s.c_str());
|
||||||
|
char* s_convert = char_array;
|
||||||
|
return s_convert;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* getCommandClassifier()
|
||||||
|
{
|
||||||
|
string s = "";
|
||||||
|
s = s.append(command).append(" ").append(PATH_OV).append(" ").append( play).append(" ").append(PATH_FILES).append(fileClassifierTraining).append(" ").append(nogui);
|
||||||
|
char char_array[s.length()+1];
|
||||||
|
strcpy(char_array, s.c_str());
|
||||||
|
char* s_convert = char_array;
|
||||||
|
return s_convert;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* getCommandStartAquisitionServer()
|
||||||
|
{
|
||||||
|
string s = "";
|
||||||
|
s = s.append(command).append(" ").append(PATH_AquisitionServer);
|
||||||
|
char char_array[s.length()+1];
|
||||||
|
strcpy(char_array, s.c_str());
|
||||||
|
char* s_convert = char_array;
|
||||||
|
return s_convert;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* getDefaultPath()
|
||||||
|
{
|
||||||
|
string s = PATH_DEFAULT;
|
||||||
|
char char_array[s.length()+1];
|
||||||
|
strcpy(char_array, s.c_str());
|
||||||
|
char* s_convert = char_array;
|
||||||
|
return s_convert;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* getPathOVFile()
|
||||||
|
{
|
||||||
|
string s = pathOVFile;
|
||||||
|
char char_array[s.length()+1];
|
||||||
|
strcpy(char_array, s.c_str());
|
||||||
|
char* s_convert = char_array;
|
||||||
|
return s_convert;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* getSpatialCFGFile()
|
||||||
|
{
|
||||||
|
string s = pathSpatialCFG;
|
||||||
|
char char_array[s.length()+1];
|
||||||
|
strcpy(char_array, s.c_str());
|
||||||
|
char* s_convert = char_array;
|
||||||
|
return s_convert;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* getClassifierCFGFile()
|
||||||
|
{
|
||||||
|
string s = pathClassifierCFG;
|
||||||
|
char char_array[s.length()+1];
|
||||||
|
strcpy(char_array, s.c_str());
|
||||||
|
char* s_convert = char_array;
|
||||||
|
return s_convert;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
8
gui.py
Normal file
8
gui.py
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
'''--------------------------------------------------------------------------------------------------
|
||||||
|
In dem File wird eine Instany des Controllers erstellt. Der Controller ist die Schnittstelle
|
||||||
|
zwischen GUI und Modell und koordiniert den Ablauf und die Erstellung der GUI
|
||||||
|
'''
|
||||||
|
|
||||||
|
from UIController import *
|
||||||
|
|
||||||
|
controller = Controller()
|
33
gui.spec
Normal file
33
gui.spec
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
# -*- mode: python ; coding: utf-8 -*-
|
||||||
|
|
||||||
|
block_cipher = None
|
||||||
|
|
||||||
|
|
||||||
|
a = Analysis(['gui.py'],
|
||||||
|
pathex=['/home/ubuntu/Desktop/BCIProjekt'],
|
||||||
|
binaries=[],
|
||||||
|
datas=[],
|
||||||
|
hiddenimports=[],
|
||||||
|
hookspath=[],
|
||||||
|
runtime_hooks=[],
|
||||||
|
excludes=[],
|
||||||
|
win_no_prefer_redirects=False,
|
||||||
|
win_private_assemblies=False,
|
||||||
|
cipher=block_cipher,
|
||||||
|
noarchive=False)
|
||||||
|
pyz = PYZ(a.pure, a.zipped_data,
|
||||||
|
cipher=block_cipher)
|
||||||
|
exe = EXE(pyz,
|
||||||
|
a.scripts,
|
||||||
|
a.binaries,
|
||||||
|
a.zipfiles,
|
||||||
|
a.datas,
|
||||||
|
[],
|
||||||
|
name='gui',
|
||||||
|
debug=False,
|
||||||
|
bootloader_ignore_signals=False,
|
||||||
|
strip=False,
|
||||||
|
upx=True,
|
||||||
|
upx_exclude=[],
|
||||||
|
runtime_tmpdir=None,
|
||||||
|
console=True )
|
2
script.sh
Normal file
2
script.sh
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
sudo apt-get install python-tk
|
||||||
|
sudo apt-get install xdotool
|
80
test.py
Normal file
80
test.py
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
|
||||||
|
from subprocess import *
|
||||||
|
from threading import Thread
|
||||||
|
import time
|
||||||
|
|
||||||
|
class Modell(Thread):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
Thread.__init__(self)
|
||||||
|
self.aktiv= True
|
||||||
|
|
||||||
|
self.aktiv2 = True
|
||||||
|
|
||||||
|
def stop(self):
|
||||||
|
print("stop thread")
|
||||||
|
self.aktiv = False
|
||||||
|
|
||||||
|
def setFunktion(self, func, args=None, kwargs=None):
|
||||||
|
self.func = func
|
||||||
|
self.args = args or []
|
||||||
|
self.kwargs = kwargs or {}
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
print("start thread")
|
||||||
|
#self.aktiv = True
|
||||||
|
t = Thread(target=self.func, args=self.args, kwargs=self.kwargs)
|
||||||
|
t.setDaemon(True)
|
||||||
|
t.start()
|
||||||
|
|
||||||
|
while self.aktiv:
|
||||||
|
time.sleep(0.1)
|
||||||
|
|
||||||
|
def counter(self):
|
||||||
|
n = 0
|
||||||
|
while self.aktiv2:
|
||||||
|
print(n)
|
||||||
|
time.sleep(0.1)
|
||||||
|
n = n+1
|
||||||
|
|
||||||
|
if not self.aktiv2:
|
||||||
|
print("stop")
|
||||||
|
break
|
||||||
|
|
||||||
|
def stop2(self):
|
||||||
|
self.aktiv2 = False
|
||||||
|
#self.aktiv = False
|
||||||
|
|
||||||
|
def test(self):
|
||||||
|
command = ["bash", "meta/dist/Release/openvibe-designer.sh", "--play", "Projekte/OpenViBE_visual_BCI-master/openvibe_visual_bci/p300-visual-1-acquisition.xml", "--no-gui"]
|
||||||
|
process = Popen(command, stdout=PIPE, universal_newlines=True)
|
||||||
|
while self.aktiv2:
|
||||||
|
output = process.stdout.readline()
|
||||||
|
print(output.strip())
|
||||||
|
x = output.find("Application terminated")
|
||||||
|
y = output.find("Error")
|
||||||
|
z = output.find("Initialization")
|
||||||
|
if(x != -1):
|
||||||
|
print("Training finished")
|
||||||
|
process.terminate()
|
||||||
|
break
|
||||||
|
elif(y != -1 ):
|
||||||
|
process.terminate()
|
||||||
|
break
|
||||||
|
if not self.aktiv:
|
||||||
|
print("stop")
|
||||||
|
break
|
||||||
|
|
||||||
|
|
||||||
|
m = Modell()
|
||||||
|
m.setFunktion(m.test)
|
||||||
|
m.start()
|
||||||
|
time.sleep(2)
|
||||||
|
m.stop()
|
||||||
|
m.join()
|
||||||
|
while True:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user