def __init__( self, f_tee: Optional[tuple] = None, f_mock: Optional[Any] = None, ) -> None: log.debug('creating core') fname_precomputed_preorders: Optional[str] try: fname_precomputed_preorders = platform_specific.get_embedded_file_path( 'preorders-7.bin') except platform_specific.FileNotFound: fname_precomputed_preorders = None cmdline = [ platform_specific.get_embedded_file_path( 'prest-core.exe', # deployment Windows 'prest-core', # deployment elsewhere (?) 'core/target/release/prest-core.exe', # CI Windows 'core/target/release/prest-core', # CI elsewhere ) ] if fname_precomputed_preorders: cmdline += ['--precomputed-preorders', fname_precomputed_preorders] try: self.core = subprocess.Popen( cmdline, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, ) self.stdin: FileOut self.stdout: FileIn if f_tee: f_in, f_out = f_tee self.stdin = typing.cast(FileOut, Tee(self.core.stdin, f_in)) self.stdout = typing.cast(FileIn, Tee(self.core.stdout, f_out)) else: self.stdin = typing.cast(FileOut, self.core.stdin) if f_mock: self.stdout = typing.cast(FileIn, f_mock) else: self.stdout = typing.cast(FileIn, self.core.stdout) self.stderr: FileIn = typing.cast(FileIn, self.core.stderr) except OSError: raise CoreError('could not run core') self.stderr_reader = StreamReader(self.stderr) self.stderr_reader.start() log.debug('the core is running')
def __init__(self, ds: 'BudgetaryConsistency') -> None: QDialog.__init__(self) self.setupUi(self) help_icon = QIcon( platform_specific.get_embedded_file_path( 'images/qm-16.png', # deploy 'gui/images/qm-16.png', # devel )) F = util.tree_model.Field self.ds = ds self.model = util.tree_model.TreeModel( RootNode(ds.subjects), headers=[ 'Subject', 'Cycle length', F( 'GARP', help_icon, 'consistency/cons_budgetary.html#generalized-axiom-of-revealed-preference-garp' ), F( 'SARP', help_icon, 'consistency/cons_budgetary.html#strong-axiom-of-revealed-preference-sarp' ), F( 'WARP (strict)', help_icon, 'consistency/cons_budgetary.html#weak-axiom-of-revealed-preference-warp' ), F( 'WARP (non-strict)', help_icon, 'consistency/cons_budgetary.html#weak-axiom-of-revealed-preference-warp' ), F('HM (GARP)', help_icon, 'consistency/cons_budgetary.html#houtman-maks-index-hm'), F('HM (SARP)', help_icon, 'consistency/cons_budgetary.html#houtman-maks-index-hm'), F('HM (WARP strict)', help_icon, 'consistency/cons_budgetary.html#houtman-maks-index-hm'), F('HM (WARP non-strict)', help_icon, 'consistency/cons_budgetary.html#houtman-maks-index-hm'), ], ) self.twRows.setModel(self.model) hdr = self.twRows.header() hdr.setSectionResizeMode(QHeaderView.ResizeToContents) hdr.setStretchLastSection(False) hdr.setSectionsClickable(True) hdr.sectionClicked.connect(self.header_clicked)
def __init__(self) -> None: QDialog.__init__(self) self.setupUi(self) self.lblPrest.setPixmap( QPixmap( platform_specific.get_embedded_file_path( 'images/prest-logo.png', # deployment 'gui/images/prest-logo.png', # development ))) self.lblVersion.setText(branding.VERSION) self.lblLicense.linkActivated.connect(self.catch_exc( self.open_license))
def __init__(self, ds: 'ConsistencyResult') -> None: QDialog.__init__(self) self.setupUi(self) help_icon = QIcon( platform_specific.get_embedded_file_path( 'images/qm-16.png', # deploy 'gui/images/qm-16.png', # devel )) # we assign model to self to prevent GC F = util.tree_model.Field self.model = util.tree_model.TreeModel( RootNode(ds.subjects), headers=( 'Subject', 'Cycle length', F( 'WARP (pairs)', help_icon, 'consistency/cons_general.html#weak-axiom-of-revealed-preference-warp' ), F( 'WARP (all)', help_icon, 'consistency/cons_general.html#weak-axiom-of-revealed-preference-warp' ), F('Congruence', help_icon, 'consistency/cons_general.html#congruence'), F( 'Strict general cycles', help_icon, 'consistency/cons_general.html#strict-choice-consistency' ), # SARP F( 'Binary cycles', help_icon, 'consistency/cons_general.html#binary-choice-consistency' ), F( 'Strict binary cycles', help_icon, 'consistency/cons_general.html#strict-binary-choice-consistency' ), # SARP-binary ), ) self.twRows.setModel(self.model) hdr = self.twRows.header() hdr.setSectionsClickable(True) hdr.sectionClicked.connect(self.header_clicked) hdr.setSectionResizeMode(QHeaderView.ResizeToContents) hdr.setStretchLastSection(False)
def fill_table(self): self.checkboxes = [] help_icon = QIcon(platform_specific.get_embedded_file_path( 'images/qm-16.png', # deploy 'gui/images/qm-16.png', # devel )) self.twModels.clear() def add_item(parent, item): if isinstance(item, model.Category): twi = QTreeWidgetItem(parent, [item.name, None, None]) twi.setFirstColumnSpanned(True) for child in item.children: add_item(twi, child) elif isinstance(item, model.ModelGroup): twi = QTreeWidgetItem(parent) twi.setDisabled(not item.variants) cell = QWidget() layout = QHBoxLayout(cell) layout.setContentsMargins(4,2,4,2) # l,t,r,b lblName = QLabel(item.name) layout.addWidget(lblName, alignment=Qt.AlignVCenter) self.twModels.setItemWidget(twi, 1, cell) if item.help_url: btn = QPushButton(help_icon, '') btn.setFlat(True) # create a closure for `html` def connect(url): btn.clicked.connect(self.catch_exc( lambda _checked: doc.open_in_browser(url) )) connect(item.help_url) self.twModels.setItemWidget(twi, 0, btn) for i, name_model in enumerate(item.variants, 2): if name_model is None: continue # the identifier "model" would clash with the module import name_html, model_def = name_model cb = QCheckBox() label = QLabel(name_html) label.setAlignment(Qt.AlignLeft | Qt.AlignVCenter) cell = QWidget() layout = QHBoxLayout(cell) layout.setSpacing(4) layout.setContentsMargins(4,0,4,0) # l,t,r,b layout.addWidget(cb, stretch=0, alignment=Qt.AlignVCenter) layout.addWidget(label, stretch=1, alignment=Qt.AlignVCenter) # all extra space (stretch) goes to the label because stretch ratio is 1:0 self.twModels.setItemWidget(twi, i, cell) self.checkboxes.append((cb, model_def)) else: raise Exception('unknown item: %s' % item) root = self.twModels.invisibleRootItem() for item in model.MODELS: add_item(root, item)
def __init__(self): # window setup log.debug('creating GUI') QMainWindow.__init__(self) self.setupUi(self) # icon self.setWindowIcon( QIcon( platform_specific.get_embedded_file_path( 'images/prest.ico', # deployment 'gui/images/prest.ico', # development ))) # instance attributes self.workspace = workspace.Workspace() # main menu self.actionGenerate_random_subjects.triggered.connect( self.catch_exc(self.dlg_simulation)) self.actionWorkspaceClear.triggered.connect( self.catch_exc(self.dlg_workspace_clear)) self.actionWorkspaceLoad.triggered.connect( self.catch_exc(self.dlg_workspace_load)) self.actionWorkspaceSave.triggered.connect( self.catch_exc(self.dlg_workspace_save)) self.actionWorkspaceSaveAs.triggered.connect( self.catch_exc(self.dlg_workspace_save_as)) self.actionDatasetImport.triggered.connect( self.catch_exc(self.dlg_dataset_import)) self.actionImport_budgetary_dataset.triggered.connect( self.catch_exc(self.dlg_budgetary_import)) self.actionHelp.triggered.connect(self.catch_exc(self.dlg_help_show)) self.actionAbout_Prest.triggered.connect(self.catch_exc( self.dlg_about)) self.actionQuit.triggered.connect( self.close) # self.close is a slot -> not wrapping # debug self.actionShow_console_window.toggled.connect( self.catch_exc(self.show_console_window)) self.actionCrash_core.triggered.connect( self.catch_exc(self.dlg_crash_core)) self.actionSoft_core_failure.triggered.connect( self.catch_exc(self.dlg_soft_core_failure)) self.actionHidden_features.toggled.connect( self.catch_exc(self.enable_hidden_features)) self.tblDataSets.doubleClicked.connect( self.catch_exc(self.dlg_view_current_dataset)) self.tblDataSets.customContextMenuRequested.connect( self.catch_exc(self.context_menu)) self.tblDataSets.horizontalHeader().setSectionResizeMode( QHeaderView.ResizeToContents) self.tblDataSets.horizontalHeader().setStretchLastSection(False) if not platform_specific.is_windows(): self.actionShow_console_window.setEnabled(False) self.enableDebuggingTools = QShortcut( QKeySequence(Qt.CTRL + Qt.Key_D), self, ) self.enableDebuggingTools.activated.connect( self.enable_debugging_tools) self.menuDebugging_tools.menuAction().setVisible(False) self.hidden_features_enabled = False try: doc.start_daemon( platform_specific.get_embedded_file_path( 'html', # deployment 'docs/build/html', # development )) except OSError as e: log.exception('could not start doc server')
def context_menu(self, pos) -> None: item = self.tblDataSets.itemAt(pos) if item is None: log.debug('context menu requested but no item selected') return ds = self.workspace.datasets[self.tblDataSets.row(item)] menu = QMenu(self) icon_hidden = QIcon( platform_specific.get_embedded_file_path( 'images/experimental.png', # deployment 'gui/images/experimental.png', # development )) a_view = QAction("View...", menu) a_view.triggered.connect(self.catch_exc(ds.dlg_view)) a_view.setStatusTip( 'Display the dataset in a separate window. Also available via double click.' ) menu.addAction(a_view) analyses = ds.get_analyses() if analyses: m_analyses = QMenu(menu) a_analyses = QAction("Analysis", menu) a_analyses.setMenu(m_analyses) a_analyses.setStatusTip('Run various analyses on the dataset.') menu.addAction(a_analyses) for analysis in analyses: if analysis.is_hidden: if self.hidden_features_enabled: icon = icon_hidden else: # skip this one continue else: icon = None def mkanalyse(analysis): def analyse(_flag): new_ds = ds.analyse(analysis) if new_ds is not None: self.add_dataset(new_ds) return analyse if analysis.config: analysis_name = analysis.name + '...' else: analysis_name = analysis.name a_analysis = QAction(analysis_name, m_analyses) if icon: a_analysis.setIcon(icon) a_analysis.analyse = mkanalyse( analysis) # create and save the closure a_analysis.triggered.connect(self.catch_exc( a_analysis.analyse)) m_analyses.addAction(a_analysis) export_variants = ds.get_export_variants() if export_variants: m_exports = QMenu(menu) a_exports = QAction("Export", menu) a_exports.setMenu(m_exports) a_exports.setStatusTip('Export the dataset into a file on disk.') menu.addAction(a_exports) for export_variant in export_variants: def mkexport(export_variant): def export(_flag): fname, fformat = QFileDialog.getSaveFileName( self, "Export dataset", filter= "Excel 2010+ (*.xlsx);;Comma Separated Values (*.csv)" ) if not fname: return class MyWorker(Worker): def work(self): ds.export(fname, fformat, export_variant, self) try: MyWorker().run_with_progress( None, "Exporting to %s..." % fname) except Cancelled: log.info('export cancelled') return export a_export = QAction(export_variant.name + '...', m_exports) a_export.export = mkexport( export_variant) # create and save the closure a_export.triggered.connect(self.catch_exc(a_export.export)) m_exports.addAction(a_export) menu.addSeparator() def delete(_flag): answer = QMessageBox.question( self, "Delete dataset", "Do you really want to delete the selected dataset?", defaultButton=QMessageBox.No) if answer == QMessageBox.Yes: self.delete_dataset(ds) a_delete = QAction("Delete", menu) a_delete.delete = delete a_delete.triggered.connect(self.catch_exc(a_delete.delete)) a_delete.setStatusTip( 'Remove the dataset from the workspace. Asks for confirmation.') menu.addAction(a_delete) menu.popup(self.tblDataSets.viewport().mapToGlobal(pos))
import platform_specific with open(platform_specific.get_embedded_file_path('version.txt')) as f: VERSION = f.read().strip() PREST_VERSION = f'Prest {VERSION}'