def onItemSelected(self, selected, deselected): """Executed when an episode in the tableview is clicked""" # Get the information of last selected item if not selected and not deselected: return try: ind = selected.indexes()[-1].row() except: ind = deselected.indexes()[-1].row() sequence = self.tableview.sequence drugName = sequence['Drug Name'][ind] if not drugName: # in case of empty string drugName = str(sequence['Drug Level'][ind]) ep_info_str = "ts: {:0.1f} ms; Drug: {} ({})".format( sequence['Sampling Rate'][ind], drugName, sequence['Drug Time'][ind]) self.statusBar().showMessage(ep_info_str) self.setWindowTitle("{} {}".format(__version__, sequence['Dirs'][ind])) # Get selected row indexes = self.tableview.selectionModel().selectedRows() rows = [index.row() for index in sorted(indexes)] # if not rows: # When nothing is selected, keep the last selected item on the Scope # return # Call scope window if not hasattr(self, 'sw'): # Start up a new window # self.sw = ScopeWindow(parent=self) self.sw = ScopeWindow(partner=self, hideDock=self.hideScopeToolbox, layout=self.scopeLayout) # new window if self.sw.isclosed: self.sw.show() self.sw.isclosed = False # update existing window self.sw.updateEpisodes(episodes=sequence, index=rows)
def onItemClicked(self, index): """Executed when an episode in the tableview is clicked""" # self.tableview.model.selectedRow = index.row() # print('clicked row:%d, col:%d'%(index.row(), index.column())) # Get the information of currently selected item ind = index.row() sequence = self.tableview.sequence drugName = sequence['Drug Name'][ind] if not drugName: # in case of empty string drugName = str(sequence['Drug Level'][ind]) ep_info_str = "ts: {:0.1f} ms; Drug: {} ({})".format( sequence['Sampling Rate'][ind], drugName, sequence['Drug Time'][ind]) self.statusBar().showMessage(ep_info_str) self.setWindowTitle("{} {}".format(__version__, sequence['Dirs'][ind])) # Get selected row indexes = self.tableview.selectionModel().selectedRows() rows = [index.row() for index in sorted(indexes)] # Call scope window if not hasattr(self, 'sw'): # Start up a new window self.sw = ScopeWindow(parent=self) if self.sw.isclosed: self.sw.show() self.sw.isclosed = False # update existing window self.sw.updateEpisodes(episodes=sequence, index=rows)
def onItemSelected(self, selected, deselected): """Executed when an episode in the tableview is clicked""" # Get the information of last selected item if not selected and not deselected: return try: ind = selected.indexes()[-1].row() except: ind = deselected.indexes()[-1].row() sequence = self.tableview.sequence drugName = sequence['Drug Name'][ind] if not drugName: # in case of empty string drugName = str(sequence['Drug Level'][ind]) ep_info_str = "ts: {:0.1f} ms; Drug: {} ({})".format(sequence['Sampling Rate'][ind], drugName, sequence['Drug Time'][ind]) self.statusBar().showMessage(ep_info_str) self.setWindowTitle("{} {}".format(__version__, sequence['Dirs'][ind])) # Get selected row indexes = self.tableview.selectionModel().selectedRows() rows = [index.row() for index in sorted(indexes)] # if not rows: # When nothing is selected, keep the last selected item on the Scope # return # Call scope window if not hasattr(self, 'sw'): # Start up a new window # self.sw = ScopeWindow(parent=self) self.sw = ScopeWindow(partner=self, hideDock=self.hideScopeToolbox, layout=self.scopeLayout) # new window if self.sw.isclosed: self.sw.show() self.sw.isclosed = False # update existing window self.sw.updateEpisodes(episodes=sequence, index=rows)
def onItemClicked(self, index): """Executed when an episode in the tableview is clicked""" # self.tableview.model.selectedRow = index.row() # print('clicked row:%d, col:%d'%(index.row(), index.column())) # Get the information of currently selected item ind = index.row() sequence = self.tableview.sequence drugName = sequence['Drug Name'][ind] if not drugName: # in case of empty string drugName = str(sequence['Drug Level'][ind]) ep_info_str = "ts: {:0.1f} ms; Drug: {} ({})".format(sequence['Sampling Rate'][ind], drugName, sequence['Drug Time'][ind]) self.statusBar().showMessage(ep_info_str) self.setWindowTitle("{} {}".format(__version__, sequence['Dirs'][ind])) # Get selected row indexes = self.tableview.selectionModel().selectedRows() rows = [index.row() for index in sorted(indexes)] # Call scope window if not hasattr(self, 'sw'): # Start up a new window self.sw = ScopeWindow(parent=self) if self.sw.isclosed: self.sw.show() self.sw.isclosed = False # update existing window self.sw.updateEpisodes(episodes=sequence, index=rows)
class Synapse_MainWindow(QtGui.QMainWindow): def __init__(self, parent=None): super(Synapse_MainWindow, self).__init__(parent) # Set up the GUI window self.setupUi(self) # Set the treeview model for directory self.setDataBrowserTreeView() def setupUi(self, MainWindow): """This function is converted from the .ui file from the designer""" # Set up basic layout of the main window MainWindow.setObjectName(_fromUtf8("Synpase TreeView")) MainWindow.resize(1000, 500) self.centralwidget = QtGui.QWidget(MainWindow) self.centralwidget.setObjectName(_fromUtf8("centralwidget")) self.horizontalLayout = QtGui.QHBoxLayout(self.centralwidget) self.horizontalLayout.setObjectName(_fromUtf8("horizontalLayout")) # Set splitter for two panels self.splitter = QtGui.QSplitter(self.centralwidget) sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.splitter.sizePolicy().hasHeightForWidth()) self.splitter.setSizePolicy(sizePolicy) self.splitter.setOrientation(QtCore.Qt.Horizontal) self.splitter.setObjectName(_fromUtf8("splitter")) # Set treeview self.treeview = QtGui.QTreeView(self.splitter) sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Expanding) sizePolicy.setHorizontalStretch(1) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.treeview.sizePolicy().hasHeightForWidth()) self.treeview.setSizePolicy(sizePolicy) self.treeview.setTextElideMode(QtCore.Qt.ElideNone) self.treeview.setObjectName(_fromUtf8("treeview")) # Set up Episode list table view self.tableview = QtGui.QTableView(self.splitter) sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding) sizePolicy.setHorizontalStretch(3) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.tableview.sizePolicy().hasHeightForWidth()) self.tableview.setSizePolicy(sizePolicy) self.tableview.setObjectName(_fromUtf8("tableview")) # additional tableview customizations self.tableview.setSelectionMode(QtGui.QAbstractItemView.ExtendedSelection) self.tableview.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows) self.tableview.setItemDelegate(TablviewDelegate(self.tableview)) self.tableview.headers = ['Epi', 'Time', 'Duration', 'Drug Level', 'Drug Name', 'Drug Time', 'Comment','Dirs'] self.tableview.hiddenColumnList = [4, 5, 7] # Drug Name, Drug Time, Dirs self.horizontalLayout.addWidget(self.splitter) MainWindow.setCentralWidget(self.centralwidget) # Set up menu bar self.menubar = QtGui.QMenuBar(MainWindow) self.menubar.setGeometry(QtCore.QRect(0, 0, 638, 100)) self.menubar.setObjectName(_fromUtf8("menubar")) self.setMenuBarItems() # call function to set menubar MainWindow.setMenuBar(self.menubar) # Set up status bar self.statusbar = QtGui.QStatusBar(MainWindow) self.statusbar.setObjectName(_fromUtf8("statusbar")) MainWindow.setStatusBar(self.statusbar) # Execution self.retranslateUi(MainWindow) QtCore.QMetaObject.connectSlotsByName(MainWindow) # ---------------- Additional main window behaviors ----------------------- def setMenuBarItems(self): # File Menu fileMenu = self.menubar.addMenu('&File') # File: Exit exitAction = QtGui.QAction(QtGui.QIcon('exit.png'),'Exit', self) exitAction.setShortcut('Ctrl+Q') exitAction.setStatusTip('Exit Synapse') exitAction.triggered.connect(self.close) fileMenu.addAction(exitAction) # View Menu viewMenu = self.menubar.addMenu('&View') # View: Column columnMenu = viewMenu.addMenu('&Additional Columns') drugNameAction = QtGui.QAction('Drug Name', self, checkable=True, checked=False) drugNameAction.triggered.connect(lambda: self.toggleTableViewColumnAction(4, drugNameAction)) columnMenu.addAction(drugNameAction) drugTimeAction = QtGui.QAction('Drug Time', self, checkable=True, checked=False) drugTimeAction.triggered.connect(lambda: self.toggleTableViewColumnAction(5, drugTimeAction)) columnMenu.addAction(drugTimeAction) dirsAction = QtGui.QAction('Directory', self, checkable=True, checked=False) dirsAction.triggered.connect(lambda: self.toggleTableViewColumnAction(7, dirsAction)) columnMenu.addAction(dirsAction) def toggleTableViewColumnAction(self, column, action): if self.tableview.isColumnHidden(column): self.tableview.showColumn(column) action.setChecked(True) self.tableview.hiddenColumnList.remove(column) else: self.tableview.hideColumn(column) action.setChecked(False) self.tableview.hiddenColumnList.append(column) def closeEvent(self, event): """Override default behavior when closing the main window""" #quit_msg = "Are you sure you want to exit the program?" #reply = QtGui.QMessageBox.question(self, 'Message', quit_msg, # QtGui.QMessageBox.Yes, # QtGui.QMessageBox.No) #if reply == QtGui.QMessageBox.Yes: # event.accept() #else: # event.ignore() def retranslateUi(self, MainWindow): """Set window title and other miscellaneous""" MainWindow.setWindowTitle(_translate(__version__, __version__, None)) # ---------------- Data browser behaviors --------------------------------- def setDataBrowserTreeView(self): # Set file system as model of the tree view # self.treeview.model = QtGui.QFileSystemModel() self.treeview.model = FileSystemTreeModel() self.treeview.setModel(self.treeview.model) # Set behavior upon clicked self.treeview.clicked.connect(self.onSequenceClicked) @QtCore.pyqtSlot(QtCore.QModelIndex) def onSequenceClicked(self, index): """ Display a list of episodes upon sequence clicked""" #indexItem = self.treeview.model.index(index.row(), 0, index.parent()) node = self.treeview.model.getNode(index) # Check if the item clicked is sequence instead of a folder / file if node.type == "sequence": # populuate the table view on the other panel self.setEpisodeListTableView(node.info) # --------------- Episode list behaviors ---------------------------------- def setEpisodeListTableView(self, sequence=None): if not sequence: return # do nothing if there is no sequence information # Render the data frame from sequence df = pd.DataFrame.from_dict(sequence) # sort the data frame by 'Epi' column epi_sort = df['Epi'].tolist() ind = pd.DataFrame([[int(k) for k in re.findall('\d+', m)] \ for m in epi_sort]) ind = ind.sort_values([0,1], ascending=[1,1]).index.tolist() df = df.reindex_axis(ind, axis=0) self.tableview.sequence = df.reset_index(drop=True).to_dict('list') # data information self.tableview.sequence['Name'] = self.tableview.sequence['Name'][0] # remove any duplication # get the subset of columns based on column settings df = df.reindex_axis(self.tableview.headers, axis=1) self.tableview.model = EpisodeTableModel(df) self.tableview.setModel(self.tableview.model) self.tableview.verticalHeader().hide() # Hide some columns from display for c in self.tableview.hiddenColumnList: # Drug Name, Drug Time, Dirs self.tableview.setColumnHidden(c, True) # Set behavior upon selection self.tableview.clicked.connect(self.onItemClicked) @QtCore.pyqtSlot(QtCore.QModelIndex) def onItemClicked(self, index): """Executed when an episode in the tableview is clicked""" # self.tableview.model.selectedRow = index.row() # print('clicked row:%d, col:%d'%(index.row(), index.column())) # Get the information of currently selected item ind = index.row() sequence = self.tableview.sequence drugName = sequence['Drug Name'][ind] if not drugName: # in case of empty string drugName = str(sequence['Drug Level'][ind]) ep_info_str = "ts: {:0.1f} ms; Drug: {} ({})".format(sequence['Sampling Rate'][ind], drugName, sequence['Drug Time'][ind]) self.statusBar().showMessage(ep_info_str) self.setWindowTitle("{} {}".format(__version__, sequence['Dirs'][ind])) # Get selected row indexes = self.tableview.selectionModel().selectedRows() rows = [index.row() for index in sorted(indexes)] # Call scope window if not hasattr(self, 'sw'): # Start up a new window self.sw = ScopeWindow(parent=self) if self.sw.isclosed: self.sw.show() self.sw.isclosed = False # update existing window self.sw.updateEpisodes(episodes=sequence, index=rows)
class Synapse_MainWindow(QtGui.QMainWindow): def __init__(self, parent=None, startpath=None, hideScopeToolbox=True, layout=None): super(Synapse_MainWindow, self).__init__(parent) # Set up the GUI window self.setupUi(self) # Set the treeview model for directory self.setDataBrowserTreeView(startpath=startpath) self.hideScopeToolbox = hideScopeToolbox self.scopeLayout = layout def setupUi(self, MainWindow): """This function is converted from the .ui file from the designer""" # Set up basic layout of the main window MainWindow.setObjectName(_fromUtf8("Synpase TreeView")) MainWindow.resize(1000, 500) self.centralwidget = QtGui.QWidget(MainWindow) self.centralwidget.setObjectName(_fromUtf8("centralwidget")) self.horizontalLayout = QtGui.QHBoxLayout(self.centralwidget) self.horizontalLayout.setObjectName(_fromUtf8("horizontalLayout")) # Set splitter for two panels self.splitter = QtGui.QSplitter(self.centralwidget) sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( self.splitter.sizePolicy().hasHeightForWidth()) self.splitter.setSizePolicy(sizePolicy) self.splitter.setOrientation(QtCore.Qt.Horizontal) self.splitter.setObjectName(_fromUtf8("splitter")) # Set treeview self.treeview = QtGui.QTreeView(self.splitter) sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Expanding) sizePolicy.setHorizontalStretch(1) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( self.treeview.sizePolicy().hasHeightForWidth()) self.treeview.setSizePolicy(sizePolicy) # self.treeview.setTextElideMode(QtCore.Qt.ElideNone) self.treeview.header().setResizeMode( QtGui.QHeaderView.ResizeToContents) self.treeview.header().setStretchLastSection(False) self.treeview.setObjectName(_fromUtf8("treeview")) # Set up Episode list table view self.tableview = QtGui.QTableView(self.splitter) sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding) sizePolicy.setHorizontalStretch(3) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( self.tableview.sizePolicy().hasHeightForWidth()) self.tableview.setSizePolicy(sizePolicy) self.tableview.setObjectName(_fromUtf8("tableview")) # additional tableview customizations self.tableview.setSelectionMode( QtGui.QAbstractItemView.ExtendedSelection) self.tableview.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows) self.tableview.setItemDelegate(TableviewDelegate(self.tableview)) self.tableview.headers = [ 'Epi', 'Time', 'Duration', 'Drug Level', 'Drug Name', 'Drug Time', 'Comment', 'Dirs' ] self.tableview.hiddenColumnList = [4, 5, 7] # Drug Name, Drug Time, Dirs self.tableview.horizontalHeader().setStretchLastSection(True) # self.tableview.setShowGrid(False) self.tableview.setStyleSheet( """QTableView{border : 20px solid white}""") self.horizontalLayout.addWidget(self.splitter) MainWindow.setCentralWidget(self.centralwidget) # Set up menu bar self.menubar = QtGui.QMenuBar(MainWindow) self.menubar.setGeometry(QtCore.QRect(0, 0, 638, 100)) self.menubar.setObjectName(_fromUtf8("menubar")) self.setMenuBarItems() # call function to set menubar MainWindow.setMenuBar(self.menubar) # Set up status bar self.statusbar = QtGui.QStatusBar(MainWindow) self.statusbar.setObjectName(_fromUtf8("statusbar")) MainWindow.setStatusBar(self.statusbar) # Execution self.retranslateUi(MainWindow) QtCore.QMetaObject.connectSlotsByName(MainWindow) # ---------------- Additional main window behaviors ----------------------- def setMenuBarItems(self): # File Menu fileMenu = self.menubar.addMenu('&File') # File: Refresh. Refresh currently selected item/directory refreshAction = QtGui.QAction('Refresh', self) refreshAction.setShortcut('F5') refreshAction.setStatusTip( 'Refresh currently selected item / directory') refreshAction.triggered.connect(self.refreshCurrentBranch) fileMenu.addAction(refreshAction) # File: Settings settingsAction = QtGui.QAction("Settings", self) settingsAction.setStatusTip('Configure settings of PySynapse') settingsAction.triggered.connect(self.openSettingsWindow) fileMenu.addAction(settingsAction) # File: Exit exitAction = QtGui.QAction(QtGui.QIcon('exit.png'), 'Exit', self) exitAction.setShortcut('Ctrl+Q') exitAction.setStatusTip('Exit Synapse') exitAction.triggered.connect(self.close) fileMenu.addAction(exitAction) # View Menu viewMenu = self.menubar.addMenu('&View') # View: Column columnMenu = viewMenu.addMenu('&Additional Columns') drugNameAction = QtGui.QAction('Drug Name', self, checkable=True, checked=False) drugNameAction.triggered.connect( lambda: self.toggleTableViewColumnAction(4, drugNameAction)) columnMenu.addAction(drugNameAction) drugTimeAction = QtGui.QAction('Drug Time', self, checkable=True, checked=False) drugTimeAction.triggered.connect( lambda: self.toggleTableViewColumnAction(5, drugTimeAction)) columnMenu.addAction(drugTimeAction) dirsAction = QtGui.QAction('Directory', self, checkable=True, checked=False) dirsAction.triggered.connect( lambda: self.toggleTableViewColumnAction(7, dirsAction)) columnMenu.addAction(dirsAction) def toggleTableViewColumnAction(self, column, action): if self.tableview.isColumnHidden(column): self.tableview.showColumn(column) action.setChecked(True) self.tableview.hiddenColumnList.remove(column) else: self.tableview.hideColumn(column) action.setChecked(False) self.tableview.hiddenColumnList.append(column) def refreshCurrentBranch(self): # Get parent index index = self.treeview.selectionModel().currentIndex() node = self.treeview.model.getNode(index) if node.type == "directory": self.treeview.model.refreshNode(index) def openSettingsWindow(self): if not hasattr(self, 'settingsWidget'): self.settingsWidget = Settings() if self.settingsWidget.isclosed: self.settingsWidget.show() self.settingsWidget.isclosed = False def closeEvent(self, event): """Override default behavior when closing the main window""" return #quit_msg = "Are you sure you want to exit the program?" #reply = QtGui.QMessageBox.question(self, 'Message', quit_msg, # QtGui.QMessageBox.Yes, # QtGui.QMessageBox.No) #if reply == QtGui.QMessageBox.Yes: # event.accept() #else: # event.ignore() # Consider if close children windows when closing Synapse main window # children = ['settingsWidget', 'sw'] # for c in children: # if hasattr(self, c): # getattr(self, c).close() def retranslateUi(self, MainWindow): """Set window title and other miscellaneous""" MainWindow.setWindowTitle(_translate(__version__, __version__, None)) MainWindow.setWindowIcon(QtGui.QIcon('resources/icons/Synapse.png')) # ---------------- Data browser behaviors --------------------------------- def setDataBrowserTreeView(self, startpath=None): # Set file system as model of the tree view # self.treeview.model = QtGui.QFileSystemModel() self.treeview.model = FileSystemTreeModel(path=startpath) self.treeview.setModel(self.treeview.model) # Set behavior upon clicked self.treeview.clicked.connect(self.onSequenceClicked) @QtCore.pyqtSlot(QtCore.QModelIndex) def onSequenceClicked(self, index): """ Display a list of episodes upon sequence clicked""" #indexItem = self.treeview.model.index(index.row(), 0, index.parent()) self.raise_() node = self.treeview.model.getNode(index) # Check if the item clicked is sequence instead of a folder / file if node.type == "sequence": # populuate the table view on the other panel self.setEpisodeListTableView(node.info) # --------------- Episode list behaviors ---------------------------------- def setEpisodeListTableView(self, sequence=None): if not sequence: return # do nothing if there is no sequence information # Render the data frame from sequence df = pd.DataFrame.from_dict(sequence) # sort the data frame by 'Epi' column epi_sort = df['Epi'].tolist() ind = pd.DataFrame([[int(k) for k in re.findall('\d+', m)] \ for m in epi_sort]) ind = ind.sort_values([0, 1], ascending=[1, 1]).index.tolist() df = df.reindex_axis(ind, axis=0) self.tableview.sequence = df.reset_index(drop=True).to_dict( 'list') # data information self.tableview.sequence['Name'] = self.tableview.sequence['Name'][ 0] # remove any duplication # get the subset of columns based on column settings df = df.reindex_axis(self.tableview.headers, axis=1) self.tableview.model = EpisodeTableModel(df) self.tableview.setModel(self.tableview.model) self.tableview.verticalHeader().hide() # Hide some columns from display for c in self.tableview.hiddenColumnList: # Drug Name, Drug Time, Dirs self.tableview.setColumnHidden(c, True) # Set behavior upon selection self.tableview.selectionModel().selectionChanged.connect( self.onItemSelected) # self.tableview.clicked.connect(self.onItemSelected) @QtCore.pyqtSlot(QtCore.QModelIndex) def onItemSelected(self, selected, deselected): """Executed when an episode in the tableview is clicked""" # Get the information of last selected item if not selected and not deselected: return try: ind = selected.indexes()[-1].row() except: ind = deselected.indexes()[-1].row() sequence = self.tableview.sequence drugName = sequence['Drug Name'][ind] if not drugName: # in case of empty string drugName = str(sequence['Drug Level'][ind]) ep_info_str = "ts: {:0.1f} ms; Drug: {} ({})".format( sequence['Sampling Rate'][ind], drugName, sequence['Drug Time'][ind]) self.statusBar().showMessage(ep_info_str) self.setWindowTitle("{} {}".format(__version__, sequence['Dirs'][ind])) # Get selected row indexes = self.tableview.selectionModel().selectedRows() rows = [index.row() for index in sorted(indexes)] # if not rows: # When nothing is selected, keep the last selected item on the Scope # return # Call scope window if not hasattr(self, 'sw'): # Start up a new window # self.sw = ScopeWindow(parent=self) self.sw = ScopeWindow(partner=self, hideDock=self.hideScopeToolbox, layout=self.scopeLayout) # new window if self.sw.isclosed: self.sw.show() self.sw.isclosed = False # update existing window self.sw.updateEpisodes(episodes=sequence, index=rows)
class Synapse_MainWindow(QtWidgets.QMainWindow): def __init__(self, parent=None, startpath=None, hideScopeToolbox=True, layout=None): super(Synapse_MainWindow, self).__init__(parent) # Set up the GUI window self.setupUi(self) # Set the treeview model for directory self.setDataBrowserTreeView(startpath=startpath) self.hideScopeToolbox = hideScopeToolbox self.scopeLayout = layout self.startpath=startpath def setupUi(self, MainWindow): """This function is converted from the .ui file from the designer""" # Set up basic layout of the main window MainWindow.setObjectName(_fromUtf8("Synpase TreeView")) MainWindow.resize(1000, 500) self.centralwidget = QtWidgets.QWidget(MainWindow) self.centralwidget.setObjectName(_fromUtf8("centralwidget")) self.horizontalLayout = QtWidgets.QHBoxLayout(self.centralwidget) self.horizontalLayout.setObjectName(_fromUtf8("horizontalLayout")) # Set splitter for two panels self.splitter = QtWidgets.QSplitter(self.centralwidget) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.splitter.sizePolicy().hasHeightForWidth()) self.splitter.setSizePolicy(sizePolicy) self.splitter.setOrientation(QtCore.Qt.Horizontal) self.splitter.setObjectName(_fromUtf8("splitter")) # Set treeview self.treeview = QtWidgets.QTreeView(self.splitter) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Expanding) sizePolicy.setHorizontalStretch(1) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.treeview.sizePolicy().hasHeightForWidth()) self.treeview.setSizePolicy(sizePolicy) # self.treeview.setTextElideMode(QtCore.Qt.ElideNone) self.treeview.header().setResizeMode(QtWidgets.QHeaderView.ResizeToContents) self.treeview.header().setStretchLastSection(False) self.treeview.setObjectName(_fromUtf8("treeview")) # Set up Episode list table view self.tableview = QtWidgets.QTableView(self.splitter) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding) sizePolicy.setHorizontalStretch(3) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.tableview.sizePolicy().hasHeightForWidth()) self.tableview.setSizePolicy(sizePolicy) self.tableview.setObjectName(_fromUtf8("tableview")) # additional tableview customizations self.tableview.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection) self.tableview.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows) self.tableview.setItemDelegate(TableviewDelegate(self.tableview)) self.tableview.horizontalHeader().setStretchLastSection(True) # self.tableview.setShowGrid(False) self.tableview.setStyleSheet("""QTableView{border : 20px solid white}""") self.horizontalLayout.addWidget(self.splitter) MainWindow.setCentralWidget(self.centralwidget) # Set up menu bar self.menubar = QtWidgets.QMenuBar(MainWindow) self.menubar.setGeometry(QtCore.QRect(0, 0, 638, 100)) self.menubar.setObjectName(_fromUtf8("menubar")) self.setMenuBarItems() # call function to set menubar MainWindow.setMenuBar(self.menubar) # Set up status bar self.statusbar = QtWidgets.QStatusBar(MainWindow) self.statusbar.setObjectName(_fromUtf8("statusbar")) MainWindow.setStatusBar(self.statusbar) # Execution self.retranslateUi(MainWindow) QtCore.QMetaObject.connectSlotsByName(MainWindow) # ---------------- Additional main window behaviors ----------------------- def setMenuBarItems(self): # File Menu fileMenu = self.menubar.addMenu('&File') # File: Load csv loadDBAction = QtWidgets.QAction('Load Database', self) loadDBAction.setStatusTip('Load a database table from a .csv, .xlsx, or .xls file') loadDBAction.triggered.connect(self.loadDatabase) fileMenu.addAction(loadDBAction) # File: Refresh. Refresh currently selected item/directory refreshAction = QtWidgets.QAction('Refresh', self) refreshAction.setShortcut('F5') refreshAction.setStatusTip('Refresh currently selected item / directory') refreshAction.triggered.connect(self.refreshCurrentBranch) fileMenu.addAction(refreshAction) # File: Settings settingsAction = QtWidgets.QAction("Settings", self) settingsAction.setStatusTip('Configure settings of PySynapse') settingsAction.triggered.connect(self.openSettingsWindow) fileMenu.addAction(settingsAction) # File: Exit exitAction = QtWidgets.QAction(QtGui.QIcon('exit.png'),'Exit', self) exitAction.setShortcut('Ctrl+Q') exitAction.setStatusTip('Exit Synapse') exitAction.triggered.connect(self.close) fileMenu.addAction(exitAction) # View Menu viewMenu = self.menubar.addMenu('&View') # View: Column columnMenu = viewMenu.addMenu('&Additional Columns') drugNameAction = QtWidgets.QAction('Drug Name', self, checkable=True, checked=False) drugNameAction.triggered.connect(lambda: self.toggleTableViewColumnAction(4, drugNameAction)) columnMenu.addAction(drugNameAction) drugTimeAction = QtWidgets.QAction('Drug Time', self, checkable=True, checked=False) drugTimeAction.triggered.connect(lambda: self.toggleTableViewColumnAction(5, drugTimeAction)) columnMenu.addAction(drugTimeAction) dirsAction = QtWidgets.QAction('Directory', self, checkable=True, checked=False) dirsAction.triggered.connect(lambda: self.toggleTableViewColumnAction(7, dirsAction)) columnMenu.addAction(dirsAction) def toggleTableViewColumnAction(self, column, action): if self.tableview.isColumnHidden(column): self.tableview.showColumn(column) action.setChecked(True) self.tableview.hiddenColumnList.remove(column) else: self.tableview.hideColumn(column) action.setChecked(False) self.tableview.hiddenColumnList.append(column) def loadDatabase(self): # TODO: Need to design this more carefully #raise(NotImplementedError()) # Opens up the file explorer filename, _ = QtWidgets.QFileDialog.getOpenFileName(self, 'Open File', '/', 'Spreadsheet (*.csv *.xlsx *.xls);;All Files (*)')# rename_dict = {"Cell":"Name", "Episode":"Epi", "SweepWindow":"Duration","Drug":"Drug Name","DrugTime":"Drug Time","WCTime":"Time", "StimDescription":"Comment"} if ".csv" in filename: df = pd.read_csv(filename) elif ".xlsx" in filename or "xls" in filename: df = pd.read_excel(filename) else: return col_lower = [c.lower() for c in df.columns.tolist()] if "show" in col_lower: df = df.loc[df.iloc[:, col_lower.index("show")],:] drop_columns = np.setdiff1d(df.columns.tolist(), list(rename_dict.keys())) df = df.drop(drop_columns, axis=1).rename(columns=rename_dict) df["Sampling Rate"] = 0.1 df["Drug Level"] = 0 df.loc[df["Drug Name"].isnull(), "Drug Name"] = "" df["Time"] = [NeuroData.epiTime(ttt) for ttt in df["Time"]] df["Drug Time"] = [NeuroData.epiTime(ttt) for ttt in df["Drug Time"]] # TODO: Tentitative path df["Dirs"] = [os.path.join(self.startpath, get_cellpath(cb, ep)).replace("\\", "/") for cb, ep in zip(df["Name"], df["Epi"])] self.tableview.sequence = df.reset_index(drop=True).to_dict('list') df = df.reindex(["Name", "Epi", "Time", "Duration", "Drug Name", "Drug Time", "Comment"], axis=1) # drop columns not to be displayed # print('loaded') # Populate the loaded data unto the table widget self.tableview.headers = df.columns.tolist() self.tableview.model = EpisodeTableModel(df) self.tableview.setModel(self.tableview.model) self.tableview.verticalHeader().hide() # Show all columns for cc in range(len(self.tableview.headers)): self.tableview.showColumn(cc) self.tableview.selectionModel().selectionChanged.connect(self.onItemSelected) def refreshCurrentBranch(self): # Get parent index index = self.treeview.selectionModel().currentIndex() node = self.treeview.model.getNode(index) if node.type == "directory": self.treeview.model.refreshNode(index) def openSettingsWindow(self): if not hasattr(self, 'settingsWidget'): self.settingsWidget = Settings() if self.settingsWidget.isclosed: self.settingsWidget.show() self.settingsWidget.isclosed = False def closeEvent(self, event): """Override default behavior when closing the main window""" return #quit_msg = "Are you sure you want to exit the program?" #reply = QtWidgets.QMessageBox.question(self, 'Message', quit_msg, # QtWidgets.QMessageBox.Yes, # QtWidgets.QMessageBox.No) #if reply == QtWidgets.QMessageBox.Yes: # event.accept() #else: # event.ignore() # Consider if close children windows when closing Synapse main window # children = ['settingsWidget', 'sw'] # for c in children: # if hasattr(self, c): # getattr(self, c).close() def retranslateUi(self, MainWindow): """Set window title and other miscellaneous""" MainWindow.setWindowTitle(_translate(__version__, __version__, None)) MainWindow.setWindowIcon(QtGui.QIcon('resources/icons/Synapse.png')) # ---------------- Data browser behaviors --------------------------------- def setDataBrowserTreeView(self, startpath=None): # Set file system as model of the tree view # self.treeview.model = QtWidgets.QFileSystemModel() self.treeview.model = FileSystemTreeModel(path=startpath) self.treeview.setModel(self.treeview.model) # Set behavior upon clicked self.treeview.clicked.connect(self.onSequenceClicked) @QtCore.pyqtSlot(QtCore.QModelIndex) def onSequenceClicked(self, index): """ Display a list of episodes upon sequence clicked""" #indexItem = self.treeview.model.index(index.row(), 0, index.parent()) self.raise_() node = self.treeview.model.getNode(index) # Check if the item clicked is sequence instead of a folder / file if node.type == "sequence": # populate the table view on the other panel self.setEpisodeListTableView(node.info) # --------------- Episode list behaviors ---------------------------------- def setEpisodeListTableView(self, sequence=None): if not sequence: return # do nothing if there is no sequence information self.tableview.headers = ['Epi', 'Time', 'Duration', 'Drug Level', 'Drug Name', 'Drug Time', 'Comment','Dirs', 'Stimulus', 'StimDuration'] self.tableview.hiddenColumnList = [4, 5, 7, 8, 9] # Drug Name, Drug Time, Dirs # Render the data frame from sequence df = pd.DataFrame.from_dict(sequence) # sort the data frame by 'Epi' column epi_sort = df['Epi'].tolist() ind = pd.DataFrame([[int(k) for k in re.findall('\d+', m)] \ for m in epi_sort]) ind = ind.sort_values([0,1], ascending=[1,1]).index.tolist() df = df.reindex(ind, axis=0) self.tableview.sequence = df.reset_index(drop=True).to_dict('list') # data information # self.tableview.sequence['Name'] = self.tableview.sequence['Name'][0] # remove any duplication # get the subset of columns based on column settings df = df.reindex(self.tableview.headers, axis=1) self.tableview.model = EpisodeTableModel(df) self.tableview.setModel(self.tableview.model) self.tableview.verticalHeader().hide() # Hide some columns from display for c in self.tableview.hiddenColumnList: # Drug Name, Drug Time, Dirs self.tableview.setColumnHidden(c, True) # Set behavior upon selection self.tableview.selectionModel().selectionChanged.connect(self.onItemSelected) # self.tableview.clicked.connect(self.onItemSelected) @QtCore.pyqtSlot(QtCore.QItemSelection, QtCore.QItemSelection) def onItemSelected(self, selected, deselected): """Executed when an episode in the tableview is clicked""" # Get the information of last selected item if not selected and not deselected: return try: ind = selected.indexes()[-1].row() except: ind = deselected.indexes()[-1].row() sequence = self.tableview.sequence drugName = sequence['Drug Name'][ind] if not drugName: # in case of empty string drugName = str(sequence['Drug Level'][ind]) ep_info_str = "ts: {:0.1f} ms; Drug: {} ({})".format(sequence['Sampling Rate'][ind], drugName, sequence['Drug Time'][ind]) self.statusBar().showMessage(ep_info_str) self.setWindowTitle("{} {}".format(__version__, sequence['Dirs'][ind])) # Get selected row indexes = self.tableview.selectionModel().selectedRows() rows = [index.row() for index in sorted(indexes)] # if not rows: # When nothing is selected, keep the last selected item on the Scope # return # Call scope window if not hasattr(self, 'sw'): # Start up a new window # self.sw = ScopeWindow(parent=self) self.sw = ScopeWindow(partner=self, hideDock=self.hideScopeToolbox, layout=self.scopeLayout) # new window if self.sw.isclosed: self.sw.show() self.sw.isclosed = False # update existing window self.sw.updateEpisodes(episodes=sequence, index=rows)