Source code for schrodinger.ui.qt.appframework2.debugwidgets

from schrodinger.Qt import QtCore
from schrodinger.Qt import QtGui
from schrodinger.Qt import QtWidgets
from schrodinger.Qt.QtCore import Qt
from schrodinger.structure import Structure


[docs]class BaseTable(QtWidgets.QTableWidget):
[docs] def __init__(self, parent=None): QtWidgets.QTableWidget.__init__(self, parent) self.setup() self.reset()
[docs] def reset(self): self.removeAllRows()
[docs] def removeAllRows(self): while self.rowCount() > 0: self.removeRow(0)
[docs] def setup(self): self.show() self.setEnabled(True) self.setFocusPolicy(QtCore.Qt.StrongFocus) self.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows) self.setColumnCount(len(self.header_titles)) self.setHorizontalHeaderLabels(self.header_titles) header = self.horizontalHeader() header.setSectionResizeMode(QtWidgets.QHeaderView.Interactive) vheader = self.verticalHeader() vheader.setVisible(False) self.setSortingEnabled(True)
[docs] def keyPressEvent(self, event): if event.matches(QtGui.QKeySequence.Copy): mime_data = QtCore.QMimeData() text = self.getSelectedText() mime_data.setText(text) QtWidgets.QApplication.clipboard().setMimeData(mime_data)
[docs] def getSelectedText(self): items = self.selectedItems() if not items: return '' current_row = items[0].row() lines = [] line = [] for item in items: row = item.row() if row > current_row: current_row = row lines.append('\t'.join(line)) line = [] line.append(item.text()) if line: lines.append('\t'.join(line)) text = '\n'.join(lines) return text
[docs]class LogTable(BaseTable): Super = BaseTable header_titles = ['Time', 'Tag', 'Caller', 'Text']
[docs] def __init__(self, parent=None): self.log = [] self.Super.__init__(self, parent)
[docs] def setup(self): self.Super.setup(self) self.setColumnWidth(0, 100) self.setColumnWidth(1, 80) self.setColumnWidth(2, 150) self.setColumnWidth(3, 500)
[docs] def addEntry(self, entry): row_idx = self.rowCount() self.setRowCount(row_idx + 1) self.setRowHeight(row_idx, 18) self.setItem(row_idx, 0, QtWidgets.QTableWidgetItem(entry.timestamp)) self.setItem(row_idx, 1, QtWidgets.QTableWidgetItem(entry.tag)) self.setItem(row_idx, 2, QtWidgets.QTableWidgetItem(entry.caller)) self.setItem(row_idx, 3, QtWidgets.QTableWidgetItem(entry.text)) self.resizeRowsToContents()
[docs]class LogTagTable(BaseTable): Super = BaseTable header_titles = ['Enable', 'Tag']
[docs] def __init__(self, parent=None): self.Super.__init__(self, parent)
[docs]def find_signals(obj_name, obj): signals = [] for name in dir(obj): attr = getattr(obj, name) if isinstance(attr, QtCore.pyqtBoundSignal): signals.append((obj_name, obj, name, attr)) return signals
EXCLUDE_DEEP_FIND_CLASSES = (Structure,)
[docs]def deep_find_signals(obj_name, obj, done_list=None, depth=0): signals = [] if isinstance(obj, EXCLUDE_DEEP_FIND_CLASSES): print('Object %s excluded from scanning.' % obj_name) return signals if depth > 8: print('Depth %i in %s' % (depth, obj_name)) if depth > 30: print('Max depth exceeded.') return signals if done_list is None: done_list = [] try: for item in done_list: if obj is item: return signals except TypeError: return signals done_list.append(obj) if not hasattr(obj, '__dict__'): return signals signals.extend(find_signals(obj_name, obj)) for sub_obj_name, sub_obj in obj.__dict__.items(): if obj_name: full_name = obj_name + '.' + sub_obj_name else: full_name = sub_obj_name signals.extend( deep_find_signals(full_name, sub_obj, done_list, depth=depth + 1)) return signals
[docs]class SignalTable(BaseTable): Super = BaseTable header_titles = ['Enable', 'Object', 'Signal']
[docs] def __init__(self, parent=None): self.connected_slots = {} self.all_slots = {} self.signals = [] self.Super.__init__(self, parent) self.cellChanged.connect(self.onCellChanged)
[docs] def setup(self): self.Super.setup(self) self.setColumnWidth(0, 50) self.setColumnWidth(1, 150) self.setColumnWidth(2, 300)
[docs] def addEntry(self, obj_name, obj, signal_name, signal): row_idx = self.rowCount() self.setRowCount(row_idx + 1) self.setRowHeight(row_idx, 18) check_item = QtWidgets.QTableWidgetItem() check_item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled | Qt.ItemIsUserCheckable) check_item.setTextAlignment(Qt.AlignHCenter | Qt.AlignVCenter) check_item.setCheckState(Qt.Unchecked) check_item.signal = signal self.setItem(row_idx, 0, check_item) self.setItem(row_idx, 1, QtWidgets.QTableWidgetItem(obj_name)) self.setItem(row_idx, 2, QtWidgets.QTableWidgetItem(signal_name))
[docs] def onCellChanged(self, row, column): if column == 0: item = self.item(row, column) if item.checkState() == QtCore.Qt.Checked: self.connectSignal(item.signal) else: self.disconnectSignal(item.signal)
[docs] def deepFindSignals(self, obj_name, obj, done_list=None): return deep_find_signals(obj_name, obj, done_list)
[docs] def scan(self, obj, exclude_objs): self.disconnectSignals() self.reset() signals = self.deepFindSignals('', obj, exclude_objs) self.signals = signals for obj_name, obj, signal_name, signal in signals: self.addEntry(obj_name, obj, signal_name, signal)
[docs] def registerSignals(self, slot_factory): for obj_name, obj, signal_name, signal in self.signals: slot = slot_factory(obj_name, signal_name, signal) self.all_slots[signal] = slot
[docs] def deregisterSignals(self): self.disconnectSignals() for signal in list(self.all_slots): self.all_slots.pop(signal)
[docs] def connectSignals(self): for signal in list(self.connected_slots): self.connectSignal(signal)
[docs] def disconnectSignals(self): for signal in list(self.connected_slots): self.disconnectSignal(signal)
[docs] def connectSignal(self, signal): if signal in self.connected_slots: return slot = self.all_slots[signal] signal.connect(slot) self.connected_slots[signal] = slot
[docs] def disconnectSignal(self, signal): if signal not in self.connected_slots: return slot = self.connected_slots.pop(signal) signal.disconnect(slot)
[docs] def applyFilter(self, filter_string): for row_idx in range(self.rowCount()): obj_name = self.item(row_idx, 1).text().lower() signal_name = self.item(row_idx, 2).text().lower() filter_string = filter_string.lower() found = filter_string in obj_name or filter_string in signal_name self.setRowHidden(row_idx, not found)
class _HistoryLineEdit(QtWidgets.QLineEdit): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.history = [] self.history_index = 0 self.temp_text = '' def keyPressEvent(self, e): if e.key() == QtCore.Qt.Key_Up: if self.history_index < len(self.history): if self.history_index == 0: self.temp_text = self.text() self.history_index += 1 text = self.history[-1 * self.history_index] self.setText(text) elif e.key() == QtCore.Qt.Key_Down: if self.history_index > 0: text = self.history[-1 * self.history_index] self.history_index -= 1 else: text = self.temp_text self.setText(text) else: super().keyPressEvent(e)
[docs]class ExecWidget(_HistoryLineEdit): statementExecuted = QtCore.pyqtSignal(object)
[docs] def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.setNamespace() self.setPlaceholderText('Execute Python code...')
[docs] def keyPressEvent(self, e): if e.key() == QtCore.Qt.Key_Return: text = self.text() self.execText() self.clear() self.history_index = 0 self.history.append(text) else: super().keyPressEvent(e)
[docs] def setNamespace(self, globals=None, locals=None): self.globals = globals self.locals = locals
[docs] def execText(self): statement = '_ = ' + self.text() exec(statement, self.globals, self.locals) _ = self.locals['_'] self.statementExecuted.emit(_)