123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425 |
- import datetime
- import glob
- import inspect
- import logging
- import os
- import sys
- import time
- from queue import Queue
- from PyQt5 import Qt, QtCore, QtGui, QtWidgets
- from PyQt5.QtCore import QThread, pyqtSignal, pyqtSlot
- from PyQt5.QtWidgets import QApplication, QGridLayout, QLabel, QWidget
- from modules import bci
- class kiapGUI(QWidget):
- lstvModelFiles = None
- txbExpLogWin = None
- btnExpStart = None
- cmbExpParadigms = None
- lblDeviceConfigFile = None
- tab1GbxDevice = None
- tab1GbxPatient = None
- btnSetConfigFile = None
- btnLoadConfigFile = None
- cmbPatients = None
- lblExpSessionInfo = None
- lblExpPatienName = None
- txbExpSelectedString = None
- selectedPatient = None
- selectedConfigFile = None
- lblExpTime = None
- selectedParadigm = None
- __app = None
- __mainWindow = None
- # recording_signal = pyqtSignal(int)
- def __init__(self, recording_status, log, params, decoder_decision, parent_conn, parent_conn2, parent_conn3, block_phase, audio_feedback_run, audio_fb_target):
- super().__init__()
- self.log = log
- self.bci = bci.Bci()
- self.bci.init(params, recording_status, decoder_decision, parent_conn, parent_conn2, parent_conn3, block_phase, audio_feedback_run, audio_fb_target)
- self.thread = QThread() # no parent!
- self.bci.moveToThread(self.thread)
- self.thread.started.connect(self.bci.start_session)
- self.thread.finished.connect(self.quit_thread)
- # 4 - Connect Worker Signals to the Thread slots
- self.bci.finished_block.connect(self.thread.quit)
- self.bci.finished_block.connect(self.block_done)
- self.bci.history.connect(self.get_message)
- # 5 - Connect Thread started signal to Worker operational slot method
- # self.thread.start()
- # self.thread.started.connect(self.bci.start_trial)
- # * - Thread finished signal will close the app if you want!
- # self.thread.finished.connect(sys.exit)
- # 6 - Start the thread
- self.__InitUI()
- def onIntReady(self, i):
- self.log.debug('got {} from thread'.format(i))
- def __btnAddFilesClicked(self):
- options = QtWidgets.QFileDialog.Options()
- options |= QtWidgets.QFileDialog.DontUseNativeDialog
- selectedFile, _ = QtWidgets.QFileDialog.getOpenFileName(None,"QFileDialog.getOpenFileName()", "","All Files (*);;Python Files (*.py)")
- if selectedFile:
- #fileName = Qt.QUrl().fromLocalFile(selectedFile).fileName()
- self.lstModelFiles.append(selectedFile)
- listModel = Qt.QStandardItemModel(self.lstvModelFiles)
- for file in self.lstModelFiles:
- f = Qt.QStandardItem(file)
- listModel.appendRow(f)
- self.lstvModelFiles.setModel(listModel)
- self.lstvModelFiles.show()
-
- print('Clicked')
- def __btnRemoveFilesClicked(self):
- a = 1
- self.lstModelFiles.remove(self.lstvModelFiles.currentIndex().data())
- listModel = Qt.QStandardItemModel(self.lstvModelFiles)
- for file in self.lstModelFiles:
- f = Qt.QStandardItem(file)
- listModel.appendRow(f)
- self.lstvModelFiles.setModel(listModel)
- self.lstvModelFiles.show()
- print('Clicked')
-
- def __btnStartClicked(self):
- if(self.btnExpStart.text() == 'Start'):
- self.btnExpStart.setText('Stop')
- self.cmbExpParadigms.setEnabled(False)
- selectedParadigm = self.cmbExpParadigms.currentText()
- self.ShowMessage(selectedParadigm + 'Block start.')
- self.StartClicked()
- else:
- self.btnExpStart.setText('Start')
- self.cmbExpParadigms.setEnabled(True)
- self.ShowMessage(self.cmbExpParadigms.currentText() + ' Stopped by operator')
- self.StopClicked()
- time.sleep(1)
- return None
- # def __btnSaveLogClicked(self):
- # fileName = Qt.QFileDialog.getSaveFileName(None,'Save Log',sys.path[0] + os.sep + 'Patients' + os.sep + self.selectedPatient + os.sep,'Log Files (*.html)')
- # if(fileName[0] != ''):
- # f = open(fileName[0],'w+')
- # f.write(self.txbExpLogWin.toHtml())
- # f.close()
- # self.txbExpLogWin.clear()
- # self.ShowMessageBox('Saving Data','Data Saved Successfully')
- # print('save log')
-
- def __btnLoadConfigFileClicked(self):
- options = QtWidgets.QFileDialog.Options()
- options |= QtWidgets.QFileDialog.DontUseNativeDialog
- self.selectedConfigFile, _ = QtWidgets.QFileDialog.getOpenFileName(None,"QFileDialog.getOpenFileName()", "","Config Files (*.yaml)")
- if self.selectedConfigFile:
- self.lblDeviceConfigFile.setText('Config File: ' + self.selectedConfigFile)
- else:
- self.lblDeviceConfigFile.setText('Config File: ')
- def __btnSetConfigFileClicked(self):
- pass
- # self.bci.load_config()
- # self.log.info('Config file reloaded!')
- # tbPallet = QtGui.QPalette()
- # if(self.btnSetConfigFile.text() == 'Set'):
- # if self.selectedConfigFile:
- # self.btnLoadConfigFile.setEnabled(False)
- # self.lblDeviceConfigFile.setEnabled(False)
- # self.btnSetConfigFile.setText('Unset')
- # tbPallet.setColor(QtGui.QPalette.Background,QtGui.QColor(50,205,50))
- # else:
- # self.ShowMessageBox('Error','Config File Not Selected')
-
- # else:
- # self.btnLoadConfigFile.setEnabled(True)
- # self.lblDeviceConfigFile.setEnabled(True)
- # self.btnSetConfigFile.setText('Set')
- # tbPallet.setColor(QtGui.QPalette.Background,QtGui.QColor(255,69,0))
-
- # self.tab1GbxDevice.setPalette(tbPallet)
- # self.tab1GbxDevice.show()
-
- def __btnSetPatientClicked(self):
- tbPallet = QtGui.QPalette()
- if(self.btnSetPatient.text() == 'Set'):
- self.cmbPatients.setEnabled(False)
- self.btnSetPatient.setText('Unset')
- tbPallet.setColor(QtGui.QPalette.Background,QtGui.QColor(50,205,50))
- self.selectedPatient = self.cmbPatients.currentText()
- self.lblExpPatienName.setText('Patient: ' + self.selectedPatient)
- else:
- self.cmbPatients.setEnabled(True)
- self.btnSetPatient.setText('Set')
- tbPallet.setColor(QtGui.QPalette.Background,QtGui.QColor(255,69,0))
- self.selectedPatient = None
- self.lblExpPatienName.setText('Patient: ')
- self.tab1GbxPatient.setPalette(tbPallet)
- self.tab1GbxPatient.show()
- def __UpdateTime(self):
- self.lblExpTime.setText(datetime.datetime.now().strftime('%H:%M:%S'))
- def __InitUI(self):
- self.__app = QtWidgets.QApplication([])
- self.__mainWindow = QtWidgets.QMainWindow()
- self.__mainWindow.setWindowTitle('KIAP - Speller V 0.1')
- self.__mainWindow.setFixedSize(600,600)
- self.__mainWindow.setWindowFlags(QtCore.Qt.WindowCloseButtonHint)
- self.__mainWindow.closeEvent = self.__WindowClosed
-
- tbMain = QtWidgets.QTabWidget()
- tbMain.setAutoFillBackground(True)
- #tbPallet = QtGui.QPalette()
- #tbPallet.setColor(QtGui.QPalette.Background,QtGui.QColor(255,0,0))
- #tbMain.setPalette(tbPallet)
-
- # tab1 = QtWidgets.QWidget()
- # tbMain.addTab(tab1,'Configuration')
- # tab1GrdMain = QtWidgets.QGridLayout()
- # tab1GrdMain.setRowStretch(0,1)
- # tab1GrdMain.setRowStretch(1,1)
- # tab1GrdMain.setRowStretch(2,1)
- # self.tab1GbxDevice = QtWidgets.QGroupBox('Device')
- # self.tab1GbxDevice.setAutoFillBackground(True)
- # grdDeviceConfig = QtWidgets.QGridLayout()
- # grdDeviceConfig.setColumnStretch(0,7)
- # grdDeviceConfig.setColumnStretch(0,1)
- # grdDeviceConfig.setRowStretch(0,1)
- # grdDeviceConfig.setRowStretch(0,1)
- # grdDeviceConfig.setRowStretch(0,1)
- # grdDeviceConfig.setRowStretch(0,1)
- # self.lblDeviceConfigFile = QtWidgets.QLabel('Selected Config File :')
- # grdDeviceConfig.addWidget(self.lblDeviceConfigFile,0,0,QtCore.Qt.AlignTop)
- # self.btnLoadConfigFile = QtWidgets.QPushButton('Load')
- # self.btnLoadConfigFile.clicked.connect(self.__btnLoadConfigFileClicked)
- # grdDeviceConfig.addWidget(self.btnLoadConfigFile,2,1)
- # self.btnSetConfigFile = QtWidgets.QPushButton('Set')
- # self.btnSetConfigFile.clicked.connect(self.__btnSetConfigFileClicked)
- # grdDeviceConfig.addWidget(self.btnSetConfigFile,3,1)
-
- # self.tab1GbxDevice.setLayout(grdDeviceConfig)
-
- # tab1GbxModel = QtWidgets.QGroupBox('Model')
- # tab1GbxModel.setEnabled(False)
- # tab1GbxModelMainLayout = QtWidgets.QHBoxLayout()
- # tab1GbxModelMainLayout.setStretch(0,1)
- # tab1GbxModelMainLayout.setStretch(1,1)
- # grdModelFileSection = QtWidgets.QGridLayout()
- # grdModelFileSection.setRowStretch(0,1)
- # grdModelFileSection.setRowStretch(1,1)
- # grdModelFileSection.setRowStretch(2,1)
- # grdModelFileSection.setRowStretch(3,1)
- # grdModelFileSection.setRowStretch(4,1)
- # grdModelFileSection.setRowStretch(5,1)
- # grdModelFileSection.setColumnStretch(0,1)
- # grdModelFileSection.setColumnStretch(1,1)
- # grdModelFileSection.setColumnStretch(2,1)
- # grdModelFileSection.setColumnStretch(3,1)
- # self.lstvModelFiles = QtWidgets.QListView()
- # self.lstvModelFiles.setWindowTitle('Files')
- # grdModelFileSection.addWidget(self.lstvModelFiles,0,0,5,2)
- # #lstvModelFiles.setModel()
- # btnModelRemoveFile = QtWidgets.QPushButton('Remove')
- # btnModelRemoveFile.setToolTip('Remove selected file from list')
- # btnModelRemoveFile.clicked.connect(self.__btnRemoveFilesClicked)
- # grdModelFileSection.addWidget(btnModelRemoveFile,5,0)
- # btnModelAddFile = QtWidgets.QPushButton('Add')
- # btnModelAddFile.setToolTip('Add files for building a model')
- # btnModelAddFile.clicked.connect(self.__btnAddFilesClicked)
- # grdModelFileSection.addWidget(btnModelAddFile,5,1)
- # txbModelBuildReport = QtWidgets.QTextEdit()
- # txbModelBuildReport.setEnabled(False)
- # grdModelFileSection.addWidget(txbModelBuildReport,0,2,3,2)
- # rbtModelFileSVM = QtWidgets.QRadioButton('SVM')
- # grdModelFileSection.addWidget(rbtModelFileSVM,3,2)
- # rbtModelFileGLM = QtWidgets.QRadioButton('GLM')
- # grdModelFileSection.addWidget(rbtModelFileGLM,3,3)
- # txbModelFileNewModelName = QtWidgets.QTextEdit('ModelName')
- # #grdModelFileSection.addWidget(txbModelFileNewModelName,4,2,1,2)
- # btnModelFileBuildModel = QtWidgets.QPushButton('Build New Model')
- # grdModelFileSection.addWidget(btnModelFileBuildModel,5,2,1,2)
- # grdModelSelection = QtWidgets.QGridLayout()
- # grdModelSelection.setRowStretch(0,1)
- # grdModelSelection.setRowStretch(1,1)
- # grdModelSelection.setRowStretch(2,1)
- # grdModelSelection.setRowStretch(3,1)
- # grdModelSelection.setRowStretch(4,1)
- # grdModelSelection.setRowStretch(5,1)
- # grdModelSelection.setColumnStretch(0,1)
- # grdModelSelection.setColumnStretch(1,1)
- # btnSetModel = QtWidgets.QPushButton('Set')
- # grdModelSelection.addWidget(btnSetModel,5,1)
- # tab1GbxModelMainLayout.addLayout(grdModelFileSection)
- # tab1GbxModelMainLayout.addLayout(grdModelSelection)
- # tab1GbxModel.setLayout(tab1GbxModelMainLayout)
-
- # self.tab1GbxPatient = QtWidgets.QGroupBox('Patient')
- # self.tab1GbxPatient.setAutoFillBackground(True)
- # grdPatientInfo = QtWidgets.QGridLayout()
- # grdPatientInfo.setColumnStretch(0,7)
- # grdPatientInfo.setColumnStretch(0,1)
- # grdPatientInfo.setRowStretch(0,1)
- # grdPatientInfo.setRowStretch(0,1)
- # grdPatientInfo.setRowStretch(0,1)
- # grdPatientInfo.setRowStretch(0,1)
- # self.cmbPatients = QtWidgets.QComboBox()
- # for p in glob.glob(sys.path[0] + '\\Patients\\*\\'):
- # self.cmbPatients.addItem(os.path.basename(p[:-1]))
- # grdPatientInfo.addWidget(self.cmbPatients,0,0,alignment=QtCore.Qt.AlignTop)
- # self.btnSetPatient = QtWidgets.QPushButton('Set')
- # self.btnSetPatient.clicked.connect(self.__btnSetPatientClicked)
- # grdPatientInfo.addWidget(self.btnSetPatient,3,2)
- # self.tab1GbxPatient.setLayout(grdPatientInfo)
-
- # tab1GrdMain.addWidget(self.tab1GbxDevice,0,0)
- # tab1GrdMain.addWidget(tab1GbxModel,1,0)
- # tab1GrdMain.addWidget(self.tab1GbxPatient,2,0)
- # tab1.layout = tab1GrdMain
- # tab1.setLayout(tab1.layout)
- tab2 = QtWidgets.QWidget()
- tbMain.addTab(tab2,'Experiment')
-
- grdExperimentTab = QtWidgets.QGridLayout()
- grdExperimentTab.setRowStretch(0,1)
- grdExperimentTab.setRowStretch(1,1)
- grdExperimentTab.setRowStretch(2,1)
- grdExperimentTab.setRowStretch(3,1)
- grdExperimentTab.setRowStretch(4,12)
- grdExperimentTab.setRowStretch(3,1)
- grdExperimentTab.setColumnStretch(0,1)
- grdExperimentTab.setColumnStretch(1,1)
- grdExperimentTab.setColumnStretch(2,1)
- grdExperimentTab.setColumnStretch(3,1)
- grdExperimentTab.setColumnStretch(4,1)
- grdExperimentTab.setColumnStretch(5,1)
- grdExperimentTab.setColumnStretch(6,1)
- grdExperimentTab.setColumnStretch(7,1)
- self.lblExpPatienName = QtWidgets.QLabel('Patient Name:')
- grdExperimentTab.addWidget(self.lblExpPatienName,0,0)
- self.lblExpSessionInfo = QtWidgets.QLabel('Session Info:')
- grdExperimentTab.addWidget(self.lblExpSessionInfo,1,0)
- self.lblExpTime = QtWidgets.QLabel()
- grdExperimentTab.addWidget(self.lblExpTime,0,6,QtCore.Qt.AlignBottom)
- self.label_update_timer = QtCore.QTimer()
- self.label_update_timer.setSingleShot(False)
- self.label_update_timer.timeout.connect(self.__UpdateTime)
- self.label_update_timer.start(1000)
- lblDate = QtWidgets.QLabel(datetime.datetime.now().strftime('%B %d, %Y'))
- grdExperimentTab.addWidget(lblDate,1,6,QtCore.Qt.AlignTop)
- sepLine = QtWidgets.QFrame()
- sepLine.setLineWidth(2)
- sepLine.setMidLineWidth(1)
- sepLine.setFrameShape(Qt.QFrame.HLine)
- sepLine.setFrameShadow(Qt.QFrame.Raised)
- grdExperimentTab.addWidget(sepLine,1,0,1,8,QtCore.Qt.AlignBottom)
- self.txbExpSelectedString = QtWidgets.QLabel('Selected String:')
- grdExperimentTab.addWidget(self.txbExpSelectedString,2,0,2,7)
- self.cmbExpParadigms = QtWidgets.QComboBox()
- for p in glob.glob(os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) + '\\paradigms\\*.py'):
- self.cmbExpParadigms.addItem(os.path.basename(p[:-3]))
- #self.cmbExpParadigms.addItem('Speller')
- #self.cmbExpParadigms.addItem('Yes / No')
- #self.cmbExpParadigms.addItem('Free Recording')
- #self.cmbExpParadigms.addItem('Motor Paradigm')
- grdExperimentTab.addWidget(self.cmbExpParadigms,2,6,1,2)
- self.btnExpStart = QtWidgets.QPushButton('Start')
- self.btnExpStart.clicked.connect(self.__btnStartClicked)
- grdExperimentTab.addWidget(self.btnExpStart,3,6,1,2)
- self.txbExpLogWin = QtWidgets.QTextBrowser()
- grdExperimentTab.addWidget(self.txbExpLogWin,4,0,2,8)
- # btnExpSaveLog = QtWidgets.QPushButton('Save Log')
- # btnExpSaveLog.clicked.connect(self.__btnSaveLogClicked)
- # grdExperimentTab.addWidget(btnExpSaveLog,9,7)
- tab2.layout = grdExperimentTab
- tab2.setLayout(tab2.layout)
- self.__mainWindow.setCentralWidget(tbMain)
-
- def __WindowClosed(self, evt):
- pass
- def StartGUI(self):
- self.__mainWindow.show()
- # self.__mainWindow.move(800, 100)
- self.__mainWindow.move(2400, 600)
- self.__app.exec()
-
- def SetSelectedSentensce(slef,sentence):
- self.txbExpSelectedString.SetText('Selected String: ' + sentence)
- @pyqtSlot(str)
- def get_message(self, msg):
- # print(msg)
- # self.log.error(f'HISTORY {msg}')
- self.ShowMessage(msg)
- def ShowMessage(self, msg):
- self.txbExpLogWin.append(str(datetime.datetime.now()) + ' | ' + msg )
-
- def ShowMessageBox(self,title,msg):
- msgbx = QtWidgets.QMessageBox()
- msgbx.setText(msg)
- msgbx.setWindowTitle(title)
- #msgbx.standardButton(QtWidgets.QMessageBox.Ok)
- msgbx.exec()
- def StartClicked(self):
- res = self.bci.load_config()
- if res > 0:
- self.__btnStartClicked()
- self.log.warning('Block not started')
- else:
- self.log.info('Config file reloaded!')
- self.thread.start()
- return None
- def StopClicked(self):
- self.bci.recording_status.value = 0
- return None
- def quit_thread(self):
- self.log.debug('Quitting thread, data_recording_status: {}\n'.format(self.bci.recording_status.value))
- self.thread.quit()
- return None
- def block_done(self):
- # self.bci.recording_status.value = 0
- self.btnExpStart.setText('Start')
- self.cmbExpParadigms.setEnabled(True)
- self.ShowMessage(self.cmbExpParadigms.currentText() + 'Block end.\n')
- return None
|