def execute(self, settings: Settings) -> bool: self.loadSetiings(settings) if self.exec() != QDialog.Accepted: return False self.saveSetiings(settings) settings.write() return True
def pack(args: Namespace) -> None: settings = Settings.from_env() projects: list[str] if args.all: librarian = Librarian(settings) projects = librarian.get_expanded_epubs().get(args.type, []) else: projects = args.projects if len(projects) > 0: print("Packing projects...") packer = Packer(settings) packer.pack_projects(projects, args.type, args.compression)
def build(args: Namespace) -> None: settings = Settings.from_env() projects: list[str] if args.all: librarian = Librarian(settings) projects = librarian.get_projects() else: projects = args.projects if len(projects) > 0: print("Building projects...") builder = Builder(settings) builder.build_projects(projects, args.type, args.bundles)
def main() -> None: default_settings = Settings() installer = Installer(default_settings) installer.install_epubcheck() project_types = sorted( path.name for path in default_settings.expanded_epubs_directory.iterdir() if path.is_dir()) for project_type in project_types: pack_all(default_settings, project_type) check_all(default_settings, project_type) release(default_settings, project_type) summary_file = summarize(default_settings) release_summary(summary_file)
def check(args: Namespace) -> None: settings = Settings.from_env() if args.install: print("Installing EPUBCheck...") installer = Installer(settings) installer.install_epubcheck() projects: list[str] if args.all: librarian = Librarian(settings) projects = librarian.get_packaged_epubs().get(args.type, []) else: projects = args.projects if len(projects) > 0: print("Checking projects...") checker = Checker(settings) checker.check_projects(projects, args.type)
def sync(args: Namespace) -> None: settings = Settings.from_env() new_books: list[str] = [] projects: list[str] if args.all: librarian = Librarian(settings) projects = librarian.get_packaged_epubs().get(args.type, []) else: projects = args.projects for project in projects: epub_project = EPUBProject(Path(settings.projects_directory, project)) metadata = epub_project.epub_metadata search_terms: list[str] = [] search_terms.append(f"title:\"={metadata.title}\"") for creator_name, creator_roles in metadata.creators.items(): if not creator_roles or "aut" in creator_roles: search_terms.append(f"author:\"={creator_name}\"") search_expression = " ".join(search_terms) book_ids = calibredb.search(search_expression, with_library=args.with_library, username=args.username, password=args.password, timeout=args.timeout) ebook_file = Path(settings.packaged_epubs_directory, args.type, f"{project}.{args.type}.epub").as_posix() if not book_ids: new_books.append(ebook_file) elif len(book_ids) == 1: a = calibredb.add_format(book_ids[0], ebook_file, with_library=args.with_library, username=args.username, password=args.password, timeout=args.timeout) print(a) else: print(f"Skipping {project} due to ambiguous metadata") if new_books: calibredb.add(new_books, with_library=args.with_library, username=args.username, password=args.password, timeout=args.timeout)
def __init__(self): self.title = u'Tracks detection' # Настройки self.settings = Settings()
class Application: def __init__(self): self.title = u'Tracks detection' # Настройки self.settings = Settings() def application_init(self): '''Инициализация Qt приложения''' # Создание приложение self.qapp = QApplication(sys.argv) self.__app_working_status = True # Установка локлизатора translator = QTranslator(self.qapp) translator.load('lang/tr_ru', os.path.dirname(__file__)) self.qapp.installTranslator(translator) self.mainDialog = MainDialog(self, self.title) self.mainDialog.closeApp.connect(self.__finalize_before_quit) self.controls = { 'step': ['X', 'Y', 'Z', 'A'], 'servo': ['B', 'C'], 'pins': { 'P1': [], 'P2': ['UV', 'VIS'] } } self.mainDialog.show() self.project_init() self.gui_init() self.communication_init() sys.exit(self.qapp.exec_()) def __finalize_before_quit(self): self.__app_working_status = False if self.grbl.connection: self.grbl.connection.close() if self.communication_thread: self.communication_thread.join() self.qapp.exit() def retuenicon(self, name): return QIcon( QPixmap( os.path.normpath( os.path.join(os.path.dirname(os.path.realpath(__file__)), '', name + '.png')))) def project_init(self): self.project = Project('New') def async_sleep(self, sleep): for i in range(sleep): time.sleep(1) if not self.__app_working_status: break def __connection_worker(self): while self.__app_working_status: status = self.__current_conacion_procedure() if status: break if status: self.__current_conacion_procedure = self.grbl.getStatus else: self.__current_conacion_procedure = self.__auto_seach__ self.async_sleep(5) self.cnc_indicator.setStatus(status) def communication_init(self): self.grbl = GRBL(HOST=self.settings.grblip) self.__current_conacion_procedure = self.__auto_seach__ self.communication_thread = threading.Thread( target=self.__connection_worker) self.communication_thread.setDaemon(True) self.communication_thread.start() def gui_init(self): pref_menu = menu_item(u'Preferences') ref_menu = menu_item(u'Reference') gen_menu = menu_item(u'Device') gen_menu.addChildren(menu_item(u'GRBL', self.showGrblDialog)) file_menu = menu_item(self.qapp.tr(u'File')) file_menu.addChildren(menu_item(u'New', self.newProject), menu_item(u'Open', self.openProject), menu_item(u'Import...', self.openFile), menu_item(u'Save', self.saveProject), menu_item(u'Exit', self.qapp.exit)) pref_menu.addChildren(gen_menu, menu_item(u'Settings')) ref_menu.addChildren(menu_item(u'Help'), menu_item(u'About', self.showAbout)) self.mainDialog.addMenuItems(file_menu, pref_menu, ref_menu) self.cnc_indicator = work_indicator(u'CNC') self.mainDialog.addStatusObj(self.cnc_indicator) self.progressBar = QProgressBar() self.progressBar.setTextVisible(True) self.progressBar.setAlignment(Qt.AlignCenter) self.progressBar.minimum = 1 self.progressBar.maximum = 100 self.mainDialog.addPermanentStatusObj(self.progressBar) '''Инициализациия таблицы содержания''' treeDock = QDockWidget(self.qapp.tr(u'Project tree'), self.mainDialog) treeDock.setAllowedAreas(Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea) self.mainDialog.addDockWidget(Qt.LeftDockWidgetArea, treeDock) self.mainnodes = [Node("Samples"), Node("Other")] self.project_tree = ProjectTree(self, self.mainnodes) self.project_tree.doubleClicked.connect(self.on_tree_clicked) treeDock.setWidget(self.project_tree) '''Инициализациия центра''' jog = JogWidget(app=self.qapp, axies=self.controls, pinAcions=self.pinAcions, motorActions=self.send_to_grbl) self.mainDialog.addToCenter(jog) jog.raise_() def send_to_grbl(self, text, send_type): if len(text): self.grbl.send_task(text, send_type) def pinAcions(self, status, pin): task = 'M62 {pin}'.format(pin=pin) if status else 'M63 {pin}'.format( pin=pin) self.grbl.send_task(task, SENDTYPE.IDLE) def setProgress(self, step, steps): value = step / float(len(steps)) * 100. indx = int(ceil(step - 1)) text = self.qapp.tr(steps[indx]) self.progressBar.setFormat("{0} - {1}%".format(text, round(value, 0))) self.progressBar.setValue(value) self.qapp.processEvents() def on_tree_clicked(self, index): item = self.project_tree.selectedIndexes()[0] if self.project.current_sample != item.model().itemFromIndex( index).obj: self.project.current_sample = item.model().itemFromIndex(index).obj self.refresh() def newProject(self): self.mainDialog.PreparedArea.clear() self.mainDialog.ThroughArea.clear() self.mainDialog.BacklightArea.clear() self.mainnodes = [Node("Samples"), Node("Other")] self.project_tree.setMainNodes(self.mainnodes) self.project = Project('TEMP') self.refresh() def openProject(self): fileName, _ = QFileDialog.getOpenFileName( self.mainDialog, self.qapp.tr("Load project"), ".\\", self.qapp.tr("Project file (*.tpr)")) infile = open(fileName, 'rb') self.project = pickle.load(infile) infile.close() self.mainDialog.PreparedArea.clear() self.mainDialog.ThroughArea.clear() self.mainDialog.BacklightArea.clear() self.mainnodes = [Node("Samples"), Node("Other")] self.project_tree.setMainNodes(self.mainnodes) self.refresh() def saveProject(self): fileName, _ = QFileDialog.getSaveFileName( self.mainDialog, self.qapp.tr("Save project"), ".\\", self.qapp.tr("Project file (*.tpr)")) outfile = open(fileName, "wb") pickle.dump(self.project, outfile) outfile.close() def draw_tree(self): target = self.mainnodes[0] children = target.children() samples_in_tree = [] for sample in self.project.samples.get_sorted_by_id(): if len(children) > 0: samples_in_tree = [node.obj for node in children] if sample not in samples_in_tree: target.addChild(Node(sample)) self.project_tree.refresh() def openFile(self): path_to_file, _ = QFileDialog.getOpenFileName( self.mainDialog, self.qapp.tr("Load Image"), self.qapp.tr(u".\example_imgs"), self.qapp.tr("Images (*.jpg)")) # path_to_file, _ = QFileDialog.getOpenFileName(self.mainDialog, self.app.tr("Load Image"), self.app.tr("~/Desktop/"), self.app.tr("Images (*.jpg)")) # Определяем тип файла на просвет или на подсветку tools.processing(path_to_file, self.project, self.separator, self.segmentation, self.counter, self.setProgress) self.refresh() def refresh(self): self.draw_tree() self.fill_table() self.updete_viewers() def fill_table(self): data = [] sample = self.project.current_sample if not sample: data = [['', '', '']] self.mainDialog.tablemodel.setData(data) return for track in sample.tracks.get_sorted(): data.append([str(track.id), str(track.count), str(track.area)]) self.mainDialog.tablemodel.setData(data) self.mainDialog.table.resizeRowsToContents() self.mainDialog.table.resizeColumnsToContents() count = round( np.sum([track.count for track in sample.tracks.get_sorted_by_id()]), 2) general_area = round( np.sum([track.area for track in sample.tracks.get_sorted_by_id()]), 2) self.mainDialog.infolabel.setText(''' <p align="center">General tracks count<br>{tracks_count}</p> <p align="center">General tracks area (%)<br>{general_area}</p> '''.format(tracks_count=count, general_area=general_area)) def draw_objects(self, viewer, sample): for track in sample.tracks.get_sorted(): viewer.add_rect(track.left, track.rigth, track.top, track.bottom) viewer.add_Polygon(track.contour, track.left, track.top) text = 'Count: {tracks_count}\nArea (%): {general_area}'.format( tracks_count=track.count, general_area=track.area) viewer.add_Text(text, track.left, track.top) def updete_viewers(self): sample = self.project.current_sample if not sample: return self.mainDialog.ThroughArea.load_image(sample.through) self.mainDialog.BacklightArea.load_image(sample.backlight) self.mainDialog.PreparedArea.load_image(sample.prepared) self.draw_objects(self.mainDialog.ThroughArea, sample) self.draw_objects(self.mainDialog.BacklightArea, sample) self.draw_objects(self.mainDialog.PreparedArea, sample) def __connect_to_grbl__(self): '''Функция подключения к CNC сканера, которая передается в настройки станка''' status = self.grbl.connect() if not status: return self.cnc_indicator.setStatus(-1) self.grbl.reset_alarm() self.cnc_indicator.setStatus(status) return status def __check_ip__(self, ip): status = False test_grbl = GRBL(HOST=self.settings.grblip) test_grbl.setHost(ip) try: status = test_grbl.connect(check=False) test_grbl.connection.close() except OSError: pass return ip if status else None def __auto_seach__(self, property=None): '''Функция авто поиска IP станка property нужен, чтобы вернуть результат в inputField окна настроек ''' if self.grbl.connection: self.grbl.connection.close() devices = [device for device in os.popen('arp -a')] ip_candidates = [ re.findall(r"\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b", device)[0] for device in devices if len(re.findall(r"\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b", device)) != 0 ] if self.settings.grblip in ip_candidates: ip_candidates.remove(self.settings.grblip) ip_candidates.insert(0, self.settings.grblip) pool = ThreadPool(4) results = pool.map(self.__check_ip__, ip_candidates) index = np.where(results != None)[0][0] if not results[index]: # print(self.qapp.tr('There is not devices in current net')) return pool.close() pool.join() self.grbl.setHost(results[index]) self.__connect_to_grbl__() if property: property.setText( results[index] ) # property нужен, чтобы вернуть результат в inputField self.settings.grblip = results[index] self.settings.write() print(self.qapp.tr('Connected to') + ' {ip}'.format(ip=results[index])) return True def showAbout(self): about = about_dialog(self) about.open() def showGrblDialog(self): dialog = grblDialog(self, connection_func=self.__connect_to_grbl__, auto_seach_func=self.__auto_seach__) dialog.execute(self.settings)
from app import db, Settings db.create_all() default_settings = Settings(owner_id=None, feedback=1, constant_time_version=0, t_value=2500, trial_count=15) db.session.add(default_settings) db.session.commit()
def openSettingsWindow(self): if not hasattr(self, 'settingsWidget'): self.settingsWidget = Settings() if self.settingsWidget.isclosed: self.settingsWidget.show() self.settingsWidget.isclosed = False
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)
def saveSetiings(self, settings: Settings): settings.grblip = self._ip_label.text
def setUp(self): app.config['TESTING'] = True app.config['BASE_URI'] = 'http://*****:*****@somewhere-org' settings.test_business_id = 'test.someone@somewhere-org' settings.submission_url = 'http://not-a-real-url' settings.test_submission_url = 'http://test-not-a-real-url' settings.verification_url = 'http://not-a-real-verification-url' settings.test_verification_url = 'http://test-not-a-real-verification-url' settings.smtp_host = 'somewhere-org' settings.smtp_port = 465 settings.smtp_login = '******' settings.smtp_pass = '******' settings.notification_email = 'someone.who.cares@somewhere-org' settings.test_notification_email = 'test.someone.who.cares@somewhere-org' settings.contact_email = 'someone.who.cares@somewhere-org' settings.test_contact_email = 'test.someone.who.cares@somewhere-org' settings.organization_name = 'Somewhere' settings.organization_url = 'http://somewhere-org' settings.paypal_rate = 0.022 settings.paypal_surcharge = 0.30 db.session.add(settings) db.session.commit()