def show_context_menu(self): """ Creates and shows the context menu for the search widget :return: QAction """ menu = QMenu(self) standard_menu = self.createStandardContextMenu() standard_menu.setTitle('Edit') menu.addMenu(standard_menu) sub_menu = QMenu(menu) sub_menu.setTitle('Space Operator') menu.addMenu(sub_menu) or_action = QAction('OR', menu) or_action.setCheckable(True) or_callback = partial(self.set_space_operator, 'or') or_action.triggered.connect(or_callback) if self.space_operator() == 'or': or_action.setChecked(True) sub_menu.addAction(or_action) and_action = QAction('AND', menu) and_action.setCheckable(True) and_callback = partial(self.set_space_operator, 'and') and_action.triggered.connect(and_callback) if self.space_operator() == 'and': and_action.setChecked(True) sub_menu.addAction(and_action) action = menu.exec_(QCursor.pos()) return action
def contextMenuEvent(self, event): data = self.page().contextMenuData() assert data.isValid() if not data.isContentEditable(): super().contextMenuEvent(event) return profile = self.page().profile() languages = profile.spellCheckLanguages() menu = self.page().createStandardContextMenu() menu.setParent(self) menu.addSeparator() spellcheckAction = QAction(self.tr("Check Spelling"), None) spellcheckAction.setCheckable(True) spellcheckAction.setChecked(profile.isSpellCheckEnabled()) spellcheckAction.toggled.connect(profile.setSpellCheckEnabled) menu.addAction(spellcheckAction) if profile.isSpellCheckEnabled(): subMenu = menu.addMenu(self.tr("Select Language")) for key, lang in self.m_spellCheckLanguages.items(): action = subMenu.addAction(key) action.setCheckable(True) action.setChecked(lang in languages) action.triggered.connect(partial(self.on_triggered, lang)) menu.aboutToHide.connect(menu.deleteLater) menu.popup(event.globalPos())
def __init__(self, parent: QWidget = None): super().__init__(parent) self.map = LightMaps() self.setCentralWidget(self.map) self.map.setFocus() osloAction = QAction(self.tr("&Oslo"), self) berlinAction = QAction(self.tr("&Berlin"), self) jakartaAction = QAction(self.tr("&Jakarta"), self) nightModeAction = QAction(self.tr("Night Mode"), self) nightModeAction.setCheckable(True) nightModeAction.setChecked(False) osmAction = QAction(self.tr("About OpenStreetMap"), self) osloAction.triggered.connect(self.chooseOslo) berlinAction.triggered.connect(self.chooseBerlin) jakartaAction.triggered.connect(self.chooseJakarta) nightModeAction.triggered.connect(self.map.toggleNightMode) osmAction.triggered.connect(self.aboutOsm) menu = self.menuBar().addMenu(self.tr("&Options")) menu.addAction(osloAction) menu.addAction(berlinAction) menu.addAction(jakartaAction) menu.addSeparator() menu.addAction(nightModeAction) menu.addAction(osmAction) self.setWindowTitle(self.tr("Light Maps"))
def create_settings_menu(self): """ Creates and returns the settings menu for this widget :return: QMenu """ menu = QMenu('Item View', self) menu.setIcon(resources.icon('eye')) menu.addSeparator() # copy_text_menu = self.tree_widget().create_copy_text_menu() # menu.addMenu(copy_text_menu) # menu.addSeparator() size_action = action.SliderAction('Size', menu) size_action.slider().setMinimum(10) size_action.slider().setMaximum(200) size_action.slider().setValue(self.zoom_amount()) size_action.slider().valueChanged.connect(self.set_zoom_amount) menu.addAction(size_action) border_action = action.SliderAction('Border', menu) border_action.slider().setMinimum(0) border_action.slider().setMaximum(20) border_action.slider().setValue(self.padding()) border_action.slider().valueChanged.connect(self.set_padding) menu.addAction(border_action) spacing_action = action.SliderAction('Spacing', menu) spacing_action.slider().setMinimum(self.DEFAULT_MIN_SPACING) spacing_action.slider().setMaximum(self.DEFAULT_MAX_SPACING) spacing_action.slider().setValue(self.spacing()) spacing_action.slider().valueChanged.connect(self.set_spacing) menu.addAction(spacing_action) menu.addAction(action.SeparatorAction('Label Options', menu)) for option in item.LabelDisplayOption.values(): option_action = QAction(option.title(), menu) option_action.setCheckable(True) option_action.setChecked(option == self.label_display_option()) option_callback = partial(self.set_label_display_option, option) option_action.triggered.connect(option_callback) menu.addAction(option_action) return menu
class PlotMainWindow(QWidget): """Base class for plot main windows.""" def __init__(self, U, plot, length=1, title=None): super().__init__() layout = QVBoxLayout() if title: title = QLabel('<b>' + title + '</b>') title.setAlignment(Qt.AlignHCenter) layout.addWidget(title) layout.addWidget(plot) plot.set(U, 0) if length > 1: hlayout = QHBoxLayout() self.slider = QSlider(Qt.Horizontal) self.slider.setMinimum(0) self.slider.setMaximum(length - 1) self.slider.setTickPosition(QSlider.TicksBelow) hlayout.addWidget(self.slider) lcd = QLCDNumber(m.ceil(m.log10(length))) lcd.setDecMode() lcd.setSegmentStyle(QLCDNumber.Flat) hlayout.addWidget(lcd) layout.addLayout(hlayout) hlayout = QHBoxLayout() toolbar = QToolBar() self.a_play = QAction(self.style().standardIcon(QStyle.SP_MediaPlay), 'Play', self) self.a_play.setCheckable(True) self.a_rewind = QAction(self.style().standardIcon(QStyle.SP_MediaSeekBackward), 'Rewind', self) self.a_toend = QAction(self.style().standardIcon(QStyle.SP_MediaSeekForward), 'End', self) self.a_step_backward = QAction(self.style().standardIcon(QStyle.SP_MediaSkipBackward), 'Step Back', self) self.a_step_forward = QAction(self.style().standardIcon(QStyle.SP_MediaSkipForward), 'Step', self) self.a_loop = QAction(self.style().standardIcon(QStyle.SP_BrowserReload), 'Loop', self) self.a_loop.setCheckable(True) toolbar.addAction(self.a_play) toolbar.addAction(self.a_rewind) toolbar.addAction(self.a_toend) toolbar.addAction(self.a_step_backward) toolbar.addAction(self.a_step_forward) toolbar.addAction(self.a_loop) if hasattr(self, 'save'): self.a_save = QAction(self.style().standardIcon(QStyle.SP_DialogSaveButton), 'Save', self) toolbar.addAction(self.a_save) self.a_save.triggered.connect(self.save) hlayout.addWidget(toolbar) self.speed = QSlider(Qt.Horizontal) self.speed.setMinimum(0) self.speed.setMaximum(100) hlayout.addWidget(QLabel('Speed:')) hlayout.addWidget(self.speed) layout.addLayout(hlayout) self.timer = QTimer() self.timer.timeout.connect(self.update_solution) self.slider.valueChanged.connect(self.slider_changed) self.slider.valueChanged.connect(lcd.display) self.speed.valueChanged.connect(self.speed_changed) self.a_play.toggled.connect(self.toggle_play) self.a_rewind.triggered.connect(self.rewind) self.a_toend.triggered.connect(self.to_end) self.a_step_forward.triggered.connect(self.step_forward) self.a_step_backward.triggered.connect(self.step_backward) self.speed.setValue(50) elif hasattr(self, 'save'): hlayout = QHBoxLayout() toolbar = QToolBar() self.a_save = QAction(self.style().standardIcon(QStyle.SP_DialogSaveButton), 'Save', self) toolbar.addAction(self.a_save) hlayout.addWidget(toolbar) layout.addLayout(hlayout) self.a_save.triggered.connect(self.save) self.setLayout(layout) self.plot = plot self.U = U self.length = length def slider_changed(self, ind): self.plot.set(self.U, ind) def speed_changed(self, val): self.timer.setInterval(val * 20) def update_solution(self): ind = self.slider.value() + 1 if ind >= self.length: if self.a_loop.isChecked(): ind = 0 else: self.a_play.setChecked(False) return self.slider.setValue(ind) def toggle_play(self, checked): if checked: if self.slider.value() + 1 == self.length: self.slider.setValue(0) self.timer.start() else: self.timer.stop() def rewind(self): self.slider.setValue(0) def to_end(self): self.a_play.setChecked(False) self.slider.setValue(self.length - 1) def step_forward(self): self.a_play.setChecked(False) ind = self.slider.value() + 1 if ind == self.length and self.a_loop.isChecked(): ind = 0 if ind < self.length: self.slider.setValue(ind) def step_backward(self): self.a_play.setChecked(False) ind = self.slider.value() - 1 if ind == -1 and self.a_loop.isChecked(): ind = self.length - 1 if ind >= 0: self.slider.setValue(ind)
def _build_ui(self): layout = QFormLayout() self.cone_option = QComboBox() self.cone_option.addItems(["Tolman (Unsymmetrical)", "Exact"]) ndx = self.cone_option.findText(self.settings.cone_option, Qt.MatchExactly) self.cone_option.setCurrentIndex(ndx) layout.addRow("method:", self.cone_option) self.radii_option = QComboBox() self.radii_option.addItems(["Bondi", "UMN"]) ndx = self.radii_option.findText(self.settings.radii, Qt.MatchExactly) self.radii_option.setCurrentIndex(ndx) layout.addRow("radii:", self.radii_option) self.display_cone = QCheckBox() self.display_cone.setChecked(self.settings.display_cone) layout.addRow("show cone:", self.display_cone) self.display_radii = QCheckBox() self.display_radii.setChecked(self.settings.display_radii) layout.addRow("show radii:", self.display_radii) set_ligand_button = QPushButton("set ligand to current selection") set_ligand_button.clicked.connect(self.set_ligand) layout.addRow(set_ligand_button) self.set_ligand_button = set_ligand_button calc_cone_button = QPushButton( "calculate cone angle for ligand on selected center") calc_cone_button.clicked.connect(self.calc_cone) layout.addRow(calc_cone_button) self.calc_cone_button = calc_cone_button remove_cone_button = QPushButton("remove cone visualizations") remove_cone_button.clicked.connect(self.del_cone) layout.addRow(remove_cone_button) self.remove_cone_button = remove_cone_button self.table = QTableWidget() self.table.setColumnCount(3) self.table.setHorizontalHeaderLabels([ 'model', 'center', 'cone angle (°)', ]) self.table.setSelectionBehavior(QTableWidget.SelectRows) self.table.setEditTriggers(QTableWidget.NoEditTriggers) self.table.resizeColumnToContents(0) self.table.resizeColumnToContents(1) self.table.resizeColumnToContents(2) self.table.horizontalHeader().setSectionResizeMode( 2, QHeaderView.Stretch) layout.addRow(self.table) menu = QMenuBar() export = menu.addMenu("&Export") clear = QAction("Clear data table", self.tool_window.ui_area) clear.triggered.connect(self.clear_table) export.addAction(clear) copy = QAction("&Copy CSV to clipboard", self.tool_window.ui_area) copy.triggered.connect(self.copy_csv) shortcut = QKeySequence(Qt.CTRL + Qt.Key_C) copy.setShortcut(shortcut) export.addAction(copy) save = QAction("&Save CSV...", self.tool_window.ui_area) save.triggered.connect(self.save_csv) #this shortcut interferes with main window's save shortcut #I've tried different shortcut contexts to no avail #thanks Qt... #shortcut = QKeySequence(Qt.CTRL + Qt.Key_S) #save.setShortcut(shortcut) #save.setShortcutContext(Qt.WidgetShortcut) export.addAction(save) delimiter = export.addMenu("Delimiter") comma = QAction("comma", self.tool_window.ui_area, checkable=True) comma.setChecked(self.settings.delimiter == "comma") comma.triggered.connect(lambda *args, delim="comma": self.settings. __setattr__("delimiter", delim)) delimiter.addAction(comma) tab = QAction("tab", self.tool_window.ui_area, checkable=True) tab.setChecked(self.settings.delimiter == "tab") tab.triggered.connect(lambda *args, delim="tab": self.settings. __setattr__("delimiter", delim)) delimiter.addAction(tab) space = QAction("space", self.tool_window.ui_area, checkable=True) space.setChecked(self.settings.delimiter == "space") space.triggered.connect(lambda *args, delim="space": self.settings. __setattr__("delimiter", delim)) delimiter.addAction(space) semicolon = QAction("semicolon", self.tool_window.ui_area, checkable=True) semicolon.setChecked(self.settings.delimiter == "semicolon") semicolon.triggered.connect(lambda *args, delim="semicolon": self. settings.__setattr__("delimiter", delim)) delimiter.addAction(semicolon) add_header = QAction("&Include CSV header", self.tool_window.ui_area, checkable=True) add_header.setChecked(self.settings.include_header) add_header.triggered.connect(self.header_check) export.addAction(add_header) comma.triggered.connect( lambda *args, action=tab: action.setChecked(False)) comma.triggered.connect( lambda *args, action=space: action.setChecked(False)) comma.triggered.connect( lambda *args, action=semicolon: action.setChecked(False)) tab.triggered.connect( lambda *args, action=comma: action.setChecked(False)) tab.triggered.connect( lambda *args, action=space: action.setChecked(False)) tab.triggered.connect( lambda *args, action=semicolon: action.setChecked(False)) space.triggered.connect( lambda *args, action=comma: action.setChecked(False)) space.triggered.connect( lambda *args, action=tab: action.setChecked(False)) space.triggered.connect( lambda *args, action=semicolon: action.setChecked(False)) semicolon.triggered.connect( lambda *args, action=comma: action.setChecked(False)) semicolon.triggered.connect( lambda *args, action=tab: action.setChecked(False)) semicolon.triggered.connect( lambda *args, action=space: action.setChecked(False)) menu.setNativeMenuBar(False) self._menu = menu layout.setMenuBar(menu) menu.setVisible(True) self.tool_window.ui_area.setLayout(layout) self.tool_window.manage(None)
def _build_ui(self): #each group has an empty widget at the bottom so they resize the way I want while also having the #labels where I want them layout = QGridLayout() self.tab_widget = QTabWidget() layout.addWidget(self.tab_widget) #layout for absolute thermo stuff absolute_widget = QWidget() absolute_layout = QGridLayout(absolute_widget) #box for sp sp_area_widget = QGroupBox("Single-point") sp_layout = QFormLayout(sp_area_widget) self.sp_selector = FilereaderComboBox(self.session, otherItems=['energy']) self.sp_selector.currentIndexChanged.connect(self.set_sp) sp_layout.addRow(self.sp_selector) self.sp_table = QTableWidget() self.sp_table.setColumnCount(3) self.sp_table.setShowGrid(False) self.sp_table.horizontalHeader().hide() self.sp_table.verticalHeader().hide() self.sp_table.setFrameShape(QTableWidget.NoFrame) self.sp_table.setSelectionMode(QTableWidget.NoSelection) self.sp_table.insertRow(0) sp_layout.addRow(self.sp_table) #box for thermo therm_area_widget = QGroupBox("Thermal corrections") thermo_layout = QFormLayout(therm_area_widget) self.thermo_selector = FilereaderComboBox(self.session, otherItems=['frequency']) self.thermo_selector.currentIndexChanged.connect(self.set_thermo_mdl) thermo_layout.addRow(self.thermo_selector) self.temperature_line = QDoubleSpinBox() self.temperature_line.setMaximum(2**31 - 1) self.temperature_line.setValue(298.15) self.temperature_line.setSingleStep(10) self.temperature_line.setSuffix(" K") self.temperature_line.setMinimum(0) self.temperature_line.valueChanged.connect(self.set_thermo) thermo_layout.addRow("T =", self.temperature_line) self.v0_edit = QDoubleSpinBox() self.v0_edit.setMaximum(4000) self.v0_edit.setValue(self.settings.w0) self.v0_edit.setSingleStep(25) self.v0_edit.setSuffix(" cm\u207b\u00b9") self.v0_edit.valueChanged.connect(self.set_thermo) self.v0_edit.setMinimum(0) self.v0_edit.setToolTip( "frequency parameter for quasi treatments of entropy") thermo_layout.addRow("𝜔<sub>0</sub> =", self.v0_edit) self.thermo_table = QTableWidget() self.thermo_table.setColumnCount(3) self.thermo_table.setShowGrid(False) self.thermo_table.horizontalHeader().hide() self.thermo_table.verticalHeader().hide() self.thermo_table.setFrameShape(QTableWidget.NoFrame) self.thermo_table.setSelectionMode(QTableWidget.NoSelection) thermo_layout.addRow(self.thermo_table) # for for total sum_area_widget = QGroupBox("Thermochemistry") sum_layout = QFormLayout(sum_area_widget) self.sum_table = QTableWidget() self.sum_table.setColumnCount(3) self.sum_table.setShowGrid(False) self.sum_table.horizontalHeader().hide() self.sum_table.verticalHeader().hide() self.sum_table.setFrameShape(QTableWidget.NoFrame) self.sum_table.setSelectionMode(QTableWidget.NoSelection) sum_layout.addRow(self.sum_table) splitter = QSplitter(Qt.Horizontal) splitter.setChildrenCollapsible(False) splitter.addWidget(sp_area_widget) splitter.addWidget(therm_area_widget) splitter.addWidget(sum_area_widget) absolute_layout.addWidget(splitter) self.status = QStatusBar() self.status.setSizeGripEnabled(False) self.status.setStyleSheet("color: red") absolute_layout.addWidget(self.status, 1, 0, 1, 1, Qt.AlignTop) self.tab_widget.addTab(absolute_widget, "absolute") relative_widget = QWidget() relative_layout = QGridLayout(relative_widget) size = [self.settings.ref_col_1, self.settings.ref_col_2] self.ref_group = ThermoGroup("reference group", self.session, self.nrg_fr, self.thermo_co, size) self.ref_group.changes.connect(self.calc_relative_thermo) relative_layout.addWidget(self.ref_group, 0, 0, 1, 3, Qt.AlignTop) size = [self.settings.other_col_1, self.settings.other_col_2] self.other_group = ThermoGroup("other group", self.session, self.nrg_fr, self.thermo_co, size) self.other_group.changes.connect(self.calc_relative_thermo) relative_layout.addWidget(self.other_group, 0, 3, 1, 3, Qt.AlignTop) self.relative_temperature = QDoubleSpinBox() self.relative_temperature.setMaximum(2**31 - 1) self.relative_temperature.setValue(self.settings.rel_temp) self.relative_temperature.setSingleStep(10) self.relative_temperature.setSuffix(" K") self.relative_temperature.setMinimum(0) self.relative_temperature.valueChanged.connect( self.calc_relative_thermo) relative_layout.addWidget(QLabel("T ="), 1, 0, 1, 1, Qt.AlignRight | Qt.AlignVCenter) relative_layout.addWidget(self.relative_temperature, 1, 1, 1, 5, Qt.AlignLeft | Qt.AlignVCenter) self.relative_v0 = QDoubleSpinBox() self.relative_v0.setMaximum(2**31 - 1) self.relative_v0.setValue(self.settings.w0) self.relative_v0.setSingleStep(25) self.relative_v0.setSuffix(" cm\u207b\u00b9") self.relative_v0.setMinimum(0) self.relative_v0.setToolTip( "frequency parameter for quasi treatments of entropy") self.relative_v0.valueChanged.connect(self.calc_relative_thermo) relative_layout.addWidget(QLabel("𝜔<sub>0</sub> ="), 2, 0, 1, 1, Qt.AlignRight | Qt.AlignVCenter) relative_layout.addWidget(self.relative_v0, 2, 1, 1, 5, Qt.AlignLeft | Qt.AlignVCenter) relative_layout.addWidget( QLabel("Boltzmann-weighted relative energies in kcal/mol:"), 3, 0, 1, 6, Qt.AlignVCenter | Qt.AlignLeft) self.relative_table = QTextBrowser() self.relative_table.setMaximumHeight( 4 * self.relative_table.fontMetrics().boundingRect("Q").height()) relative_layout.addWidget(self.relative_table, 4, 0, 1, 6, Qt.AlignTop) relative_layout.setRowStretch(0, 1) relative_layout.setRowStretch(1, 0) relative_layout.setRowStretch(2, 0) relative_layout.setRowStretch(3, 0) relative_layout.setRowStretch(4, 0) self.tab_widget.addTab(relative_widget, "relative") #menu stuff menu = QMenuBar() export = menu.addMenu("&Export") copy = QAction("&Copy CSV to clipboard", self.tool_window.ui_area) copy.triggered.connect(self.copy_csv) shortcut = QKeySequence(Qt.CTRL + Qt.Key_C) copy.setShortcut(shortcut) export.addAction(copy) self.copy = copy save = QAction("&Save CSV...", self.tool_window.ui_area) save.triggered.connect(self.save_csv) #this shortcut interferes with main window's save shortcut #I've tried different shortcut contexts to no avail #thanks Qt... #shortcut = QKeySequence(Qt.CTRL + Qt.Key_S) #save.setShortcut(shortcut) #save.setShortcutContext(Qt.WidgetShortcut) export.addAction(save) delimiter = export.addMenu("Delimiter") comma = QAction("comma", self.tool_window.ui_area, checkable=True) comma.setChecked(self.settings.delimiter == "comma") comma.triggered.connect(lambda *args, delim="comma": self.settings. __setattr__("delimiter", delim)) delimiter.addAction(comma) tab = QAction("tab", self.tool_window.ui_area, checkable=True) tab.setChecked(self.settings.delimiter == "tab") tab.triggered.connect(lambda *args, delim="tab": self.settings. __setattr__("delimiter", delim)) delimiter.addAction(tab) space = QAction("space", self.tool_window.ui_area, checkable=True) space.setChecked(self.settings.delimiter == "space") space.triggered.connect(lambda *args, delim="space": self.settings. __setattr__("delimiter", delim)) delimiter.addAction(space) semicolon = QAction("semicolon", self.tool_window.ui_area, checkable=True) semicolon.setChecked(self.settings.delimiter == "semicolon") semicolon.triggered.connect(lambda *args, delim="semicolon": self. settings.__setattr__("delimiter", delim)) delimiter.addAction(semicolon) add_header = QAction("&Include CSV header", self.tool_window.ui_area, checkable=True) add_header.setChecked(self.settings.include_header) add_header.triggered.connect(self.header_check) export.addAction(add_header) comma.triggered.connect( lambda *args, action=tab: action.setChecked(False)) comma.triggered.connect( lambda *args, action=space: action.setChecked(False)) comma.triggered.connect( lambda *args, action=semicolon: action.setChecked(False)) tab.triggered.connect( lambda *args, action=comma: action.setChecked(False)) tab.triggered.connect( lambda *args, action=space: action.setChecked(False)) tab.triggered.connect( lambda *args, action=semicolon: action.setChecked(False)) space.triggered.connect( lambda *args, action=comma: action.setChecked(False)) space.triggered.connect( lambda *args, action=tab: action.setChecked(False)) space.triggered.connect( lambda *args, action=semicolon: action.setChecked(False)) semicolon.triggered.connect( lambda *args, action=comma: action.setChecked(False)) semicolon.triggered.connect( lambda *args, action=tab: action.setChecked(False)) semicolon.triggered.connect( lambda *args, action=space: action.setChecked(False)) menu.setNativeMenuBar(False) self._menu = menu layout.setMenuBar(menu) menu.setVisible(True) self.tool_window.ui_area.setLayout(layout) self.tool_window.manage(None)
class PlotMainWindow(QWidget): """Base class for plot main windows.""" def __init__(self, U, plot, length=1, title=None): super().__init__() layout = QVBoxLayout() if title: title = QLabel('<b>' + title + '</b>') title.setAlignment(Qt.AlignHCenter) layout.addWidget(title) layout.addWidget(plot) plot.set(U, 0) if length > 1: hlayout = QHBoxLayout() self.slider = QSlider(Qt.Horizontal) self.slider.setMinimum(0) self.slider.setMaximum(length - 1) self.slider.setTickPosition(QSlider.TicksBelow) hlayout.addWidget(self.slider) lcd = QLCDNumber(m.ceil(m.log10(length))) lcd.setDecMode() lcd.setSegmentStyle(QLCDNumber.Flat) hlayout.addWidget(lcd) layout.addLayout(hlayout) hlayout = QHBoxLayout() toolbar = QToolBar() self.a_play = QAction( self.style().standardIcon(QStyle.SP_MediaPlay), 'Play', self) self.a_play.setCheckable(True) self.a_rewind = QAction( self.style().standardIcon(QStyle.SP_MediaSeekBackward), 'Rewind', self) self.a_toend = QAction( self.style().standardIcon(QStyle.SP_MediaSeekForward), 'End', self) self.a_step_backward = QAction( self.style().standardIcon(QStyle.SP_MediaSkipBackward), 'Step Back', self) self.a_step_forward = QAction( self.style().standardIcon(QStyle.SP_MediaSkipForward), 'Step', self) self.a_loop = QAction( self.style().standardIcon(QStyle.SP_BrowserReload), 'Loop', self) self.a_loop.setCheckable(True) toolbar.addAction(self.a_play) toolbar.addAction(self.a_rewind) toolbar.addAction(self.a_toend) toolbar.addAction(self.a_step_backward) toolbar.addAction(self.a_step_forward) toolbar.addAction(self.a_loop) if hasattr(self, 'save'): self.a_save = QAction( self.style().standardIcon(QStyle.SP_DialogSaveButton), 'Save', self) toolbar.addAction(self.a_save) self.a_save.triggered.connect(self.save) hlayout.addWidget(toolbar) self.speed = QSlider(Qt.Horizontal) self.speed.setMinimum(0) self.speed.setMaximum(100) hlayout.addWidget(QLabel('Speed:')) hlayout.addWidget(self.speed) layout.addLayout(hlayout) self.timer = QTimer() self.timer.timeout.connect(self.update_solution) self.slider.valueChanged.connect(self.slider_changed) self.slider.valueChanged.connect(lcd.display) self.speed.valueChanged.connect(self.speed_changed) self.a_play.toggled.connect(self.toggle_play) self.a_rewind.triggered.connect(self.rewind) self.a_toend.triggered.connect(self.to_end) self.a_step_forward.triggered.connect(self.step_forward) self.a_step_backward.triggered.connect(self.step_backward) self.speed.setValue(50) elif hasattr(self, 'save'): hlayout = QHBoxLayout() toolbar = QToolBar() self.a_save = QAction( self.style().standardIcon(QStyle.SP_DialogSaveButton), 'Save', self) toolbar.addAction(self.a_save) hlayout.addWidget(toolbar) layout.addLayout(hlayout) self.a_save.triggered.connect(self.save) self.setLayout(layout) self.plot = plot self.U = U self.length = length def slider_changed(self, ind): self.plot.set(self.U, ind) def speed_changed(self, val): self.timer.setInterval(val * 20) def update_solution(self): ind = self.slider.value() + 1 if ind >= self.length: if self.a_loop.isChecked(): ind = 0 else: self.a_play.setChecked(False) return self.slider.setValue(ind) def toggle_play(self, checked): if checked: if self.slider.value() + 1 == self.length: self.slider.setValue(0) self.timer.start() else: self.timer.stop() def rewind(self): self.slider.setValue(0) def to_end(self): self.a_play.setChecked(False) self.slider.setValue(self.length - 1) def step_forward(self): self.a_play.setChecked(False) ind = self.slider.value() + 1 if ind == self.length and self.a_loop.isChecked(): ind = 0 if ind < self.length: self.slider.setValue(ind) def step_backward(self): self.a_play.setChecked(False) ind = self.slider.value() - 1 if ind == -1 and self.a_loop.isChecked(): ind = self.length - 1 if ind >= 0: self.slider.setValue(ind)
def _build_ui(self): layout = QFormLayout() self.radii_option = QComboBox() self.radii_option.addItems(["Bondi", "UMN"]) ndx = self.radii_option.findText(self.settings.radii, Qt.MatchExactly) self.radii_option.setCurrentIndex(ndx) layout.addRow("radii:", self.radii_option) self.L_option = QComboBox() self.L_option.addItems([ "to centroid of coordinating atoms", "bisect angle between coordinating atoms" ]) ndx = self.L_option.findText(self.settings.L_option, Qt.MatchExactly) self.L_option.setCurrentIndex(ndx) layout.addRow("L axis:", self.L_option) self.sterimol2vec = QGroupBox("Sterimol2Vec") sterimol2vec_layout = QFormLayout(self.sterimol2vec) self.at_L = QDoubleSpinBox() self.at_L.setRange(-10, 30) self.at_L.setDecimals(2) self.at_L.setSingleStep(0.25) self.at_L.setValue(self.settings.at_L) sterimol2vec_layout.addRow("L value:", self.at_L) layout.addRow(self.sterimol2vec) self.sterimol2vec.setCheckable(True) self.sterimol2vec.toggled.connect(lambda x: self.at_L.setEnabled(x)) self.sterimol2vec.setChecked(self.settings.sterimol2vec) self.display_vectors = QCheckBox() self.display_vectors.setChecked(self.settings.display_vectors) layout.addRow("show vectors:", self.display_vectors) self.display_radii = QCheckBox() self.display_radii.setChecked(self.settings.display_radii) layout.addRow("show radii:", self.display_radii) calc_sterimol_button = QPushButton( "calculate parameters for selected ligands") calc_sterimol_button.clicked.connect(self.calc_sterimol) layout.addRow(calc_sterimol_button) self.calc_sterimol_button = calc_sterimol_button remove_sterimol_button = QPushButton("remove Sterimol visualizations") remove_sterimol_button.clicked.connect(self.del_sterimol) layout.addRow(remove_sterimol_button) self.remove_sterimol_button = remove_sterimol_button self.table = QTableWidget() self.table.setColumnCount(8) self.table.setHorizontalHeaderLabels([ 'model', 'coord. atoms', 'B\u2081', 'B\u2082', 'B\u2083', 'B\u2084', 'B\u2085', 'L', ]) self.table.setSelectionBehavior(QTableWidget.SelectRows) self.table.setEditTriggers(QTableWidget.NoEditTriggers) self.table.resizeColumnToContents(0) self.table.resizeColumnToContents(1) self.table.resizeColumnToContents(2) self.table.resizeColumnToContents(3) self.table.resizeColumnToContents(4) self.table.resizeColumnToContents(5) self.table.resizeColumnToContents(6) self.table.resizeColumnToContents(7) self.table.horizontalHeader().setSectionResizeMode( 2, QHeaderView.Stretch) self.table.horizontalHeader().setSectionResizeMode( 3, QHeaderView.Stretch) self.table.horizontalHeader().setSectionResizeMode( 4, QHeaderView.Stretch) self.table.horizontalHeader().setSectionResizeMode( 5, QHeaderView.Stretch) self.table.horizontalHeader().setSectionResizeMode( 6, QHeaderView.Stretch) self.table.horizontalHeader().setSectionResizeMode( 7, QHeaderView.Stretch) layout.addRow(self.table) menu = QMenuBar() export = menu.addMenu("&Export") clear = QAction("Clear data table", self.tool_window.ui_area) clear.triggered.connect(self.clear_table) export.addAction(clear) copy = QAction("&Copy CSV to clipboard", self.tool_window.ui_area) copy.triggered.connect(self.copy_csv) shortcut = QKeySequence(Qt.CTRL + Qt.Key_C) copy.setShortcut(shortcut) export.addAction(copy) save = QAction("&Save CSV...", self.tool_window.ui_area) save.triggered.connect(self.save_csv) #this shortcut interferes with main window's save shortcut #I've tried different shortcut contexts to no avail #thanks Qt... #shortcut = QKeySequence(Qt.CTRL + Qt.Key_S) #save.setShortcut(shortcut) #save.setShortcutContext(Qt.WidgetShortcut) export.addAction(save) delimiter = export.addMenu("Delimiter") comma = QAction("comma", self.tool_window.ui_area, checkable=True) comma.setChecked(self.settings.delimiter == "comma") comma.triggered.connect(lambda *args, delim="comma": self.settings. __setattr__("delimiter", delim)) delimiter.addAction(comma) tab = QAction("tab", self.tool_window.ui_area, checkable=True) tab.setChecked(self.settings.delimiter == "tab") tab.triggered.connect(lambda *args, delim="tab": self.settings. __setattr__("delimiter", delim)) delimiter.addAction(tab) space = QAction("space", self.tool_window.ui_area, checkable=True) space.setChecked(self.settings.delimiter == "space") space.triggered.connect(lambda *args, delim="space": self.settings. __setattr__("delimiter", delim)) delimiter.addAction(space) semicolon = QAction("semicolon", self.tool_window.ui_area, checkable=True) semicolon.setChecked(self.settings.delimiter == "semicolon") semicolon.triggered.connect(lambda *args, delim="semicolon": self. settings.__setattr__("delimiter", delim)) delimiter.addAction(semicolon) add_header = QAction("&Include CSV header", self.tool_window.ui_area, checkable=True) add_header.setChecked(self.settings.include_header) add_header.triggered.connect(self.header_check) export.addAction(add_header) comma.triggered.connect( lambda *args, action=tab: action.setChecked(False)) comma.triggered.connect( lambda *args, action=space: action.setChecked(False)) comma.triggered.connect( lambda *args, action=semicolon: action.setChecked(False)) tab.triggered.connect( lambda *args, action=comma: action.setChecked(False)) tab.triggered.connect( lambda *args, action=space: action.setChecked(False)) tab.triggered.connect( lambda *args, action=semicolon: action.setChecked(False)) space.triggered.connect( lambda *args, action=comma: action.setChecked(False)) space.triggered.connect( lambda *args, action=tab: action.setChecked(False)) space.triggered.connect( lambda *args, action=semicolon: action.setChecked(False)) semicolon.triggered.connect( lambda *args, action=comma: action.setChecked(False)) semicolon.triggered.connect( lambda *args, action=tab: action.setChecked(False)) semicolon.triggered.connect( lambda *args, action=space: action.setChecked(False)) menu.setNativeMenuBar(False) self._menu = menu layout.setMenuBar(menu) menu.setVisible(True) self.tool_window.ui_area.setLayout(layout) self.tool_window.manage(None)
def _build_ui(self): layout = QVBoxLayout() self.file_selector = FilereaderComboBox(self.session) self.file_selector.currentIndexChanged.connect(self.fill_table) layout.insertWidget(0, self.file_selector, 0) tabs = QTabWidget() self.tabs = tabs layout.insertWidget(1, self.tabs, 1) general_info = QWidget() general_layout = QVBoxLayout(general_info) tabs.addTab(general_info, "general") self.table = QTableWidget() self.table.setColumnCount(2) self.table.setHorizontalHeaderLabels(['Data', 'Value']) self.table.horizontalHeader().setStretchLastSection(False) self.table.horizontalHeader().setSectionResizeMode( 0, QHeaderView.Interactive) self.table.setEditTriggers(QTableWidget.NoEditTriggers) self.table.horizontalHeader().setSectionResizeMode( 1, QHeaderView.Stretch) self.table.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.MinimumExpanding) general_layout.insertWidget(1, self.table, 1) self.filter = QLineEdit() self.filter.setPlaceholderText("filter data") self.filter.textChanged.connect(self.apply_filter) self.filter.setClearButtonEnabled(True) general_layout.insertWidget(2, self.filter, 0) freq_info = QWidget() freq_layout = QVBoxLayout(freq_info) tabs.addTab(freq_info, "harmonic frequencies") self.freq_table = QTableWidget() self.freq_table.setColumnCount(4) self.freq_table.setHorizontalHeaderLabels([ "Frequency (cm\u207b\u00b9)", "symmetry", "IR intensity", "force constant (mDyne/\u212B)", ]) self.freq_table.setSortingEnabled(True) self.freq_table.setEditTriggers(QTableWidget.NoEditTriggers) for i in range(0, 4): self.freq_table.resizeColumnToContents(i) self.freq_table.horizontalHeader().setStretchLastSection(False) self.freq_table.horizontalHeader().setSectionResizeMode( 0, QHeaderView.Fixed) self.freq_table.horizontalHeader().setSectionResizeMode( 1, QHeaderView.Fixed) self.freq_table.horizontalHeader().setSectionResizeMode( 2, QHeaderView.Fixed) self.freq_table.horizontalHeader().setSectionResizeMode( 3, QHeaderView.Stretch) self.freq_table.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.MinimumExpanding) freq_layout.insertWidget(1, self.freq_table, 1) anharm_info = QWidget() anharm_layout = QVBoxLayout(anharm_info) tabs.addTab(anharm_info, "anharmonic frequencies") anharm_layout.insertWidget(0, QLabel("fundamentals:"), 0) self.fundamental_table = QTableWidget() self.fundamental_table.setColumnCount(3) self.fundamental_table.setHorizontalHeaderLabels([ "Fundamental (cm\u207b\u00b9)", "Δ\u2090\u2099\u2095 (cm\u207b\u00b9)", "IR intensity", ]) self.fundamental_table.setSortingEnabled(True) self.fundamental_table.setEditTriggers(QTableWidget.NoEditTriggers) for i in range(0, 3): self.fundamental_table.resizeColumnToContents(i) self.fundamental_table.horizontalHeader().setStretchLastSection(False) self.fundamental_table.horizontalHeader().setSectionResizeMode( 0, QHeaderView.Fixed) self.fundamental_table.horizontalHeader().setSectionResizeMode( 1, QHeaderView.Fixed) self.fundamental_table.horizontalHeader().setSectionResizeMode( 2, QHeaderView.Stretch) self.fundamental_table.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.MinimumExpanding) anharm_layout.insertWidget(1, self.fundamental_table, 1) # self.overtone_table = QTableWidget() # self.overtone_table.setColumnCount(3) # self.overtone_table.setHorizontalHeaderLabels( # [ # "Fundamental (cm\u207b\u00b9)", # "Overtone (cm\u207b\u00b9)", # "IR intensity", # ] # ) # self.overtone_table.setSortingEnabled(True) # self.overtone_table.setEditTriggers(QTableWidget.NoEditTriggers) # for i in range(0, 3): # self.overtone_table.resizeColumnToContents(i) # # self.overtone_table.horizontalHeader().setStretchLastSection(False) # self.overtone_table.horizontalHeader().setSectionResizeMode(0, QHeaderView.Fixed) # self.overtone_table.horizontalHeader().setSectionResizeMode(1, QHeaderView.Fixed) # self.overtone_table.horizontalHeader().setSectionResizeMode(2, QHeaderView.Stretch) # # self.overtone_table.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.MinimumExpanding) # anharm_layout.insertWidget(2, self.overtone_table, 1) anharm_layout.insertWidget(2, QLabel("combinations and overtones:"), 0) self.combo_table = QTableWidget() self.combo_table.setColumnCount(4) self.combo_table.setHorizontalHeaderLabels([ "Fundamental (cm\u207b\u00b9)", "Fundamental (cm\u207b\u00b9)", "Combination (cm\u207b\u00b9)", "IR intensity", ]) self.combo_table.setSortingEnabled(True) self.combo_table.setEditTriggers(QTableWidget.NoEditTriggers) for i in range(0, 3): self.combo_table.resizeColumnToContents(i) self.combo_table.horizontalHeader().setStretchLastSection(False) self.combo_table.horizontalHeader().setSectionResizeMode( 0, QHeaderView.Fixed) self.combo_table.horizontalHeader().setSectionResizeMode( 1, QHeaderView.Fixed) self.combo_table.horizontalHeader().setSectionResizeMode( 2, QHeaderView.Fixed) self.combo_table.horizontalHeader().setSectionResizeMode( 3, QHeaderView.Stretch) self.combo_table.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.MinimumExpanding) anharm_layout.insertWidget(3, self.combo_table, 1) menu = QMenuBar() export = menu.addMenu("&Export") copy = QAction("&Copy CSV to clipboard", self.tool_window.ui_area) copy.triggered.connect(self.copy_csv) shortcut = QKeySequence(Qt.CTRL + Qt.Key_C) copy.setShortcut(shortcut) export.addAction(copy) self.copy = copy save = QAction("&Save CSV...", self.tool_window.ui_area) save.triggered.connect(self.save_csv) export.addAction(save) delimiter = export.addMenu("Delimiter") comma = QAction("comma", self.tool_window.ui_area, checkable=True) comma.setChecked(self.settings.delimiter == "comma") comma.triggered.connect(lambda *args, delim="comma": self.settings. __setattr__("delimiter", delim)) delimiter.addAction(comma) tab = QAction("tab", self.tool_window.ui_area, checkable=True) tab.setChecked(self.settings.delimiter == "tab") tab.triggered.connect(lambda *args, delim="tab": self.settings. __setattr__("delimiter", delim)) delimiter.addAction(tab) # space = QAction("space", self.tool_window.ui_area, checkable=True) # space.setChecked(self.settings.delimiter == "space") # space.triggered.connect(lambda *args, delim="space": self.settings.__setattr__("delimiter", delim)) # delimiter.addAction(space) semicolon = QAction("semicolon", self.tool_window.ui_area, checkable=True) semicolon.setChecked(self.settings.delimiter == "semicolon") semicolon.triggered.connect(lambda *args, delim="semicolon": self. settings.__setattr__("delimiter", delim)) delimiter.addAction(semicolon) add_header = QAction("&Include CSV header", self.tool_window.ui_area, checkable=True) add_header.setChecked(self.settings.include_header) add_header.triggered.connect(self.header_check) export.addAction(add_header) tab.triggered.connect( lambda *args, action=semicolon: action.setChecked(False)) semicolon.triggered.connect( lambda *args, action=tab: action.setChecked(False)) archive = QAction("Include archive if present", self.tool_window.ui_area, checkable=True) archive.triggered.connect( lambda checked: setattr(self.settings, "archive", checked)) archive.triggered.connect( lambda *args: self.fill_table(self.file_selector.count() - 1)) archive.setChecked(self.settings.archive) export.addAction(archive) unit = menu.addMenu("&Units") energy = unit.addMenu("energy") hartree = QAction("Hartree", self.tool_window.ui_area, checkable=True) hartree.setChecked(self.settings.energy == "Hartree") kcal = QAction("kcal/mol", self.tool_window.ui_area, checkable=True) kcal.setChecked(self.settings.energy == "kcal/mol") kjoule = QAction("kJ/mol", self.tool_window.ui_area, checkable=True) kjoule.setChecked(self.settings.energy == "kJ/mol") energy.addAction(hartree) energy.addAction(kcal) energy.addAction(kjoule) hartree.triggered.connect( lambda *args, val="Hartree": setattr(self.settings, "energy", val)) hartree.triggered.connect( lambda *args: self.fill_table(self.file_selector.count() - 1)) hartree.triggered.connect( lambda *args, action=kcal: action.setChecked(False)) hartree.triggered.connect( lambda *args, action=kjoule: action.setChecked(False)) kcal.triggered.connect(lambda *args, val="kcal/mol": setattr( self.settings, "energy", val)) kcal.triggered.connect( lambda *args: self.fill_table(self.file_selector.count() - 1)) kcal.triggered.connect( lambda *args, action=hartree: action.setChecked(False)) kcal.triggered.connect( lambda *args, action=kjoule: action.setChecked(False)) kjoule.triggered.connect( lambda *args, val="kJ/mol": setattr(self.settings, "energy", val)) kjoule.triggered.connect( lambda *args: self.fill_table(self.file_selector.count() - 1)) kjoule.triggered.connect( lambda *args, action=hartree: action.setChecked(False)) kjoule.triggered.connect( lambda *args, action=kcal: action.setChecked(False)) mass = unit.addMenu("mass") kg = QAction("kg", self.tool_window.ui_area, checkable=True) kg.setChecked(self.settings.mass == "kg") amu = QAction("Da", self.tool_window.ui_area, checkable=True) amu.setChecked(self.settings.mass == "Da") mass.addAction(kg) mass.addAction(amu) kg.triggered.connect( lambda *args, val="kg": setattr(self.settings, "mass", val)) kg.triggered.connect( lambda *args: self.fill_table(self.file_selector.count() - 1)) kg.triggered.connect( lambda *args, action=amu: action.setChecked(False)) amu.triggered.connect( lambda *args, val="Da": setattr(self.settings, "mass", val)) amu.triggered.connect( lambda *args: self.fill_table(self.file_selector.count() - 1)) amu.triggered.connect( lambda *args, action=kg: action.setChecked(False)) rot_const = unit.addMenu("rotational constants") temperature = QAction("K", self.tool_window.ui_area, checkable=True) temperature.setChecked(self.settings.rot_const == "K") hertz = QAction("GHz", self.tool_window.ui_area, checkable=True) hertz.setChecked(self.settings.rot_const == "GHz") rot_const.addAction(temperature) rot_const.addAction(hertz) temperature.triggered.connect( lambda *args, val="K": setattr(self.settings, "rot_const", val)) temperature.triggered.connect( lambda *args: self.fill_table(self.file_selector.count() - 1)) temperature.triggered.connect( lambda *args, action=hertz: action.setChecked(False)) hertz.triggered.connect( lambda *args, val="GHz": setattr(self.settings, "rot_const", val)) hertz.triggered.connect( lambda *args: self.fill_table(self.file_selector.count() - 1)) hertz.triggered.connect( lambda *args, action=temperature: action.setChecked(False)) menu.setNativeMenuBar(False) self._menu = menu layout.setMenuBar(menu) menu.setVisible(True) if len(self.session.filereader_manager.list()) > 0: self.fill_table(0) self.tool_window.ui_area.setLayout(layout) self.tool_window.manage(None)
def _build_ui(self): layout = QGridLayout() tabs = QTabWidget() calc_widget = QWidget() calc_layout = QFormLayout(calc_widget) settings_widget = QWidget() settings_layout = QFormLayout(settings_widget) steric_map_widget = QWidget() steric_layout = QFormLayout(steric_map_widget) cutout_widget = QWidget() vol_cutout_layout = QFormLayout(cutout_widget) layout.addWidget(tabs) tabs.addTab(calc_widget, "calculation") tabs.addTab(settings_widget, "settings") tabs.addTab(steric_map_widget, "steric map") tabs.addTab(cutout_widget, "volume cutout") self.radii_option = QComboBox() self.radii_option.addItems(["Bondi", "UMN"]) ndx = self.radii_option.findText(self.settings.radii, Qt.MatchExactly) self.radii_option.setCurrentIndex(ndx) settings_layout.addRow("radii:", self.radii_option) self.scale = QDoubleSpinBox() self.scale.setValue(self.settings.vdw_scale) self.scale.setSingleStep(0.01) self.scale.setRange(1., 1.5) settings_layout.addRow("VDW scale:", self.scale) set_ligand_atoms = QPushButton("set ligands to current selection") set_ligand_atoms.clicked.connect(self.set_ligand_atoms) set_ligand_atoms.setToolTip( "specify atoms to use in calculation\n" + "by default, all atoms will be used unless a single center is specified\n" + "in the case of a single center, all atoms except the center is used" ) calc_layout.addRow(set_ligand_atoms) self.set_ligand_atoms = set_ligand_atoms self.radius = QDoubleSpinBox() self.radius.setValue(self.settings.center_radius) self.radius.setSuffix(" \u212B") self.radius.setDecimals(1) self.radius.setSingleStep(0.1) self.radius.setRange(1., 15.) settings_layout.addRow("radius around center:", self.radius) self.method = QComboBox() self.method.addItems(["Lebedev", "Monte-Carlo"]) self.method.setToolTip("Lebedev: deterministic method\n" + "Monte-Carlo: non-deterministic method") ndx = self.method.findText(self.settings.method, Qt.MatchExactly) self.method.setCurrentIndex(ndx) settings_layout.addRow("integration method:", self.method) leb_widget = QWidget() leb_layout = QFormLayout(leb_widget) leb_layout.setContentsMargins(0, 0, 0, 0) self.radial_points = QComboBox() self.radial_points.addItems(["20", "32", "64", "75", "99", "127"]) self.radial_points.setToolTip( "more radial points will give more accurate results, but integration will take longer" ) ndx = self.radial_points.findText(self.settings.radial_points, Qt.MatchExactly) self.radial_points.setCurrentIndex(ndx) leb_layout.addRow("radial points:", self.radial_points) self.angular_points = QComboBox() self.angular_points.addItems([ "110", "194", "302", "590", "974", "1454", "2030", "2702", "5810" ]) self.angular_points.setToolTip( "more angular points will give more accurate results, but integration will take longer" ) ndx = self.angular_points.findText(self.settings.angular_points, Qt.MatchExactly) self.angular_points.setCurrentIndex(ndx) leb_layout.addRow("angular points:", self.angular_points) settings_layout.addRow(leb_widget) mc_widget = QWidget() mc_layout = QFormLayout(mc_widget) mc_layout.setContentsMargins(0, 0, 0, 0) self.min_iter = QSpinBox() self.min_iter.setValue(self.settings.minimum_iterations) self.min_iter.setRange(0, 10000) self.min_iter.setToolTip( "each iteration is 3000 points\n" + "iterations continue until convergence criteria are met") mc_layout.addRow("minimum interations:", self.min_iter) settings_layout.addRow(mc_widget) if self.settings.method == "Lebedev": mc_widget.setVisible(False) elif self.settings.method == "Monte-Carlo": leb_widget.setVisible(False) self.report_component = QComboBox() self.report_component.addItems(["total", "quadrants", "octants"]) ndx = self.report_component.findText(self.settings.report_component, Qt.MatchExactly) self.report_component.setCurrentIndex(ndx) settings_layout.addRow("report volume:", self.report_component) self.use_scene = QCheckBox() self.use_scene.setChecked(self.settings.use_scene) self.use_scene.setToolTip( "quadrants/octants will use the orientation the molecule is displayed in" ) settings_layout.addRow("use display orientation:", self.use_scene) self.method.currentTextChanged.connect( lambda text, widget=leb_widget: widget.setVisible(text == "Lebedev" )) self.method.currentTextChanged.connect( lambda text, widget=mc_widget: widget.setVisible(text == "Monte-Carlo")) self.use_centroid = QCheckBox() self.use_centroid.setChecked(self.settings.use_centroid) self.use_centroid.setToolTip( "place the center between selected atoms\n" + "might be useful for polydentate ligands") calc_layout.addRow("use centroid of centers:", self.use_centroid) self.steric_map = QCheckBox() self.steric_map.setChecked(self.settings.steric_map) self.steric_map.setToolTip( "produce a 2D projection of steric bulk\ncauses buried volume to be reported for individual quadrants" ) steric_layout.addRow("create steric map:", self.steric_map) self.num_pts = QSpinBox() self.num_pts.setRange(25, 250) self.num_pts.setValue(self.settings.num_pts) self.num_pts.setToolTip("number of points along x and y axes") steric_layout.addRow("number of points:", self.num_pts) self.include_vbur = QCheckBox() self.include_vbur.setChecked(self.settings.include_vbur) steric_layout.addRow("label quadrants with %V<sub>bur</sub>", self.include_vbur) self.map_shape = QComboBox() self.map_shape.addItems(["circle", "square"]) ndx = self.map_shape.findText(self.settings.map_shape, Qt.MatchExactly) self.map_shape.setCurrentIndex(ndx) steric_layout.addRow("map shape:", self.map_shape) self.auto_minmax = QCheckBox() self.auto_minmax.setChecked(self.settings.auto_minmax) steric_layout.addRow("automatic min. and max.:", self.auto_minmax) self.map_min = QDoubleSpinBox() self.map_min.setRange(-15., 0.) self.map_min.setSuffix(" \u212B") self.map_min.setSingleStep(0.1) self.map_min.setValue(self.settings.map_min) steric_layout.addRow("minimum value:", self.map_min) self.map_max = QDoubleSpinBox() self.map_max.setRange(0., 15.) self.map_max.setSuffix(" \u212B") self.map_max.setSingleStep(0.1) self.map_max.setValue(self.settings.map_max) steric_layout.addRow("maximum value:", self.map_max) self.num_pts.setEnabled(self.settings.steric_map) self.steric_map.stateChanged.connect( lambda state, widget=self.num_pts: widget.setEnabled(state == Qt. Checked)) self.include_vbur.setEnabled(self.settings.steric_map) self.steric_map.stateChanged.connect( lambda state, widget=self.include_vbur: widget.setEnabled( state == Qt.Checked)) self.map_shape.setEnabled(self.settings.steric_map) self.steric_map.stateChanged.connect( lambda state, widget=self.map_shape: widget.setEnabled(state == Qt. Checked)) self.auto_minmax.setEnabled(self.settings.steric_map) self.steric_map.stateChanged.connect( lambda state, widget=self.auto_minmax: widget.setEnabled( state == Qt.Checked)) self.map_min.setEnabled(not self.settings.auto_minmax and self.settings.steric_map) self.steric_map.stateChanged.connect( lambda state, widget=self.map_min, widget2=self.auto_minmax: widget .setEnabled(state == Qt.Checked and not widget2.isChecked())) self.auto_minmax.stateChanged.connect( lambda state, widget=self.map_min, widget2=self.steric_map: widget. setEnabled(not state == Qt.Checked and widget2.isChecked())) self.map_max.setEnabled(not self.settings.auto_minmax and self.settings.steric_map) self.steric_map.stateChanged.connect( lambda state, widget=self.map_max, widget2=self.auto_minmax: widget .setEnabled(state == Qt.Checked and not widget2.isChecked())) self.auto_minmax.stateChanged.connect( lambda state, widget=self.map_max, widget2=self.steric_map: widget. setEnabled(not state == Qt.Checked and widget2.isChecked())) self.display_cutout = QComboBox() self.display_cutout.addItems(["no", "free", "buried"]) ndx = self.display_cutout.findText(self.settings.display_cutout, Qt.MatchExactly) self.display_cutout.setCurrentIndex(ndx) self.display_cutout.setToolTip("show free or buried volume") vol_cutout_layout.addRow("display volume:", self.display_cutout) self.point_spacing = QDoubleSpinBox() self.point_spacing.setDecimals(3) self.point_spacing.setRange(0.01, 0.5) self.point_spacing.setSingleStep(0.005) self.point_spacing.setSuffix(" \u212B") self.point_spacing.setValue(self.settings.point_spacing) self.point_spacing.setToolTip( "distance between points on cutout\n" + "smaller spacing will narrow gaps, but increase time to create the cutout" ) vol_cutout_layout.addRow("point spacing:", self.point_spacing) self.intersection_scale = QDoubleSpinBox() self.intersection_scale.setDecimals(2) self.intersection_scale.setRange(1., 10.) self.intersection_scale.setSingleStep(0.5) self.intersection_scale.setSuffix("x") self.intersection_scale.setToolTip( "relative density of points where VDW radii intersect\n" + "higher density will narrow gaps, but increase time to create cutout" ) self.intersection_scale.setValue(self.settings.intersection_scale) vol_cutout_layout.addRow("intersection density:", self.intersection_scale) self.cutout_labels = QComboBox() self.cutout_labels.addItems(["none", "quadrants", "octants"]) ndx = self.cutout_labels.findText(self.settings.cutout_labels, Qt.MatchExactly) self.cutout_labels.setCurrentIndex(ndx) vol_cutout_layout.addRow("label sections:", self.cutout_labels) self.point_spacing.setEnabled(self.settings.display_cutout != "no") self.intersection_scale.setEnabled( self.settings.display_cutout != "no") self.cutout_labels.setEnabled(self.settings.display_cutout != "no") self.display_cutout.currentTextChanged.connect( lambda text, widget=self.point_spacing: widget.setEnabled(text != "no")) self.display_cutout.currentTextChanged.connect( lambda text, widget=self.intersection_scale: widget.setEnabled( text != "no")) self.display_cutout.currentTextChanged.connect( lambda text, widget=self.cutout_labels: widget.setEnabled(text != "no")) calc_vbur_button = QPushButton( "calculate % buried volume for selected centers") calc_vbur_button.clicked.connect(self.calc_vbur) calc_layout.addRow(calc_vbur_button) self.calc_vbur_button = calc_vbur_button remove_vbur_button = QPushButton( "remove % buried volume visualizations") remove_vbur_button.clicked.connect(self.del_vbur) vol_cutout_layout.addRow(remove_vbur_button) self.table = QTableWidget() self.table.setColumnCount(3) self.table.setHorizontalHeaderLabels(['model', 'center', '%Vbur']) self.table.setSelectionBehavior(QTableWidget.SelectRows) self.table.setEditTriggers(QTableWidget.NoEditTriggers) self.table.resizeColumnToContents(0) self.table.resizeColumnToContents(1) self.table.resizeColumnToContents(2) self.table.horizontalHeader().setSectionResizeMode( 0, QHeaderView.Interactive) self.table.horizontalHeader().setSectionResizeMode( 1, QHeaderView.Interactive) self.table.horizontalHeader().setSectionResizeMode( 2, QHeaderView.Stretch) calc_layout.addRow(self.table) menu = QMenuBar() export = menu.addMenu("&Export") clear = QAction("Clear data table", self.tool_window.ui_area) clear.triggered.connect(self.clear_table) export.addAction(clear) copy = QAction("&Copy CSV to clipboard", self.tool_window.ui_area) copy.triggered.connect(self.copy_csv) shortcut = QKeySequence(Qt.CTRL + Qt.Key_C) copy.setShortcut(shortcut) export.addAction(copy) self.copy = copy save = QAction("&Save CSV...", self.tool_window.ui_area) save.triggered.connect(self.save_csv) #this shortcut interferes with main window's save shortcut #I've tried different shortcut contexts to no avail #thanks Qt... #shortcut = QKeySequence(Qt.CTRL + Qt.Key_S) #save.setShortcut(shortcut) #save.setShortcutContext(Qt.WidgetShortcut) export.addAction(save) delimiter = export.addMenu("Delimiter") comma = QAction("comma", self.tool_window.ui_area, checkable=True) comma.setChecked(self.settings.delimiter == "comma") comma.triggered.connect(lambda *args, delim="comma": self.settings. __setattr__("delimiter", delim)) delimiter.addAction(comma) tab = QAction("tab", self.tool_window.ui_area, checkable=True) tab.setChecked(self.settings.delimiter == "tab") tab.triggered.connect(lambda *args, delim="tab": self.settings. __setattr__("delimiter", delim)) delimiter.addAction(tab) space = QAction("space", self.tool_window.ui_area, checkable=True) space.setChecked(self.settings.delimiter == "space") space.triggered.connect(lambda *args, delim="space": self.settings. __setattr__("delimiter", delim)) delimiter.addAction(space) semicolon = QAction("semicolon", self.tool_window.ui_area, checkable=True) semicolon.setChecked(self.settings.delimiter == "semicolon") semicolon.triggered.connect(lambda *args, delim="semicolon": self. settings.__setattr__("delimiter", delim)) delimiter.addAction(semicolon) add_header = QAction("&Include CSV header", self.tool_window.ui_area, checkable=True) add_header.setChecked(self.settings.include_header) add_header.triggered.connect(self.header_check) export.addAction(add_header) comma.triggered.connect( lambda *args, action=tab: action.setChecked(False)) comma.triggered.connect( lambda *args, action=space: action.setChecked(False)) comma.triggered.connect( lambda *args, action=semicolon: action.setChecked(False)) tab.triggered.connect( lambda *args, action=comma: action.setChecked(False)) tab.triggered.connect( lambda *args, action=space: action.setChecked(False)) tab.triggered.connect( lambda *args, action=semicolon: action.setChecked(False)) space.triggered.connect( lambda *args, action=comma: action.setChecked(False)) space.triggered.connect( lambda *args, action=tab: action.setChecked(False)) space.triggered.connect( lambda *args, action=semicolon: action.setChecked(False)) semicolon.triggered.connect( lambda *args, action=comma: action.setChecked(False)) semicolon.triggered.connect( lambda *args, action=tab: action.setChecked(False)) semicolon.triggered.connect( lambda *args, action=space: action.setChecked(False)) menu.setNativeMenuBar(False) self._menu = menu layout.setMenuBar(menu) menu.setVisible(True) self.tool_window.ui_area.setLayout(layout) self.tool_window.manage(None)
def _build_ui(self): layout = QFormLayout() self.radii_option = QComboBox() self.radii_option.addItems(["Bondi", "UMN"]) ndx = self.radii_option.findText(self.settings.radii, Qt.MatchExactly) self.radii_option.setCurrentIndex(ndx) layout.addRow("radii:", self.radii_option) self.L_style = QComboBox() self.L_style.addItems(["FORTRAN", "AaronTools"]) ndx = self.L_style.findText(self.settings.L_style, Qt.MatchExactly) self.L_style.setCurrentIndex(ndx) self.L_style.setToolTip( """FORTRAN: Add 0.4 + the ideal X-H bond length to the length of the substituent AaronTools: add VDW radius to the length of the substituent""") layout.addRow("L correction:", self.L_style) self.display_vectors = QCheckBox() self.display_vectors.setChecked(self.settings.display_vectors) layout.addRow("show vectors:", self.display_vectors) self.display_radii = QCheckBox() self.display_radii.setChecked(self.settings.display_radii) layout.addRow("show radii:", self.display_radii) calc_sterimol_button = QPushButton( "calculate parameters for selected substituents") calc_sterimol_button.clicked.connect(self.calc_sterimol) layout.addRow(calc_sterimol_button) self.calc_sterimol_button = calc_sterimol_button remove_sterimol_button = QPushButton("remove Sterimol visualizations") remove_sterimol_button.clicked.connect(self.del_sterimol) layout.addRow(remove_sterimol_button) self.remove_sterimol_button = remove_sterimol_button self.table = QTableWidget() self.table.setColumnCount(8) self.table.setHorizontalHeaderLabels([ 'model', 'substituent atom', 'B\u2081', 'B\u2082', 'B\u2083', 'B\u2084', 'B\u2085', 'L', ]) self.table.setSelectionBehavior(QTableWidget.SelectRows) self.table.setEditTriggers(QTableWidget.NoEditTriggers) self.table.resizeColumnToContents(0) self.table.resizeColumnToContents(1) self.table.resizeColumnToContents(2) self.table.resizeColumnToContents(3) self.table.resizeColumnToContents(4) self.table.resizeColumnToContents(5) self.table.resizeColumnToContents(6) self.table.resizeColumnToContents(7) self.table.horizontalHeader().setSectionResizeMode( 2, QHeaderView.Stretch) self.table.horizontalHeader().setSectionResizeMode( 3, QHeaderView.Stretch) self.table.horizontalHeader().setSectionResizeMode( 4, QHeaderView.Stretch) self.table.horizontalHeader().setSectionResizeMode( 5, QHeaderView.Stretch) self.table.horizontalHeader().setSectionResizeMode( 6, QHeaderView.Stretch) self.table.horizontalHeader().setSectionResizeMode( 7, QHeaderView.Stretch) layout.addRow(self.table) menu = QMenuBar() export = menu.addMenu("&Export") clear = QAction("Clear data table", self.tool_window.ui_area) clear.triggered.connect(self.clear_table) export.addAction(clear) copy = QAction("&Copy CSV to clipboard", self.tool_window.ui_area) copy.triggered.connect(self.copy_csv) shortcut = QKeySequence(Qt.CTRL + Qt.Key_C) copy.setShortcut(shortcut) export.addAction(copy) save = QAction("&Save CSV...", self.tool_window.ui_area) save.triggered.connect(self.save_csv) #this shortcut interferes with main window's save shortcut #I've tried different shortcut contexts to no avail #thanks Qt... #shortcut = QKeySequence(Qt.CTRL + Qt.Key_S) #save.setShortcut(shortcut) #save.setShortcutContext(Qt.WidgetShortcut) export.addAction(save) delimiter = export.addMenu("Delimiter") comma = QAction("comma", self.tool_window.ui_area, checkable=True) comma.setChecked(self.settings.delimiter == "comma") comma.triggered.connect(lambda *args, delim="comma": self.settings. __setattr__("delimiter", delim)) delimiter.addAction(comma) tab = QAction("tab", self.tool_window.ui_area, checkable=True) tab.setChecked(self.settings.delimiter == "tab") tab.triggered.connect(lambda *args, delim="tab": self.settings. __setattr__("delimiter", delim)) delimiter.addAction(tab) space = QAction("space", self.tool_window.ui_area, checkable=True) space.setChecked(self.settings.delimiter == "space") space.triggered.connect(lambda *args, delim="space": self.settings. __setattr__("delimiter", delim)) delimiter.addAction(space) semicolon = QAction("semicolon", self.tool_window.ui_area, checkable=True) semicolon.setChecked(self.settings.delimiter == "semicolon") semicolon.triggered.connect(lambda *args, delim="semicolon": self. settings.__setattr__("delimiter", delim)) delimiter.addAction(semicolon) add_header = QAction("&Include CSV header", self.tool_window.ui_area, checkable=True) add_header.setChecked(self.settings.include_header) add_header.triggered.connect(self.header_check) export.addAction(add_header) comma.triggered.connect( lambda *args, action=tab: action.setChecked(False)) comma.triggered.connect( lambda *args, action=space: action.setChecked(False)) comma.triggered.connect( lambda *args, action=semicolon: action.setChecked(False)) tab.triggered.connect( lambda *args, action=comma: action.setChecked(False)) tab.triggered.connect( lambda *args, action=space: action.setChecked(False)) tab.triggered.connect( lambda *args, action=semicolon: action.setChecked(False)) space.triggered.connect( lambda *args, action=comma: action.setChecked(False)) space.triggered.connect( lambda *args, action=tab: action.setChecked(False)) space.triggered.connect( lambda *args, action=semicolon: action.setChecked(False)) semicolon.triggered.connect( lambda *args, action=comma: action.setChecked(False)) semicolon.triggered.connect( lambda *args, action=tab: action.setChecked(False)) semicolon.triggered.connect( lambda *args, action=space: action.setChecked(False)) menu.setNativeMenuBar(False) self._menu = menu layout.setMenuBar(menu) menu.setVisible(True) self.tool_window.ui_area.setLayout(layout) self.tool_window.manage(None)