def __init__(self): super(MainWindow, self).__init__() self.settings = QSettings("IK", "Netshut") self.th = None self.ui = Ui_MainWindow() self.ui.setupUi(self) self.init_ui() self.center() # Compile Re's self._pat_arp = re.compile( "^(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\s+(\S+)", re.MULTILINE) self._pat_gip = re.compile("inet\s(.+)/") self._cut_hosts = {} self._hosts = {} self._hosts_names = {} self._gw = self.get_gateway() self._gw_mac = "" self._iface = "wlp2s0" self._mac = "" self._ip = self.get_ip() self.prompt_iface() self.ui.lbl_gw.setText("<b>{}</b>".format(self._gw)) self.ui.lbl_mac.setText("<b>{}</b>".format(self._mac)) self.ui.lbl_ip.setText("<b>{}</b>".format(self._ip)) self.ui.lbl_iface.setText("<b>{}</b>".format(self._iface)) self.cut_all = False self.open_config_file() self.ui.act_scan.trigger()
def __init__(self, connection, update): from ui.addEditCoffeeForm_ui import Ui_MainWindow super().__init__() self.ui = Ui_MainWindow() self.ui.setupUi(self) self.update = update self.con = connection self.cur = self.con.cursor() self.sort_order = [] for ind, sort in self.cur.execute("""SELECT * FROM Sort""").fetchall(): self.ui.comboBox.addItem(sort) self.sort_order.append(sort) self.roast_order = [] for ind, roast in self.cur.execute( """SELECT * FROM Roast""").fetchall(): self.ui.comboBox_2.addItem(roast) self.roast_order.append(roast) self.sort = 1 self.ui.comboBox.activated.connect(self.combobox_click) self.roast = 1 self.ui.comboBox_2.activated.connect(self.combobox_2_click) self.ui.pushButton.clicked.connect(self.add) self.ui.pushButton_2.clicked.connect(self.clear) self.ui.pushButton_3.clicked.connect(self.change) self.ui.pushButton_4.clicked.connect(self.save) self.changing_id = -1
class Application(QMainWindow): def __init__(self): from ui.main_ui import Ui_MainWindow super().__init__() self.ui = Ui_MainWindow() self.ui.setupUi(self) self.con = sqlite3.connect("../data/coffee.sqlite") self.cur = self.con.cursor() self.ui.tableWidget.setRowCount(0) self.cur.execute("pragma table_info(Coffee)") titles = [(ind, name) for ind, name, *args in self.cur.fetchall()] self.ui.tableWidget.setColumnCount(len(titles)) for j, title_name in titles: self.ui.tableWidget.setHorizontalHeaderItem( j, QTableWidgetItem(title_name)) self.edit_page = EditPage(self.con, self.update) self.ui.pushButton.clicked.connect(lambda: self.edit_page.show()) self.update() def update(self): self.ui.tableWidget.setRowCount(0) for i, row in enumerate( self.cur.execute("SELECT * FROM Coffee").fetchall()): self.ui.tableWidget.setRowCount(self.ui.tableWidget.rowCount() + 1) row = change_values(self.cur, row) for j, elem in enumerate(row): self.ui.tableWidget.setItem(i, j, QTableWidgetItem(str(elem)))
def __init__(self): super().__init__() self.print_outs = 0 self.ui = Ui_MainWindow() self.ui.setupUi(self) self.show() self.editors: List[List[minor_c.QCodeEditor]] = [] self.add_tab() self.console = ''
def __init__(self, parent=None): self.configs = [] self.urls = {'auth': '', 'engine': ''} super().__init__(parent) # uic.loadUi(os.path.join(UI_DIR, 'main.ui'), self) self.ui = Ui_MainWindow() self.ui.setupUi(self) self.mod_manager = ModuleManager() self.current_config = None self.logger = logging.getLogger(log_config.LOGGER_NAME) self.logger.addHandler(UiLogHandler(self.ui.logPtx)) self.load_login() self.init_task_fields() self.init_ui() pass
def __init__(self,app,onlyDBAccess=False): '''main window init''' QtGui.QMainWindow.__init__(self) self.ui = Ui_MainWindow() self.ui.setupUi(self) self.db = DB(self) self.settings=Settings(self) self.onlyDBAccess=onlyDBAccess if onlyDBAccess: return #GUI setting guiSettings(self) connectSignals(self) changeStyle(self) self.taskOpened = False self.app = app loadContexts(self) self.currentContext = self.settings.getInitContext() selectCurrentContext(self) self.loadTasksList(init=True) self.tray=Trayicon(self) self.timer=TaskReminder(self) self.shortcuts=ShortcutsHandler(self,self.settings['keyMainWindowToggle']) finalizeInit(self) self.translate() self.adjustHeight(init=True)
def __init__(self): from ui.main_ui import Ui_MainWindow super().__init__() self.ui = Ui_MainWindow() self.ui.setupUi(self) self.con = sqlite3.connect("../data/coffee.sqlite") self.cur = self.con.cursor() self.ui.tableWidget.setRowCount(0) self.cur.execute("pragma table_info(Coffee)") titles = [(ind, name) for ind, name, *args in self.cur.fetchall()] self.ui.tableWidget.setColumnCount(len(titles)) for j, title_name in titles: self.ui.tableWidget.setHorizontalHeaderItem( j, QTableWidgetItem(title_name)) self.edit_page = EditPage(self.con, self.update) self.ui.pushButton.clicked.connect(lambda: self.edit_page.show()) self.update()
def __init__(self, model, controller, parent=None): super().__init__(parent) self.model = model self.controller = controller self.mod_manager = ModuleManager() self.ui = Ui_MainWindow() self.ui.setupUi(self) if os.path.isfile(self.ICON_FILE): self.setWindowIcon(QIcon(self.ICON_FILE)) self.logger = logging.getLogger(log_config.LOGGER_NAME) self.logger.addHandler(UiLogHandler(self.ui.logPtx)) self.load_menu_bar() self.connect_widgets() self.connect_model_signals() self.controller_loads() self.load_modules()
def __init__(self, parent=None): QtGui.QWidget.__init__(self, parent) self.ui = Ui_MainWindow() self.ui.setupUi(self) self.dialog = QtGui.QMainWindow self.filename = '' self.threshold = 0 self.message_num = 0 QtCore.QObject.connect(self.ui.pushButtonAdd, QtCore.SIGNAL("clicked()"), self.add_to_view) QtCore.QObject.connect(self.ui.pushButtonReset, QtCore.SIGNAL("clicked()"), self.clear_view) QtCore.QObject.connect(self.ui.pushButton_browse, QtCore.SIGNAL("clicked()"), self.browse) QtCore.QObject.connect(self.ui.pushButton_auto_threshold, QtCore.SIGNAL("clicked()"), self.auto_threshold) QtCore.QObject.connect(self.ui.doubleSpinBox_threshold, QtCore.SIGNAL("valueChanged(const QString&)"), self.update_thresh) QtCore.QObject.connect( self.ui.comboBox_test_num, QtCore.SIGNAL("currentIndexChanged(const QString&)"), self.load_traces) QtCore.QObject.connect( self.ui.comboBox_trace, QtCore.SIGNAL("currentIndexChanged(const QString&)"), self.load_channels) self.ui.view.threshLine.sigPositionChangeFinished.connect( self.update_thresh2) self.ui.preview.threshLine.sigPositionChangeFinished.connect( self.update_thresh2) self.ui.preview.removeLegend()
def __init__(self, parent=None): QtGui.QWidget.__init__(self, parent) self.ui = Ui_MainWindow() self.ui.setupUi(self) self.dialog = QtGui.QMainWindow self.filename = '' self.threshold = 0 self.message_num = 0 self.ui.textEdit.setReadOnly(True) # TODO Complete Spike Rates # self.ui.pushButton_spike_rates.setEnabled(False) QtCore.QObject.connect(self.ui.pushButton_raster, QtCore.SIGNAL("clicked()"), self.graph_raster) QtCore.QObject.connect(self.ui.pushButton_historgram, QtCore.SIGNAL("clicked()"), self.graph_historgram) QtCore.QObject.connect(self.ui.pushButton_tuning_curve, QtCore.SIGNAL("clicked()"), self.graph_tuning_curve) # QtCore.QObject.connect(self.ui.pushButton_io_test, QtCore.SIGNAL("clicked()"), self.graph_io_test) QtCore.QObject.connect(self.ui.pushButton_io_test, QtCore.SIGNAL("clicked()"), self.graph_multi_io_test) QtCore.QObject.connect(self.ui.pushButton_spike_rates, QtCore.SIGNAL("clicked()"), self.graph_spike_rates) QtCore.QObject.connect(self.ui.pushButton_abr, QtCore.SIGNAL("clicked()"), self.graph_abr) QtCore.QObject.connect(self.ui.pushButton_browse, QtCore.SIGNAL("clicked()"), self.browse) QtCore.QObject.connect(self.ui.pushButton_auto_threshold, QtCore.SIGNAL("clicked()"), self.auto_threshold) QtCore.QObject.connect(self.ui.radioButton_normal, QtCore.SIGNAL("toggled(bool)"), self.generate_view) QtCore.QObject.connect(self.ui.doubleSpinBox_threshold, QtCore.SIGNAL("valueChanged(const QString&)"), self.update_thresh) QtCore.QObject.connect(self.ui.comboBox_test_num, QtCore.SIGNAL("currentIndexChanged(const QString&)"), self.load_traces) QtCore.QObject.connect(self.ui.comboBox_trace, QtCore.SIGNAL("currentIndexChanged(const QString&)"), self.load_reps) QtCore.QObject.connect(self.ui.comboBox_rep, QtCore.SIGNAL("currentIndexChanged(const QString&)"), self.load_channels) QtCore.QObject.connect(self.ui.comboBox_channel, QtCore.SIGNAL("currentIndexChanged(const QString&)"), self.generate_view) QtCore.QObject.connect(self.ui.checkBox_custom_window, QtCore.SIGNAL("toggled(bool)"), self.update_window) QtCore.QObject.connect(self.ui.doubleSpinBox_xmax, QtCore.SIGNAL("valueChanged(const QString&)"), self.update_window) QtCore.QObject.connect(self.ui.doubleSpinBox_xmin, QtCore.SIGNAL("valueChanged(const QString&)"), self.update_window) QtCore.QObject.connect(self.ui.doubleSpinBox_ymax, QtCore.SIGNAL("valueChanged(const QString&)"), self.update_window) QtCore.QObject.connect(self.ui.doubleSpinBox_ymin, QtCore.SIGNAL("valueChanged(const QString&)"), self.update_window) self.ui.view.sigRangeChanged.connect(self.update_view_range) self.ui.view.threshLine.sigPositionChangeFinished.connect(self.update_thresh2)
def __init__(self, app, parent=None): super(JottaGui, self).__init__(parent) self.app = app self.ui = Ui_MainWindow() self.ui.setupUi(self) self.jottaModel = None self.loginStatusChanged.connect(self.populateDevices) self.ui.listDevices.currentIndexChanged[str].connect(self.populateJottaRoot) __preview = QtGui.QWidget() __layout = QtGui.QVBoxLayout() __thumbnail = QtGui.QLabel(__preview) __thumbnail.setObjectName('thumbnail') __layout.addWidget(__thumbnail) __details = QtGui.QLabel(__preview) __details.setObjectName('details') __layout.addWidget(__details) self.btnget = QtGui.QPushButton('Get') __layout.addWidget(self.btnget) __preview.setLayout(__layout) self.btnget.clicked.connect(self.get) self.ui.jottafsView.setPreviewWidget(__preview) self.ui.actionLogin.triggered.connect(self.showModalLogin) self.downloading.connect(self.downloadActive) self.progress.connect(lambda x: self.ui.progressBar.setValue(x))
class Workload(QtGui.QMainWindow): def __init__(self,app,onlyDBAccess=False): '''main window init''' QtGui.QMainWindow.__init__(self) self.ui = Ui_MainWindow() self.ui.setupUi(self) self.db = DB(self) self.settings=Settings(self) self.onlyDBAccess=onlyDBAccess if onlyDBAccess: return #GUI setting guiSettings(self) connectSignals(self) changeStyle(self) self.taskOpened = False self.app = app loadContexts(self) self.currentContext = self.settings.getInitContext() selectCurrentContext(self) self.loadTasksList(init=True) self.tray=Trayicon(self) self.timer=TaskReminder(self) self.shortcuts=ShortcutsHandler(self,self.settings['keyMainWindowToggle']) finalizeInit(self) self.translate() self.adjustHeight(init=True) def resizeEvent(self,e): path=QtGui.QPainterPath() rect=e.size() path.addRoundedRect(-1,-1,rect.width()+1,rect.height()+1,7,7) region=QtGui.QRegion(path.toFillPolygon().toPolygon()) self.setMask(region) def taskListFocusIn(self,e): if e.reason()==QtCore.Qt.FocusReason.TabFocusReason: try: item=self.ui.taskList.itemAt(0) self.ui.taskList.setCurrentItem(self.ui.taskList.itemAt(0)) except: pass def toggle(self): if self.isVisible(): self.hide() else: self.show() def dropTask(self,e): Task.dropTask(self, e) def resizeColumns(self): self.ui.taskList.setColumnWidth(0, 20) self.ui.taskList.setColumnWidth(1, 20) self.ui.taskList.hideColumn(0) def setMarker(self,tasks): icon=QtGui.QIcon(':res/status/clock.png') items=self.ui.taskList.findItems("",QtCore.Qt.MatchContains|QtCore.Qt.MatchRecursive) for i in items: removeicon=QtGui.QIcon() i.setIcon(2,removeicon) for i in tasks: for j in items: if j.data(0,32)==i: j.setIcon(2,icon) def drawRow(self,painter,myopt,index): myopt.decorationPosition=QtGui.QStyleOptionViewItem.Right myopt.decorationAlignment=QtCore.Qt.AlignCenter QtGui.QTreeWidget.drawRow(self.ui.taskList,painter,myopt,index) # TASKS RELATED ACTIONS def addTask(self): t = self.ui.taskInput.text().strip() if t =="": return False self.ui.taskInput.clear() priority = 0 try: if t[1] == ":": priority = int(t[0]) if priority<6: t = t[2:] else: priority = 0 elif t[-2] == ":": priority = int(t[-1]) if priority<6: t = t[:-2] else: priority = 0 except: pass #TODO: create new function to handle input (regexp etc) if len(t)>50: taskname=t[:50] taskDescription=t else: taskname=t taskDescription="" if self.checkIfExist(taskname) is not True: duedate=self.defaultDueDate() taskid = self.db.addTask(taskname,priority, taskDescription, duedate, self.currentContext) self.createTaskItem(taskname, taskid, priority) self.adjustHeight() self.ui.statusbar.showMessage(QtGui.QApplication.translate("ui","New task created."),3300) else: self.ui.taskInput.setText(taskname) self.taskAlreadyExistMsg() def defaultDueDate(self): if self.settings["defaultDueDateOn"]: dueValue=int(self.settings["defaultDueDateValue"]) if self.settings["defaultDueDateUnit"]=="0": td=datetime.timedelta(hours=dueValue) else: td=datetime.timedelta(days=dueValue) return timestamp(datetime.datetime.now()+td) else: return None def createTaskItem(self, t, taskid=None, priority=0): item = QtGui.QTreeWidgetItem([str(priority),"", t]) item.setData(0, 32, taskid) item.setSizeHint(1, QtCore.QSize(0, 22)) self.ui.taskList.addTopLevelItem(item) self.setPriorityColor(item, priority) self.ui.taskList.sortItems(0,QtCore.Qt.AscendingOrder) def checkIfExist(self,t): if len(self.ui.taskList.findItems(t,QtCore.Qt.MatchFlags(QtCore.Qt.MatchExactly),2))>0: return True def taskAlreadyExistMsg(self,parent=None): text=QtGui.QApplication.translate("ui","Task with same name already exist, choose another") windowtitle=QtGui.QApplication.translate("ui","Task name already exists") msgWindow=QtGui.QMessageBox() if parent is not None: self=parent msgWindow.information(self, windowtitle, text, buttons=QtGui.QMessageBox.Ok ) def loadTasksList(self, archived=False,init=False): self.ui.taskList.clear() for i in self.db.getTasks(self.currentContext): self.createTaskItem(i[1], i[0],i[2]) def deleteSelectedTasks(self, force=False): selectedItems = self.ui.taskList.selectedItems() if len(selectedItems)>0: tasks = [] for item in selectedItems: tasks.append(item) windowtitle=QtGui.QApplication.translate("ui","Delete task") text=QtGui.QApplication.translate("ui","Do you really want to delete selected task(s) ?") if force: self.deleteTasks(tasks) windowtitle=QtGui.QApplication.translate("ui","Delete task") text=QtGui.QApplication.translate("ui","Do you really want to delete selected task(s) ?") elif self.questionPopup(windowtitle,text): self.deleteTasks(tasks) self.adjustHeight(downSize=True) def deleteTasks(self, tasks): for item in tasks: self.db.deleteTask(item.data(0, 32)) index = self.ui.taskList.indexOfTopLevelItem(item) self.ui.taskList.takeTopLevelItem(index) self.ui.statusbar.showMessage(QtGui.QApplication.translate("ui","Task removed."),3300) def setTaskPriority(self,priority): selectedItems = self.ui.taskList.selectedItems() for item in selectedItems: self.db.setTaskPriority(item.data(0, 32),priority) self.setPriorityColor(item, priority) item.setText(0,str(priority)) self.ui.taskList.sortItems(0,QtCore.Qt.AscendingOrder) self.ui.statusbar.showMessage(QtGui.QApplication.translate("ui","Priority updated."),3300) def setPriorityColor(self,item,priority): icon=QtGui.QIcon(':res/status/'+str(priority)+'.png') item.setIcon(1,icon) def openTask(self,taskname=None): if not self.taskOpened: item = self.getSelectedItem() if item: Task(self,item.data(0, 32)) def getSelectedItem(self): selectedItems = self.ui.taskList.selectedItems() if len(selectedItems) == 1: item = self.ui.taskList.selectedItems()[0] return item else: return False # SHORTCUTS AND KEYBOARD EVENTS RELATED ACTIONS def getKeysOnList(self, e): if e.key() == 16777223: # delete if (QtCore.Qt.ShiftModifier & e.modifiers()): self.deleteSelectedTasks(True) elif e.key()>48 and e.key()<54: self.setTaskPriority(e.key()-48) elif e.key()==78: self.ui.taskInput.setFocus() else: QtGui.QTreeWidget.keyPressEvent(self.ui.taskList,e) def getKeysOnInput(self, e): if e.key()==16777221 or e.key()==16777220: # enter/return if (QtCore.Qt.AltModifier & e.modifiers()): self.createTask() else: self.addTask() else: QtGui.QLineEdit.keyPressEvent(self.ui.taskInput,e) input=self.ui.taskInput.text() if len(input)>50: taskname=input[:50].strip() taskname=taskname.replace("\r\n","\n") taskname=taskname.replace("\n"," ") taskname=taskname.replace("\t"," ") taskname=taskname.replace(" ","") description=input Task(self,taskid=0,taskname=taskname,description=description) self.ui.taskInput.clear() #ADDITIONAL FUNTIONS def questionPopup(self, title, msg): window=QtGui.QMessageBox() window.setWindowFlags(QtCore.Qt.FramelessWindowHint) resp = window.question(self, title, msg, buttons=QtGui.QMessageBox.Ok | QtGui.QMessageBox.Cancel) if resp == QtGui.QMessageBox.Ok: return True else: return False #WINDOWS MOVEMENT def mouseMoveEvent(self, e): if e.buttons() & QtCore.Qt.LeftButton: try: self.posx self.posy except: self.posx=e.x() self.posy=e.y() y=e.globalY()-self.posy x=e.globalX()-self.posx self.move(x,y) #e.accept() def mouseReleaseEvent(self, e): try: del(self.posx) del(self.posy) except: pass def adjustHeight(self,downSize=False,init=False): tasks=self.db.getTasks(self.currentContext) if len(tasks)>0: item=self.ui.taskList.topLevelItem(0) qmodel=self.ui.taskList.indexFromItem(item) taskheight=self.ui.taskList.rowHeight(qmodel) else: taskheight=22 if init: winheight=320 listheight=252 else: winheight=self.height() listheight=self.ui.taskList.height() desiredHeight=taskheight*len(tasks)+winheight-listheight+6 if ( desiredHeight>self.height() or downSize ) and desiredHeight<QtGui.QApplication.desktop().height(): self.resize(self.width(),desiredHeight) def closeEvent(self, e=None): self.hide() if e: e.ignore() ###### MENU FUNCTIONS def importTasklist(self): fname=QtGui.QFileDialog.getOpenFileName(self, QtGui.QApplication.translate("ui","Open"), "", QtGui.QApplication.translate("ui","Workload Import File (*.w)")) if fname[0]: filename=fname[0] from lib import importexport importexport.importTasks(self,filename,self.settings["dateFormat"]) def exportTaskList(self): fname=QtGui.QFileDialog.getSaveFileName(self,QtGui.QApplication.translate("ui","Save"), "", QtGui.QApplication.translate("ui","Workload Export File (*.w)")) if fname[0]: includeArchive=self.questionPopup(QtGui.QApplication.translate("ui","Exporting tasks"), QtGui.QApplication.translate("ui","Do you want to include completed tasks?")) tasks=self.db.exportTasks(self.currentContext, includeArchive) from lib import importexport filename=fname[0] importexport.export(tasks, filename,self.settings["dateFormat"]) def about(self): f=open("about.html") text=f.read() f.close() QtGui.QMessageBox.information(self, QtGui.QApplication.translate("ui","About"), text, buttons=QtGui.QMessageBox.Ok ) def exit(self,exitcode=0): exit_=False if self.settings["askOnExit"]: if self.questionPopup(QtGui.QApplication.translate("ui","Exit"), QtGui.QApplication.translate("ui","Are you sure?")): exit_=True else: exit_=True if exit_==True: self.settings.setCurrentContextAsLast() self.shortcuts.terminate() self.app.exit(exitcode) def createTask(self): Task(self,taskid=0) def completeTasks(self): if self.ui.taskList.hasFocus(): tasks=self.ui.taskList.selectedItems() for i in tasks: self.db.completeTask(i.data(0,32)) index = self.ui.taskList.indexOfTopLevelItem(i) self.ui.taskList.takeTopLevelItem(index) self.ui.statusbar.showMessage(QtGui.QApplication.translate("ui","Task completed."),3300) def showHistory(self): ArchiveWindow(self) def hoyKeyError(self): QtGui.QMessageBox.critical(self,QtGui.QApplication.translate("ui","Error"),QtGui.QApplication.translate("ui","Unable to register global shortcut")) def changeEvent(self, e): if e.type()==QtCore.QEvent.LanguageChange: self.ui.retranslateUi(self) self.ui.statusbar.showMessage(QtGui.QApplication.translate("ui","Hello! Ready to work ;-)"),3600) loadContexts(self) selectCurrentContext(self) QtGui.QMainWindow.changeEvent(self,e) def translate(self,lang=None): if lang is None: lang= self.settings["lang"] translate=True if lang=="auto": locale = QtCore.QLocale.system().name() elif lang=="en": translate=False try: self.app.removeTranslator(self.qtTranslator) except: pass else: locale=lang if translate: self.qtTranslator = QtCore.QTranslator() self.qtTranslator.load("i18n"+os.sep+"workload_"+locale+".qm") self.app.installTranslator(self.qtTranslator) def showMsg(self,msg): msgWindow=QtGui.QMessageBox() msgWindow.information(self, "Workload - Information", msg, buttons=QtGui.QMessageBox.Ok )
class MainView(QMainWindow): ICON_FILE = f'{os.path.dirname(__file__)}\\camunda_logo.png' def __init__(self, model, controller, parent=None): super().__init__(parent) self.model = model self.controller = controller self.mod_manager = ModuleManager() self.ui = Ui_MainWindow() self.ui.setupUi(self) if os.path.isfile(self.ICON_FILE): self.setWindowIcon(QIcon(self.ICON_FILE)) self.logger = logging.getLogger(log_config.LOGGER_NAME) self.logger.addHandler(UiLogHandler(self.ui.logPtx)) self.load_menu_bar() self.connect_widgets() self.connect_model_signals() self.controller_loads() self.load_modules() def controller_loads(self): self.controller.question_method = self.open_question self.controller.load_login() self.controller.load_urls() self.controller.load_configs() def connect_widgets(self): self.ui.loginBtn.clicked.connect(self.open_login_win) self.ui.addConfigBtn.clicked.connect(self.controller.add_config) self.ui.removeConfigBtn.clicked.connect(self.controller.remove_config) self.ui.sendRequestBtn.clicked.connect(self.controller.send_request) self.ui.configList.itemSelectionChanged.connect( self.configs_selection_changed) self.ui.taskTabs.currentChanged.connect(self.current_module_changed) self.config_field_changing(self.ui.configNameTbx, 'name') self.config_field_changing(self.ui.hostTxb, 'host') self.config_field_changing(self.ui.instanceTxb, 'instance') def connect_model_signals(self): self.model.login_changed.connect(self.ui.loginLbl.setText) self.model.urls_changed.connect(self.reload_urls_menu) self.model.configs_changed.connect(self.on_configs_changed) self.model.current_config_changed.connect( self.on_current_config_changed) self.model.config_added.connect(self.add_config_widget) self.model.config_added.connect(self.remove_config_widget) # region UI properties @property def config_name(self): return self.ui.configNameTbx.text() @config_name.setter def config_name(self, value): self.ui.configNameTbx.setText(value) @property def host(self): return self.ui.hostTxb.text() @host.setter def host(self, value): self.ui.hostTxb.setText(value) @property def instance(self): return self.ui.instanceTxb.text() @instance.setter def instance(self, value): self.ui.instanceTxb.setText(value) # endregion @try_except_wrapper def load_modules(self): modules = self.mod_manager.get_views() self.ui.taskTabs.clear() for name, wid in modules.items(): wid.model.can_send_changed.connect(self.update_send_btn_status) wid.setObjectName(name) self.ui.taskTabs.addTab(wid, name.capitalize().replace('_', ' ')) self.register_module_vars(name) @try_except_wrapper def register_module_vars(self, module_name): def connecting(s, f): s.connect(lambda v: self.controller.update_config_field(f, v)) mod = self.mod_manager.get_model_by_name(module_name) for field in mod.__dict__.keys(): prop = field[1:] signal = getattr(mod, f'{prop}_changed') field_path = f'utils.[{module_name}].[{prop}]' connecting(signal, field_path) def load_menu_bar(self): self.ui.menuBar.clear() self.urls_menu = QMenu(self.ui.menuBar) self.urls_menu.setTitle('Urls') self.ui.menuBar.addAction(self.urls_menu.menuAction()) self.about = QAction(self.ui.menuBar) self.about.setText('About') self.about.triggered.connect(self.open_about) self.ui.menuBar.addAction(self.about) def config_field_changing(self, widget, field): if isinstance(widget, QLineEdit): widget.textChanged.connect( lambda v: self.controller.update_config_field(field, v)) elif isinstance(widget, QCheckBox): widget.toggled.connect( lambda v: self.controller.update_config_field(field, v)) def on_configs_changed(self, configs): self.ui.configList.clear() for c in configs: self.add_config_widget(c) @try_except_wrapper @pyqtSlot(Config) def add_config_widget(self, config): item = QListWidgetItem() item.config = config widget = ConfigWidget(config, self.ui.configList) item.setSizeHint(widget.sizeHint()) self.ui.configList.addItem(item) self.ui.configList.setItemWidget(item, widget) @try_except_wrapper @pyqtSlot(Config) def remove_config_widget(self, config): items = [ self.ui.configList.item(i) for i in range(self.ui.configList.count()) ] item = [ i for i in items if hasattr(i, 'config') and i.config == config ] if len(item) > 0: self.ui.configList.takeItem(self.ui.configList.row(item[0])) @pyqtSlot(object) def on_current_config_changed(self, value): if value: self.__select_config(value) self.ui.configParamsContainer.setEnabled(True) else: self.ui.configParamsContainer.setEnabled(False) @try_except_wrapper def __select_config(self, config): self.config_name = config.name self.host = config.host self.instance = config.instance for name, fields in config.utils.items(): model = self.mod_manager.get_model_by_name(name) for field, value in fields.items(): setattr(model, field, value) @try_except_wrapper @pyqtSlot(dict) def reload_urls_menu(self, menus): self.urls_menu.clear() for n, u in menus.items(): url_menu = InputMenuAction(self.ui.menuBar) url_menu.label = n url_menu.valueLE.setText(u) url_menu.valueChanged.connect(self.controller.update_url) self.urls_menu.addAction(url_menu.get_widget_action( self.urls_menu)) def open_login_win(self): win = LoginDialog(self) win.show() win.exec_() if win.confirm: self.controller.load_login() self.logger.info('Login updated') @try_except_wrapper def update_send_btn_status(self): current_module = self.ui.taskTabs.currentWidget() model = current_module.model self.ui.sendRequestBtn.setEnabled(model.can_send) def current_module_changed(self, ind): if ind < 0: return self.controller.select_module( self.ui.taskTabs.widget(ind).objectName()) self.update_send_btn_status() def open_about(self): about_msg = ''' <h3>Camunda helper</h3> <p> <b>Author:</b> Abissov Sergey <br> <b>Source code:</b> <a href="https://github.com/Serega-SPb/camunda_helper">Github</a> </p>''' QMessageBox.information(self, 'About', about_msg) def open_question(self, msg): answer = QMessageBox.question(self, 'Send this?', msg, QMessageBox.Yes | QMessageBox.No) return True if answer == QMessageBox.Yes else False def configs_selection_changed(self): selected = self.ui.configList.selectedItems() self.controller.select_config( selected[0].config if len(selected) > 0 else None) def closeEvent(self, *args, **kwargs): self.controller.save_urls() self.controller.save_configs()
class MyForm(QtGui.QMainWindow): def __init__(self, parent=None): QtGui.QWidget.__init__(self, parent) self.ui = Ui_MainWindow() self.ui.setupUi(self) self.dialog = QtGui.QMainWindow self.filename = '' self.threshold = 0 self.message_num = 0 QtCore.QObject.connect(self.ui.pushButtonAdd, QtCore.SIGNAL("clicked()"), self.add_to_view) QtCore.QObject.connect(self.ui.pushButtonReset, QtCore.SIGNAL("clicked()"), self.clear_view) QtCore.QObject.connect(self.ui.pushButton_browse, QtCore.SIGNAL("clicked()"), self.browse) QtCore.QObject.connect(self.ui.pushButton_auto_threshold, QtCore.SIGNAL("clicked()"), self.auto_threshold) QtCore.QObject.connect(self.ui.doubleSpinBox_threshold, QtCore.SIGNAL("valueChanged(const QString&)"), self.update_thresh) QtCore.QObject.connect( self.ui.comboBox_test_num, QtCore.SIGNAL("currentIndexChanged(const QString&)"), self.load_traces) QtCore.QObject.connect( self.ui.comboBox_trace, QtCore.SIGNAL("currentIndexChanged(const QString&)"), self.load_channels) self.ui.view.threshLine.sigPositionChangeFinished.connect( self.update_thresh2) self.ui.preview.threshLine.sigPositionChangeFinished.connect( self.update_thresh2) self.ui.preview.removeLegend() def browse(self): self.ui.comboBox_test_num.clear() QtGui.QFileDialog(self) self.filename = QtGui.QFileDialog.getOpenFileName() self.ui.lineEdit_file_name.setText(self.filename) # If the filename is not blank, attempt to extract test numbers and place them into the combobox if self.filename != '': if '.hdf5' in self.filename: try: h_file = h5py.File(unicode(self.filename), 'r') except IOError: self.add_message('Error: I/O Error') self.ui.lineEdit_comments.setEnabled(False) self.ui.lineEdit_comments.setText('') self.ui.comboBox_test_num.setEnabled(False) return tests = {} for key in h_file.keys(): if 'segment' in key: for test in h_file[key].keys(): tests[test] = int(test.replace('test_', '')) sorted_tests = sorted(tests.items(), key=operator.itemgetter(1)) for test in sorted_tests: self.ui.comboBox_test_num.addItem(test[0]) self.ui.lineEdit_comments.setEnabled(True) self.ui.comboBox_test_num.setEnabled(True) h_file.close() else: self.add_message('Error: Must select a .hdf5 file.') self.ui.lineEdit_comments.setEnabled(False) self.ui.lineEdit_comments.setText('') self.ui.comboBox_test_num.setEnabled(False) return else: self.add_message('Error: Must select a file to open.') self.ui.lineEdit_comments.setEnabled(False) self.ui.lineEdit_comments.setText('') self.ui.comboBox_test_num.setEnabled(False) return def auto_threshold(self): thresh_fraction = 0.7 filename = self.filename = self.ui.lineEdit_file_name.text() # Validate filename if self.valid_filename(filename): h_file = h5py.File(unicode(self.filename), 'r') target_test = self.ui.comboBox_test_num.currentText() else: return # Find target segment for segment in h_file.keys(): for test in h_file[segment].keys(): if target_test == test: target_seg = segment target_test = test trace_data = h_file[target_seg][target_test].value if len(trace_data.shape) == 4: trace_data = trace_data.squeeze() # Still shape of 4 if len(trace_data.shape) == 4: trace_data = trace_data[:, :, 1, :] trace_data = trace_data.squeeze() if len(trace_data.shape) == 2: # Compute threshold from just one rep average_max = np.array(np.max(np.abs(trace_data[1, :]))).mean() thresh = thresh_fraction * average_max else: # Compute threshold from average maximum of traces max_trace = [] for n in range(len(trace_data[1, :, 0])): max_trace.append(np.max(np.abs(trace_data[1, n, :]))) average_max = np.array(max_trace).mean() thresh = thresh_fraction * average_max self.ui.doubleSpinBox_threshold.setValue(thresh) self.update_thresh() h_file.close() def add_to_view(self): filename = self.filename = self.ui.lineEdit_file_name.text() # Validate filename if self.valid_filename(filename): h_file = h5py.File(unicode(self.filename), 'r') target_test = self.ui.comboBox_test_num.currentText() else: return for key in h_file.keys(): if 'segment' in key: for test in h_file[key].keys(): if target_test == test: target_seg = key target_test = test # Makes the assumption that all of the traces are of the same type stim_info = eval(h_file[target_seg][target_test].attrs['stim']) self.ui.label_stim_type.setText(stim_info[ int(self.ui.comboBox_trace.currentText().replace('trace_', '')) - 1]['components'][0]['stim_type']) fs = h_file[target_seg].attrs['samplerate_ad'] target_trace = [] target_rep = [] target_chan = [] # Get the values from the combo boxes self.ui.comboBox_test_num.currentText() if self.ui.comboBox_trace.currentText() != '': target_trace = int(self.ui.comboBox_trace.currentText().replace( 'trace_', '')) - 1 if self.ui.comboBox_channel.currentText() != '': target_chan = int(self.ui.comboBox_channel.currentText().replace( 'channel_', '')) - 1 test_data = h_file[target_seg][target_test].value # Get the presentation data depending on if there is a channel field or not if len(test_data.shape) == 4: presentation = test_data[target_trace, target_rep, target_chan, :] elif len(test_data.shape) == 3: presentation = test_data[target_trace, target_rep, :] # TODO Is presentation portion needed still? len_presentation = len(presentation) # Get the length of the window and length of presentation depending on if all is selected or not if len_presentation != 0: window = len(presentation) / float(fs) else: if len(test_data.shape) == 4: window = len(test_data[0, 0, 0, :]) / float(fs) len_presentation = len(test_data[0, 0, 0, :]) elif len(test_data.shape) == 3: window = len(test_data[0, 0, :]) / float(fs) len_presentation = len(test_data[0, 0, :]) xlist = np.linspace(0, float(window), len_presentation) ylist = presentation # Set window size if len(presentation) > 0: ymin = min(presentation) ymax = max(presentation) else: ymin = 0 ymax = 0 if len(test_data.shape) == 3: rep_len = test_data.shape[1] for i in range(rep_len): if min(test_data[target_trace, i, :]) < ymin: ymin = min(test_data[target_trace, i, :]) if max(test_data[target_trace, i, :]) > ymax: ymax = max(test_data[target_trace, i, :]) else: rep_len = test_data.shape[1] for i in range(rep_len): if min(test_data[target_trace, i, target_chan, :]) < ymin: ymin = min(test_data[target_trace, i, target_chan, :]) if max(test_data[target_trace, i, target_chan, :]) > ymax: ymax = max(test_data[target_trace, i, target_chan, :]) self.ui.view.setXRange(0, window, 0) self.ui.view.setYRange(ymin, ymax, 0.1) label = target_test + ' trace_' + str(target_trace + 1) + ' chan_' + str(target_chan + 1) if len(test_data.shape) == 3: # Average reps of test_data temp_data = np.mean(test_data[target_trace, :, :], axis=0) # Create empty storage avg_test_data = np.zeros([1, test_data.shape[3]]) avg_test_data[0, :] = temp_data self.ui.view.addTraceAverage(xlist, avg_test_data, label, self.ui.spinBox_red.value(), self.ui.spinBox_green.value(), self.ui.spinBox_blue.value()) else: # Average reps of test_data temp_data = np.mean(test_data[target_trace, :, target_chan, :], axis=0) # Create empty storage avg_test_data = np.zeros([1, test_data.shape[3]]) avg_test_data[0, :] = temp_data self.ui.view.addTraceAverage(xlist, avg_test_data, label, self.ui.spinBox_red.value(), self.ui.spinBox_green.value(), self.ui.spinBox_blue.value()) h_file.close() def generate_preview(self): filename = self.filename = self.ui.lineEdit_file_name.text() # Validate filename if self.valid_filename(filename): h_file = h5py.File(unicode(self.filename), 'r') target_test = self.ui.comboBox_test_num.currentText() else: return # clear view self.clear_preview() for key in h_file.keys(): if 'segment' in key: for test in h_file[key].keys(): if target_test == test: target_seg = key target_test = test # Makes the assumption that all of the traces are of the same type stim_info = eval(h_file[target_seg][target_test].attrs['stim']) self.ui.label_stim_type.setText(stim_info[ int(self.ui.comboBox_trace.currentText().replace('trace_', '')) - 1]['components'][0]['stim_type']) fs = h_file[target_seg].attrs['samplerate_ad'] target_trace = [] target_rep = [] target_chan = [] # Get the values from the combo boxes self.ui.comboBox_test_num.currentText() if self.ui.comboBox_trace.currentText() != '': target_trace = int(self.ui.comboBox_trace.currentText().replace( 'trace_', '')) - 1 if self.ui.comboBox_channel.currentText() != '': target_chan = int(self.ui.comboBox_channel.currentText().replace( 'channel_', '')) - 1 test_data = h_file[target_seg][target_test].value # Get the presentation data depending on if there is a channel field or not if len(test_data.shape) == 4: presentation = test_data[target_trace, target_rep, target_chan, :] elif len(test_data.shape) == 3: presentation = test_data[target_trace, target_rep, :] # TODO Is presentation portion needed still? # print 'presentation', presentation len_presentation = len(presentation) # Get the length of the window and length of presentation depending on if all is selected or not if len_presentation != 0: window = len(presentation) / float(fs) else: if len(test_data.shape) == 4: window = len(test_data[0, 0, 0, :]) / float(fs) len_presentation = len(test_data[0, 0, 0, :]) elif len(test_data.shape) == 3: window = len(test_data[0, 0, :]) / float(fs) len_presentation = len(test_data[0, 0, :]) xlist = np.linspace(0, float(window), len_presentation) ylist = presentation # Set window size if len(presentation) > 0: ymin = min(presentation) ymax = max(presentation) else: ymin = 0 ymax = 0 if len(test_data.shape) == 3: rep_len = test_data.shape[1] for i in range(rep_len): if min(test_data[target_trace, i, :]) < ymin: ymin = min(test_data[target_trace, i, :]) if max(test_data[target_trace, i, :]) > ymax: ymax = max(test_data[target_trace, i, :]) else: rep_len = test_data.shape[1] for i in range(rep_len): if min(test_data[target_trace, i, target_chan, :]) < ymin: ymin = min(test_data[target_trace, i, target_chan, :]) if max(test_data[target_trace, i, target_chan, :]) > ymax: ymax = max(test_data[target_trace, i, target_chan, :]) self.ui.preview.setXRange(0, window, 0) self.ui.preview.setYRange(ymin, ymax, 0.1) # self.ui.preview.tracePlot.clear() # Fix xlist to be the length of presentation if len(test_data.shape) == 3: self.ui.preview.addTraceAveragePreview( xlist, test_data[target_trace, :, :], target_test + ' trace_' + str(target_trace + 1) + ' chan_' + str(target_chan + 1)) else: self.ui.preview.addTraceAveragePreview( xlist, test_data[target_trace, :, target_chan, :], target_test + ' trace_' + str(target_trace) + ' chan_' + str(target_chan)) h_file.close() def valid_filename(self, filename): # Validate filename if filename != '': if '.hdf5' in filename: try: temp_file = h5py.File(unicode(self.filename), 'r') temp_file.close() except IOError: self.add_message('Error: I/O Error') return False else: self.add_message('Error: Must select a .hdf5 file.') return False else: self.add_message('Error: Must select a file to open.') return False return True def load_traces(self): self.ui.comboBox_trace.clear() # Validate filename if self.valid_filename(self.filename): h_file = h5py.File(unicode(self.filename), 'r') target_test = self.ui.comboBox_test_num.currentText() else: self.ui.comboBox_trace.setEnabled(False) return if self.ui.comboBox_test_num.currentText( ) == 'All' or self.ui.comboBox_test_num.currentText() == '': self.ui.comboBox_trace.setEnabled(False) self.ui.comboBox_trace.clear() h_file.close() return else: self.ui.comboBox_trace.setEnabled(True) for key in h_file.keys(): if 'segment' in key: for test in h_file[key].keys(): if target_test == test: target_seg = key target_test = test traces = h_file[target_seg][target_test].value.shape[0] for i in range(traces): self.ui.comboBox_trace.addItem('trace_' + str(i + 1)) self.ui.comboBox_trace.setEnabled(True) comment = h_file[target_seg].attrs['comment'] self.ui.lineEdit_comments.setText(comment) h_file.close() def load_channels(self): self.ui.comboBox_channel.clear() # Validate filename if self.valid_filename(self.filename): h_file = h5py.File(unicode(self.filename), 'r') target_test = self.ui.comboBox_test_num.currentText() else: self.ui.comboBox_trace.setEnabled(False) return if self.ui.comboBox_trace.currentText( ) == '' or self.ui.comboBox_channel.count() < 2: self.ui.comboBox_channel.setEnabled(False) self.ui.comboBox_channel.clear() else: self.ui.comboBox_channel.setEnabled(True) if self.ui.comboBox_test_num.count() == 0: h_file.close() return for key in h_file.keys(): if 'segment' in key: for test in h_file[key].keys(): if target_test == test: target_seg = key target_test = test if len(h_file[target_seg][target_test].value.shape) > 3: channels = h_file[target_seg][target_test].value.shape[2] else: channels = 1 if channels == 1: self.ui.comboBox_channel.addItem('channel_1') else: for i in range(channels): self.ui.comboBox_channel.addItem('channel_' + str(i + 1)) if self.ui.comboBox_trace.currentText( ) != '' and self.ui.comboBox_channel != '': self.generate_preview() h_file.close() def update_thresh(self): self.ui.view.setThreshold(self.ui.doubleSpinBox_threshold.value()) self.ui.view.update_thresh() self.ui.preview.setThreshold(self.ui.doubleSpinBox_threshold.value()) self.ui.preview.update_thresh() def update_thresh2(self): self.ui.doubleSpinBox_threshold.setValue(self.ui.view.getThreshold()) self.ui.doubleSpinBox_threshold.setValue( self.ui.preview.getThreshold()) def count_spikes(self): pass def GetFreqsAttns(self, freqTuningHisto): # Frequency Tuning Curve method """ Helper method for ShowSTH() to organize the frequencies in ascending order separated for each intensity. :param freqTuningHisto: dict of pandas.DataFrames with spike data :type freqTuningHisto: str :returns: ordered list of frequencies (DataFrame keys()) numpy array of frequencies numpy array of intensities """ freqs = np.array([]) attns = np.array([]) for histoKey in list(freqTuningHisto): if histoKey != 'None_None': freq = histoKey.split('_')[0] freqs = np.hstack([freqs, float(freq) / 1000]) attn = histoKey.split('_')[1] attns = np.hstack([attns, float(attn)]) attnCount = stats.itemfreq(attns) freqs = np.unique(freqs) attns = np.unique(attns) if np.max(attnCount[:, 1]) != np.min(attnCount[:, 1]): abortedAttnIdx = np.where( attnCount[:, 1] != np.max(attnCount[:, 1])) attns = np.delete(attns, abortedAttnIdx) orderedKeys = [] for attn in attns: freqList = [] for freq in freqs: key = str(int(freq * 1000)) + '_' + str(int(attn)) freqList.append(key) orderedKeys.append(freqList) return orderedKeys, freqs, attns def add_message(self, message): self.message_num += 1 self.ui.textEdit.append('[' + str(self.message_num) + ']: ' + message + '\n') def clear_view(self): self.ui.view.clearTraces() self.ui.view.clearMouse() self.ui.view.clearFocus() self.ui.view.clearMask() self.ui.view.clearData(axeskey='response') self.ui.view.tracePlot.clear() self.ui.view.rasterPlot.clear() self.ui.view.stimPlot.clear() self.ui.view.trace_stash = [] def clear_preview(self): self.ui.preview.clearTraces() self.ui.preview.clearMouse() self.ui.preview.clearFocus() self.ui.preview.clearMask() self.ui.preview.clearData(axeskey='response') self.ui.preview.tracePlot.clear() self.ui.preview.rasterPlot.clear() self.ui.preview.stimPlot.clear() self.ui.preview.trace_stash = []
class EditPage(QMainWindow): def __init__(self, connection, update): from ui.addEditCoffeeForm_ui import Ui_MainWindow super().__init__() self.ui = Ui_MainWindow() self.ui.setupUi(self) self.update = update self.con = connection self.cur = self.con.cursor() self.sort_order = [] for ind, sort in self.cur.execute("""SELECT * FROM Sort""").fetchall(): self.ui.comboBox.addItem(sort) self.sort_order.append(sort) self.roast_order = [] for ind, roast in self.cur.execute( """SELECT * FROM Roast""").fetchall(): self.ui.comboBox_2.addItem(roast) self.roast_order.append(roast) self.sort = 1 self.ui.comboBox.activated.connect(self.combobox_click) self.roast = 1 self.ui.comboBox_2.activated.connect(self.combobox_2_click) self.ui.pushButton.clicked.connect(self.add) self.ui.pushButton_2.clicked.connect(self.clear) self.ui.pushButton_3.clicked.connect(self.change) self.ui.pushButton_4.clicked.connect(self.save) self.changing_id = -1 def change(self): coffee_data = self.cur.execute("""SELECT * FROM Coffee""").fetchall() str_coffee_data = [] for coffee in coffee_data: str_coffee_data.append(str(change_values(self.cur, coffee))) res, ok_btn_pressed = QInputDialog.getItem(self, "Выберите коффе", f"Выберите коффе", str_coffee_data) if ok_btn_pressed: ind = str_coffee_data.index(res) current = change_values(self.cur, coffee_data[ind]) self.sort = self.cur.execute( """SELECT name FROM Sort""").fetchall().index( (current[1], )) + 1 self.ui.comboBox_2.setCurrentText(current[2]) self.roast = self.cur.execute( """SELECT name FROM Roast""").fetchall().index( (current[2], )) + 1 self.ui.checkBox.setChecked(current[3]) self.ui.lineEdit_2.setText(current[4]) self.ui.lineEdit.setText(str(current[5])) self.ui.lineEdit_3.setText(str(current[6])) self.changing_id = current[0] def save(self): try: sort = self.sort roast = self.roast grain = bool(self.ui.checkBox.checkState()) taste = self.ui.lineEdit_2.text() price = int(self.ui.lineEdit.text()) quantity = int(self.ui.lineEdit_3.text()) except ValueError: return self.cur.execute( f"UPDATE Coffee " f"SET sort_name = ?, " f"roasting_degree = ?, " f"grain = ?, " f"taste = ?, " f"price = ?, " f"quantity = ? " f"WHERE id = ?", (sort, roast, grain, taste, price, quantity, self.changing_id)) self.con.commit() self.update() def add(self): try: sort = self.sort roast = self.roast grain = bool(self.ui.checkBox.checkState()) taste = self.ui.lineEdit_2.text() price = int(self.ui.lineEdit.text()) quantity = int(self.ui.lineEdit_3.text()) except ValueError: return self.cur.execute( "INSERT INTO Coffee(sort_name, roasting_degree, grain, taste, price, quantity) " "VALUES(?, ?, ?, ?, ?, ?)", (sort, roast, grain, taste, price, quantity)) self.con.commit() self.clear() self.update() def clear(self): self.ui.checkBox.setChecked(False) self.ui.lineEdit.setText("") self.ui.lineEdit_2.setText("") self.ui.lineEdit_3.setText("") def combobox_click(self, index: int): self.sort = index + 1 print(self.sort) def combobox_2_click(self, index: int): self.roast = index + 1
class MainWindow(QtWidgets.QMainWindow): def __init__(self): super().__init__() self.print_outs = 0 self.ui = Ui_MainWindow() self.ui.setupUi(self) self.show() self.editors: List[List[minor_c.QCodeEditor]] = [] self.add_tab() self.console = '' def add_tab(self): container = QtWidgets.QWidget() container.setObjectName("tab_3") text_edit = minor_c.QCodeEditor(container) text_edit2 = angus_editor.QCodeEditor(container) text_edit.setGeometry(QtCore.QRect(10, 10, 521, 361)) text_edit2.setGeometry(QtCore.QRect(550, 10, 521, 361)) text_edit.setObjectName("textEdit_{}".format(self.ui.tabWidget.count())) font = QtGui.QFont() font.setFamily("Monaco") text_edit.setFont(font) text_edit2.setFont(font) palette = QtGui.QPalette() brush = QtGui.QBrush(QtGui.QColor(248, 248, 242)) brush.setStyle(QtCore.Qt.SolidPattern) palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.Text, brush) palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.Text, brush) brush = QtGui.QBrush(QtGui.QColor(39, 40, 34)) brush.setStyle(QtCore.Qt.SolidPattern) palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.Base, brush) palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.Base, brush) # text_edit.setPalette(palette) self.editors.append([text_edit, text_edit2]) self.ui.tabWidget.addTab(container, '') # for i in range(self.ui.tabWidget.count()): self.ui.tabWidget.setTabText(self.ui.tabWidget.count() - 1, "Untitled-{}".format(self.ui.tabWidget.count())) self.ui.tabWidget.setCurrentIndex(self.ui.tabWidget.count() - 1) def close_current_tab(self): index = self.ui.tabWidget.currentIndex() count = self.ui.tabWidget.count() - 1 if count > 0: self.ui.tabWidget.removeTab(index) del self.editors[index] def on_close_tab(self, index: int): count = self.ui.tabWidget.count() - 1 if count > 0: self.ui.tabWidget.removeTab(index) del self.editors[index] # ====================================== debug ====================================== def debug(self): index = self.ui.tabWidget.currentIndex() txt = self.editors[index][1].toPlainText() if len(txt) > 2: def println(t: str): self.print(t) root = debug_ast(txt, self, println) self.ui.lb_debug_active.setText('TRUE') self.ui.debugline.setText(str(root.line)) def step(self): root = step() self.ui.debugline.setText(str(root.line)) def stop_debug(self): root = step() self.ui.debugline.setText(str(root.line)) def stop_run(self): self.ui.debugline.setText(str(0)) self.ui.lb_debug_active.setText('false') # //====================================== debug ====================================== # ====================================== Files ====================================== def open_file(self): dirr = QtCore.QDir() qfile = QtWidgets.QFileDialog.getOpenFileName(self, "Open File", dirr.absoluteFilePath("."), "Files (*.*)") if len(qfile[0]) == 0: return file = QtCore.QFile(qfile[0]) file.open(QtCore.QFile.ReadOnly) filename = file.fileName() txt = str(file.readAll().data(), encoding='utf-8') index = self.ui.tabWidget.currentIndex() parts = filename.split("/") self.editors[index][0].path = filename self.editors[index][0].filename = parts[len(parts) - 1] self.editors[index][0].setPlainText(txt) self.ui.tabWidget.setTabText(index, self.editors[index][0].filename) self.ui.tabWidget.setTabToolTip(self.ui.tabWidget.count() - 1, filename) def save_file(self): dirr = QtCore.QDir() index = self.ui.tabWidget.currentIndex() code_editor = self.editors[index][0] if code_editor.path == "": qfile = QtWidgets.QFileDialog.getSaveFileName(self, "Save File", dirr.absoluteFilePath('.'), "OLC2 Files (*.txt)") if len(qfile[0]) == 0: return parts = qfile[0].split("/") code_editor.path = qfile[0] code_editor.filename = parts[len(parts) - 1] self.ui.tabWidget.setTabText(index, code_editor.filename) file = open(code_editor.path, 'w') file.write(code_editor.toPlainText()) file.close() def save_as(self): index = self.ui.tabWidget.currentIndex() code_editor = self.editors[index][0] qfile = QtWidgets.QFileDialog.getSaveFileName(self, "Save File", QtCore.QDir.homePath(), "OLC2 Files (*.txt)") if len(qfile[0]) == 0: return code_editor.path = qfile[0] file = open(code_editor.path, 'w') file.write(code_editor.toPlainText()) file.close() # //====================================== Files ====================================== def run_desc(self): index = self.ui.tabWidget.currentIndex() txt = self.editors[index][1].toPlainText() if len(txt) > 2: def println(t: str): self.print(t) root = get_ast(txt, self, println) def run_convert(self): index = self.ui.tabWidget.currentIndex() txt = self.editors[index][0].toPlainText() if len(txt) > 2: def println(t: str): self.print(t) root = run_minor_c.get_ast(txt, self, println) self.editors[index][1].setPlainText(root) def run_asc(self): pass # //====================================== Reports Angus ====================================== def report_errors(self): path = os.getcwd() + '/report_angus_errores.html' file = open(path, 'w') rows = ['<tr><th>Type</th><th>Line</th><th>Col</th><th>descrip</th></tr>'] for el in globales.lErroresSemanticos: rows.append('<tr><td>{}</td><td>{}</td><td>{}</td><td>{}</td></tr>'.format(el.t, el.line, el.col, el.decrip)) for el in globales.lErrores: rows.append('<tr><td>{}</td><td>{}</td><td>{}</td><td>{}</td></tr>'.format(el.t, el.line, el.col, el.decrip)) html = """ <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Tabla de simbolos</title> <style> table {{ font-family: "Trebuchet MS", Arial, Helvetica, sans-serif; border-collapse: collapse; width: 100%; max-width: 500px; margin: 0 auto; }} table td, table th {{ border: 1px solid #ddd; padding: 8px; }} table tr:nth-child(even){{background-color: #f2f2f2;}} table tr:hover {{background-color: #ddd;}} table th {{ padding-top: 12px; padding-bottom: 12px; text-align: left; background-color: #4CAF50; color: white; }} </style> </head> <body> <table> {} </table> </body> </html> """.format('\n'.join(rows)) file.write(html) file.close() subprocess.Popen(["open", path]) def report_var_table(self): path = os.getcwd() + '/report_angus_functions.html' file = open(path, 'w') rows = ['<tr><th>Function</th><th>Type</th></tr>'] for key in globales.all_tags: rows.append('<tr><td>{}</td><td>{}</td></tr>'.format(key, globales.all_tags[key].typee)) html = """ <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Tabla de simbolos</title> <style> table {{ font-family: "Trebuchet MS", Arial, Helvetica, sans-serif; border-collapse: collapse; width: 100%; max-width: 500px; margin: 0 auto; }} table td, table th {{ border: 1px solid #ddd; padding: 8px; }} table tr:nth-child(even){{background-color: #f2f2f2;}} table tr:hover {{background-color: #ddd;}} table th {{ padding-top: 12px; padding-bottom: 12px; text-align: left; background-color: #4CAF50; color: white; }} </style> </head> <body> <table> {} </table> </body> </html> """.format('\n'.join(rows)) file.write(html) file.close() subprocess.Popen(["open", path]) def report_sym_tab(self): path = os.getcwd() + '/report_angus_sym.html' file = open(path, 'w') rows = ['<tr><th>Key</th><th>Value</th></tr>'] for i in globales.sym_table: rows.append('<tr><td>{}</td><td>{}</td></tr>'.format(i.key, str(i.value))) html = """ <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Tabla de simbolos</title> <style> table {{ font-family: "Trebuchet MS", Arial, Helvetica, sans-serif; border-collapse: collapse; width: 100%; max-width: 500px; margin: 0 auto; }} table td, table th {{ border: 1px solid #ddd; padding: 8px; }} table tr:nth-child(even){{background-color: #f2f2f2;}} table tr:hover {{background-color: #ddd;}} table th {{ padding-top: 12px; padding-bottom: 12px; text-align: left; background-color: #4CAF50; color: white; }} </style> </head> <body> <table> {} </table> </body> </html> """.format('\n'.join(rows)) file.write(html) file.close() subprocess.Popen(["open", path]) def report_ast(self): path = os.getcwd() + '/report_angus_graph.svg' subprocess.Popen(["open", path]) # //====================================== Reports Aguns ====================================== # //====================================== Reports MinorC ====================================== def report_errors_minorc(self): path = os.getcwd() + '/report_minorc_errores.html' file = open(path, 'w') rows = ['<tr><th>Type</th><th>Line</th><th>Col</th><th>descrip</th></tr>'] for el in globales2.lErroresSemanticos: rows.append('<tr><td>{}</td><td>{}</td><td>{}</td><td>{}</td></tr>'.format(el.t, el.line, el.col, el.decrip)) for el in globales2.lErrores: rows.append('<tr><td>{}</td><td>{}</td><td>{}</td><td>{}</td></tr>'.format(el.t, el.line, el.col, el.decrip)) html = """ <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Tabla de simbolos</title> <style> table {{ font-family: "Trebuchet MS", Arial, Helvetica, sans-serif; border-collapse: collapse; width: 100%; max-width: 500px; margin: 0 auto; }} table td, table th {{ border: 1px solid #ddd; padding: 8px; }} table tr:nth-child(even){{background-color: #f2f2f2;}} table tr:hover {{background-color: #ddd;}} table th {{ padding-top: 12px; padding-bottom: 12px; text-align: left; background-color: #4CAF50; color: white; }} </style> </head> <body> <table> {} </table> </body> </html> """.format('\n'.join(rows)) file.write(html) file.close() subprocess.Popen(["open", path]) def report_var_table_minorc(self): path = os.getcwd() + '/report_minorc_functions.html' file = open(path, 'w') rows = ['<tr><th>Function</th><th>Type</th></tr>'] for i in globales2.r_shiftreduce_grammar: rows.append('<tr><td>{}</td><td>{}</td></tr>'.format(i[0], str(i[1]))) html = """ <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Tabla de simbolos</title> <style> table {{ font-family: "Trebuchet MS", Arial, Helvetica, sans-serif; border-collapse: collapse; width: 100%; max-width: 500px; margin: 0 auto; }} table td, table th {{ border: 1px solid #ddd; padding: 8px; }} table tr:nth-child(even){{background-color: #f2f2f2;}} table tr:hover {{background-color: #ddd;}} table th {{ padding-top: 12px; padding-bottom: 12px; text-align: left; background-color: #4CAF50; color: white; }} </style> </head> <body> <table> {} </table> </body> </html> """.format('\n'.join(rows)) file.write(html) file.close() subprocess.Popen(["open", path]) def report_sym_tab_minorc(self): path = os.getcwd() + '/report_minorc_sym.html' file = open(path, 'w') rows = ['<tr><th>Key</th><th>Value</th></tr>'] for i in globales2.sym_table: rows.append('<tr><td>{}</td><td>{}</td></tr>'.format(i.key, str(i.value))) html = """ <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Tabla de simbolos</title> <style> table {{ font-family: "Trebuchet MS", Arial, Helvetica, sans-serif; border-collapse: collapse; width: 100%; max-width: 500px; margin: 0 auto; }} table td, table th {{ border: 1px solid #ddd; padding: 8px; }} table tr:nth-child(even){{background-color: #f2f2f2;}} table tr:hover {{background-color: #ddd;}} table th {{ padding-top: 12px; padding-bottom: 12px; text-align: left; background-color: #4CAF50; color: white; }} </style> </head> <body> <table> {} </table> </body> </html> """.format('\n'.join(rows)) file.write(html) file.close() subprocess.Popen(["open", path]) def report_sym_tab_fun_minorc(self): path = os.getcwd() + '/report_minorc_sym_fun.html' file = open(path, 'w') rows = ['<tr><th>Funcion</th><th>Line</th></tr>'] for i in globales2.sym_table_fun: rows.append('<tr><td>{}</td><td>{}</td></tr>'.format(i.key, str(i.line))) html = """ <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Tabla de simbolos Funciones</title> <style> table {{ font-family: "Trebuchet MS", Arial, Helvetica, sans-serif; border-collapse: collapse; width: 100%; max-width: 500px; margin: 0 auto; }} table td, table th {{ border: 1px solid #ddd; padding: 8px; }} table tr:nth-child(even){{background-color: #f2f2f2;}} table tr:hover {{background-color: #ddd;}} table th {{ padding-top: 12px; padding-bottom: 12px; text-align: left; background-color: #4CAF50; color: white; }} </style> </head> <body> <table> {} </table> </body> </html> """.format('\n'.join(rows)) file.write(html) file.close() subprocess.Popen(["open", path]) def report_ast_minorc(self): path = os.getcwd() + '/report_minorc_graph.svg' subprocess.Popen(["open", path]) # //====================================== Reports MinorC ====================================== def print(self, txt: str): print("> {}".format(txt)) self.print_outs += 1 out = "{}> {}\n".format(self.console, txt) self.console = out self.ui.teConsole.setPlainText(str(self.console)) self.ui.teConsole.verticalScrollBar().setSliderPosition(self.ui.teConsole.verticalScrollBar().maximum())
class MyForm(QtGui.QMainWindow): def __init__(self, parent=None): QtGui.QWidget.__init__(self, parent) self.ui = Ui_MainWindow() self.ui.setupUi(self) self.dialog = QtGui.QMainWindow self.filename = '' self.threshold = 0 self.message_num = 0 self.ui.textEdit.setReadOnly(True) # TODO Complete Spike Rates # self.ui.pushButton_spike_rates.setEnabled(False) QtCore.QObject.connect(self.ui.pushButton_raster, QtCore.SIGNAL("clicked()"), self.graph_raster) QtCore.QObject.connect(self.ui.pushButton_historgram, QtCore.SIGNAL("clicked()"), self.graph_historgram) QtCore.QObject.connect(self.ui.pushButton_tuning_curve, QtCore.SIGNAL("clicked()"), self.graph_tuning_curve) # QtCore.QObject.connect(self.ui.pushButton_io_test, QtCore.SIGNAL("clicked()"), self.graph_io_test) QtCore.QObject.connect(self.ui.pushButton_io_test, QtCore.SIGNAL("clicked()"), self.graph_multi_io_test) QtCore.QObject.connect(self.ui.pushButton_spike_rates, QtCore.SIGNAL("clicked()"), self.graph_spike_rates) QtCore.QObject.connect(self.ui.pushButton_abr, QtCore.SIGNAL("clicked()"), self.graph_abr) QtCore.QObject.connect(self.ui.pushButton_browse, QtCore.SIGNAL("clicked()"), self.browse) QtCore.QObject.connect(self.ui.pushButton_auto_threshold, QtCore.SIGNAL("clicked()"), self.auto_threshold) QtCore.QObject.connect(self.ui.radioButton_normal, QtCore.SIGNAL("toggled(bool)"), self.generate_view) QtCore.QObject.connect(self.ui.doubleSpinBox_threshold, QtCore.SIGNAL("valueChanged(const QString&)"), self.update_thresh) QtCore.QObject.connect(self.ui.comboBox_test_num, QtCore.SIGNAL("currentIndexChanged(const QString&)"), self.load_traces) QtCore.QObject.connect(self.ui.comboBox_trace, QtCore.SIGNAL("currentIndexChanged(const QString&)"), self.load_reps) QtCore.QObject.connect(self.ui.comboBox_rep, QtCore.SIGNAL("currentIndexChanged(const QString&)"), self.load_channels) QtCore.QObject.connect(self.ui.comboBox_channel, QtCore.SIGNAL("currentIndexChanged(const QString&)"), self.generate_view) QtCore.QObject.connect(self.ui.checkBox_custom_window, QtCore.SIGNAL("toggled(bool)"), self.update_window) QtCore.QObject.connect(self.ui.doubleSpinBox_xmax, QtCore.SIGNAL("valueChanged(const QString&)"), self.update_window) QtCore.QObject.connect(self.ui.doubleSpinBox_xmin, QtCore.SIGNAL("valueChanged(const QString&)"), self.update_window) QtCore.QObject.connect(self.ui.doubleSpinBox_ymax, QtCore.SIGNAL("valueChanged(const QString&)"), self.update_window) QtCore.QObject.connect(self.ui.doubleSpinBox_ymin, QtCore.SIGNAL("valueChanged(const QString&)"), self.update_window) self.ui.view.sigRangeChanged.connect(self.update_view_range) self.ui.view.threshLine.sigPositionChangeFinished.connect(self.update_thresh2) def browse(self): self.ui.comboBox_test_num.clear() QtGui.QFileDialog(self) self.filename = QtGui.QFileDialog.getOpenFileName() self.ui.lineEdit_file_name.setText(self.filename) # If the filename is not blank, attempt to extract test numbers and place them into the combobox if self.filename != '': if '.hdf5' in self.filename: try: h_file = h5py.File(unicode(self.filename), 'r') except IOError: self.add_message('Error: I/O Error') self.ui.label_test_num.setEnabled(False) self.ui.label_comments.setEnabled(False) self.ui.lineEdit_comments.setEnabled(False) self.ui.lineEdit_comments.setText('') self.ui.comboBox_test_num.setEnabled(False) return tests = {} for key in h_file.keys(): if 'segment' in key: for test in h_file[key].keys(): tests[test] = int(test.replace('test_', '')) sorted_tests = sorted(tests.items(), key=operator.itemgetter(1)) for test in sorted_tests: self.ui.comboBox_test_num.addItem(test[0]) self.ui.label_test_num.setEnabled(True) self.ui.label_comments.setEnabled(True) self.ui.lineEdit_comments.setEnabled(True) self.ui.comboBox_test_num.setEnabled(True) h_file.close() else: self.add_message('Error: Must select a .hdf5 file.') self.ui.label_test_num.setEnabled(False) self.ui.label_comments.setEnabled(False) self.ui.lineEdit_comments.setEnabled(False) self.ui.lineEdit_comments.setText('') self.ui.comboBox_test_num.setEnabled(False) return else: self.add_message('Error: Must select a file to open.') self.ui.label_test_num.setEnabled(False) self.ui.label_comments.setEnabled(False) self.ui.lineEdit_comments.setEnabled(False) self.ui.lineEdit_comments.setText('') self.ui.comboBox_test_num.setEnabled(False) return def auto_threshold(self): thresh_fraction = 0.7 filename = self.filename = self.ui.lineEdit_file_name.text() # Validate filename if self.valid_filename(filename): h_file = h5py.File(unicode(self.filename), 'r') target_test = self.ui.comboBox_test_num.currentText() else: return # Find target segment for segment in h_file.keys(): for test in h_file[segment].keys(): if target_test == test: target_seg = segment target_test = test trace_data = h_file[target_seg][target_test].value if len(trace_data.shape) == 4: trace_data = trace_data.squeeze() # Still shape of 4 if len(trace_data.shape) == 4: target_chan = int(self.ui.comboBox_channel.currentText().replace('channel_', '')) - 1 trace_data = trace_data[:, :, target_chan, :] trace_data = trace_data.squeeze() # Compute threshold from average maximum of traces max_trace = [] for n in range(len(trace_data[1, :, 0])): max_trace.append(np.max(np.abs(trace_data[1, n, :]))) average_max = np.array(max_trace).mean() thresh = thresh_fraction * average_max self.ui.doubleSpinBox_threshold.setValue(thresh) self.update_thresh() h_file.close() def generate_view(self): filename = self.filename = self.ui.lineEdit_file_name.text() # Validate filename if self.valid_filename(filename): h_file = h5py.File(unicode(self.filename), 'r') target_test = self.ui.comboBox_test_num.currentText() else: return # clear view self.clear_view() if self.ui.radioButton_normal.isChecked(): self.ui.view.invertPolarity(False) if self.ui.radioButton_inverse.isChecked(): self.ui.view.invertPolarity(True) for key in h_file.keys(): if 'segment' in key: for test in h_file[key].keys(): if target_test == test: target_seg = key target_test = test # Makes the assumption that all of the traces are of the same type stim_info = eval(h_file[target_seg][target_test].attrs['stim']) self.ui.label_stim_type.setText(stim_info[1]['components'][0]['stim_type']) fs = h_file[target_seg].attrs['samplerate_ad'] target_trace = [] target_rep = [] target_chan = [] # Get the values from the combo boxes self.ui.comboBox_test_num.currentText() if self.ui.comboBox_trace.currentText() != '': target_trace = int(self.ui.comboBox_trace.currentText().replace('trace_', '')) - 1 if self.ui.comboBox_rep.currentText() != 'All' and self.ui.comboBox_rep.currentText() != '': target_rep = int(self.ui.comboBox_rep.currentText().replace('rep_', '')) - 1 if self.ui.comboBox_channel.currentText() != '': target_chan = int(self.ui.comboBox_channel.currentText().replace('channel_', '')) - 1 test_data = h_file[target_seg][target_test].value # Get the presentation data depending on if there is a channel field or not if len(test_data.shape) == 4: presentation = test_data[target_trace, target_rep, target_chan, :] elif len(test_data.shape) == 3: presentation = test_data[target_trace, target_rep, :] len_presentation = len(presentation) # Get the length of the window and length of presentation depending on if all is selected or not if len_presentation != 0: window = len(presentation) / float(fs) else: if len(test_data.shape) == 4: window = len(test_data[0, 0, 0, :]) / float(fs) len_presentation = len(test_data[0, 0, 0, :]) elif len(test_data.shape) == 3: window = len(test_data[0, 0, :]) / float(fs) len_presentation = len(test_data[0, 0, :]) xlist = np.linspace(0, float(window), len_presentation) ylist = presentation # Set window size if not self.ui.checkBox_custom_window.checkState(): if len(presentation) > 0: ymin = min(presentation) ymax = max(presentation) else: ymin = 0 ymax = 0 if len(test_data.shape) == 3: rep_len = test_data.shape[1] for i in range(rep_len): if min(test_data[target_trace, i, :]) < ymin: ymin = min(test_data[target_trace, i, :]) if max(test_data[target_trace, i, :]) > ymax: ymax = max(test_data[target_trace, i, :]) else: rep_len = test_data.shape[1] for i in range(rep_len): if min(test_data[target_trace, i, target_chan, :]) < ymin: ymin = min(test_data[target_trace, i, target_chan, :]) if max(test_data[target_trace, i, target_chan, :]) > ymax: ymax = max(test_data[target_trace, i, target_chan, :]) self.ui.view.setXRange(0, window, 0) self.ui.view.setYRange(ymin, ymax, 0.1) if self.ui.comboBox_rep.currentText() == 'All': self.ui.view.tracePlot.clear() # Fix xlist to be the length of presentation if len(test_data.shape) == 3: self.ui.view.addTraces(xlist, test_data[target_trace, :, :]) else: self.ui.view.addTraces(xlist, test_data[target_trace, :, target_chan, :]) self.ui.radioButton_normal.setChecked(True) self.ui.radioButton_normal.setEnabled(False) self.ui.radioButton_inverse.setEnabled(False) else: self.ui.view.updateData(axeskey='response', x=xlist, y=ylist) self.ui.radioButton_normal.setEnabled(True) self.ui.radioButton_inverse.setEnabled(True) h_file.close() def valid_filename(self, filename): # Validate filename if filename != '': if '.hdf5' in filename: try: temp_file = h5py.File(unicode(self.filename), 'r') temp_file.close() except IOError: self.add_message('Error: I/O Error') return False else: self.add_message('Error: Must select a .hdf5 file.') return False else: self.add_message('Error: Must select a file to open.') return False return True def load_traces(self): self.ui.comboBox_trace.clear() # Validate filename if self.valid_filename(self.filename): h_file = h5py.File(unicode(self.filename), 'r') target_test = self.ui.comboBox_test_num.currentText() else: self.ui.label_trace.setEnabled(False) self.ui.comboBox_trace.setEnabled(False) return if self.ui.comboBox_test_num.currentText() == 'All' or self.ui.comboBox_test_num.currentText() == '': self.ui.label_trace.setEnabled(False) self.ui.comboBox_trace.setEnabled(False) self.ui.comboBox_trace.clear() h_file.close() return else: self.ui.label_trace.setEnabled(True) self.ui.comboBox_trace.setEnabled(True) for key in h_file.keys(): if 'segment' in key: for test in h_file[key].keys(): if target_test == test: target_seg = key target_test = test traces = h_file[target_seg][target_test].value.shape[0] for i in range(traces): self.ui.comboBox_trace.addItem('trace_' + str(i+1)) self.ui.label_trace.setEnabled(True) self.ui.comboBox_trace.setEnabled(True) comment = h_file[target_seg].attrs['comment'] self.ui.lineEdit_comments.setText(comment) h_file.close() def load_reps(self): self.ui.comboBox_rep.clear() # Validate filename if self.valid_filename(self.filename): h_file = h5py.File(unicode(self.filename), 'r') target_test = self.ui.comboBox_test_num.currentText() else: self.ui.label_rep.setEnabled(False) self.ui.comboBox_rep.setEnabled(False) return if self.ui.comboBox_trace.currentText() == 'All' or self.ui.comboBox_trace.currentText() == '': self.ui.label_rep.setEnabled(False) self.ui.comboBox_rep.setEnabled(False) self.ui.comboBox_rep.clear() h_file.close() return else: self.ui.label_rep.setEnabled(True) self.ui.comboBox_rep.setEnabled(True) self.ui.comboBox_rep.addItem('All') for key in h_file.keys(): if 'segment' in key: for test in h_file[key].keys(): if target_test == test: target_seg = key target_test = test reps = h_file[target_seg][target_test].value.shape[1] for i in range(reps): self.ui.comboBox_rep.addItem('rep_' + str(i+1)) h_file.close() def load_channels(self): self.ui.comboBox_channel.clear() # Validate filename if self.valid_filename(self.filename): h_file = h5py.File(unicode(self.filename), 'r') target_test = self.ui.comboBox_test_num.currentText() else: self.ui.label_rep.setEnabled(False) self.ui.comboBox_rep.setEnabled(False) return if self.ui.comboBox_test_num.count() == 0: h_file.close() self.clear_view() return for key in h_file.keys(): if 'segment' in key: for test in h_file[key].keys(): if target_test == test: target_seg = key target_test = test if len(h_file[target_seg][target_test].value.shape) > 3: channels = h_file[target_seg][target_test].value.shape[2] else: channels = 1 if channels == 1: self.ui.comboBox_channel.addItem('channel_1') else: for i in range(channels): self.ui.comboBox_channel.addItem('channel_' + str(i+1)) if self.ui.comboBox_rep.currentText() == '' or self.ui.comboBox_channel.count() < 2: self.ui.label_channel.setEnabled(False) self.ui.comboBox_channel.setEnabled(False) self.ui.comboBox_channel.clear() else: self.ui.label_channel.setEnabled(True) self.ui.comboBox_channel.setEnabled(True) if self.ui.comboBox_trace.currentText() != '' and self.ui.comboBox_rep.currentText() != '' and self.ui.comboBox_channel != '': self.generate_view() h_file.close() def update_thresh(self): self.ui.view.setThreshold(self.ui.doubleSpinBox_threshold.value()) self.ui.view.update_thresh() def update_thresh2(self): self.ui.doubleSpinBox_threshold.setValue(self.ui.view.getThreshold()) def update_window(self): if self.ui.checkBox_custom_window.checkState(): self.ui.view.setXRange(self.ui.doubleSpinBox_xmin.value(), self.ui.doubleSpinBox_xmax.value(), 0) self.ui.view.setYRange(self.ui.doubleSpinBox_ymin.value(), self.ui.doubleSpinBox_ymax.value(), 0) def update_view_range(self): view_range = self.ui.view.visibleRange() self.ui.doubleSpinBox_xmin.setValue(view_range.left()) self.ui.doubleSpinBox_xmax.setValue(view_range.right()) self.ui.doubleSpinBox_ymin.setValue(view_range.top()) self.ui.doubleSpinBox_ymax.setValue(view_range.bottom()) def count_spikes(self): pass def generate_rasters(self): filename = self.filename = self.ui.lineEdit_file_name.text() # Validate filename if not self.valid_filename(filename): return target_test = self.ui.comboBox_test_num.currentText() thresh = self.ui.doubleSpinBox_threshold.value() h_file = h5py.File(unicode(filename), 'r') # Find target segment for segment in h_file.keys(): for test in h_file[segment].keys(): if target_test == test: target_seg = segment target_test = test fs = h_file[target_seg].attrs['samplerate_ad'] reps = h_file[target_seg][target_test].attrs['reps'] start_time = h_file[target_seg][target_test].attrs['start'] trace_data = h_file[target_seg][target_test].value if len(trace_data.shape) == 4: pass stim_info = eval(h_file[target_seg][target_test].attrs['stim']) duration = trace_data.shape[-1] / fs * 1000 if stim_info[1]['components'][0]['stim_type'] != 'Pure Tone': self.add_message('Cannot generate raster with stim type "' + str(stim_info[1]['components'][0]['stim_type']) + '".') h_file.close() return autoRasters = {} for tStim in range(1, len(stim_info)): freq = int(stim_info[tStim]['components'][0]['frequency']) spl = int(stim_info[tStim]['components'][0]['intensity']) trace_key = str(freq) + '_' + str(spl) num_reps = trace_data.shape[1] # ???: Same as reps = h_file[target_seg][target_test].attrs['reps'] spikeTrains = pd.DataFrame([]) nspk = 0 for tRep in range(reps): if len(trace_data.shape) == 3: trace = trace_data[tStim][tRep] pass elif len(trace_data.shape) == 4: tchan = int(self.ui.comboBox_channel.currentText().replace('channel_', '')) - 1 trace = trace_data[tStim][tRep][tchan] pass else: self.add_message('Cannot handle trace_data of shape: ' + str(trace_data.shape)) return spike_times = 1000 * np.array(get_spike_times(trace, thresh, fs)) spike_times_s = pd.Series(spike_times) if spike_times_s.size > nspk: spikeTrains = spikeTrains.reindex(spike_times_s.index) nspk = spike_times_s.size spikeTrains[str(tRep)] = spike_times_s autoRasters[trace_key] = spikeTrains h_file.close() return autoRasters def graph_spike_rates(self): self.dialog = SpikeRatesDialog() filename = self.filename = self.ui.lineEdit_file_name.text() # Validate filename if not self.valid_filename(filename): return self.dialog.populate_checkboxes(filename) self.dialog.setWindowIcon(QtGui.QIcon('images/horsey.ico')) self.dialog.setWindowTitle('Sparkle Analysis - Spike Rates') self.dialog.show() def graph_multi_io_test(self): self.dialog = MultiIODialog() filename = self.filename = self.ui.lineEdit_file_name.text() # Validate filename if not self.valid_filename(filename): return self.dialog.populate_checkboxes(filename, self.ui.doubleSpinBox_threshold.value()) self.dialog.setWindowIcon(QtGui.QIcon('images/horsey.ico')) self.dialog.setWindowTitle('Sparkle Analysis - I/O Test') self.dialog.show() def graph_abr(self): self.dialog = ABRDialog() filename = self.filename = self.ui.lineEdit_file_name.text() # Validate filename if not self.valid_filename(filename): return self.dialog.populate_boxes(filename) self.dialog.setWindowIcon(QtGui.QIcon('images/horsey.ico')) self.dialog.setWindowTitle('Sparkle Analysis - ABRs') self.dialog.show() def graph_tuning_curve(self): self.dialog = TuningCurveDialog() filename = self.filename = self.ui.lineEdit_file_name.text() # Validate filename if not self.valid_filename(filename): return self.dialog.populate_boxes(filename) self.dialog.set_threshold(self.ui.doubleSpinBox_threshold.value()) self.dialog.set_test_num(self.ui.comboBox_test_num.currentIndex()) self.dialog.set_channel_num(self.ui.comboBox_channel.currentIndex()) self.dialog.set_trace_num(self.ui.comboBox_trace.currentIndex()) self.dialog.setWindowIcon(QtGui.QIcon('images/horsey.ico')) self.dialog.setWindowTitle('Sparkle Analysis - Tuning Curve Generator') self.dialog.show() def graph_io_test(self): filename = self.filename = self.ui.lineEdit_file_name.text() # Validate filename if not self.valid_filename(filename): return target_test = self.ui.comboBox_test_num.currentText() thresh = self.ui.doubleSpinBox_threshold.value() h_file = h5py.File(unicode(filename), 'r') # Find target segment for segment in h_file.keys(): for test in h_file[segment].keys(): if target_test == test: target_seg = segment target_test = test fs = h_file[target_seg].attrs['samplerate_ad'] reps = h_file[target_seg][target_test].attrs['reps'] start_time = h_file[target_seg][target_test].attrs['start'] trace_data = h_file[target_seg][target_test].value if len(trace_data.shape) == 4: pass stim_info = eval(h_file[target_seg][target_test].attrs['stim']) duration = trace_data.shape[-1] / fs * 1000 autoRasters = {} for tStim in range(1, len(stim_info)): spl = int(stim_info[tStim]['components'][0]['intensity']) traceKey = 'None_' + str(spl).zfill(2) spikeTrains = pd.DataFrame([]) nspk = 0 for tRep in range(reps): if len(trace_data.shape) == 3: trace = trace_data[tStim][tRep] pass elif len(trace_data.shape) == 4: tchan = int(self.ui.comboBox_channel.currentText().replace('channel_', '')) - 1 trace = trace_data[tStim][tRep][tchan] pass else: self.add_message('Cannot handle trace_data of shape: ' + str(trace_data.shape)) return spike_times = 1000 * np.array(get_spike_times(trace, thresh, fs)) spike_times_s = pd.Series(spike_times) if spike_times_s.size >= nspk: spikeTrains = spikeTrains.reindex(spike_times_s.index) nspk = spike_times_s.size spikeTrains[str(tRep)] = spike_times_s autoRasters[traceKey] = spikeTrains rasters = autoRasters h_file.close() tuning = [] sortedKeys = sorted(rasters.keys()) for traceKey in sortedKeys: spl = int(traceKey.split('_')[-1]) raster = rasters[traceKey] res = ResponseStats(raster) tuning.append({'intensity': spl, 'response': res[0], 'responseSTD': res[1]}) tuningCurves = pd.DataFrame(tuning) tuningCurves.plot(x='intensity', y='response', yerr='responseSTD', capthick=1, label=str(target_test)) plt.legend(loc='upper left', fontsize=12, frameon=True) sns.despine() plt.grid(False) plt.xlabel('Intensity (dB)', size=14) plt.ylabel('Response Rate (Hz)', size=14) plt.tick_params(axis='both', which='major', labelsize=14) plt.title(str.split(str(filename), '/')[-1].replace('.hdf5', '') + ' ' + str(self.ui.comboBox_test_num.currentText()).replace('test_', 'Test ')) plt.show() def graph_raster(self): filename = self.filename = self.ui.lineEdit_file_name.text() # Validate filename if not self.valid_filename(filename): return target_test = self.ui.comboBox_test_num.currentText() thresh = self.ui.doubleSpinBox_threshold.value() h_file = h5py.File(unicode(filename), 'r') # Find target segment for segment in h_file.keys(): for test in h_file[segment].keys(): if target_test == test: target_seg = segment target_test = test target_trace = int(self.ui.comboBox_trace.currentText().replace('trace_', '')) - 1 fs = h_file[target_seg].attrs['samplerate_ad'] reps = h_file[target_seg][target_test].attrs['reps'] start_time = h_file[target_seg][target_test].attrs['start'] trace_data = h_file[target_seg][target_test].value if len(trace_data.shape) == 4: pass stim_info = eval(h_file[target_seg][target_test].attrs['stim']) duration = trace_data.shape[-1] / fs * 1000 autoRasters = {} tStim = target_trace spikeTrains = pd.DataFrame([]) nspk = 0 for tRep in range(reps): if len(trace_data.shape) == 3: trace = trace_data[tStim][tRep] pass elif len(trace_data.shape) == 4: tchan = int(self.ui.comboBox_channel.currentText().replace('channel_', '')) - 1 trace = trace_data[tStim][tRep][tchan] pass else: self.add_message('Cannot handle trace_data of shape: ' + str(trace_data.shape)) h_file.close() return spike_times = 1000 * np.array(get_spike_times(trace, thresh, fs)) spike_times_s = pd.Series(spike_times) if spike_times_s.size > nspk: spikeTrains = spikeTrains.reindex(spike_times_s.index) nspk = spike_times_s.size spikeTrains[str(tRep)] = spike_times_s rasters = spikeTrains h_file.close() if len(rasters.shape) > 1: spks = np.array([]) trns = np.array([]) for trnNum in range(len(rasters.columns)): spkTrn = np.array(rasters.iloc[:, trnNum].dropna()) trns = np.hstack([trns, (trnNum + 1) * np.ones(len(spkTrn))]) spks = np.hstack([spks, spkTrn]) # --- Raster plot of spikes --- sns.set_style("white") sns.set_style("ticks") raster_f = plt.figure(figsize=(8, 2)) sns.despine() plt.grid(False) ax = plt.scatter(spks, trns, marker='s', s=5, color='k') plt.ylim(len(rasters.columns) + 0.5, 0.5) plt.xlim(0, duration) plt.xlabel('Time (ms)') plt.ylabel('Presentation cycle') plt.title(str.split(str(filename), '/')[-1].replace('.hdf5', '') + ' ' + str(self.ui.comboBox_test_num.currentText()).replace('test_', 'Test ')) plt.tick_params(axis='both', which='major', labelsize=14) raster_f.show() else: self.add_message('Only spike timing information provided, requires presentation numbers for raster.') return ax def graph_historgram(self): filename = self.filename = self.ui.lineEdit_file_name.text() # Validate filename if not self.valid_filename(filename): return target_test = self.ui.comboBox_test_num.currentText() thresh = self.ui.doubleSpinBox_threshold.value() h_file = h5py.File(unicode(filename), 'r') # Find target segment for segment in h_file.keys(): for test in h_file[segment].keys(): if target_test == test: target_seg = segment target_test = test target_trace = int(self.ui.comboBox_trace.currentText().replace('trace_', '')) - 1 fs = h_file[target_seg].attrs['samplerate_ad'] reps = h_file[target_seg][target_test].attrs['reps'] start_time = h_file[target_seg][target_test].attrs['start'] trace_data = h_file[target_seg][target_test].value if len(trace_data.shape) == 4: pass stim_info = eval(h_file[target_seg][target_test].attrs['stim']) duration = trace_data.shape[-1] / fs * 1000 autoRasters = {} tStim = target_trace spikeTrains = pd.DataFrame([]) nspk = 0 for tRep in range(reps): if len(trace_data.shape) == 3: trace = trace_data[tStim][tRep] pass elif len(trace_data.shape) == 4: tchan = int(self.ui.comboBox_channel.currentText().replace('channel_', '')) - 1 trace = trace_data[tStim][tRep][tchan] pass else: self.add_message('Cannot handle trace_data of shape: ' + str(trace_data.shape)) return spike_times = 1000 * np.array(get_spike_times(trace, thresh, fs)) spike_times_s = pd.Series(spike_times) if spike_times_s.size > nspk: spikeTrains = spikeTrains.reindex(spike_times_s.index) nspk = spike_times_s.size spikeTrains[str(tRep)] = spike_times_s rasters = spikeTrains h_file.close() if len(rasters.shape) > 1: spks = np.array([]) trns = np.array([]) for trnNum in range(len(rasters.columns)): spkTrn = np.array(rasters.iloc[:, trnNum].dropna()) trns = np.hstack([trns, (trnNum + 1) * np.ones(len(spkTrn))]) spks = np.hstack([spks, spkTrn]) spikeTimes = rasters.stack() else: spikeTimes = rasters.dropna() # --- Histogram of spike times (1 ms bins)--- sns.set_style("white") sns.set_style("ticks") histogram_f = plt.figure(figsize=(8, 3)) axHist = spikeTimes.hist(bins=int(duration / 1), range=(0, duration)) # , figsize=(8,3)) sns.despine() plt.xlim(0, duration) plt.xlabel('Time (ms)', size=14) plt.ylabel('Number of spikes', size=14) plt.title(str.split(str(filename), '/')[-1].replace('.hdf5', '') + ' ' + str(self.ui.comboBox_test_num.currentText()).replace('test_', 'Test ')) plt.tick_params(axis='both', which='major', labelsize=14) plt.grid(False) histogram_f.show() return axHist def graph_abr_old(self): # Assumes there will only be one channel print 'Graphing ABR' filename = self.filename = self.ui.lineEdit_file_name.text() # Validate filename if not self.valid_filename(filename): return # clear view self.clear_view() target_test = self.ui.comboBox_test_num.currentText() h_file = h5py.File(unicode(filename), 'r') # Find target segment for segment in h_file.keys(): for test in h_file[segment].keys(): if target_test == test: target_seg = segment target_test = test # Makes the assumption that all of the traces are of the same type stim_info = eval(h_file[target_seg][target_test].attrs['stim']) self.ui.label_stim_type.setText(stim_info[1]['components'][0]['stim_type']) fs = h_file[target_seg].attrs['samplerate_ad'] trace_data = h_file[target_seg][target_test].value if len(trace_data.shape) == 4: pass samples = trace_data.shape[-1] traces = trace_data.shape[0] reps = trace_data.shape[1] average = np.empty(samples) abr = np.empty(shape=(traces, 1, 1, samples)) intensity = [] # Average the rep data into one trace if len(trace_data.shape) == 4: for t in range(traces): for s in range(samples): # print s for r in range(reps): # print r average[s] += trace_data[0, r, 0, s] average[s] /= reps + 1 abr[t, 0, 0, s] = average[s] intensity.append(stim_info[t]['components'][0]['intensity']) elif len(trace_data.shape) == 3: for t in range(traces): for s in range(samples): # print s for r in range(reps): # print r average[s] += trace_data[0, r, s] average[s] /= reps + 1 abr[t, 0, 0, s] = average[s] intensity.append(stim_info[t]['components'][0]['intensity']) else: self.add_message('Cannot handle trace_data of shape: ' + str(trace_data.shape)) return self.ui.view.tracePlot.clear() # Get the presentation data depending on if there is a channel field or not if len(abr.shape) == 4: presentation = abr[[], [], [], :] elif len(abr.shape) == 3: presentation = abr[[], [], :] len_presentation = len(presentation) # Get the length of the window and length of presentation depending on if all is selected or not if len_presentation != 0: window = len(presentation) / float(fs) else: if len(abr.shape) == 4: window = len(abr[0, 0, 0, :]) / float(fs) len_presentation = len(abr[0, 0, 0, :]) elif len(abr.shape) == 3: window = len(abr[0, 0, :]) / float(fs) len_presentation = len(abr[0, 0, :]) xlist = np.linspace(0, float(window), len_presentation) ylist = presentation # Fix xlist to be the length of presentation if len(abr.shape) == 3: self.ui.view.addTracesABR(xlist, abr[:, 0, :], intensity) else: self.ui.view.addTracesABR(xlist, abr[:, 0, 0, :], intensity) self.ui.radioButton_normal.setChecked(True) self.ui.radioButton_normal.setEnabled(False) self.ui.radioButton_inverse.setEnabled(False) def GetFreqsAttns(self, freqTuningHisto): # Frequency Tuning Curve method """ Helper method for ShowSTH() to organize the frequencies in ascending order separated for each intensity. :param freqTuningHisto: dict of pandas.DataFrames with spike data :type freqTuningHisto: str :returns: ordered list of frequencies (DataFrame keys()) numpy array of frequencies numpy array of intensities """ freqs = np.array([]) attns = np.array([]) for histoKey in list(freqTuningHisto): if histoKey != 'None_None': freq = histoKey.split('_')[0] freqs = np.hstack([freqs, float(freq) / 1000]) attn = histoKey.split('_')[1] attns = np.hstack([attns, float(attn)]) attnCount = stats.itemfreq(attns) freqs = np.unique(freqs) attns = np.unique(attns) if np.max(attnCount[:, 1]) != np.min(attnCount[:, 1]): abortedAttnIdx = np.where(attnCount[:, 1] != np.max(attnCount[:, 1])) attns = np.delete(attns, abortedAttnIdx) orderedKeys = [] for attn in attns: freqList = [] for freq in freqs: key = str(int(freq * 1000)) + '_' + str(int(attn)) freqList.append(key) orderedKeys.append(freqList) return orderedKeys, freqs, attns def add_message(self, message): self.message_num += 1 self.ui.textEdit.append('[' + str(self.message_num) + ']: ' + message + '\n') def clear_view(self): self.ui.view.clearTraces() self.ui.view.clearMouse() self.ui.view.clearFocus() self.ui.view.clearMask() self.ui.view.clearData(axeskey='response') self.ui.view.tracePlot.clear() self.ui.view.rasterPlot.clear() self.ui.view.stimPlot.clear() self.ui.view.trace_stash = []
class JottaGui(QtGui.QMainWindow): loginStatusChanged = QtCore.pyqtSignal(bool) downloading = QtCore.pyqtSignal(bool) # a boolean flag to indicate download activity progress = QtCore.pyqtSignal(int) # an integer (0-100) to indicate progress def __init__(self, app, parent=None): super(JottaGui, self).__init__(parent) self.app = app self.ui = Ui_MainWindow() self.ui.setupUi(self) self.jottaModel = None self.loginStatusChanged.connect(self.populateDevices) self.ui.listDevices.currentIndexChanged[str].connect(self.populateJottaRoot) __preview = QtGui.QWidget() __layout = QtGui.QVBoxLayout() __thumbnail = QtGui.QLabel(__preview) __thumbnail.setObjectName('thumbnail') __layout.addWidget(__thumbnail) __details = QtGui.QLabel(__preview) __details.setObjectName('details') __layout.addWidget(__details) self.btnget = QtGui.QPushButton('Get') __layout.addWidget(self.btnget) __preview.setLayout(__layout) self.btnget.clicked.connect(self.get) self.ui.jottafsView.setPreviewWidget(__preview) self.ui.actionLogin.triggered.connect(self.showModalLogin) self.downloading.connect(self.downloadActive) self.progress.connect(lambda x: self.ui.progressBar.setValue(x)) def login(self, username, password): try: self.jfs = jottalib.JFS.JFS(username, password) self.loginStatusChanged.emit(True) except Exception as e: logging.exception(e) self.loginStatusChanged.emit(False) def showModalLogin(self): usernamepassword, ok = LoginDialog.getLogin() if ok: u,p = usernamepassword logging.debug('Got login %s', u) self.login(u, p) def populateChildNodes(self, idx, oldidx): logging.debug('populateChildNodes(self, %s, %s)' % (idx, oldidx)) self.jottaModel.populateChildNodes(idx) # pass it on to model to expand children self.showJottaDetails(idx) def populateDevices(self, loggedin): # devices = self.jfs.devices() if not loggedin: self.ui.listDevices.clear() else: self.ui.listDevices.addItems([d.name for d in self.jfs.devices]) self.populateJottaRoot(unicode(self.ui.listDevices.currentText())) def populateJottaRoot(self, device): self.jottaModel = jottalib.qt.JFSModel(self.jfs, '/%s' % device) self.ui.jottafsView.setModel(self.jottaModel) self.ui.jottafsView.selectionModel().currentChanged.connect(self.populateChildNodes) def showJottaDetails(self, idx): # some item was single clicked/selected, show details self.progress.emit(0) item = self.jottaModel.itemFromIndex(idx) logging.debug('selected: %s' % unicode(item.text())) __details = self.ui.jottafsView.previewWidget() if isinstance(item, jottalib.qt.JFSFileNode): s = """<b>Name</b>: %s<br><b>Size:</b> %s<br> <b>Created</b>: %s<br><b>Modified</b>:%s""" % \ (item.obj.name, sizeof_fmt(item.obj.size), item.obj.created, item.obj.modified) else: s = """<b>Name</b>: %s<br>""" % (item.obj.name,) __details.findChild(QtGui.QLabel, 'details').setText(s) __preview = __details.findChild(QtGui.QLabel, 'thumbnail') __coverPix = QtGui.QPixmap() if isinstance(item, jottalib.qt.JFSFileNode) and item.obj.is_image(): logging.debug('%s is an image, get thumb' % item.obj.name) __coverPix.loadFromData(item.obj.thumb(jottalib.JFS.JFSFile.MEDIUMTHUMB)) __preview.setPixmap(__coverPix) def get(self): "Download current selected resource" # TODO find dlfolder based on content. # QDesktopServices::DesktopLocation 0 Returns the user's desktop directory. # QDesktopServices::DocumentsLocation 1 Returns the user's document. # QDesktopServices::FontsLocation 2 Returns the user's fonts. # QDesktopServices::ApplicationsLocation 3 Returns the user's applications. # QDesktopServices::MusicLocation 4 Returns the users music. # QDesktopServices::MoviesLocation 5 Returns the user's movies. # QDesktopServices::PicturesLocation 6 Returns the user's pictures. # QDesktopServices::TempLocation 7 Returns the system's temporary directory. # QDesktopServices::HomeLocation 8 Returns the user's home directory. dlfolder = QtGui.QDesktopServices.storageLocation(QtGui.QDesktopServices.PicturesLocation) selected = [self.jottaModel.itemFromIndex(idx) for idx in self.ui.jottafsView.selectedIndexes()] self.progress.emit(0) self.threads = [] self.downloads = [] self.downloading.emit(False) for item in selected: if isinstance(item, jottalib.qt.JFSFileNode): logging.debug('downloading %s ...' % item.obj.name) base,ext = os.path.splitext(item.obj.name) p = os.path.join(dlfolder, '%s-%s%s' % (base, item.obj.uuid, ext)) T = QtCore.QThread() down = Downloader(item.obj, p) down.moveToThread(T) down.finished.connect(T.quit) down.finished.connect(lambda: self.notify("%s downloaded to %s" % (item.obj.name, p))) down.finished.connect(lambda: self.downloading.emit(False)) down.progress.connect(self.ui.progressBar.setValue) T.started.connect(down.stream) self.downloading.emit(True) T.start() self.threads.append(T) self.downloads.append(down) def notify(self, msg): "Popup a non-intrusive textual notification" logging.info(msg) if not QtGui.QSystemTrayIcon.supportsMessages(): return False pop = QtGui.QSystemTrayIcon() pop.showMessage(u'JottaGui', msg) def downloadActive(self, boolean): "Called when a download is active and when it finishes" self.btnget.setText('Downloading...' if boolean else 'Get') self.btnget.setDisabled(boolean) def run(self, app): self.show() sys.exit(app.exec_()) def setLanguage(self, language): if self.translator is not None: self.app.removeTranslator(self.translator) else: self.translator = Core.QTranslator(self.app) print "loading translation: odometer_%s" % language self.translator.load(':data/translation_%s' % language) self.app.installTranslator(self.translator) # also for qt strings if self.translatorQt is not None: self.app.removeTranslator(self.translatorQt) else: self.translatorQt = Core.QTranslator(self.app) print "loading Qttranslation: qt_%s" % language self.translatorQt.load(':data/qt_%s' % language) self.app.installTranslator(self.translatorQt)
class MainWindow(QMainWindow): def __init__(self): super(MainWindow, self).__init__() self.settings = QSettings("IK", "Netshut") self.th = None self.ui = Ui_MainWindow() self.ui.setupUi(self) self.init_ui() self.center() # Compile Re's self._pat_arp = re.compile( "^(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\s+(\S+)", re.MULTILINE) self._pat_gip = re.compile("inet\s(.+)/") self._cut_hosts = {} self._hosts = {} self._hosts_names = {} self._gw = self.get_gateway() self._gw_mac = "" self._iface = "wlp2s0" self._mac = "" self._ip = self.get_ip() self.prompt_iface() self.ui.lbl_gw.setText("<b>{}</b>".format(self._gw)) self.ui.lbl_mac.setText("<b>{}</b>".format(self._mac)) self.ui.lbl_ip.setText("<b>{}</b>".format(self._ip)) self.ui.lbl_iface.setText("<b>{}</b>".format(self._iface)) self.cut_all = False self.open_config_file() self.ui.act_scan.trigger() def open_config_file(self): if os.path.exists(PWD + "/config"): f = open(PWD + "/config") self._hosts_names = json.load(f) f.close() def closeEvent(self, event): msg = QMessageBox() msg.setWindowTitle("NetShut") msg.setText("Are you sure you want to quit NetShut ?") msg.setInformativeText("All cut hosts will be resumed") msg.setStandardButtons(QMessageBox.Yes | QMessageBox.No) msg.setIcon(QMessageBox.Warning) if msg.exec() == QMessageBox.Yes: self.resume_all_hosts() with open("config", mode="w") as f: json.dump(self._hosts_names, f) event.accept() else: event.ignore() def init_ui(self): self.setWindowTitle(TITLE) self.setWindowIcon(QIcon("img/icon.png")) self.ui.action_Help.setIcon(QIcon("img/help-circle.png")) self.ui.action_About.triggered.connect(self.act_about_triggered) self.ui.act_scan.triggered.connect(self.act_scan_triggered) self.ui.act_scan.setIcon(QIcon("img/scan.png")) self.ui.act_cut.setIcon(QIcon("img/cut_all.png")) self.ui.act_cut.triggered.connect(self.act_cutall_triggered) self.ui.tbl_hosts.setSelectionBehavior(QAbstractItemView.SelectRows) self.ui.tbl_hosts.verticalHeader().setVisible(False) self.ui.tbl_hosts.setColumnCount(TABLE_COLUMN_COUNT) self.ui.tbl_hosts.setHorizontalHeaderLabels([ "IP Address", "MAC Address", "Device Manufacturer", "Custom Name", "Status" ]) self.ui.tbl_hosts.setColumnWidth(0, 100) self.ui.tbl_hosts.setColumnWidth(1, 100) self.ui.tbl_hosts.setColumnWidth(2, 240) self.ui.tbl_hosts.setColumnWidth(3, 100) self.ui.tbl_hosts.setShowGrid(False) self.ui.tbl_hosts.itemChanged.connect(self.hosts_item_changed) self.ui.actionShow_Icons_Text.setData(Qt.ToolButtonTextUnderIcon) self.ui.actionShow_Icons.setData(Qt.ToolButtonIconOnly) self.ui.actionCustom_Name.setData(R_NAME) self.ui.actionIP_Address.setData(R_IP) self.ui.actionMAC_Address.setData(R_MAC) self.ui.actionDevice_Manifacturer.setData(R_MAC_MAN) self.ui.actionCustom_Name.setChecked( self.settings.value("tbl_show_{}".format(R_NAME), 1, type=int)) self.ui.actionIP_Address.setChecked( self.settings.value("tbl_show_{}".format(R_IP), 1, type=int)) self.ui.actionMAC_Address.setChecked( self.settings.value("tbl_show_{}".format(R_MAC), 1, type=int)) self.ui.actionDevice_Manifacturer.setChecked( self.settings.value("tbl_show_{}".format(R_MAC_MAN), 1, type=int)) group = QActionGroup(self) group.addAction(self.ui.actionShow_Icons) group.addAction(self.ui.actionShow_Icons_Text) group.triggered.connect(self.act_toolbar_show) group2 = QActionGroup(self) group2.setExclusive(False) group2.addAction(self.ui.actionCustom_Name) group2.addAction(self.ui.actionIP_Address) group2.addAction(self.ui.actionMAC_Address) group2.addAction(self.ui.actionDevice_Manifacturer) group2.triggered.connect(self.act_setting_show) for a in group2.actions(): if a.isChecked(): self.ui.tbl_hosts.showColumn(a.data()) else: self.ui.tbl_hosts.hideColumn(a.data()) if int(self.settings.value( "toolbar_show", Qt.ToolButtonIconOnly)) == Qt.ToolButtonIconOnly: self.ui.actionShow_Icons.setChecked(True) self.ui.toolBar.setToolButtonStyle(Qt.ToolButtonIconOnly) else: self.ui.actionShow_Icons_Text.setChecked(True) self.ui.toolBar.setToolButtonStyle(Qt.ToolButtonTextUnderIcon) def hosts_item_changed(self, item): if item.column() == R_NAME and not item.text() == "Not Set": self._hosts_names[self.ui.tbl_hosts.item( item.row(), R_MAC).text()] = item.text() def act_setting_show(self, action): a = "tbl_show_{}".format(action.data()) self.settings.setValue(a, int(action.isChecked())) if action.isChecked(): self.ui.tbl_hosts.showColumn(action.data()) else: self.ui.tbl_hosts.hideColumn(action.data()) def act_toolbar_show(self, action): self.settings.setValue("toolbar_show", action.data()) self.ui.toolBar.setToolButtonStyle(action.data()) def act_cutall_triggered(self): if self.cut_all: # Resume all hosts self.resume_all_hosts() self.cut_all = False self.ui.act_cut.setIcon(QIcon("img/cut_all.png")) self.ui.act_cut.setText("Cut All") else: # Cut all hosts self.cut_all_hosts() self.cut_all = True self.ui.act_cut.setIcon(QIcon("img/uncut_all.png")) self.ui.act_cut.setText("Resume All") def resume_all_hosts(self): for i, host_ip in enumerate(self._hosts): if host_ip in self._cut_hosts: btn = self.ui.tbl_hosts.cellWidget(i, R_STATUS) btn.setFocus() btn.click() def cut_all_hosts(self): for i, host_ip in enumerate(self._hosts): if host_ip not in self._cut_hosts: btn = self.ui.tbl_hosts.cellWidget(i, R_STATUS) btn.setFocus() btn.click() def get_ip(self): (s_code, s_out) = subprocess.getstatusoutput("ip addr show {}".format( self._iface)) try: return self._pat_gip.findall(s_out)[0] except IndexError: return "" def prompt_iface(self): ifaces_names = [] ifaces_macs = [] ifaces = QtNetwork.QNetworkInterface.allInterfaces() for i in ifaces: ifaces_names.append(str(i.name())) ifaces_macs.append(str(i.hardwareAddress())) if not self.settings.value("iface") or self.settings.value( "iface") not in ifaces_names: result, ok = QInputDialog.getItem( self, self.tr("Network Interfaces"), self.tr("Select your Interface:"), ifaces_names, 0, False) if ok: self._iface = result self._mac = ifaces_macs[ifaces_names.index(result)] self.settings.setValue("iface", self._iface) else: QMessageBox.critical(self, TITLE, "You must select an interface card") exit() else: self._iface = self.settings.value("iface") self._mac = ifaces_macs[ifaces_names.index(self._iface)] def get_gateway(self): (s_code, s_out) = subprocess.getstatusoutput("ip route list") try: gw_ip = s_out.split("\n")[0].split(" ")[2] except IndexError: print("COULD NOT GET GATEWAY IP") exit() return gw_ip def populate_model(self): self.ui.tbl_hosts.setRowCount(len(self._hosts)) for i, k in enumerate(self._hosts): item = QTableWidgetItem(k) item.setFlags(item.flags() & ~Qt.ItemIsEditable) self.ui.tbl_hosts.setItem(i, R_IP, item) item = QTableWidgetItem(self._hosts[k][0]) item.setFlags(item.flags() & ~Qt.ItemIsEditable) self.ui.tbl_hosts.setItem(i, R_MAC, item) item = QTableWidgetItem(self._hosts[k][1]) item.setFlags(item.flags() & ~Qt.ItemIsEditable) self.ui.tbl_hosts.setItem(i, R_MAC_MAN, item) self.ui.tbl_hosts.setItem( i, R_NAME, QTableWidgetItem( self._hosts_names.get(self._hosts[k][0], "Not Set"))) self.btn_cut = QPushButton("") self.btn_cut.setCheckable(True) if k in self._cut_hosts: self.btn_cut.setText("Uncut") self.btn_cut.setIcon(QIcon("img/lan-disconnect.png")) self.btn_cut.setChecked(True) else: self.btn_cut.setText("Cut") self.btn_cut.setChecked(False) self.btn_cut.setIcon(QIcon("img/lan-connect.png")) self.btn_cut.clicked.connect(self.btn_cut_clicked) self.ui.tbl_hosts.setCellWidget(i, R_STATUS, self.btn_cut) def set_device_man(self): f = open(PWD + "/oui.txt") for line in f.readlines(): for i, k in enumerate(self._hosts): mac = self._hosts[k][0].replace(":", "").upper()[:6] if line.startswith(mac): self._hosts[k][1] = line[7:] break f.close() def get_device_name(self, mac): f = open(PWD + "/oui.txt") for line in f.readlines(): mac = mac.replace(":", "").upper()[:6] if line.startswith(mac): f.close() return line[7:] else: f.close() return "" def act_scan_triggered(self): self.ui.tbl_hosts.clearContents() self.ui.tbl_hosts.setRowCount(0) self.ui.act_scan.setEnabled(False) self.ui.statusbar.showMessage("Scanning") ct = CommandThread( "{} --interface={} {}/24".format(CMD_ARPSCAN, self._iface, self._gw), self) ct.results.connect(self.scan_completed) ct.start() def act_about_triggered(self): about_dlg = AboutDialog(self) about_dlg.set_version(VERSION) about_dlg.show() def scan_completed(self, s_code, s_out): if s_code == 0: hosts = self._pat_arp.findall(s_out) # Get gatway mac address hosts = dict(hosts) self._gw_mac = hosts[self._gw] # Remove gateway from list del hosts[self._gw] self._hosts = hosts self._hosts = OrderedDict( {k: [v, "Unknown"] for k, v in self._hosts.items()}) self.set_device_man() self.populate_model() self.ui.tbl_hosts.resizeColumnsToContents() self.ui.lbl_gw.setText("<b>{} ({})</b>".format( self._gw, self.get_device_name(self._gw_mac))) self.ui.lbl_mac.setText("<b>{} ({})</b>".format( self._mac, self.get_device_name(self._mac))) else: QMessageBox.critical(self, TITLE, s_out) self.ui.statusbar.showMessage("Done") self.ui.act_scan.setEnabled(True) def btn_cut_clicked(self): button = qApp.focusWidget() # or button = self.sender() index = self.ui.tbl_hosts.indexAt(button.pos()) if index.isValid(): self.ui.tbl_hosts.selectRow(index.row()) ip = self.ui.tbl_hosts.item(index.row(), R_IP).text() if button.isChecked(): status = self.cut_host(ip) if status: button.setText("&Uncut") button.setIcon(QIcon("img/lan-disconnect.png")) else: status = self.resume_host(ip) if status: button.setText("&Cut") button.setIcon(QIcon("img/lan-connect.png")) def cut_host(self, ip): po1 = subprocess.Popen( [CMD_ARPSPOOF, "-i", self._iface, "-t", self._gw, ip], stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE, shell=False) po2 = subprocess.Popen( [CMD_ARPSPOOF, "-i", self._iface, "-t", ip, self._gw], stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE, shell=False) self._cut_hosts[ip] = [po1, po2] return True def resume_host(self, ip): if ip in self._cut_hosts.keys(): for p in self._cut_hosts[ip]: p.terminate() p.kill() del self._cut_hosts[ip] return True def center(self): qr = self.frameGeometry() cp = QDesktopWidget().availableGeometry().center() qr.moveCenter(cp) self.move(qr.topLeft())
class MainWindow(QMainWindow): TASK_FIELDS = {} def __init__(self, parent=None): self.configs = [] self.urls = {'auth': '', 'engine': ''} super().__init__(parent) # uic.loadUi(os.path.join(UI_DIR, 'main.ui'), self) self.ui = Ui_MainWindow() self.ui.setupUi(self) self.mod_manager = ModuleManager() self.current_config = None self.logger = logging.getLogger(log_config.LOGGER_NAME) self.logger.addHandler(UiLogHandler(self.ui.logPtx)) self.load_login() self.init_task_fields() self.init_ui() pass # region Properties @property def current_config(self): return self.__current_config @current_config.setter def current_config(self, value): self.__current_config = value if value: self.__select_config(value) self.ui.configParamsContainer.setEnabled(True) else: self.ui.configParamsContainer.setEnabled(False) @property def config_name(self): return self.ui.configNameTbx.text() @config_name.setter def config_name(self, value): self.ui.configNameTbx.setText(value) @property def host(self): return self.ui.hostTxb.text() @host.setter def host(self, value): self.ui.hostTxb.setText(value) @property def instance(self): return self.ui.instanceTxb.text() @instance.setter def instance(self, value): self.ui.instanceTxb.setText(value) @property def login_pass(self): return self.login @login_pass.setter def login_pass(self, value): self.login = value if value: lg = self.login.split(':')[0] else: lg = 'anon' self.ui.loginLbl.setText(lg) # endregion def init_ui(self): self.load_urls() self.fill_menu_bar() self.load_configs() self.ui.addConfigBtn.clicked.connect(self.add_config) self.ui.removeConfigBtn.clicked.connect(self.remove_config) # self.ui.saveBtn.clicked.connect(self.save_configs) self.ui.sendRequestBtn.clicked.connect(self.send_request) self.ui.configList.itemSelectionChanged.connect( self.configs_selection_changed) self.ui.loginBtn.clicked.connect(self.open_login_win) self.ui_subscribe(self.ui.configNameTbx, 'name') self.ui_subscribe(self.ui.hostTxb, 'host') self.ui_subscribe(self.ui.instanceTxb, 'instance') def fill_menu_bar(self): def set_url(key, value): self.urls[key] = value self.ui.menuBar.clear() # self.ui.urlMenus = [] urls_menu = QMenu(self.ui.menuBar) urls_menu.setTitle('Urls') for n, u in self.urls.items(): url_menu = InputMenuAction(self.ui.menuBar) url_menu.setObjectName(n) # self.ui.urlMenus.append(url_menu) url_menu.label = n url_menu.valueLE.setText(u) url_menu.valueChanged.connect(set_url) urls_menu.addAction(url_menu.get_widget_action(urls_menu)) self.ui.menuBar.addAction(urls_menu.menuAction()) def init_task_fields(self): move_task = { 'is_close': self.ui.closeTaskChbx, 'is_start': self.ui.startTaskChbx, 'close': self.ui.closeTaskTxb, 'start': self.ui.startTaskTxb, } self.TASK_FIELDS['move_task'] = move_task for task, fields in self.TASK_FIELDS.items(): for f, w in fields.items(): self.ui_subscribe(w, f'utils.[{task}].[{f}]') def load_login(self): if not os.path.isfile('login.txt'): return with open('login.txt', 'rb') as file: data = file.read() self.login_pass = base64.b64decode(data).decode() def open_login_win(self): win = LoginDialog(self) win.show() win.exec_() if win.confirm: self.load_login() self.logger.info('Login updated') # region Event handlers def closeEvent(self, *args, **kwargs): self.save_urls() self.save_configs() def ui_subscribe(self, widget, config_field): def handler(value): if not self.current_config: return set_field_value(self.current_config, config_field, value) if isinstance(widget, QLineEdit): widget.textChanged.connect(handler) pass elif isinstance(widget, QCheckBox): widget.toggled.connect(handler) pass # elif isinstance(widget, QCheckBox): pass def configs_selection_changed(self): selected = self.ui.configList.selectedItems() self.current_config = selected[0].config if len(selected) > 0 else None # endregion def __add_config_widget(self, config): item = QListWidgetItem() item.config = config widget = ConfigWidget(config, self.ui.configList) item.setSizeHint(widget.sizeHint()) self.ui.configList.addItem(item) self.ui.configList.setItemWidget(item, widget) @try_except_wrapper def load_urls(self): if not os.path.isfile(URLS_FILE): return with open(URLS_FILE, 'r', encoding='utf-8') as file: data = yaml.load(file, yaml.FullLoader) self.urls = {n: data.get(n, '') for n, u in self.urls.items()} self.logger.debug('urls loaded') @try_except_wrapper def save_urls(self): with open(URLS_FILE, 'w', encoding='utf-8') as file: yaml.dump(self.urls, file, default_flow_style=False) self.logger.debug('urls saved') @try_except_wrapper def load_configs(self): def check_utils(config): for t, field in self.TASK_FIELDS.items(): if t not in config.utils: config.utils[t] = {f: None for f in field.keys()} if not os.path.isfile(CONFIGS_FILE): return with open(CONFIGS_FILE, 'r', encoding='utf-8') as file: data = yaml.load(file, yaml.FullLoader) if not data: self.logger.warning(f'{CONFIGS_FILE} is empty') return self.configs = [Config.from_dict(d) for d in data] for c in self.configs: check_utils(c) self.__add_config_widget(c) self.logger.debug('configs loaded') @try_except_wrapper def save_configs(self, *args): data = [c.get_dict() for c in self.configs] with open(CONFIGS_FILE, 'w', encoding='utf-8') as file: yaml.dump(data, file, default_flow_style=False) self.logger.debug('configs saved') @try_except_wrapper def add_config(self, *args): conf = Config() for t, field in self.TASK_FIELDS.items(): conf.utils[t] = {f: None for f in field.keys()} self.configs.append(conf) self.__add_config_widget(conf) @try_except_wrapper def remove_config(self, *args): items = [ self.ui.configList.item(i) for i in range(self.ui.configList.count()) ] item = [ i for i in items if hasattr(i, 'config') and i.config == self.current_config ] if len(item) > 0: self.configs.remove(self.current_config) self.ui.configList.takeItem(self.ui.configList.row(item[0])) self.save_configs() def __select_config(self, config): self.config_name = config.name self.host = config.host self.instance = config.instance for t, field in self.TASK_FIELDS.items(): for f, w in field.items(): value = config.utils[t][f] if isinstance(w, QLineEdit): w.setText(value if value else '') elif isinstance(w, QCheckBox): w.setChecked(value if value else False) @try_except_wrapper def send_request(self, *args): curr_tab = self.ui.taskTabs.currentWidget() self.save_configs() conf = self.current_config