class SerialInputGui(QWidget): def __init__(self): super().__init__() self.layout = QGridLayout() self._setup() self.setLayout(self.layout) def send(self): text = self.text.toPlainText() self.text.clear() def send_if_checked(self): if self.send_on_enter.isChecked(): self.send() def _setup(self): self.text = QPlainTextEdit() self.text.setReadOnly(False) #self.text.returnPressed.connect(self.send_if_checked) send_button = QPushButton("Send") send_button.clicked.connect(self.send) self.send_on_enter = QCheckBox("Send on Enter") self.send_on_enter.setCheckState(Qt.Checked) self.layout.addWidget(self.text, 0, 0, -1, 1) self.layout.addWidget(send_button, 0, 1, 1, 1) self.layout.addWidget(self.send_on_enter, 1, 1, 1, 1)
def funcDisplayFacilities(self): for i in reversed(range(self.facilitiesTable.rowCount())): self.facilitiesTable.removeRow(i) cur = db.cur facilities = cur.execute("SELECT * FROM facilities") for row_data in facilities: row_number = self.facilitiesTable.rowCount() self.facilitiesTable.insertRow(row_number) # Add checkboxes to the table qwidget = QWidget() checkbox = QCheckBox() checkbox.setCheckState(Qt.Unchecked) checkbox.stateChanged.connect(self.funcActivateBtnsWithCheckbox) qhboxlayout = QHBoxLayout(qwidget) qhboxlayout.addWidget(checkbox) qhboxlayout.setAlignment(Qt.AlignCenter) self.facilitiesTable.setCellWidget(row_number, 0, qwidget) self.facilitiesTable.setItem(row_number, 0, QTableWidgetItem(row_number)) for column_number, data in enumerate(row_data, start=1): if column_number == 1: self.facilitiesTable.setItem( row_number, column_number, QTableWidgetItem("FCL#" + str(data))) else: self.facilitiesTable.setItem(row_number, column_number, QTableWidgetItem(str(data))) self.facilitiesTable.setEditTriggers(QAbstractItemView.NoEditTriggers) self.facilitiesTable.setSelectionBehavior(QTableView.SelectRows)
def paint(self, painter, option, index): checked = bool(index.data()) checkbox = QCheckBox() if (index.flags() & Qt.ItemIsEditable) > 0: checkbox.setEnabled(True) else: checkbox.setEnabled(False) # Implement tristate checkboxe for folder nodes if checked: checkbox.setCheckState(Qt.Checked) else: checkbox.setCheckState(Qt.Unchecked) if self.parent(): checkbox.setStyleSheet(self.parent().styleSheet()) width = option.widget.columnWidth(1) height = option.widget.rowHeight(0) painter.save() painter.translate(option.rect.topLeft()) checkbox.rect = option.rect checkbox.setFixedSize(width, height) checkbox.render(painter, QPoint(0, 0)) painter.restore()
class ToggleButton: def __init__(self, frame_text: str, checkbox_text: str = 'Default'): self.box = QVBoxLayout() self.lbl = QLabel(frame_text) self.checkbox = QCheckBox(checkbox_text) self.checkbox.setCheckState(Qt.Unchecked) self.numeric = QSpinBox() self.numeric.setValue(-1) self.box.addWidget(self.lbl) self.box.addWidget(self.numeric) self.box.addWidget(self.checkbox) self.checkbox.stateChanged.connect(self.checkbox_toggle) self.numeric.valueChanged.connect(self.numeric_change) self.use_default = False self.value = -1 @Slot() def checkbox_toggle(self, checked): self.use_default = self.checkbox.checkState() == Qt.Checked self.numeric.setDisabled(self.use_default) @Slot() def numeric_change(self, checked): self.value = self.numeric.value()
def funcSearchIssues(self): value = self.searchIssuesEntry.text() if value == "": QMessageBox.information(self, "Warning", "Search string cannot be empty") self.funcDisplayIssues() else: # Erase search entry self.searchIssuesEntry.setText("") try: query = "SELECT * FROM issues WHERE " \ "issue_id LIKE ? " \ "OR issue_date LIKE ?" \ "OR issue_priority LIKE ?" \ "OR issue_observer LIKE ?" \ "OR issue_team LIKE ?" \ "OR issue_inspection LIKE ?" \ "OR issue_theme LIKE ?" \ "OR issue_facility LIKE ?" \ "OR issue_fac_supervisor LIKE ?" \ "OR issue_spec_loc LIKE ?" \ "OR issue_insp_dept LIKE ?" \ "OR issue_insp_contr LIKE ?" \ "OR issue_insp_subcontr LIKE ?" \ "OR issue_deadline LIKE ?" results = db.cur.execute(query, ('%' + value + '%', '%' + value + '%', '%' + value + '%', '%' + value + '%', '%' + value + '%', '%' + value + '%', '%' + value + '%', '%' + value + '%', '%' + value + '%', '%' + value + '%', '%' + value + '%', '%' + value + '%', '%' + value + '%', '%' + value + '%',)).fetchall() if results == []: QMessageBox.information(self, "Info", "Nothing was found") self.funcDisplayIssues() else: for i in reversed(range(self.issuesTable.rowCount())): self.issuesTable.removeRow(i) for row_data in results: row_number = self.issuesTable.rowCount() self.issuesTable.insertRow(row_number) # Add checkboxes to the table qwidget = QWidget() checkbox = QCheckBox() checkbox.setCheckState(Qt.Unchecked) qhboxlayout = QHBoxLayout(qwidget) qhboxlayout.addWidget(checkbox) qhboxlayout.setAlignment(Qt.AlignCenter) self.issuesTable.setCellWidget(row_number, 0, qwidget) self.issuesTable.setItem(row_number, 0, QTableWidgetItem(row_number)) for column_number, data in enumerate(row_data, start=1): if column_number == 1: self.issuesTable.setItem(row_number, column_number, QTableWidgetItem("ISS#" + str(data))) else: self.issuesTable.setItem(row_number, column_number, QTableWidgetItem(str(data))) except: QMessageBox.information(self, "Info", "Cannot access database")
def __init__(self): super().__init__() checkbox = QCheckBox("3옵션 체크박스") checkbox.stateChanged.connect(self.state_changed) checkbox.setTristate(True) checkbox.setCheckState(Qt.PartiallyChecked) self.setCentralWidget(checkbox)
def __init__(self): super().__init__() self.setWindowTitle("My App") widget = QCheckBox("This is a checkbox") widget.setCheckState(Qt.Checked) # For tristate: widget.setCheckState(Qt.PartiallyChecked) # Or: widget.setTristate(True) widget.stateChanged.connect(self.show_state) self.setCentralWidget(widget)
def _createCheckableType(self, a: PluginAttribute): """ Creates widget for attribute of CHECKABLE type. :param a: The attribute. :type a: PluginAttribute :return: Widget for attribute. :rtype: QWidget """ inputW = QCheckBox() inputW.setCheckState(Qt.Checked if a.value else Qt.Unchecked) inputW.stateChanged.connect(a.setValue) return self._createWidget(a, inputW, False)
def paint(self, painter, option, index): checked = bool(index.data()) checkbox = QCheckBox() if (index.flags() & Qt.ItemIsEditable) > 0: checkbox.setEnabled(True) else: checkbox.setEnabled(False) if checked: checkbox.setCheckState(Qt.Checked) else: checkbox.setCheckState(Qt.Unchecked) checkbox.rect = self.getCheckBoxRect(option) #checkbox.setCheckState(QStyle.State_Enabled) style = '''QCheckBox, QRadioButton { color: #546E7A; } QCheckBox::indicator::unchecked { background-color: #FFFFFF; border: 1px solid #536D79; } QCheckBox::indicator::checked, QTreeView::indicator::checked { background-color: qradialgradient(cx:0.5, cy:0.5, fx:0.25, fy:0.15, radius:0.3, stop:0 #80CBC4, stop:1 #FFFFFF); border: 1px solid #536D79; } QCheckBox::indicator:disabled, QRadioButton::indicator:disabled, QTreeView::indicator:disabled { background-color: #444444; /* Not sure what this looks like */ } QCheckBox::indicator::checked:disabled, QRadioButton::indicator::checked:disabled, QTreeView::indicator::checked:disabled { background-color: qradialgradient(cx:0.5, cy:0.5, fx:0.25, fy:0.15, radius:0.3, stop:0 #BBBBBB, stop:1 #444444); /* Not sure what this looks like */ } ''' checkbox.setStyleSheet(style) painter.save() painter.translate(option.rect.topLeft()) checkbox.render(painter, QPoint(0, 0)) painter.restore()
class DFAStateEditor(QDialog): signalEditedStateInfo = Signal(dict, dict) def __init__(self, state=None): super(DFAStateEditor, self).__init__() self.setModal(True) self.initialInfo = { 'stateId': state.id, 'isAcceptable': state.isAcceptable } self.isAcceptableCheckBox = QCheckBox('State is acceptable ', self) self.accepted = QPushButton('OK', self) self.rejected = QPushButton('Cancel', self) if state is not None: self.setCheckBox(self.isAcceptableCheckBox, state.isAcceptable) else: self.isAcceptableCheckBox.setCheckState(QCheckBox.Unchecked) self.accepted.clicked.connect(self.sendCollectedInfo) self.rejected.clicked.connect(self.reject) self.setMaximumHeight(200) self.setMaximumWidth(200) layout = QGridLayout() # layout.setParent(self) layout.addWidget(self.isAcceptableCheckBox, 0, 0) layout.addWidget(self.accepted, 1, 0) layout.addWidget(self.rejected, 1, 1) self.setLayout(layout) def setCheckBox(self, checkbox, value): if value is True: checkbox.setChecked(True) else: checkbox.setChecked(False) @Slot() def sendCollectedInfo(self): info = { 'stateId': self.initialInfo['stateId'], 'isAcceptable': self.isAcceptableCheckBox.isChecked() } self.signalEditedStateInfo.emit(info, self.initialInfo) self.accept()
class MillerArrayTableForm(QDialog): def __init__(self, parent=None): super(MillerArrayTableForm, self).__init__(parent.window) self.setWindowFlag(Qt.WindowContextHelpButtonHint, False) self.setWindowTitle("Tabulated Reflection Data") self.precision_spinBox = QSpinBox() self.precision_spinBox.setSingleStep(1) self.precision_spinBox.setRange(1, 20) self.precision_spinBox.setValue(3) self.precision_spinBox.valueChanged.connect(parent.onPrecisionChanged) precision_labeltxt = QLabel() precision_labeltxt.setText("Precision:") self.SortComboBox = QComboBox() self.SortComboBox.activated.connect(parent.onSortComboBoxSelchange) sort_labeltxt = QLabel() sort_labeltxt.setText("Sort according to:") self.sortChkbox = QCheckBox() self.sortChkbox.setCheckState(Qt.Unchecked) self.sortChkbox.setText("Ascending order") self.sortChkbox.clicked.connect(parent.onSortChkbox) self.myGroupBox = QGroupBox() self.layout = QGridLayout() self.layout.addWidget(precision_labeltxt, 0, 0, 1, 1) self.layout.addWidget(self.precision_spinBox, 0, 1, 1, 1) self.layout.addWidget(sort_labeltxt, 0, 2, 1, 1) self.layout.addWidget(self.SortComboBox, 0, 3, 1, 1) self.layout.addWidget(self.sortChkbox, 0, 4, 1, 1) self.layout.addWidget(parent.millerarraytable, 1, 0, 1, 5) self.layout.setColumnStretch(0, 0) self.layout.setColumnStretch(1, 0) self.layout.setColumnStretch(2, 0) self.layout.setColumnStretch(3, 0) self.layout.setColumnStretch(4, 1) self.myGroupBox.setLayout(self.layout) self.mainLayout = QGridLayout() self.mainLayout.addWidget(self.myGroupBox, 0, 0) self.setLayout(self.mainLayout) def eventFilter(self, source, event): if (event.type() == QEvent.KeyPress and event.matches(QKeySequence.Copy)): self.parent().parent.millerarraytable.copySelection() return True return super(MillerArrayTableForm, self).eventFilter(source, event)
def funcDisplayPeople(self): for i in reversed(range(self.peopleTable.rowCount())): self.peopleTable.removeRow(i) cur = db.cur people = cur.execute("SELECT * FROM people") for row_data in people: row_number = self.peopleTable.rowCount() self.peopleTable.insertRow(row_number) # Add checkboxes to the table widget = QWidget() checkBox = QCheckBox() checkBox.setCheckState(Qt.Unchecked) checkBox.stateChanged.connect(self.funcActivateBtnsWithCheckbox) hBoxLayout = QHBoxLayout(widget) hBoxLayout.addWidget(checkBox) hBoxLayout.setAlignment(Qt.AlignCenter) self.peopleTable.setCellWidget(row_number, 0, widget) self.peopleTable.setItem(row_number, 0, QTableWidgetItem(row_number)) # Add photo photos_thumbnails to the table thumbWidget = QWidget() pic = QPixmap(str(row_data[10])) thumbLabel = QLabel() thumbLabel.setPixmap(pic) thumbLayout = QHBoxLayout(thumbWidget) thumbLayout.addWidget(thumbLabel) self.peopleTable.setCellWidget(row_number, 1, thumbWidget) self.peopleTable.setItem(row_number, 0, QTableWidgetItem(row_number)) # Fill the rest of the data for column_number, data in enumerate(row_data, start=2): if column_number == 2: self.peopleTable.setItem( row_number, column_number, QTableWidgetItem("PRN#" + str(data))) else: self.peopleTable.setItem(row_number, column_number, QTableWidgetItem(str(data))) self.peopleTable.setEditTriggers(QAbstractItemView.NoEditTriggers) self.peopleTable.setSelectionBehavior(QTableView.SelectRows)
def createTopLeftGroupBox(self): self.topLeftGroupBox = QGroupBox("Group 1") radioButton1 = QRadioButton("Radio button 1") radioButton2 = QRadioButton("Radio button 2") radioButton3 = QRadioButton("Radio button 3") radioButton1.setChecked(True) checkBox = QCheckBox("Tri-state check box") checkBox.setTristate(True) checkBox.setCheckState(Qt.PartiallyChecked) layout = QVBoxLayout() layout.addWidget(radioButton1) layout.addWidget(radioButton2) layout.addWidget(radioButton3) layout.addWidget(checkBox) layout.addStretch(1) self.topLeftGroupBox.setLayout(layout)
class OTIOExportUI(hiero.ui.TaskUIBase): def __init__(self, preset): """Initialize""" hiero.ui.TaskUIBase.__init__( self, OTIOExportTask, preset, "OTIO Exporter" ) def includeMarkersCheckboxChanged(self, state): # Slot to handle change of checkbox state self._preset.properties()["includeTags"] = state == QtCore.Qt.Checked def populateUI(self, widget, exportTemplate): layout = widget.layout() formLayout = FormLayout() # Hiero ~= 10.0v4 if layout is None: layout = formLayout widget.setLayout(layout) else: layout.addLayout(formLayout) # Checkboxes for whether the OTIO should contain markers or not self.includeMarkersCheckbox = QCheckBox() self.includeMarkersCheckbox.setToolTip( "Enable to include Tags as markers in the exported OTIO file." ) self.includeMarkersCheckbox.setCheckState(QtCore.Qt.Unchecked) if self._preset.properties()["includeTags"]: self.includeMarkersCheckbox.setCheckState(QtCore.Qt.Checked) self.includeMarkersCheckbox.stateChanged.connect( self.includeMarkersCheckboxChanged ) # Add Checkbox to layout formLayout.addRow("Include Tags:", self.includeMarkersCheckbox)
class BasicSelector(SimpleSelector): # User-visible usage message. Can be used as tool tip. kUsage = maya.stringTable['y_simpleSelector.kBasicSelectorUsage'] # User-visible display type. kDisplayType = maya.stringTable[ 'y_simpleSelector.kBasicSelectorDisplayType'] # Corresponding data model type. kModelType = selector.BasicSelector.kTypeName def __init__(self, selector): super(BasicSelector, self).__init__(selector) self.includeHierarchy = None def build(self, layout): super(BasicSelector, self).build(layout, populate=False) self._setupIncludeHierarchy(self.addToCollectionGroupBoxLayout) self.populateFields() def _setupIncludeHierarchy(self, layout): self.includeHierarchy = QCheckBox( maya.stringTable['y_simpleSelector.kIncludeHierarchy']) self.includeHierarchy.setToolTip( maya.stringTable['y_simpleSelector.kIncludeHierarchyTooltipStr']) self.includeHierarchy.stateChanged.connect( lambda x: self.setIncludeHierarchy(x == Qt.Checked)) layout.addWidget(self.includeHierarchy) @ifNotBlockChangeMessages def setIncludeHierarchy(self, value): self._selector.setIncludeHierarchy(value) @guard.member('_blockChangeMessages', True) def populateFields(self): super(BasicSelector, self).populateFields() self.includeHierarchy.setCheckState( Qt.Checked if self._selector.getIncludeHierarchy( ) else Qt.Unchecked)
def __init__(self): super().__init__() self.setWindowTitle("My App") widget = QLabel("Hello") # In order to modify the font, we retrieve it, # change it, and set it back font = widget.font() font.setPointSize(30) widget.setFont(font) widget.setAlignment(Qt.AlignHCenter | Qt.AlignVCenter) widget.setPixmap(QPixmap('assets/example.jpg')) widget.setScaledContents(True) widget.setFixedSize(QSize(200, 100)) checkbox = QCheckBox("A checkbox") checkbox.setCheckState(Qt.Checked) checkbox.setTristate(True) checkbox.stateChanged.connect(self.show_state) # self.setCentralWidget(checkbox) self.setCentralWidget(widget)
def createNotificationPopup(self): popup = QDialog(self) popup.setFixedSize(popup.sizeHint().height(), popup.sizeHint().width()) popup.setWindowTitle("Évènements") innerLayout = QVBoxLayout() GroupBox = QGroupBox("Activer les notifications") GroupBox.setCheckable(True) GroupBox.setChecked(self.notification) checkBox_popup = QCheckBox("Afficher une popup") checkBox_notification = QCheckBox("Afficher une notification") checkBox_sound = QCheckBox("Jouer un son") if self.notification_popup: checkBox_popup.setCheckState(Qt.Checked) if self.notification_tray: checkBox_notification.setCheckState(Qt.Checked) if self.notification_sound: checkBox_sound.setCheckState(Qt.Checked) innerLayout.addWidget(checkBox_popup) innerLayout.addWidget(checkBox_notification) innerLayout.addWidget(checkBox_sound) innerLayout.addStretch(1) GroupBox.setLayout(innerLayout) button = QPushButton("Ok") button.clicked.connect(lambda: self.changeNotificationSettings( popup, GroupBox, checkBox_popup, checkBox_notification, checkBox_sound)) outerLayout = QVBoxLayout() outerLayout.addWidget(GroupBox) outerLayout.addWidget(button) popup.setLayout(outerLayout) popup.exec_()
class ExportFileDialog(QFileDialog): """ Create a custom Export-File Dialog with options like BOM etc. """ def __init__(self, *args, **kwargs): super(ExportFileDialog, self).__init__(*args, **kwargs) self.mainWindow = self.parent() self.setWindowTitle("Export nodes to CSV") self.setAcceptMode(QFileDialog.AcceptSave) self.setOption(QFileDialog.DontUseNativeDialog) #self.setFilter("CSV Files (*.csv)") self.setDefaultSuffix("csv") self.optionBOM = QCheckBox("Use a BOM", self) self.optionBOM.setCheckState(Qt.CheckState.Checked) self.optionLinebreaks = QCheckBox("Remove line breaks", self) self.optionLinebreaks.setCheckState(Qt.CheckState.Checked) self.optionSeparator = QComboBox(self) self.optionSeparator.insertItems(0, [";", "\\t", ","]) self.optionSeparator.setEditable(True) # if none or all are selected, export all # if one or more are selected, export selective self.optionAll = QComboBox(self) self.optionAll.insertItems(0, [ 'All nodes (faster for large datasets, ordered by internal ID)', 'Selected nodes (ordered like shown in nodes view)' ]) if self.mainWindow.tree.noneOrAllSelected(): self.optionAll.setCurrentIndex(0) else: self.optionAll.setCurrentIndex(1) layout = self.layout() row = layout.rowCount() layout.addWidget(QLabel('Options'), row, 0) options = QHBoxLayout() options.addWidget(self.optionBOM) options.addWidget(self.optionLinebreaks) options.addWidget(QLabel('Separator')) options.addWidget(self.optionSeparator) options.addStretch(1) layout.addLayout(options, row, 1, 1, 2) layout.addWidget(QLabel('Export mode'), row + 2, 0) layout.addWidget(self.optionAll, row + 2, 1, 1, 2) self.setLayout(layout) if self.exec_(): if os.path.isfile(self.selectedFiles()[0]): os.remove(self.selectedFiles()[0]) output = open(self.selectedFiles()[0], 'w', newline='', encoding='utf8') if self.optionBOM.isChecked(): output.write('\ufeff') try: if self.optionAll.currentIndex() == 0: self.exportAllNodes(output) else: self.exportSelectedNodes(output) finally: output.close() def exportSelectedNodes(self, output): progress = ProgressBar("Exporting data...", self.mainWindow) #indexes = self.mainWindow.tree.selectionModel().selectedRows() #if child nodes should be exported as well, uncomment this line an comment the previous one indexes = self.mainWindow.tree.selectedIndexesAndChildren() indexes = list(indexes) progress.setMaximum(len(indexes)) try: delimiter = self.optionSeparator.currentText() delimiter = delimiter.encode('utf-8').decode('unicode_escape') writer = csv.writer(output, delimiter=delimiter, quotechar='"', quoting=csv.QUOTE_ALL, doublequote=True, lineterminator='\r\n') #headers row = [ str(val) for val in self.mainWindow.tree.treemodel.getRowHeader() ] if self.optionLinebreaks.isChecked(): row = [ val.replace('\n', ' ').replace('\r', ' ') for val in row ] writer.writerow(row) #rows for no in range(len(indexes)): if progress.wasCanceled: break row = [ str(val) for val in self.mainWindow.tree.treemodel.getRowData(indexes[no]) ] if self.optionLinebreaks.isChecked(): row = [ val.replace('\n', ' ').replace('\r', ' ') for val in row ] writer.writerow(row) progress.step() finally: progress.close() def exportAllNodes(self, output): progress = ProgressBar("Exporting data...", self.mainWindow) progress.setMaximum(Node.query.count()) try: delimiter = self.optionSeparator.currentText() delimiter = delimiter.encode('utf-8').decode('unicode_escape') writer = csv.writer(output, delimiter=delimiter, quotechar='"', quoting=csv.QUOTE_ALL, doublequote=True, lineterminator='\r\n') #headers row = [ "level", "id", "parent_id", "object_id", "object_type", "query_status", "query_time", "query_type" ] for key in self.mainWindow.tree.treemodel.customcolumns: row.append(key) if self.optionLinebreaks.isChecked(): row = [ val.replace('\n', ' ').replace('\r', ' ') for val in row ] writer.writerow(row) #rows page = 0 while True: allnodes = Node.query.offset(page * 5000).limit(5000) if allnodes.count() == 0: break for node in allnodes: if progress.wasCanceled: break row = [ node.level, node.id, node.parent_id, node.objectid, node.objecttype, node.querystatus, node.querytime, node.querytype ] for key in self.mainWindow.tree.treemodel.customcolumns: row.append(node.getResponseValue(key)) if self.optionLinebreaks.isChecked(): row = [ str(val).replace('\n', ' ').replace('\r', ' ') for val in row ] writer.writerow(row) # step the Bar progress.step() if progress.wasCanceled: break else: page += 1 finally: progress.close()
class NGL_HKLViewer(QWidget): def __init__(self, parent=None): super(NGL_HKLViewer, self).__init__(parent) self.verbose = 0 self.UseOSbrowser = False self.jscriptfname = "" self.devmode = False for e in sys.argv: if "verbose" in e: self.verbose = e.split("verbose=")[1] if "UseOSbrowser" in e: self.UseOSbrowser = e.split("UseOSbrowser=")[1] if "jscriptfname" in e: self.jscriptfname = e.split("jscriptfname=")[1] if "devmode" in e: self.devmode = True self.zmq_context = None self.bufsize = 20000 self.originalPalette = QApplication.palette() self.openFileNameButton = QPushButton("Load reflection file") self.openFileNameButton.setDefault(True) self.openFileNameButton.clicked.connect(self.OpenReflectionsFile) self.debugbutton = QPushButton("Debug") self.debugbutton.clicked.connect(self.DebugInteractively) self.settingsbtn = QPushButton("Settings") self.settingsbtn.clicked.connect(self.SettingsDialog) self.mousemoveslider = QSlider(Qt.Horizontal) self.mousemoveslider.setMinimum(0) self.mousemoveslider.setMaximum(300) self.mousemoveslider.setValue(0) self.mousemoveslider.sliderReleased.connect( self.onFinalMouseSensitivity) self.mousemoveslider.valueChanged.connect(self.onMouseSensitivity) self.mousesensitxtbox = QLineEdit('') self.mousesensitxtbox.setReadOnly(True) self.fontspinBox = QDoubleSpinBox() self.fontspinBox.setSingleStep(1) self.fontspinBox.setRange(4, 50) self.font = QFont() self.font.setFamily(self.font.defaultFamily()) self.fontspinBox.setValue(self.font.pointSize()) #self.fontspinBox.setValue(self.font.pixelSize()) self.fontspinBox.valueChanged.connect(self.onFontsizeChanged) self.Fontsize_labeltxt = QLabel() self.Fontsize_labeltxt.setText("Font size:") self.cameraPerspectCheckBox = QCheckBox() self.cameraPerspectCheckBox.setText("Perspective camera") self.cameraPerspectCheckBox.clicked.connect(self.onCameraPerspect) self.cameraPerspectCheckBox.setCheckState(Qt.Unchecked) self.settingsform = SettingsForm(self) self.MillerComboBox = QComboBox() self.MillerComboBox.activated.connect(self.onMillerComboSelchange) #self.MillerComboBox.setSizeAdjustPolicy(QComboBox.AdjustToContents) self.MillerLabel = QLabel() self.MillerLabel.setText("Selected HKL Scene") self.HKLnameedit = QLineEdit('') self.HKLnameedit.setReadOnly(True) self.textInfo = QTextEdit() self.textInfo.setLineWrapMode(QTextEdit.NoWrap) self.textInfo.setReadOnly(True) labels = [ "Label", "Type", "no. of HKLs", "Span of HKLs", "Min Max data", "Min Max sigmas", "d_min, d_max", "Symmetry unique", "Anomalous" ] self.millertable = QTableWidget(0, len(labels)) self.millertable.setHorizontalHeaderLabels(labels) self.millertable.horizontalHeader().setDefaultAlignment(Qt.AlignLeft) # don't allow editing this table self.millertable.setEditTriggers(QTableWidget.NoEditTriggers) self.createExpansionBox() self.createFileInfoBox() self.CreateSliceTabs() self.createRadiiScaleGroupBox() self.createBinsBox() self.CreateFunctionTabs() mainLayout = QGridLayout() mainLayout.addWidget(self.FileInfoBox, 0, 0) mainLayout.addWidget(self.MillerLabel, 1, 0) mainLayout.addWidget(self.MillerComboBox, 2, 0) mainLayout.addWidget(self.functionTabWidget, 3, 0) mainLayout.addWidget(self.settingsbtn, 4, 0, 1, 1) #import code, traceback; code.interact(local=locals(), banner="".join( traceback.format_stack(limit=10) ) ) if self.UseOSbrowser == False: self.BrowserBox = QWebEngineView() mainLayout.addWidget(self.BrowserBox, 0, 1, 5, 3) self.BrowserBox.setUrl("https://cctbx.github.io/") #self.BrowserBox.setUrl("https://webglreport.com/") #self.BrowserBox.loadFinished.connect(self.onLoadFinished) mainLayout.setColumnStretch(2, 1) mainLayout.setRowStretch(0, 1) mainLayout.setRowStretch(1, 0) mainLayout.setRowStretch(2, 1) mainLayout.setRowStretch(3, 1) mainLayout.setColumnStretch(4, 0) self.setLayout(mainLayout) self.setWindowTitle("HKL-Viewer") self.cctbxproc = None self.LaunchCCTBXPython() self.out = None self.err = None self.comboviewwidth = 0 self.hklscenes_arrays = [] self.array_infotpls = [] self.matching_arrays = [] self.bin_infotpls = None self.bin_opacities = None self.html_url = "" self.spacegroups = [] self.info = [] self.infostr = "" self.fileisvalid = False self.NewFileLoaded = False self.NewHKLscenes = False self.updatingNbins = False self.binstableitemchanges = False self.show() def SettingsDialog(self): self.settingsform.show() def update(self): if self.cctbxproc: if self.cctbxproc.stdout: print(self.cctbxproc.stdout.read().decode("utf-8")) if self.cctbxproc.stderr: print(self.cctbxproc.stderr.read().decode("utf-8")) if self.out: print(self.out.decode("utf-8")) if self.err: print(self.err.decode("utf-8")) if self.zmq_context: try: msg = self.socket.recv( flags=zmq.NOBLOCK ) #To empty the socket from previous messages msgstr = msg.decode() self.infodict = eval(msgstr) #print("received from cctbx: " + str(self.infodict)) if self.infodict: if self.infodict.get("hklscenes_arrays"): self.hklscenes_arrays = self.infodict.get( "hklscenes_arrays", []) if self.infodict.get("array_infotpls"): self.array_infotpls = self.infodict.get( "array_infotpls", []) if self.infodict.get("bin_data_label"): self.BinDataComboBox.setCurrentText( self.infodict["bin_data_label"]) if self.infodict.get("bin_infotpls"): self.bin_infotpls = self.infodict["bin_infotpls"] self.nbins = len(self.bin_infotpls) self.updatingNbins = True self.Nbins_spinBox.setValue(self.nbins) self.updatingNbins = False self.binstable.clearContents() self.binstable.setRowCount(self.nbins) for row, bin_infotpl in enumerate(self.bin_infotpls): for col, elm in enumerate(bin_infotpl): # only allow changing the last column with opacity values if col != 3: item = QTableWidgetItem(str(elm)) else: item = QTableWidgetItem() item.setFlags(Qt.ItemIsUserCheckable | Qt.ItemIsEnabled) item.setCheckState(Qt.Checked) item.setFlags(item.flags() ^ Qt.ItemIsEditable) self.binstable.setItem(row, col, item) if self.bin_opacities: self.update_table_opacities() if self.infodict.get("bin_opacities"): self.bin_opacities = self.infodict["bin_opacities"] if self.binstable.rowCount() > 0: self.update_table_opacities() if self.infodict.get("html_url"): self.html_url = self.infodict["html_url"] if self.UseOSbrowser == False: self.BrowserBox.setUrl(self.html_url) # workaround for background colour bug in chromium # https://bugreports.qt.io/browse/QTBUG-41960 self.BrowserBox.page().setBackgroundColor( QColor(100, 100, 100, 1.0)) if self.infodict.get("spacegroups"): self.spacegroups = self.infodict.get("spacegroups", []) self.SpaceGroupComboBox.clear() self.SpaceGroupComboBox.addItems(self.spacegroups) if self.infodict.get("merge_data"): self.mergedata = self.infodict["merge_data"] currentinfostr = "" if self.infodict.get("info"): currentinfostr = self.infodict.get("info", []) if self.infodict.get("NewFileLoaded"): self.NewFileLoaded = self.infodict.get( "NewFileLoaded", False) if self.infodict.get("NewHKLscenes"): self.NewHKLscenes = self.infodict.get( "NewHKLscenes", False) self.fileisvalid = True #print("ngl_hkl_infodict: " + str(ngl_hkl_infodict)) if currentinfostr: #print(currentinfostr) self.infostr += currentinfostr + "\n" # display no more than self.bufsize bytes of text self.infostr = self.infostr[-self.bufsize:] self.textInfo.setPlainText(self.infostr) self.textInfo.verticalScrollBar().setValue( self.textInfo.verticalScrollBar().maximum()) if self.NewFileLoaded and self.NewHKLscenes: #if self.mergedata == True : val = Qt.CheckState.Checked #if self.mergedata == None : val = Qt.CheckState.PartiallyChecked #if self.mergedata == False : val = Qt.CheckState.Unchecked #self.mergecheckbox.setCheckState(val ) #print("got hklscenes: " + str(self.hklscenes_arrays)) self.MillerComboBox.clear() self.MillerComboBox.addItems( [e[3] for e in self.hklscenes_arrays]) self.MillerComboBox.setCurrentIndex( -1) # unselect the first item in the list self.comboviewwidth = 0 for e in self.hklscenes_arrays: self.comboviewwidth = max( self.comboviewwidth, self.MillerComboBox.fontMetrics().width(e[3])) self.MillerComboBox.view().setMinimumWidth( self.comboviewwidth) self.millertable.clearContents() self.millertable.setRowCount(len( self.hklscenes_arrays)) for n, millarr in enumerate(self.array_infotpls): for m, elm in enumerate(millarr): self.millertable.setItem( n, m, QTableWidgetItem(str(elm))) self.functionTabWidget.setDisabled(True) self.NewFileLoaded = False if self.NewHKLscenes: self.BinDataComboBox.clear() self.BinDataComboBox.addItems( ["Resolution"] + [e[3] for e in self.hklscenes_arrays]) self.BinDataComboBox.view().setMinimumWidth( self.comboviewwidth) #self.BinDataComboBox.setCurrentIndex(-1) # unselect the first item in the list self.NewHKLscenes = False except Exception as e: errmsg = str(e) if "Resource temporarily unavailable" not in errmsg: print(errmsg + traceback.format_exc(limit=10)) pass def onFinalMouseSensitivity(self): val = self.mousemoveslider.value() / 100.0 self.NGL_HKL_command( 'NGL_HKLviewer.viewer.NGL.mouse_sensitivity = %f' % val) def onMouseSensitivity(self): val = self.mousemoveslider.value() / 100.0 self.mousesensitxtbox.setText("%2.2f" % val) def onFontsizeChanged(self, val): font = app.font() font.setPointSize(val) app.setFont(font) self.settingsform.setFixedSize(self.settingsform.sizeHint()) def onCameraPerspect(self, val): if self.cameraPerspectCheckBox.isChecked(): self.NGL_HKL_command("NGL_HKLviewer.camera_type = perspective") else: self.NGL_HKL_command("NGL_HKLviewer.camera_type = orthographic") def MergeData(self): if self.mergecheckbox.checkState() == Qt.CheckState.Checked: self.NGL_HKL_command('NGL_HKLviewer.mergedata = True') if self.mergecheckbox.checkState() == Qt.CheckState.PartiallyChecked: self.NGL_HKL_command('NGL_HKLviewer.mergedata = None') if self.mergecheckbox.checkState() == Qt.CheckState.Unchecked: self.NGL_HKL_command('NGL_HKLviewer.mergedata = False') def ExpandToP1(self): if self.expandP1checkbox.isChecked(): self.NGL_HKL_command('NGL_HKLviewer.viewer.expand_to_p1 = True') else: self.NGL_HKL_command('NGL_HKLviewer.viewer.expand_to_p1 = False') def ExpandAnomalous(self): if self.expandAnomalouscheckbox.isChecked(): self.NGL_HKL_command( 'NGL_HKLviewer.viewer.expand_anomalous = True') else: self.NGL_HKL_command( 'NGL_HKLviewer.viewer.expand_anomalous = False') def showSysAbsent(self): if self.sysabsentcheckbox.isChecked(): self.NGL_HKL_command( 'NGL_HKLviewer.viewer.show_systematic_absences = True') else: self.NGL_HKL_command( 'NGL_HKLviewer.viewer.show_systematic_absences = False') def showMissing(self): if self.missingcheckbox.isChecked(): self.NGL_HKL_command('NGL_HKLviewer.viewer.show_missing = True') else: self.NGL_HKL_command('NGL_HKLviewer.viewer.show_missing = False') def showOnlyMissing(self): if self.onlymissingcheckbox.isChecked(): self.NGL_HKL_command( 'NGL_HKLviewer.viewer.show_only_missing = True') else: self.NGL_HKL_command( 'NGL_HKLviewer.viewer.show_only_missing = False') def showSlice(self): if self.showslicecheckbox.isChecked(): self.NGL_HKL_command('NGL_HKLviewer.viewer.slice_mode = True') if self.expandP1checkbox.isChecked(): self.NGL_HKL_command("""NGL_HKLviewer.viewer { expand_to_p1 = True inbrowser = False } """) if self.expandAnomalouscheckbox.isChecked(): self.NGL_HKL_command("""NGL_HKLviewer.viewer { expand_anomalous = True inbrowser = False } """) else: self.NGL_HKL_command("""NGL_HKLviewer.viewer { slice_mode = False inbrowser = True } """) def onSliceComboSelchange(self, i): rmin = self.array_infotpls[self.MillerComboBox.currentIndex()][3][0][i] rmax = self.array_infotpls[self.MillerComboBox.currentIndex()][3][1][i] self.sliceindexspinBox.setRange(rmin, rmax) self.NGL_HKL_command("NGL_HKLviewer.viewer.slice_axis = %s" % self.sliceaxis[i]) def onSliceIndexChanged(self, val): self.sliceindex = val self.NGL_HKL_command("NGL_HKLviewer.viewer.slice_index = %d" % self.sliceindex) def onBindataComboSelchange(self, i): if self.BinDataComboBox.currentText(): if self.BinDataComboBox.currentIndex() > 0: bin_scene_label = str(self.BinDataComboBox.currentIndex() - 1) else: bin_scene_label = "Resolution" self.NGL_HKL_command("NGL_HKLviewer.bin_scene_label = %s" % bin_scene_label) def update_table_opacities(self, allalpha=None): bin_opacitieslst = eval(self.bin_opacities) self.binstable_isready = False for binopacity in bin_opacitieslst: if not allalpha: alpha = float(binopacity.split(",")[0]) else: alpha = allalpha bin = int(binopacity.split(",")[1]) item = QTableWidgetItem() item.setFlags(Qt.ItemIsUserCheckable | Qt.ItemIsEnabled) if alpha < 0.5: item.setCheckState(Qt.Unchecked) else: item.setCheckState(Qt.Checked) item.setFlags(item.flags() ^ Qt.ItemIsEditable) self.binstable.setItem(bin, 3, item) self.binstable_isready = True def SetOpaqueAll(self): if self.binstableitemchanges: return bin_opacitieslst = eval(self.bin_opacities) nbins = len(bin_opacitieslst) sum = 0 for binopacity in bin_opacitieslst: sum += float(binopacity.split(",")[0]) if sum >= nbins: self.OpaqueAllCheckbox.setCheckState(Qt.Checked) if sum == 0: self.OpaqueAllCheckbox.setCheckState(Qt.Unchecked) if sum > 0.0 and sum < nbins: self.OpaqueAllCheckbox.setCheckState(Qt.PartiallyChecked) def onBinsTableItemChanged(self, item): row = item.row() column = item.column() try: if item.checkState() == Qt.Unchecked: newval = 0 else: newval = 1.0 if column == 3 and self.binstable_isready: # changing opacity assert (newval <= 1.0 and newval >= 0.0) bin_opacitieslst = eval(self.bin_opacities) bin_opacitieslst[row] = str(newval) + ', ' + str(row) self.bin_opacities = str(bin_opacitieslst) self.SetOpaqueAll() self.NGL_HKL_command( 'NGL_HKLviewer.viewer.NGL.bin_opacities = "%s"' % self.bin_opacities) except Exception as e: print(str(e)) #self.binstable.currentItem().setText( self.currentSelectedBinsTableVal) def onBinsTableItemSelectionChanged(self): row = self.binstable.currentItem().row() column = self.binstable.currentItem().column() self.currentSelectedBinsTableVal = self.binstable.currentItem().text() #print( "in itemSelectionChanged " + self.currentSelectedBinsTableVal) def onOpaqueAll(self): self.binstableitemchanges = True bin_opacitieslst = eval(self.bin_opacities) nbins = len(bin_opacitieslst) bin_opacitieslst = [] self.binstable_isready = False if self.OpaqueAllCheckbox.isChecked(): for i in range(nbins): bin_opacitieslst.append("1.0, %d" % i) else: for i in range(nbins): bin_opacitieslst.append("0.0, %d" % i) self.bin_opacities = str(bin_opacitieslst) self.NGL_HKL_command('NGL_HKLviewer.viewer.NGL.bin_opacities = "%s"' % self.bin_opacities) self.binstableitemchanges = False self.binstable_isready = True """ def onLoadFinished(self, val): pass #print("web page finished loading now") def onBinsTableitemActivated(self, item): row = item.row() column = item.column() currentval = item.text() #print( "in itemActivated " + currentval) def onBinsTableCellentered(self, row, col): pass #print( "in Cellentered " + self.binstable.currentItem().text() ) def onBinsTableCellPressed(self, row, col): pass #print( "in CellPressed " + self.binstable.currentItem().text() ) """ def onNbinsChanged(self, val): self.nbins = val if not self.updatingNbins: # avoid possible endless loop to cctbx self.NGL_HKL_command("NGL_HKLviewer.nbins = %d" % self.nbins) def onRadiiScaleChanged(self, val): self.radii_scale = val self.NGL_HKL_command(""" NGL_HKLviewer.viewer { nth_power_scale_radii = %f scale = %f } """ % (self.nth_power_scale, self.radii_scale)) def onPowerScaleChanged(self, val): self.nth_power_scale = val self.NGL_HKL_command(""" NGL_HKLviewer.viewer { nth_power_scale_radii = %f scale = %f } """ % (self.nth_power_scale, self.radii_scale)) def onManualPowerScale(self): if self.ManualPowerScalecheckbox.isChecked(): self.NGL_HKL_command( 'NGL_HKLviewer.viewer.nth_power_scale_radii = %f' % self.nth_power_scale) self.power_scale_spinBox.setEnabled(True) else: self.NGL_HKL_command( 'NGL_HKLviewer.viewer.nth_power_scale_radii = -1.0') self.power_scale_spinBox.setEnabled(False) self.nth_power_scale = -1.0 def OpenReflectionsFile(self): options = QFileDialog.Options() fileName, filtr = QFileDialog.getOpenFileName( self, "Load reflections file", "", "All Files (*);;MTZ Files (*.mtz);;CIF (*.cif)", "", options) if fileName: self.HKLnameedit.setText(fileName) #self.infostr = "" self.textInfo.setPlainText("") self.fileisvalid = False self.NGL_HKL_command('NGL_HKLviewer.filename = "%s"' % fileName) self.MillerComboBox.clear() self.BinDataComboBox.clear() def createExpansionBox(self): self.SpaceGroupComboBox = QComboBox() self.SpaceGroupComboBox.activated.connect(self.SpacegroupSelchange) self.SpacegroupLabel = QLabel() self.SpacegroupLabel.setText("Space Subgroups") self.mergecheckbox = QCheckBox() self.mergecheckbox.setText("Merge data") #self.mergecheckbox.setTristate (True) self.mergecheckbox.clicked.connect(self.MergeData) self.expandP1checkbox = QCheckBox() self.expandP1checkbox.setText("Expand to P1") self.expandP1checkbox.clicked.connect(self.ExpandToP1) self.expandAnomalouscheckbox = QCheckBox() self.expandAnomalouscheckbox.setText("Show Friedel pairs") self.expandAnomalouscheckbox.clicked.connect(self.ExpandAnomalous) self.sysabsentcheckbox = QCheckBox() self.sysabsentcheckbox.setText("Show Systematic Absences") self.sysabsentcheckbox.clicked.connect(self.showSysAbsent) self.missingcheckbox = QCheckBox() self.missingcheckbox.setText("Show Missing") self.missingcheckbox.clicked.connect(self.showMissing) self.onlymissingcheckbox = QCheckBox() self.onlymissingcheckbox.setText("Only Show Missing") self.onlymissingcheckbox.clicked.connect(self.showOnlyMissing) self.ExpansionBox = QGroupBox("Expansions") layout = QGridLayout() layout.addWidget(self.SpacegroupLabel, 0, 0) layout.addWidget(self.SpaceGroupComboBox, 0, 1) #layout.addWidget(self.mergecheckbox, 1, 0) layout.addWidget(self.expandP1checkbox, 1, 0) layout.addWidget(self.expandAnomalouscheckbox, 1, 1) layout.addWidget(self.sysabsentcheckbox, 2, 0) layout.addWidget(self.missingcheckbox, 3, 0) layout.addWidget(self.onlymissingcheckbox, 3, 1) layout.setRowStretch(0, 0) layout.setRowStretch(1, 0) layout.setRowStretch(2, 0) layout.setRowStretch(3, 1) self.ExpansionBox.setLayout(layout) def CreateSliceTabs(self): self.showslicecheckbox = QCheckBox() self.showslicecheckbox.setText("Show Slice") self.showslicecheckbox.clicked.connect(self.showSlice) self.sliceindexspinBox = QDoubleSpinBox() self.sliceindex = 0 self.sliceindexspinBox.setValue(self.sliceindex) self.sliceindexspinBox.setDecimals(0) self.sliceindexspinBox.setSingleStep(1) self.sliceindexspinBox.setRange(0, 20) self.sliceindexspinBox.valueChanged.connect(self.onSliceIndexChanged) self.SliceLabelComboBox = QComboBox() self.SliceLabelComboBox.activated.connect(self.onSliceComboSelchange) self.sliceaxis = ["h", "k", "l"] self.SliceLabelComboBox.addItems(self.sliceaxis) self.sliceTabWidget = QTabWidget() tab1 = QWidget() layout1 = QGridLayout() layout1.addWidget(self.showslicecheckbox, 0, 0, 1, 1) layout1.addWidget(self.SliceLabelComboBox, 0, 1, 1, 1) layout1.addWidget(self.sliceindexspinBox, 0, 2, 1, 1) tab1.setLayout(layout1) tab2 = QWidget() layout2 = QGridLayout() self.hvec_spinBox = QDoubleSpinBox(self.sliceTabWidget) self.hvecval = 2.0 self.hvec_spinBox.setValue(self.hvecval) self.hvec_spinBox.setDecimals(2) self.hvec_spinBox.setSingleStep(0.5) self.hvec_spinBox.setRange(-100.0, 10.0) self.hvec_spinBox.valueChanged.connect(self.onHvecChanged) self.hvec_Label = QLabel() self.hvec_Label.setText("H") layout2.addWidget(self.hvec_Label, 0, 0, 1, 1) layout2.addWidget(self.hvec_spinBox, 0, 1, 1, 1) self.kvec_spinBox = QDoubleSpinBox(self.sliceTabWidget) self.kvecval = 0.0 self.kvec_spinBox.setValue(self.kvecval) self.kvec_spinBox.setDecimals(2) self.kvec_spinBox.setSingleStep(0.5) self.kvec_spinBox.setRange(-100.0, 100.0) self.kvec_spinBox.valueChanged.connect(self.onKvecChanged) self.kvec_Label = QLabel() self.kvec_Label.setText("K") layout2.addWidget(self.kvec_Label, 1, 0, 1, 1) layout2.addWidget(self.kvec_spinBox, 1, 1, 1, 1) self.lvec_spinBox = QDoubleSpinBox(self.sliceTabWidget) self.lvecval = 0.0 self.lvec_spinBox.setValue(self.lvecval) self.lvec_spinBox.setDecimals(2) self.lvec_spinBox.setSingleStep(0.5) self.lvec_spinBox.setRange(-100.0, 100.0) self.lvec_spinBox.valueChanged.connect(self.onLvecChanged) self.lvec_Label = QLabel() self.lvec_Label.setText("L") layout2.addWidget(self.lvec_Label, 2, 0, 1, 1) layout2.addWidget(self.lvec_spinBox, 2, 1, 1, 1) self.hkldist_spinBox = QDoubleSpinBox(self.sliceTabWidget) self.hkldistval = 0.0 self.hkldist_spinBox.setValue(self.hkldistval) self.hkldist_spinBox.setDecimals(2) self.hkldist_spinBox.setSingleStep(0.5) self.hkldist_spinBox.setRange(-100.0, 100.0) self.hkldist_spinBox.valueChanged.connect(self.onHKLdistChanged) self.hkldist_Label = QLabel() self.hkldist_Label.setText("Distance from Origin") layout2.addWidget(self.hkldist_Label, 3, 0, 1, 1) layout2.addWidget(self.hkldist_spinBox, 3, 1, 1, 1) self.clipwidth_spinBox = QDoubleSpinBox(self.sliceTabWidget) self.clipwidthval = 0.5 self.clipwidth_spinBox.setValue(self.clipwidthval) self.clipwidth_spinBox.setDecimals(2) self.clipwidth_spinBox.setSingleStep(0.05) self.clipwidth_spinBox.setRange(0.0, 100.0) self.clipwidth_spinBox.valueChanged.connect(self.onClipwidthChanged) self.clipwidth_Label = QLabel() self.clipwidth_Label.setText("Clip Plane Width") layout2.addWidget(self.clipwidth_Label, 4, 0, 1, 1) layout2.addWidget(self.clipwidth_spinBox, 4, 1, 1, 1) self.ClipBox = QGroupBox("Normal Vector to Clip Plane") self.ClipBox.setLayout(layout2) layout3 = QGridLayout() self.ClipPlaneChkBox = QCheckBox(self.sliceTabWidget) self.ClipPlaneChkBox.setText( "Use clip plane normal to HKL vector pointing out") self.ClipPlaneChkBox.clicked.connect(self.onClipPlaneChkBox) layout3.addWidget(self.ClipPlaneChkBox, 0, 0) layout3.addWidget(self.ClipBox, 1, 0) tab2.setLayout(layout3) self.sliceTabWidget.addTab(tab1, "Explicit Slicing") self.sliceTabWidget.addTab(tab2, "Clip Plane Slicing") self.ClipBox.setDisabled(True) def onClipPlaneChkBox(self): if self.ClipPlaneChkBox.isChecked(): self.ClipBox.setDisabled(False) philstr = """NGL_HKLviewer.normal_clip_plane { h = %s k = %s l = %s hkldist = %s clipwidth = %s } NGL_HKLviewer.viewer.NGL.fixorientation = %s """ %(self.hvecval, self.kvecval, self.lvecval, self.hkldistval, self.clipwidthval, \ str(self.fixedorientcheckbox.isChecked()) ) self.NGL_HKL_command(philstr) else: self.ClipBox.setDisabled(True) self.NGL_HKL_command( "NGL_HKLviewer.normal_clip_plane.clipwidth = None") def onClipwidthChanged(self, val): self.clipwidthval = val self.NGL_HKL_command("NGL_HKLviewer.normal_clip_plane.clipwidth = %f" % self.clipwidthval) def onHKLdistChanged(self, val): self.hkldistval = val self.NGL_HKL_command("NGL_HKLviewer.normal_clip_plane.hkldist = %f" % self.hkldistval) def onHvecChanged(self, val): self.hvecval = val self.NGL_HKL_command("NGL_HKLviewer.normal_clip_plane.h = %f" % self.hvecval) def onKvecChanged(self, val): self.kvecval = val self.NGL_HKL_command("NGL_HKLviewer.normal_clip_plane.k = %f" % self.kvecval) def onLvecChanged(self, val): self.lvecval = val self.NGL_HKL_command("NGL_HKLviewer.normal_clip_plane.l = %f" % self.lvecval) def onFixedorient(self): self.NGL_HKL_command('NGL_HKLviewer.viewer.NGL.fixorientation = %s' \ %str(self.fixedorientcheckbox.isChecked())) def onMillerComboSelchange(self, i): self.NGL_HKL_command("NGL_HKLviewer.scene_id = %d" % i) #self.MillerComboBox.setCurrentIndex(i) if self.MillerComboBox.currentText(): self.functionTabWidget.setEnabled(True) self.expandAnomalouscheckbox.setEnabled(True) # don' allow anomalous expansion for data that's already anomalous for arrayinfo in self.array_infotpls: isanomalous = arrayinfo[-1] label = arrayinfo[0] if isanomalous and label == self.MillerComboBox.currentText( )[:len(label)]: self.expandAnomalouscheckbox.setDisabled(True) else: self.functionTabWidget.setDisabled(True) self.SpaceGroupComboBox.clear() self.SpaceGroupComboBox.addItems(self.spacegroups) # need to supply issymunique flag in infotuple #if self.hklscenes_arrays[ i ][6] == 0: # self.mergecheckbox.setEnabled(True) #else: # self.mergecheckbox.setEnabled(False) def createFileInfoBox(self): self.FileInfoBox = QGroupBox("Reflection File Information") layout = QGridLayout() layout.addWidget(self.openFileNameButton, 0, 0, 1, 2) if self.devmode: layout.addWidget(self.debugbutton, 0, 2, 1, 1) layout.addWidget(self.HKLnameedit, 1, 0, 1, 3) layout.addWidget(self.millertable, 2, 0, 1, 3) layout.addWidget(self.textInfo, 3, 0, 1, 3) #layout.setColumnStretch(1, 2) self.FileInfoBox.setLayout(layout) def createRadiiScaleGroupBox(self): self.RadiiScaleGroupBox = QGroupBox("Radii Size of HKL Spheres") self.ManualPowerScalecheckbox = QCheckBox() self.ManualPowerScalecheckbox.setText( "Manual Power Scaling of Sphere Radii") self.ManualPowerScalecheckbox.clicked.connect(self.onManualPowerScale) self.power_scale_spinBox = QDoubleSpinBox(self.RadiiScaleGroupBox) self.nth_power_scale = 0.5 self.power_scale_spinBox.setValue(self.nth_power_scale) self.power_scale_spinBox.setDecimals(2) self.power_scale_spinBox.setSingleStep(0.05) self.power_scale_spinBox.setRange(0.0, 1.0) self.power_scale_spinBox.valueChanged.connect(self.onPowerScaleChanged) self.power_scale_spinBox.setEnabled(False) self.powerscaleLabel = QLabel() self.powerscaleLabel.setText("Power scale Factor") self.radii_scale_spinBox = QDoubleSpinBox(self.RadiiScaleGroupBox) self.radii_scale = 1.0 self.radii_scale_spinBox.setValue(self.radii_scale) self.radii_scale_spinBox.setDecimals(1) self.radii_scale_spinBox.setSingleStep(0.1) self.radii_scale_spinBox.setRange(0.2, 2.0) self.radii_scale_spinBox.valueChanged.connect(self.onRadiiScaleChanged) self.radiiscaleLabel = QLabel() self.radiiscaleLabel.setText("Linear Scale Factor") layout = QGridLayout() layout.addWidget(self.ManualPowerScalecheckbox, 1, 0, 1, 2) layout.addWidget(self.powerscaleLabel, 2, 0, 1, 2) layout.addWidget(self.power_scale_spinBox, 2, 1, 1, 2) layout.addWidget(self.radiiscaleLabel, 3, 0, 1, 2) layout.addWidget(self.radii_scale_spinBox, 3, 1, 1, 2) layout.setColumnStretch(0, 1) layout.setColumnStretch(1, 0) self.RadiiScaleGroupBox.setLayout(layout) def createBinsBox(self): self.binstable = QTableWidget(0, 4) self.binstable_isready = False labels = [ "no. of HKLs", "lower bin value", "upper bin value", "opacity" ] self.binstable.setHorizontalHeaderLabels(labels) self.binstable.horizontalHeader().setDefaultAlignment(Qt.AlignLeft) self.bindata_labeltxt = QLabel() self.bindata_labeltxt.setText("Data binned:") self.Nbins_spinBox = QSpinBox() self.Nbins_spinBox.setSingleStep(1) self.Nbins_spinBox.setRange(1, 40) self.Nbins_spinBox.valueChanged.connect(self.onNbinsChanged) self.Nbins_labeltxt = QLabel() self.Nbins_labeltxt.setText("Number of bins:") self.OpaqueAllCheckbox = QCheckBox() #self.OpaqueAllCheckbox.setTristate() self.OpaqueAllCheckbox.setText("Show all data in bins") self.OpaqueAllCheckbox.clicked.connect(self.onOpaqueAll) self.binstable.itemChanged.connect(self.onBinsTableItemChanged) self.binstable.itemSelectionChanged.connect( self.onBinsTableItemSelectionChanged) self.BinDataComboBox = QComboBox() self.BinDataComboBox.activated.connect(self.onBindataComboSelchange) self.BinsGroupBox = QGroupBox("Bins") layout = QGridLayout() layout.addWidget(self.bindata_labeltxt, 0, 0) layout.addWidget(self.BinDataComboBox, 0, 1) layout.addWidget(self.Nbins_labeltxt, 0, 2) layout.addWidget(self.Nbins_spinBox, 0, 3) layout.addWidget(self.OpaqueAllCheckbox, 1, 2) layout.addWidget(self.binstable, 2, 0, 1, 4) layout.setColumnStretch(0, 0) layout.setColumnStretch(1, 2) layout.setColumnStretch(3, 1) self.BinsGroupBox.setLayout(layout) def DebugInteractively(self): import code, traceback code.interact(local=locals(), banner="".join(traceback.format_stack(limit=10))) def CreateFunctionTabs(self): self.functionTabWidget = QTabWidget() tab1 = QWidget() layout1 = QGridLayout() layout1.addWidget(self.ExpansionBox, 0, 0) layout1.setRowStretch(0, 0) tab1.setLayout(layout1) tab2 = QWidget() layout2 = QGridLayout() self.fixedorientcheckbox = QCheckBox(self.sliceTabWidget) self.fixedorientcheckbox.setText( "Fix orientation but allow zoom and translation") self.fixedorientcheckbox.clicked.connect(self.onFixedorient) layout2.addWidget(self.fixedorientcheckbox, 0, 0) layout2.addWidget(self.sliceTabWidget, 1, 0) tab2.setLayout(layout2) tab3 = QWidget() layout3 = QGridLayout() layout3.addWidget(self.RadiiScaleGroupBox, 0, 0) tab3.setLayout(layout3) tab4 = QWidget() layout4 = QGridLayout() layout4.addWidget(self.BinsGroupBox, 0, 0) tab4.setLayout(layout4) self.functionTabWidget.addTab(tab1, "Expand") self.functionTabWidget.addTab(tab2, "Slice") self.functionTabWidget.addTab(tab3, "Size") self.functionTabWidget.addTab(tab4, "Bins") self.functionTabWidget.setDisabled(True) def SpacegroupSelchange(self, i): self.NGL_HKL_command("NGL_HKLviewer.spacegroup_choice = %d" % i) def find_free_port(self): import socket s = socket.socket() s.bind(('', 0)) # Bind to a free port provided by the host. port = s.getsockname()[1] s.close() return port def LaunchCCTBXPython(self): self.sockport = self.find_free_port() self.zmq_context = zmq.Context() self.socket = self.zmq_context.socket(zmq.PAIR) self.socket.bind("tcp://127.0.0.1:%s" % self.sockport) try: msg = self.socket.recv( flags=zmq.NOBLOCK) #To empty the socket from previous messages except Exception as e: pass cmdargs = 'cctbx.python.bat -i -c "from crys3d.hklview import cmdlineframes;' \ + ' myHKLview = cmdlineframes.HKLViewFrame(useGuiSocket=%s, high_quality=True,' %self.sockport \ + ' jscriptfname = \'%s\', ' %self.jscriptfname \ + ' verbose=%s, UseOSBrowser= %s )"\n' %(self.verbose, str(self.UseOSbrowser)) self.cctbxproc = subprocess.Popen(cmdargs, shell=True, stdin=subprocess.PIPE, stdout=sys.stdout, stderr=sys.stderr) #time.sleep(1) def NGL_HKL_command(self, cmdstr): #print("sending:\n" + cmdstr) self.socket.send(bytes(cmdstr, "utf-8"))
def __init__(self, game): """ La fenêtre principale est initialisée avec l'organisation suivante : +--------------------------------------------------------------------------+ | self.menu = self.menuBar() | | | +--------------------------------------------------------------------------+ | toolbar = QToolBar() (déplacement/sélection des robots, | | boutons annuler, indice et solution) | +------------------------layout0 = QHBoxLayout()---------------------------+ | layout2 = QHBoxLayout() + moves_label | | l + | | | a grid_choice | nb_robots_choice | (affichage des | +-y--------------------+----------------------+ L | | o | a mouvements effectués) | | u | y | | t +--o-------------------------+ | = label = QLabel() | u | | Q | t tip_label | | V contient la grille de jeu | 3 | | B | (Affichage de l'indice| | o | = | | x | si demandé) | | L | Q | | a +--V+------------------------+ | y | B solution_label | | o | o | | u | x (Affichage de la | | t | | | | solution si demandée) | +---------------------------------------------+----------------------------+ """ super().__init__() self.game = game self.initial_game_state = self.game.get_state() self.number_moves = 0 self.setWindowTitle("Robot Ricochet") self.resize(self.DIMENSION + 150, self.DIMENSION + 100) # label contient la grille de jeu self.label = QLabel() canvas = QPixmap(self.DIMENSION, self.DIMENSION) canvas.fill(Qt.white) self.label.setPixmap(canvas) # layout0 contient, à gauche, les barres d'outils et la grille, # et à droite, la liste des états et l'indice affiché par le solveur layout0 = QHBoxLayout() layout0.setContentsMargins(0, 0, 0, 0) layout0.setSpacing(0) layout = QVBoxLayout() layout.setContentsMargins(0, 0, 0, 0) layout.setSpacing(0) layout2 = QHBoxLayout() # Choix de la grille self.choice_of_grid_menu() # choix du nombre de robots self.nb_robots_choice_menu() # CheckBox placement aléatoire widget3 = QCheckBox("Placement aléatoire des robots et de l'objectif") widget3.setCheckState(Qt.Checked) widget3.stateChanged.connect(self.placer_aleatoirement) # layout2 contient les 3 widgets horizontaux de choix de grille, robots et aléa layout2.addWidget(self.grid_choice) layout2.addWidget(self.nb_robots_choice) #layout2.addWidget(widget3) layout2.setContentsMargins(0, 0, 0, 0) layout2.setSpacing(0) widget2 = QWidget() widget2.setLayout(layout2) layout.addWidget(widget2) layout.addWidget(self.label) # liste des mouvement effectués, indice et solution: layout3 = QVBoxLayout() layout3.setContentsMargins(0, 0, 0, 0) layout3.setSpacing(0) self.moves_label = QLabel() self.print_moves_list() self.tip_label = QLabel() self.solution_label = QLabel() layout3.addWidget(self.moves_label) layout3.addWidget(self.tip_label) layout3.addWidget(self.solution_label) layout0.addLayout(layout) layout0.addLayout(layout3) widget = QWidget() widget.setLayout(layout0) self.setCentralWidget(widget) # Menu self.menu = self.menuBar() self.file_menu = self.menu.addMenu("File") self.help_menu = self.menu.addMenu("Aide et instructions") # A faire self.size_fenetre = self.geometry() # Play QAction play_action = QAction("Réinitialiser !", self) play_action.triggered.connect(self.replay) self.file_menu.addAction(play_action) # Open_grid QAction open_grid_action = QAction("Ouvrir une grille", self) open_grid_action.setShortcut('Ctrl+O') open_grid_action.triggered.connect(self.open_grid) self.file_menu.addAction(open_grid_action) # Open_game QAction open_game_action = QAction("Ouvrir un jeu", self) open_game_action.triggered.connect(self.open_game) self.file_menu.addAction(open_game_action) # Save_grid QAction save_grid_action = QAction("Enregistrer cette grille", self) save_grid_action.triggered.connect(self.save_grid) self.file_menu.addAction(save_grid_action) # Save_game QAction save_game_action = QAction("Enregistrer ce jeu", self) save_game_action.triggered.connect(self.save_game) self.file_menu.addAction(save_game_action) # Exit QAction exit_action = QAction("Quitter", self) exit_action.setShortcut(QKeySequence.Quit) exit_action.triggered.connect(self.close) self.file_menu.addAction(exit_action) # Help QAction help_action = QAction("Aide", self) help_action.triggered.connect(self.help) self.help_menu.addAction(help_action) self.toolbar_menus() #Le robot rouge est sélectionné par défaut self.selected_robot = 'R' self.draw_robots_and_goal()
class MyGui(QWidget, GitCmd): def __init__(self, title="Create By ZZZ", path=DEFAULT_GIT_REPO): super(MyGui, self).__init__() GitCmd.__init__(self, path) # 初始化命令 self.show_info = None self.cmd_history = None self.cmd_history_cmd_list = list() # 复选框 self.check_box_select_all = None self.check_box = list() self.check_box_button = None # 默认值 self.show_log_num = DEFAULT_GIT_LOG_NUM self.file_list = DEFAULT_GIT_ADD_LIST self.gridLayout = QGridLayout(self) self.setGeometry(100, 100, 800, 700) self.setWindowTitle(title) # 记录当前widget最大行号 self.max_line_no = 0 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # 显示信息相关 def add_info_text(self): # 添加消息显示框,我们使用列表方式显示 self.show_info = QListWidget() self.show_info.setFixedSize(800, 600) self.gridLayout.addWidget(self.show_info, 0, 0, 1, 4) # 单击触发绑定的槽函数 self.show_info.itemClicked.connect(self.text_block_clicked) # 命令行显示,我们使用下拉框 self.cmd_history = QComboBox() self.gridLayout.addWidget(self.cmd_history, 1, 0, 1, 4) # 设置行号 self.max_line_no = 2 def add_cmd(self, cmd): if len(self.cmd_history_cmd_list) < 10: self.cmd_history_cmd_list.append(cmd) else: self.cmd_history_cmd_list = self.cmd_history_cmd_list[1:].append(cmd) self.cmd_history.clear() self.cmd_history.addItems(reversed(self.cmd_history_cmd_list)) def update_cmd(self, extra: str): cur_cmd = self.cmd_history.currentText().split(" ") new_cmd = cur_cmd[:2] + [extra] # 拆分出来git和后面的命令,拼接参数 if cur_cmd: self.cmd_history.setItemText(0, " ".join(new_cmd)) # 对每一行都进行上色 def my_print(self, text_list: list, background: list): # self.show_info.clear() 这个可以清空显示 self.show_info.addItems([". . . . . . . . . . . . . . . . . . . . . . . . . " ". . . . . . . . . . . . . . . . . . . . . . . . . "]) for ind in range(len(text_list)): item = QListWidgetItem('%s' % text_list[ind]) item.setBackground(QColor(background[ind])) # 上色 self.show_info.addItem(item) self.show_info.scrollToBottom() # 自动到最后行 @staticmethod def text_block_clicked(item): # 这里没有什么要做的 # QMessageBox.information(self, "命令历史", "你选择了: " + item.text()) pass # . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # 添加按钮 def add_git_button(self): cmd_add = QPushButton('Git Add') cmd_reset = QPushButton('Git Reset') cmd_status = QPushButton('Git Status') cmd_log = QPushButton('Git Log') cmd_run = QPushButton('Run Cmd') line_no = self.max_line_no self.gridLayout.addWidget(cmd_add, line_no, 0) self.gridLayout.addWidget(cmd_reset, line_no, 1) self.gridLayout.addWidget(cmd_status, line_no, 2) self.gridLayout.addWidget(cmd_log, line_no, 3) self.gridLayout.addWidget(cmd_run, line_no + 1, 0) self.max_line_no = self.max_line_no + 2 cmd_log.clicked.connect(self.git_log) cmd_add.clicked.connect(self.git_add) cmd_reset.clicked.connect(self.git_reset) cmd_status.clicked.connect(self.git_status) cmd_run.clicked.connect(self.run_git) def run_git(self): cur_cmd = self.cmd_history.currentText() # 执行代码 if cur_cmd.startswith("git add"): result, background = self.cmd_git_add(self.file_list) self.my_print(result, background) elif cur_cmd.startswith("git status"): result, background = self.cmd_git_status() self.my_print(result, background) elif cur_cmd.startswith("git log"): result, background = self.cmd_git_log(self.show_log_num) self.my_print(result, background) elif cur_cmd.startswith("git reset"): result, background = self.cmd_git_reset(self.file_list) self.my_print(result, background) def git_log(self): # 日常清理 self.cleanup() # 记录命令 self.add_cmd("git log -" + self.show_log_num) # 可以直接运行 self.run_git() def git_add(self): # 日常清理 self.cleanup() # 文件选择 files = self.get_file_list_by_status() self.create_check_box(files) # 记录命令 self.add_cmd("git add .") def git_status(self): # 日常清理 self.cleanup() # 记录命令 self.add_cmd("git status") # 可以直接运行 self.run_git() def git_reset(self): # 日常清理 self.cleanup() # 文件选择 files = self.get_file_list_by_status() self.create_check_box(files) # 记录命令 self.add_cmd("git reset .") # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # 创建复选框 def create_check_box(self, opt_list: list): # 创建 self.check_box_select_all = QCheckBox('全选') # lambda可以传参:lambda: self.check_box_changes_all(<参数>) self.check_box_select_all.stateChanged.connect(lambda: self.check_box_changes_all()) for ind in range(len(opt_list)): self.check_box.append(QCheckBox(opt_list[ind])) self.check_box[ind].stateChanged.connect(lambda: self.check_box_changes()) # self.check_box_button = QPushButton('提交') # 布局 ind = self.max_line_no self.gridLayout.addWidget(self.check_box_select_all, ind, 0) ind = ind + 1 for check_box in self.check_box: self.gridLayout.addWidget(check_box, ind, 0) ind = ind + 1 # self.gridLayout.addWidget(self.check_box_button, ind, 0) # 添加按钮回调 # self.check_box_button.clicked.connect(self.check_box_ok) # 更新行号 # self.max_line_no = ind + 1 self.max_line_no = ind def check_box_ok(self): # 清除小部件 if self.check_box: self.file_list.clear() for check_box in self.check_box: # 更新列表 # if check_box.checkState() == Qt.Checked: # self.file_list.append(check_box.text()) # 清除 check_box.deleteLater() self.check_box.clear() if self.check_box_select_all: self.check_box_select_all.deleteLater() self.check_box_select_all = None if self.check_box_button: self.check_box_button.deleteLater() self.check_box_button = None def check_box_changes_all(self): if self.check_box_select_all.checkState() == Qt.Checked: for check_box in self.check_box: check_box.setChecked(True) elif self.check_box_select_all.checkState() == Qt.Unchecked: for check_box in self.check_box: check_box.setChecked(False) def check_box_changes(self): all_checked = True # one_checked = False self.file_list.clear() for check_box in self.check_box: if not check_box.isChecked(): all_checked = False # 只要有一个没勾选 else: self.file_list.append(check_box.text()) # 更新列表 # else: # one_checked = True # 只要有一个勾选 if all_checked: self.check_box_select_all.setCheckState(Qt.Checked) # elif one_checked: # self.check_box_select_all.setTristate() # 设置为3态选择框 # self.check_box_select_all.setCheckState(Qt.PartiallyChecked) # else: # self.check_box_select_all.setTristate() # 设置为3态选择框 # self.check_box_select_all.setCheckState(Qt.Unchecked) # 更新命令 files = " ".join(self.file_list) self.update_cmd(files) # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # 清理临时的小部件 def cleanup(self): self.check_box_ok() # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # 例子 def addButtonExample(self): # 创建一些小部件放在顶级窗口中 btn = QPushButton('press me') text = QLineEdit('enter text') listw = QListWidget() listw.addItems(["aa", "bb", "cc"]) # self.gridLayout = QGridLayout(self) # 将部件添加到布局中的适当位置, # addWidget参数:Widget实例, 起始row, 起始column, 占多少行(高度),占多少列(宽度) self.gridLayout.addWidget(btn, 0, 0) self.gridLayout.addWidget(text, 1, 0) self.gridLayout.addWidget(listw, 2, 0) # self.setLayout(self.gridLayout) # 画图1 def linePlot(self): plt1 = pg.PlotWidget() plt1.plot([i for i in range(10)], [i * i for i in range(10)]) self.gridLayout.addWidget(plt1, 0, 1, 1, 1) # 画图2 def scatterPlot(self): plt2 = pg.PlotWidget() x = np.random.normal(size=1000) y = np.random.normal(size=1000) plt2.plot(x, y, pen=None, symbol="o") self.gridLayout.addWidget(plt2, 1, 1, 1, 1) # 画图3 def three_curves(self): plt3 = pg.PlotWidget(title="Three plot curves") x = np.arange(1000) y = np.random.normal(size=(3, 1000)) for i in range(3): plt3.plot(x, y[i], pen=(i, 3)) # setting pen=(i,3) 自动创建3个不同颜色的笔 self.gridLayout.addWidget(plt3, 2, 1, 1, 1)
def funcListPeople(self): if self.allPeopleRadioBtn.isChecked(): self.funcDisplayPeople() elif self.employeesPeopleRadioBtn.isChecked(): try: query = "SELECT * FROM people WHERE person_empl_type = 'Employee'" people = db.cur.execute(query).fetchall() for i in reversed(range(self.peopleTable.rowCount())): self.peopleTable.removeRow(i) for row_data in people: row_number = self.peopleTable.rowCount() self.peopleTable.insertRow(row_number) # Add checkboxes to the table widget = QWidget() checkBox = QCheckBox() checkBox.setCheckState(Qt.Unchecked) hBoxLayout = QHBoxLayout(widget) hBoxLayout.addWidget(checkBox) hBoxLayout.setAlignment(Qt.AlignCenter) self.peopleTable.setCellWidget(row_number, 0, widget) self.peopleTable.setItem(row_number, 0, QTableWidgetItem(row_number)) # Add photo photos_thumbnails to the table thumbWidget = QWidget() pic = QPixmap( "assets/media/people-media/photos_thumbnails/01Aug2020_18h01mtrtgzteuzuspxrp_thumbnail.png" ) thumbLabel = QLabel() thumbLabel.setPixmap(pic) thumbLayout = QHBoxLayout(thumbWidget) thumbLayout.addWidget(thumbLabel) self.peopleTable.setCellWidget(row_number, 1, thumbWidget) self.peopleTable.setItem(row_number, 0, QTableWidgetItem(row_number)) # Fill the rest of the data for column_number, data in enumerate(row_data, start=2): if column_number == 2: self.peopleTable.setItem( row_number, column_number, QTableWidgetItem("PRN#" + str(data))) else: self.peopleTable.setItem( row_number, column_number, QTableWidgetItem(str(data))) except: QMessageBox.information(self, "Info", "Cannot access database") elif self.contractorsPeopleRadioBtn.isChecked(): try: query = "SELECT * FROM people WHERE person_empl_type = 'Contractor'" people = db.cur.execute(query).fetchall() for i in reversed(range(self.peopleTable.rowCount())): self.peopleTable.removeRow(i) for row_data in people: row_number = self.peopleTable.rowCount() self.peopleTable.insertRow(row_number) # Add checkboxes to the table widget = QWidget() checkBox = QCheckBox() checkBox.setCheckState(Qt.Unchecked) hBoxLayout = QHBoxLayout(widget) hBoxLayout.addWidget(checkBox) hBoxLayout.setAlignment(Qt.AlignCenter) self.peopleTable.setCellWidget(row_number, 0, widget) self.peopleTable.setItem(row_number, 0, QTableWidgetItem(row_number)) # Add photo photos_thumbnails to the table thumbWidget = QWidget() pic = QPixmap( "assets/media/people-media/photos_thumbnails/01Aug2020_18h01mtrtgzteuzuspxrp_thumbnail.png" ) thumbLabel = QLabel() thumbLabel.setPixmap(pic) thumbLayout = QHBoxLayout(thumbWidget) thumbLayout.addWidget(thumbLabel) self.peopleTable.setCellWidget(row_number, 1, thumbWidget) self.peopleTable.setItem(row_number, 0, QTableWidgetItem(row_number)) # Fill the rest of the data for column_number, data in enumerate(row_data, start=2): if column_number == 2: self.peopleTable.setItem( row_number, column_number, QTableWidgetItem("PRN#" + str(data))) else: self.peopleTable.setItem( row_number, column_number, QTableWidgetItem(str(data))) except: QMessageBox.information(self, "Info", "Cannot access database") elif self.subcontractorsPeopleRadioBtn.isChecked(): try: query = "SELECT * FROM people WHERE person_empl_type = 'Subcontractor'" people = db.cur.execute(query).fetchall() for i in reversed(range(self.peopleTable.rowCount())): self.peopleTable.removeRow(i) for row_data in people: row_number = self.peopleTable.rowCount() self.peopleTable.insertRow(row_number) # Add checkboxes to the table widget = QWidget() checkBox = QCheckBox() checkBox.setCheckState(Qt.Unchecked) hBoxLayout = QHBoxLayout(widget) hBoxLayout.addWidget(checkBox) hBoxLayout.setAlignment(Qt.AlignCenter) self.peopleTable.setCellWidget(row_number, 0, widget) self.peopleTable.setItem(row_number, 0, QTableWidgetItem(row_number)) # Add photo photos_thumbnails to the table thumbWidget = QWidget() pic = QPixmap( "assets/media/people-media/photos_thumbnails/01Aug2020_18h01mtrtgzteuzuspxrp_thumbnail.png" ) thumbLabel = QLabel() thumbLabel.setPixmap(pic) thumbLayout = QHBoxLayout(thumbWidget) thumbLayout.addWidget(thumbLabel) self.peopleTable.setCellWidget(row_number, 1, thumbWidget) self.peopleTable.setItem(row_number, 0, QTableWidgetItem(row_number)) # Fill the rest of the data for column_number, data in enumerate(row_data, start=2): if column_number == 2: self.peopleTable.setItem( row_number, column_number, QTableWidgetItem("PRN#" + str(data))) else: self.peopleTable.setItem( row_number, column_number, QTableWidgetItem(str(data))) except: QMessageBox.information(self, "Info", "Cannot access database")
class StatsManager: GROUP_BY = ['filename', 'lineno', 'traceback'] # index in the combo box GROUP_BY_FILENAME = 0 GROUP_BY_LINENO = 1 GROUP_BY_TRACEBACK = 2 def __init__(self, window, app): self.app = app self.window = window self.snapshots = window.snapshots self.source = window.source self.filename_parts = 3 self._auto_refresh = False self.filters = [] self.history = History(self) self.model = StatsModel(self) self.view = QTableView(window) self.view.setModel(self.model) self.cumulative_checkbox = QCheckBox(window.tr("Cumulative sizes"), window) self.group_by = QtGui.QComboBox(window) self.group_by.addItems([ window.tr("Filename"), window.tr("Line number"), window.tr("Traceback"), ]) self.filters_label = QLabel(window) self.summary = QLabel(window) self.view.verticalHeader().hide() self.view.resizeColumnsToContents() self.view.setSortingEnabled(True) window.connect(self.group_by, QtCore.SIGNAL("currentIndexChanged(int)"), self.group_by_changed) window.connect(self.view, QtCore.SIGNAL("doubleClicked(const QModelIndex&)"), self.double_clicked) window.connect(self.cumulative_checkbox, QtCore.SIGNAL("stateChanged(int)"), self.change_cumulative) window.connect(self.snapshots.load_button, QtCore.SIGNAL("clicked(bool)"), self.load_snapshots) window.connect( self.view.selectionModel(), QtCore.SIGNAL( "selectionChanged(const QItemSelection&, const QItemSelection&)" ), self.selection_changed) self.clear() self._auto_refresh = True def clear(self): del self.filters[:] self.cumulative_checkbox.setCheckState(Qt.Unchecked) self.group_by.setCurrentIndex(self.GROUP_BY_FILENAME) self.history.clear() self.append_history() self.refresh() def load_snapshots(self, checked): self.source.clear() self.clear() def append_history(self): group_by = self.group_by.currentIndex() filters = self.filters[:] cumulative = self.cumulative_checkbox.checkState() state = HistoryState(group_by, filters, cumulative) self.history.append(state) def restore_state(self, state): self.filters = state.filters[:] self._auto_refresh = False self.cumulative_checkbox.setCheckState(state.cumulative) self.group_by.setCurrentIndex(state.group_by) self._auto_refresh = True self.refresh() def format_filename(self, filename): parts = filename.split(os.path.sep) if len(parts) > self.filename_parts: parts = [MORE_TEXT] + parts[-self.filename_parts:] return os.path.join(*parts) def get_group_by(self): index = self.group_by.currentIndex() return self.GROUP_BY[index] def get_cumulative(self): return (self.cumulative_checkbox.checkState() == Qt.Checked) def refresh(self): group_by = self.get_group_by() if group_by != 'traceback': cumulative = self.get_cumulative() else: # FIXME: add visual feedback cumulative = False snapshot1, snapshot2 = self.snapshots.load_snapshots(self.filters) self.view.clearSelection() group_by = self.get_group_by() self.model.set_stats(snapshot1, snapshot2, group_by, cumulative) self.view.resizeColumnsToContents() self.view.sortByColumn(self.model.get_default_sort_column(), Qt.DescendingOrder) if self.filters: filters = [] for filter in self.filters: text = self.format_filename(filter.filename_pattern) if filter.lineno: text = "%s:%s" % (text, filter.lineno) if filter.all_frames: text += self.window.tr(" (any frame)") if filter.inclusive: text = fmt(self.window.tr("include %s"), text) else: text = fmt(self.window.tr("exclude %s"), text) filters.append(text) filters_text = ", ".join(filters) else: filters_text = self.window.tr("(none)") filters_text = fmt(self.window.tr("Filters: %s"), filters_text) self.filters_label.setText(filters_text) total = self.model.total_text lines = len(self.model.stats) if group_by == 'filename': lines = fmt(self.window.tr("Files: %s"), lines) elif group_by == 'lineno': lines = fmt(self.window.tr("Lines: %s"), lines) else: lines = fmt(self.window.tr("Tracebacks: %s"), lines) total = fmt(self.window.tr("%s - Total: %s"), lines, total) self.summary.setText(total) def selection_changed(self, selected, unselected): indexes = selected.indexes() if not indexes: return stat = self.model.get_stat(indexes[0]) if stat is None: return self.source.set_traceback(stat.traceback, self.get_group_by() != 'filename') self.source.show_frame(stat.traceback[0]) def double_clicked(self, index): stat = self.model.get_stat(index) if stat is None: return group_by = self.get_group_by() if group_by == 'filename': all_frames = self.get_cumulative() self.filters.append( tracemalloc.Filter(True, stat.traceback[0].filename, all_frames=all_frames)) self._auto_refresh = False self.group_by.setCurrentIndex(self.GROUP_BY_LINENO) self.append_history() self._auto_refresh = True self.refresh() elif group_by == 'lineno': # Replace filter by filename with filter by line new_filter = tracemalloc.Filter(True, stat.traceback[0].filename, stat.traceback[0].lineno, all_frames=False) if self.filters: old_filter = self.filters[-1] replace = (old_filter.inclusive == new_filter.inclusive and old_filter.filename_pattern == new_filter.filename_pattern and old_filter.lineno == None) else: replace = False if replace: self.filters[-1] = new_filter else: self.filters.append(new_filter) self._auto_refresh = False self.group_by.setCurrentIndex(self.GROUP_BY_TRACEBACK) self.append_history() self._auto_refresh = True self.refresh() def group_by_changed(self, index): if not self._auto_refresh: return self.append_history() self.refresh() def change_cumulative(self, state): if not self._auto_refresh: return self.append_history() self.refresh()
class ExportFileDialog(QFileDialog): """ Create a custom Export-File Dialog with options like BOM etc. """ def __init__(self,*args,**kwargs): super(ExportFileDialog,self).__init__(*args,**kwargs) self.mainWindow = self.parent() self.setWindowTitle("Export nodes to CSV") self.setAcceptMode(QFileDialog.AcceptSave) self.setOption(QFileDialog.DontUseNativeDialog) #self.setFilter("CSV Files (*.csv)") self.setDefaultSuffix("csv") self.optionBOM = QCheckBox("Use a BOM",self) self.optionBOM.setCheckState(Qt.CheckState.Checked) self.optionLinebreaks = QCheckBox("Remove line breaks",self) self.optionLinebreaks.setCheckState(Qt.CheckState.Checked) self.optionSeparator = QComboBox(self) self.optionSeparator.insertItems(0, [";","\\t",","]) self.optionSeparator.setEditable(True) #self.optionLinebreaks.setCheckState(Qt.CheckState.Checked) self.optionWide = QCheckBox("Convert to wide format (experimental feature)",self) self.optionWide.setCheckState(Qt.CheckState.Unchecked) # if none or all are selected, export all # if one or more are selected, export selective self.optionAll = QComboBox(self) self.optionAll.insertItems(0, ['All nodes (faster for large datasets, ordered by internal ID)','Selected nodes (ordered like shown in nodes view)']) if self.mainWindow.tree.noneOrAllSelected(): self.optionAll.setCurrentIndex(0) else: self.optionAll.setCurrentIndex(1) layout = self.layout() row = layout.rowCount() layout.addWidget(QLabel('Options'),row,0) options = QHBoxLayout() options.addWidget(self.optionBOM) options.addWidget(self.optionLinebreaks) options.addWidget(QLabel('Separator')) options.addWidget(self.optionSeparator) options.addStretch(1) layout.addLayout(options,row,1,1,2) layout.addWidget(QLabel('Post processing'),row+1,0) layout.addWidget(self.optionWide,row+1,1,1,2) layout.addWidget(QLabel('Export mode'),row+2,0) layout.addWidget(self.optionAll,row+2,1,1,2) self.setLayout(layout) if self.exec_(): if os.path.isfile(self.selectedFiles()[0]): os.remove(self.selectedFiles()[0]) output = open(self.selectedFiles()[0], 'w', newline='', encoding='utf8') if self.optionBOM.isChecked() and not self.optionWide.isChecked(): output.write('\ufeff') try: if self.optionAll.currentIndex() == 0: self.exportAllNodes(output) else: self.exportSelectedNodes(output) finally: output.close() if self.optionWide.isChecked(): self.convertToWideFormat(self.selectedFiles()[0]) def exportSelectedNodes(self,output): progress = ProgressBar("Exporting data...", self.mainWindow) #indexes = self.mainWindow.tree.selectionModel().selectedRows() #if child nodes should be exported as well, uncomment this line an comment the previous one indexes = self.mainWindow.tree.selectedIndexesAndChildren() progress.setMaximum(len(indexes)) try: delimiter = self.optionSeparator.currentText() delimiter = delimiter.encode('utf-8').decode('unicode_escape') writer = csv.writer(output, delimiter=delimiter, quotechar='"', quoting=csv.QUOTE_ALL, doublequote=True, lineterminator='\r\n') #headers row = [str(val) for val in self.mainWindow.tree.treemodel.getRowHeader()] if self.optionLinebreaks.isChecked(): row = [val.replace('\n', ' ').replace('\r',' ') for val in row] writer.writerow(row) #rows for no in range(len(indexes)): if progress.wasCanceled: break row = [str(val) for val in self.mainWindow.tree.treemodel.getRowData(indexes[no])] if self.optionLinebreaks.isChecked(): row = [val.replace('\n', ' ').replace('\r',' ') for val in row] writer.writerow(row) progress.step() finally: progress.close() def exportAllNodes(self,output): progress = ProgressBar("Exporting data...", self.mainWindow) progress.setMaximum(Node.query.count()) try: delimiter = self.optionSeparator.currentText() delimiter = delimiter.encode('utf-8').decode('unicode_escape') writer = csv.writer(output, delimiter=delimiter, quotechar='"', quoting=csv.QUOTE_ALL, doublequote=True, lineterminator='\r\n') #headers row = ["level", "id", "parent_id", "object_id", "object_type", "query_status", "query_time", "query_type"] for key in self.mainWindow.tree.treemodel.customcolumns: row.append(key) if self.optionLinebreaks.isChecked(): row = [val.replace('\n', ' ').replace('\r',' ') for val in row] writer.writerow(row) #rows page = 0 while True: allnodes = Node.query.offset(page * 5000).limit(5000) if allnodes.count() == 0: break for node in allnodes: if progress.wasCanceled: break row = [node.level, node.id, node.parent_id, node.objectid, node.objecttype, node.querystatus, node.querytime, node.querytype] for key in self.mainWindow.tree.treemodel.customcolumns: row.append(node.getResponseValue(key)) if self.optionLinebreaks.isChecked(): row = [str(val).replace('\n', ' ').replace('\r',' ') for val in row] writer.writerow(row) # step the Bar progress.step() if progress.wasCanceled: break else: page += 1 finally: progress.close() def convertToWideFormat(self,filename): progress = ProgressBar("Converting data...", self.mainWindow) try: #Separate levels def flattenTable(fulltable,levelcol,idcol,parentidcol,countchildren,removeempty): fulltable[[levelcol]] = fulltable[[levelcol]].astype(int) levels = dict(list(fulltable.groupby(levelcol))) minlevel = fulltable.level.min() for level, data in sorted(levels.items()): #First level is the starting point for the following merges if level == minlevel: #data = data[[idcol,'object_id','object_type']] data = data.add_prefix('level_{}-'.format(level)) flattable = data else: #Aggregate object types and join them for col_countchildren in countchildren: children = data[parentidcol].groupby([data[parentidcol],data[col_countchildren]]).count() children = children.unstack(col_countchildren) children['total'] = children.sum(axis=1) children = children.add_prefix('level_{}-children-{}-'.format(level-1,col_countchildren)) leftkey = 'level_{}-id'.format(level-1) flattable = merge(flattable,children,how='left',left_on=leftkey,right_index=True) flattable[children.columns.values.tolist()] = flattable[children.columns.values.tolist()].fillna(0).astype(int) #Join data data['childnumber'] = data.groupby(parentidcol).cumcount() leftkey = 'level_{}-{}'.format(level-1,idcol) rightkey = 'level_{}-{}'.format(level,parentidcol) data = data.drop([levelcol],axis=1) data = data.add_prefix('level_{}-'.format(level)) flattable = merge(flattable,data,how="outer",left_on=leftkey,right_on=rightkey) if removeempty: flattable = flattable.dropna(axis=1,how='all') return flattable try: #delimiter delimiter = self.optionSeparator.currentText() delimiter = delimiter.encode('utf-8').decode('unicode_escape') #open data = read_csv(filename, sep=delimiter,encoding='utf-8',dtype=str) #convert newdata = flattenTable(data,'level','id','parent_id',['object_type','query_status','query_type'],False) #save outfile = open(filename, 'w',newline='',encoding='utf8') try: if self.optionBOM.isChecked(): outfile.write('\ufeff') #UTF8 BOM newdata.to_csv(outfile,sep=delimiter,index=False,encoding="utf-8") finally: outfile.close() except Exception as e: self.mainWindow.logmessage(e) finally: progress.close()
class ExportDialog(QWidget): def __init__(self, parent=None): super().__init__(parent) self.model = ExportChangesModel() self.error_dialog = None self.setWindowIcon(QIcon("paragon.ico")) self.setWindowTitle("Export") main_layout = QVBoxLayout(self) self.export_button = QPushButton() self.export_button.setText("Export") self.main_view = QTreeView() self.main_view.setModel(self.model) self.main_view.setHeaderHidden(True) self.main_view.setEditTriggers( QtWidgets.QAbstractItemView.NoEditTriggers) self.remember_selections_checkbox = QCheckBox() self.remember_selections_checkbox.setText("Remember selections.") main_layout.addWidget(self.export_button) main_layout.addWidget(self.main_view) main_layout.addWidget(self.remember_selections_checkbox) self.setLayout(main_layout) self.main_view.expanded.connect(self._on_item_expanded) self.export_button.clicked.connect(self._on_export_triggered) self.remember_selections_checkbox.stateChanged.connect( self._on_remember_selections_state_changed) self._set_remember_checkbox_state_from_settings() def _set_remember_checkbox_state_from_settings(self): settings_service = locator.get_static("SettingsService") if settings_service.get_remember_exports(): self.remember_selections_checkbox.setCheckState(QtCore.Qt.Checked) @staticmethod def _on_remember_selections_state_changed(state: int): should_remember = state == QtCore.Qt.Checked locator.get_static("SettingsService").set_remember_exports( should_remember) def closeEvent(self, event: QtGui.QCloseEvent): self.model.save_selected_items_tree() event.accept() def _on_export_triggered(self): file_name, ok = QFileDialog.getSaveFileName( self, caption="Select Changes File Destination", filter="*.json") if ok: self._try_export_and_write(file_name) def _try_export_and_write(self, file_name): logging.debug("Exporting selected data to %s" % file_name) try: export_data = self.model.export_selected_items() with open(file_name, "w", encoding="utf-8") as f: json.dump(export_data, f, indent=4, ensure_ascii=False) except: logging.exception("An error occurred while exporting data.") self.error_dialog = ErrorDialog( "An error occurred while exporting. See the log for details.") self.error_dialog.show() def _on_item_expanded(self, index: QModelIndex): self.model.update_data_for_index(index)
class ToolBox(QVBoxLayout): sig = QtCore.Signal(object) listThread = None groupBoxThreadInfo = None threadvbox = None mode = None def __init__(self, mode, parentQWidget = None): QVBoxLayout.__init__(self) self.sig.connect(self.addThreadList) self.mode = mode self.sizePolicy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Expanding) self.groupBoxSearch = QGroupBox() self.groupBoxSearch.setStyleSheet("QGroupBox {border: 1px solid gray; border-radius: 4px; };") vboxSearch = QVBoxLayout() self.searchTitle = QLabel("Search Messages") vboxSearch.addWidget(self.searchTitle) self.searchHLayout = QHBoxLayout() self.editTextSearch = QTextEdit('') self.editTextSearch.setFixedSize(200,30) self.buttonSearch = QPushButton('Search') self.buttonSearch.setFixedSize(100,30) self.buttonSearch.clicked.connect(self.searchMsg) vboxSearch.addWidget(self.editTextSearch) self.searchHLayout.addWidget(self.buttonSearch) self.searchCursor = QLabel() self.searchHLayout.addWidget(self.searchCursor) vboxSearch.addLayout(self.searchHLayout) self.browseHLayout = QHBoxLayout() self.buttonLookUp = QPushButton('\u21e7') #Arrow up self.buttonLookUp.setFixedWidth(100) self.buttonLookUp.clicked.connect(self.moveToPrev) self.buttonLookDown = QPushButton('\u21e9') #Arrow down self.buttonLookDown.setFixedWidth(100) self.buttonLookDown.clicked.connect(self.moveToNext) self.browseHLayout.addWidget(self.buttonLookUp) self.browseHLayout.addWidget(self.buttonLookDown) vboxSearch.addLayout(self.browseHLayout) self.groupBoxSearch.setLayout(vboxSearch) self.addWidget(self.groupBoxSearch) self.groupBoxSearch.setSizePolicy(QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)) self.buttonHiddenLifelines = QPushButton('Show hidden life-lines') self.buttonHiddenLifelines.setFixedWidth(200) self.buttonHiddenLifelines.clicked.connect(self.showHiddenLifelines) self.addWidget(self.buttonHiddenLifelines) self.buttonHiddenMessages = QPushButton('Show hidden Messages') self.buttonHiddenMessages.setFixedWidth(200) self.buttonHiddenMessages.clicked.connect(self.showHiddenMessages) self.addWidget(self.buttonHiddenMessages) if const.mode_interactive == mode: self.buttonCapture = QPushButton('Capture') self.buttonCapture.setFixedWidth(200) self.buttonCapture.clicked.connect(self.notifyCapture) self.addWidget(self.buttonCapture) self.msgRcv = [] self.msgInfo = QLabel("Message Info.") self.groupBoxMessageInfo = QGroupBox() self.groupBoxMessageInfo.setStyleSheet("QGroupBox {border: 1px solid gray; border-radius: 9px; margin-top: 0.5em} QGroupBox::title {subcontrol-origin: margin; left: 10px; padding: 0 3px 0 3px;") vbox = QVBoxLayout() vbox.addWidget(self.msgInfo) self.tableTime = QTableWidget(3,2) self.tableTime.setHorizontalHeaderLabels(['-','time']) self.tableTime.setColumnWidth(0,80) self.tableTime.setColumnWidth(1,150) vwidth = self.tableTime.verticalHeader().length() hwidth = self.tableTime.horizontalHeader().height() fwidth = self.tableTime.frameWidth() * 2 self.tableTime.setFixedHeight(vwidth + hwidth + fwidth) self.tableTime.horizontalHeader().setStretchLastSection(True) self.tableTime.setItem(0,0,QTableWidgetItem('begin')) self.tableTime.setItem(0,1,QTableWidgetItem(' - ')) self.tableTime.setItem(1,0,QTableWidgetItem('end')) self.tableTime.setItem(1,1,QTableWidgetItem(' - ')) self.tableTime.setItem(2,0,QTableWidgetItem('duration')) self.tableTime.setItem(2,1,QTableWidgetItem(' - ')) vbox.addWidget(self.tableTime) self.titleArg = QLabel('Argument List') vbox.addWidget(self.titleArg) max_arg_num = 10 self.tableArgs = QTableWidget(max_arg_num,2) self.tableArgs.setHorizontalHeaderLabels(['type','value']) for idx in range(0,max_arg_num): self.tableArgs.setItem(idx,0,QTableWidgetItem()) self.tableArgs.setItem(idx,1,QTableWidgetItem()) self.tableArgs.horizontalHeader().setStretchLastSection(True) vbox.addWidget(self.tableArgs) self.titleArg = QLabel('Return Value List') vbox.addWidget(self.titleArg) max_ret_num = 4 self.tableRet = QTableWidget(max_ret_num,2) self.tableRet.setHorizontalHeaderLabels(['type','value']) for idx in range(0,max_ret_num): self.tableRet.setItem(idx,0,QTableWidgetItem()) self.tableRet.setItem(idx,1,QTableWidgetItem()) self.tableRet.horizontalHeader().setStretchLastSection(True) vwidth = self.tableRet.verticalHeader().length() hwidth = self.tableRet.horizontalHeader().height() fwidth = self.tableRet.frameWidth() * 2 self.tableRet.setFixedHeight(vwidth + hwidth + fwidth) vbox.addWidget(self.tableRet) self.buttonSrcView = QPushButton('view code') self.buttonSrcView.setFixedWidth(200) self.buttonSrcView.clicked.connect(self.openSourceViewer) self.buttonHide = QPushButton('Hide') self.buttonHide.setFixedWidth(200) self.buttonHide.clicked.connect(self.notifyHide) self.buttonHideAllMsg = QPushButton('Hide All') self.buttonHideAllMsg.setFixedWidth(200) self.buttonHideAllMsg.clicked.connect(self.hideAllMsgNamedAsSelected) self.groupBoxMessageInfo.setLayout(vbox) self.checkHideCircular = QCheckBox('Hide Circular Messages') self.checkHideCircular.setCheckState(QtCore.Qt.Unchecked) self.checkHideCircular.stateChanged.connect(self.changeHideCircularMessage) self.addWidget(self.checkHideCircular) self.addWidget(self.groupBoxMessageInfo) self.groupBoxMessageInfo.setSizePolicy(self.sizePolicy) def reset(self): for idx in reversed(range(0,self.listThread.count())): self.listThread.takeItem(idx) def setMsgInfoMessage(self,msg): self.strMessage = msg def changeHideCircularMessage(self,state): if state == QtCore.Qt.Unchecked: self.diagramView.hideCircularChanged(False) elif state == QtCore.Qt.Checked: self.diagramView.hideCircularChanged(True) def setMsgInfoModule(self,module): self.strModule = module def updateSearchStatus(self,curr,number): self.searchCursor.setText("%d/%d" % (curr,number)) def connectSourceViewer(self,viewer): self.srcViewer = viewer def openSourceViewer(self): self.srcViewer.openViewer(self.strModule,self.strMessage) def setMessageInfoTime(self,begin,end,duration): self.tableTime.item(0,1).setText(begin) self.tableTime.item(1,1).setText(end) self.tableTime.item(2,1).setText(duration + ' msec') def setMessageInfoArg(self,listParam,listArg): # Clear the contents in the table max_arg_num = 10 for idx in range(0,max_arg_num): self.tableArgs.item(idx,0).setText('') self.tableArgs.item(idx,1).setText('') if listArg: for idx, text in enumerate(listArg): self.tableArgs.item(idx,1).setText(text) for idx, text in enumerate(listParam): self.tableArgs.item(idx,0).setText(text) else: for idx in range(0,self.tableArgs.rowCount()): self.tableArgs.item(idx,1).setText('') self.tableArgs.item(idx,0).setText('') def setMessageInfoRet(self,listRet): if listRet: for idx, text in enumerate(listRet): self.tableRet.item(idx,1).setText(text) else: for idx in range(0,self.tableRet.rowCount()): self.tableRet.item(idx,1).setText('') self.tableRet.item(idx,0).setText('') def notifyInteractiveStateChanged(self,state): if const.mode_interactive != self.mode: return if const.STATE_INTERACTIVE_CAPTURING == state: self.buttonCapture.setEnabled(True) self.buttonCapture.setText('Stop Capture') if const.STATE_INTERACTIVE_PROCESSING == state: self.buttonCapture.setEnabled(False) if const.STATE_INTERACTIVE_IDLE == state: self.buttonCapture.setEnabled(True) self.buttonCapture.setText('Capture') if const.STATE_INTERACTIVE_RESET == state: self.buttonCapture.setEnabled(True) self.buttonCapture.setText('Capture') elif const.STATE_INTERACTIVE_ACTIVE == state: self.buttonCapture.setEnabled(True) self.buttonCapture.setText('Capture') def setMessageInfo(self,info): self.msgInfo.setText(info) def setAvailable(self,threads): self.sig.emit(threads) def toggleThreadDisplay(self,item): print(self.listThread.currentRow()) #if item.isSelected(): # print(item.text() + " is selected") #else: # print(item.text() + " is not selected") self.diagramView.showThread(self.listThread.currentRow(),item.isSelected()) def hideAllMsgNamedAsSelected(self): self.diagramView.hideAllMessageSelected() def addThreadList(self,threads): if not self.groupBoxThreadInfo: self.groupBoxThreadInfo = QGroupBox() self.threadInfo = QLabel("Thread Info.") self.groupBoxThreadInfo.setStyleSheet("QGroupBox {border: 1px solid gray; border-radius: 9px; margin-top: 0.5em} QGroupBox::title {subcontrol-origin: margin; left: 10px; padding: 0 3px 0 3px;") if not self.threadvbox: self.threadvbox = QVBoxLayout() if not self.listThread: self.listThread = QListWidget() self.listThread.setFixedWidth(200) self.listThread.setSelectionMode(QAbstractItemView.MultiSelection) QtCore.QObject.connect(self.listThread, QtCore.SIGNAL("itemClicked(QListWidgetItem *)"), self.toggleThreadDisplay) self.threadvbox.addWidget(self.threadInfo) self.threadvbox.addWidget(self.listThread) self.groupBoxThreadInfo.setLayout(self.threadvbox) self.addWidget(self.groupBoxThreadInfo) self.groupBoxThreadInfo.setSizePolicy(self.sizePolicy) for id in threads: item = QListWidgetItem(id) self.listThread.addItem(item) def connectController(self,controller): self.controller = controller self.connect(controller,QtCore.SIGNAL('setAvailable()'),self.setAvailable) def connectDiagramView(self,view): self.diagramView = view def disconnectMsgRcv(self,receiver): print("Implement this method !!! disconnectMsgRcv") def connectMsgRcv(self,receiver): self.msgRcv.append(receiver) def notifyHide(self): for rcv in self.msgRcv: rcv.activateHide(True) def showHiddenLifelines(self): response, selected_items = HiddenDialog.HiddenDialog.getSelectedItems(self.diagramView.getHiddenLifeLines()) if response: self.diagramView.showLifelines(selected_items) def showHiddenMessages(self): response, selected_items = HiddenMessageDialog.HiddenMessageDialog.getSelectedItems(self.diagramView.getHiddenMessages(),self.diagramView.getHiddenLifeLines()) if response: if selected_items[3] in self.diagramView.getHiddenLifeLines(): confirmation = ShowLifeLineDialog.ShowLifeLineDialog.confirmToShowLifeLine(selected_items[3]) if confirmation: self.diagramView.showLifelines([selected_items[3]]) self.diagramView.showMessages(selected_items) else: self.diagramView.showMessages(selected_items) def notifyCapture(self): for rcv in self.msgRcv: rcv.activateCapture(True) def moveToPrev(self): for rcv in self.msgRcv: rcv.moveToPrev() def moveToNext(self): for rcv in self.msgRcv: rcv.moveToNext() def searchMsg(self): str = self.editTextSearch.toPlainText() for rcv in self.msgRcv: rcv.searchMessage(str)
class ToolBox(QVBoxLayout): sig = QtCore.Signal(object) listThread = None groupBoxThreadInfo = None threadvbox = None mode = None def __init__(self, mode, parentQWidget=None): QVBoxLayout.__init__(self) self.sig.connect(self.addThreadList) self.mode = mode self.sizePolicy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Expanding) self.groupBoxSearch = QGroupBox() self.groupBoxSearch.setStyleSheet( "QGroupBox {border: 1px solid gray; border-radius: 4px; };") vboxSearch = QVBoxLayout() self.searchTitle = QLabel("Search Messages") vboxSearch.addWidget(self.searchTitle) self.searchHLayout = QHBoxLayout() self.editTextSearch = QTextEdit('') self.editTextSearch.setFixedSize(200, 30) self.buttonSearch = QPushButton('Search') self.buttonSearch.setFixedSize(100, 30) self.buttonSearch.clicked.connect(self.searchMsg) vboxSearch.addWidget(self.editTextSearch) self.searchHLayout.addWidget(self.buttonSearch) self.searchCursor = QLabel() self.searchHLayout.addWidget(self.searchCursor) vboxSearch.addLayout(self.searchHLayout) self.browseHLayout = QHBoxLayout() self.buttonLookUp = QPushButton('\u21e7') #Arrow up self.buttonLookUp.setFixedWidth(100) self.buttonLookUp.clicked.connect(self.moveToPrev) self.buttonLookDown = QPushButton('\u21e9') #Arrow down self.buttonLookDown.setFixedWidth(100) self.buttonLookDown.clicked.connect(self.moveToNext) self.browseHLayout.addWidget(self.buttonLookUp) self.browseHLayout.addWidget(self.buttonLookDown) vboxSearch.addLayout(self.browseHLayout) self.groupBoxSearch.setLayout(vboxSearch) self.addWidget(self.groupBoxSearch) self.groupBoxSearch.setSizePolicy( QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)) self.buttonHiddenLifelines = QPushButton('Show hidden life-lines') self.buttonHiddenLifelines.setFixedWidth(200) self.buttonHiddenLifelines.clicked.connect(self.showHiddenLifelines) self.addWidget(self.buttonHiddenLifelines) self.buttonHiddenMessages = QPushButton('Show hidden Messages') self.buttonHiddenMessages.setFixedWidth(200) self.buttonHiddenMessages.clicked.connect(self.showHiddenMessages) self.addWidget(self.buttonHiddenMessages) if const.mode_interactive == mode: self.buttonCapture = QPushButton('Capture') self.buttonCapture.setFixedWidth(200) self.buttonCapture.clicked.connect(self.notifyCapture) self.addWidget(self.buttonCapture) self.msgRcv = [] self.msgInfo = QLabel("Message Info.") self.groupBoxMessageInfo = QGroupBox() self.groupBoxMessageInfo.setStyleSheet( "QGroupBox {border: 1px solid gray; border-radius: 9px; margin-top: 0.5em} QGroupBox::title {subcontrol-origin: margin; left: 10px; padding: 0 3px 0 3px;" ) vbox = QVBoxLayout() vbox.addWidget(self.msgInfo) self.tableTime = QTableWidget(3, 2) self.tableTime.setHorizontalHeaderLabels(['-', 'time']) self.tableTime.setColumnWidth(0, 80) self.tableTime.setColumnWidth(1, 150) vwidth = self.tableTime.verticalHeader().length() hwidth = self.tableTime.horizontalHeader().height() fwidth = self.tableTime.frameWidth() * 2 self.tableTime.setFixedHeight(vwidth + hwidth + fwidth) self.tableTime.horizontalHeader().setStretchLastSection(True) self.tableTime.setItem(0, 0, QTableWidgetItem('begin')) self.tableTime.setItem(0, 1, QTableWidgetItem(' - ')) self.tableTime.setItem(1, 0, QTableWidgetItem('end')) self.tableTime.setItem(1, 1, QTableWidgetItem(' - ')) self.tableTime.setItem(2, 0, QTableWidgetItem('duration')) self.tableTime.setItem(2, 1, QTableWidgetItem(' - ')) vbox.addWidget(self.tableTime) self.titleArg = QLabel('Argument List') vbox.addWidget(self.titleArg) max_arg_num = 10 self.tableArgs = QTableWidget(max_arg_num, 2) self.tableArgs.setHorizontalHeaderLabels(['type', 'value']) for idx in range(0, max_arg_num): self.tableArgs.setItem(idx, 0, QTableWidgetItem()) self.tableArgs.setItem(idx, 1, QTableWidgetItem()) self.tableArgs.horizontalHeader().setStretchLastSection(True) vbox.addWidget(self.tableArgs) self.titleArg = QLabel('Return Value List') vbox.addWidget(self.titleArg) max_ret_num = 4 self.tableRet = QTableWidget(max_ret_num, 2) self.tableRet.setHorizontalHeaderLabels(['type', 'value']) for idx in range(0, max_ret_num): self.tableRet.setItem(idx, 0, QTableWidgetItem()) self.tableRet.setItem(idx, 1, QTableWidgetItem()) self.tableRet.horizontalHeader().setStretchLastSection(True) vwidth = self.tableRet.verticalHeader().length() hwidth = self.tableRet.horizontalHeader().height() fwidth = self.tableRet.frameWidth() * 2 self.tableRet.setFixedHeight(vwidth + hwidth + fwidth) vbox.addWidget(self.tableRet) self.buttonSrcView = QPushButton('view code') self.buttonSrcView.setFixedWidth(200) self.buttonSrcView.clicked.connect(self.openSourceViewer) self.buttonHide = QPushButton('Hide') self.buttonHide.setFixedWidth(200) self.buttonHide.clicked.connect(self.notifyHide) self.buttonHideAllMsg = QPushButton('Hide All') self.buttonHideAllMsg.setFixedWidth(200) self.buttonHideAllMsg.clicked.connect(self.hideAllMsgNamedAsSelected) self.groupBoxMessageInfo.setLayout(vbox) self.checkHideCircular = QCheckBox('Hide Circular Messages') self.checkHideCircular.setCheckState(QtCore.Qt.Unchecked) self.checkHideCircular.stateChanged.connect( self.changeHideCircularMessage) self.addWidget(self.checkHideCircular) self.addWidget(self.groupBoxMessageInfo) self.groupBoxMessageInfo.setSizePolicy(self.sizePolicy) def reset(self): for idx in reversed(range(0, self.listThread.count())): self.listThread.takeItem(idx) def setMsgInfoMessage(self, msg): self.strMessage = msg def changeHideCircularMessage(self, state): if state == QtCore.Qt.Unchecked: self.diagramView.hideCircularChanged(False) elif state == QtCore.Qt.Checked: self.diagramView.hideCircularChanged(True) def setMsgInfoModule(self, module): self.strModule = module def updateSearchStatus(self, curr, number): self.searchCursor.setText("%d/%d" % (curr, number)) def connectSourceViewer(self, viewer): self.srcViewer = viewer def openSourceViewer(self): self.srcViewer.openViewer(self.strModule, self.strMessage) def setMessageInfoTime(self, begin, end, duration): self.tableTime.item(0, 1).setText(begin) self.tableTime.item(1, 1).setText(end) self.tableTime.item(2, 1).setText(duration + ' msec') def setMessageInfoArg(self, listParam, listArg): # Clear the contents in the table max_arg_num = 10 for idx in range(0, max_arg_num): self.tableArgs.item(idx, 0).setText('') self.tableArgs.item(idx, 1).setText('') if listArg: for idx, text in enumerate(listArg): self.tableArgs.item(idx, 1).setText(text) for idx, text in enumerate(listParam): self.tableArgs.item(idx, 0).setText(text) else: for idx in range(0, self.tableArgs.rowCount()): self.tableArgs.item(idx, 1).setText('') self.tableArgs.item(idx, 0).setText('') def setMessageInfoRet(self, listRet): if listRet: for idx, text in enumerate(listRet): self.tableRet.item(idx, 1).setText(text) else: for idx in range(0, self.tableRet.rowCount()): self.tableRet.item(idx, 1).setText('') self.tableRet.item(idx, 0).setText('') def notifyInteractiveStateChanged(self, state): if const.mode_interactive != self.mode: return if const.STATE_INTERACTIVE_CAPTURING == state: self.buttonCapture.setEnabled(True) self.buttonCapture.setText('Stop Capture') if const.STATE_INTERACTIVE_PROCESSING == state: self.buttonCapture.setEnabled(False) if const.STATE_INTERACTIVE_IDLE == state: self.buttonCapture.setEnabled(True) self.buttonCapture.setText('Capture') if const.STATE_INTERACTIVE_RESET == state: self.buttonCapture.setEnabled(True) self.buttonCapture.setText('Capture') elif const.STATE_INTERACTIVE_ACTIVE == state: self.buttonCapture.setEnabled(True) self.buttonCapture.setText('Capture') def setMessageInfo(self, info): self.msgInfo.setText(info) def setAvailable(self, threads): self.sig.emit(threads) def toggleThreadDisplay(self, item): print(self.listThread.currentRow()) #if item.isSelected(): # print(item.text() + " is selected") #else: # print(item.text() + " is not selected") self.diagramView.showThread(self.listThread.currentRow(), item.isSelected()) def hideAllMsgNamedAsSelected(self): self.diagramView.hideAllMessageSelected() def addThreadList(self, threads): if not self.groupBoxThreadInfo: self.groupBoxThreadInfo = QGroupBox() self.threadInfo = QLabel("Thread Info.") self.groupBoxThreadInfo.setStyleSheet( "QGroupBox {border: 1px solid gray; border-radius: 9px; margin-top: 0.5em} QGroupBox::title {subcontrol-origin: margin; left: 10px; padding: 0 3px 0 3px;" ) if not self.threadvbox: self.threadvbox = QVBoxLayout() if not self.listThread: self.listThread = QListWidget() self.listThread.setFixedWidth(200) self.listThread.setSelectionMode(QAbstractItemView.MultiSelection) QtCore.QObject.connect(self.listThread, QtCore.SIGNAL("itemClicked(QListWidgetItem *)"), self.toggleThreadDisplay) self.threadvbox.addWidget(self.threadInfo) self.threadvbox.addWidget(self.listThread) self.groupBoxThreadInfo.setLayout(self.threadvbox) self.addWidget(self.groupBoxThreadInfo) self.groupBoxThreadInfo.setSizePolicy(self.sizePolicy) for id in threads: item = QListWidgetItem(id) self.listThread.addItem(item) def connectController(self, controller): self.controller = controller self.connect(controller, QtCore.SIGNAL('setAvailable()'), self.setAvailable) def connectDiagramView(self, view): self.diagramView = view def disconnectMsgRcv(self, receiver): print("Implement this method !!! disconnectMsgRcv") def connectMsgRcv(self, receiver): self.msgRcv.append(receiver) def notifyHide(self): for rcv in self.msgRcv: rcv.activateHide(True) def showHiddenLifelines(self): response, selected_items = HiddenDialog.HiddenDialog.getSelectedItems( self.diagramView.getHiddenLifeLines()) if response: self.diagramView.showLifelines(selected_items) def showHiddenMessages(self): response, selected_items = HiddenMessageDialog.HiddenMessageDialog.getSelectedItems( self.diagramView.getHiddenMessages(), self.diagramView.getHiddenLifeLines()) if response: if selected_items[3] in self.diagramView.getHiddenLifeLines(): confirmation = ShowLifeLineDialog.ShowLifeLineDialog.confirmToShowLifeLine( selected_items[3]) if confirmation: self.diagramView.showLifelines([selected_items[3]]) self.diagramView.showMessages(selected_items) else: self.diagramView.showMessages(selected_items) def notifyCapture(self): for rcv in self.msgRcv: rcv.activateCapture(True) def moveToPrev(self): for rcv in self.msgRcv: rcv.moveToPrev() def moveToNext(self): for rcv in self.msgRcv: rcv.moveToNext() def searchMsg(self): str = self.editTextSearch.toPlainText() for rcv in self.msgRcv: rcv.searchMessage(str)
class AreaSelectTool(QWidget): ''' Select areas of your screen ''' def __init__(self, screen_size, pixel_ratio): super(AreaSelectTool, self).__init__() # account for high-dpi screens self.screen_size = screen_size self.pixel_ratio = pixel_ratio # keep track of area(s) selected self.selected_areas = [] # TODO add method to detect screen size... screen = { "top": 0, "left": 0, "width": screen_size.width(), "height": screen_size.height() } self.camera = Camera(screen, pixel_ratio) # ---------- Setup GUI ---------- self.layout = QVBoxLayout(self) # camera controls self.camera_button = QPushButton("Start Camera") self.camera_button.clicked.connect(self.toggle_camera) # setup widget for selecting areas of the screen self.area_edit_widget = AreaEditWidget() self._make_connection(self.area_edit_widget) # button to add / remove a specific area self.edit_area_button = QPushButton("Add / Remove Areas") self.edit_area_button.clicked.connect(self.edit_area) # checkbox to show / hide selected areas self.show_selected_areas = QCheckBox("Show Selected Areas") self.show_selected_areas.setCheckState(Qt.CheckState.Checked) self.show_selected_areas.stateChanged.connect( self.toggle_selected_areas) # save the selected areas to a file self.save_button = QPushButton("Save and Exit") self.save_button.clicked.connect(self.save) # reset selected areas self.reset_button = QPushButton("Reset") self.reset_button.clicked.connect(self.reset) # add all ui elements to layout self.layout.addWidget(self.camera_button) self.layout.addWidget(self.edit_area_button) self.layout.addWidget(self.show_selected_areas) self.layout.addWidget(self.reset_button) self.layout.addWidget(self.save_button) def _make_connection(self, ssw_object): # connect the buttons to AreaEditWidgets signals ssw_object.areaSelected.connect(self.area_selected) ssw_object.areaRemoved.connect(self.area_removed) def edit_area(self): self.hide() self.area_edit_widget.resize(self.screen_size.width(), self.screen_size.height()) self.area_edit_widget.show() def toggle_camera(self): # update the list of areas to segment self.camera.rects_to_segment = [] for area in self.selected_areas: self.camera.rects_to_segment.append(area.geometry()) # show / hide selected areas self.toggle_selected_areas() # start / stop the camera if not self.camera._running: self.camera.start() self.camera_button.setText("Stop Camera") else: self.camera.terminate() self.camera_button.setText("Start Camera") @Slot(QRect) def area_selected(self, rect): self.area_edit_widget.hide() # add the selected area # new_area = HeadsUpWidget(opacity=0.5) new_area = HeadsUpWidget() new_area.setGeometry(rect) new_area.randomize_color() new_area.show() # add the new area to the list self.selected_areas.append(new_area) self.show() @Slot(QPoint) def area_removed(self, pos): self.area_edit_widget.hide() # remove the area that was clicked on for i, a in enumerate(self.selected_areas): if a.geometry().contains(pos): a.close() del self.selected_areas[i] self.show() def toggle_selected_areas(self): for area in self.selected_areas: if not area.isHidden(): area.hide() else: area.show() def reset(self): '''remove all selected areas''' for area in self.selected_areas: area.close() del self.selected_areas self.selected_areas = [] def save(self): '''Save the selected areas to a json file and quit the app''' outdict = { i: [ a.geometry().x(), a.geometry().y(), a.geometry().width(), a.geometry().height() ] for i, a in enumerate(self.selected_areas) } # FIXME switch to something else like pickle with open('rects.json', 'w') as outfile: json.dump(outdict, outfile) app.exit()
class LayerManager(QWidget): """ Class to manage the layers of a viewer. Allow to change the order of layers by drag and drop. """ def __init__(self, viewer): super(LayerManager, self).__init__() self.selected_layer = None self.viewer = viewer self.layers = dict() self.layer_widget = Layers(self.viewer) self.alpha_slider = QSlider(QtCore.Qt.Horizontal) self.checkbox_enable = QCheckBox() self.alpha_label = QLabel(f"Select Layer to change Opacity") self.enable_label = QLabel(f"Select Layer to enable/disable") layout = QGridLayout() layout.addWidget(self.layer_widget, 0, 0, 1, 1) layout.addWidget(self.alpha_label, 1, 0, 1, 1) layout.addWidget(self.alpha_slider, 2, 0, 1, 1) layout.addWidget(self.enable_label, 3, 0, 1, 1) layout.addWidget(self.checkbox_enable, 4, 0, 1, 1) self.setLayout(layout) self.layer_widget.itemClicked.connect(self.select_layer) self.checkbox_enable.stateChanged.connect(self.checkbox_changed) self.alpha_slider.valueChanged.connect(self.slider_changed) self.alpha_slider.setValue(99) def add_layer(self, layer, name, state=True): """ Add new layer to be managed. Args: layer (Object): object that implements a draw function. name (str): String which is the name of the layer. """ self.layers[name] = {"layer": layer, "alpha": 1, "state": state} self.layer_widget.addItem(name) def get_layers(self): """ Get list of layers representing the order of the LayerManager in the UI. Returns: [Objects]: objects which implement a draw function """ names = [ self.layer_widget.item(i).data(0) for i in range(self.layer_widget.count()) ] result = [(self.layers[name]["layer"], self.layers[name]["alpha"]) for name in names if self.layers[name]["state"]] return result def select_layer(self, item): """ Select a layer to change opacity. Args: item: item of the list """ name = item.data(0) self.selected_layer = name self.alpha_label.setText(f"Opacity ({self.selected_layer}):") self.enable_label.setText(f"Enable/Disable ({self.selected_layer}):") # set slider to current value value = self.layers[name]["alpha"] value = value * 100 - 1 self.alpha_slider.setValue(value) # set checkbox state = self.layers[name]["state"] if state: self.checkbox_enable.setCheckState(Qt.Checked) else: self.checkbox_enable.setCheckState(Qt.Unchecked) def slider_changed(self, value): """ Callback when the opacity slider was moved. Args: value (int): slider value 0-99 """ value = (value + 1) / 100 if self.selected_layer in self.layers: self.layers[self.selected_layer]["alpha"] = value self.viewer.update() def checkbox_changed(self): """ Callback when the Checkbox is changed. The layer is (not) drawn anymore. """ if self.selected_layer in self.layers: if self.checkbox_enable.isChecked(): self.layers[self.selected_layer]["state"] = True else: self.layers[self.selected_layer]["state"] = False self.viewer.update()
class ExportFileDialog(QFileDialog): """ Create a custom Export-File Dialog with options like BOM etc. """ def __init__(self, *args, **kwargs): super(ExportFileDialog, self).__init__(*args, **kwargs) self.mainWindow = self.parent() self.setWindowTitle("Export nodes to CSV") self.setAcceptMode(QFileDialog.AcceptSave) self.setOption(QFileDialog.DontUseNativeDialog) #self.setFilter("CSV Files (*.csv)") self.setDefaultSuffix("csv") self.optionBOM = QCheckBox("Use a BOM", self) self.optionBOM.setCheckState(Qt.CheckState.Checked) self.optionLinebreaks = QCheckBox("Remove line breaks", self) self.optionLinebreaks.setCheckState(Qt.CheckState.Checked) self.optionSeparator = QComboBox(self) self.optionSeparator.insertItems(0, [";", "\\t", ","]) self.optionSeparator.setEditable(True) #self.optionLinebreaks.setCheckState(Qt.CheckState.Checked) self.optionWide = QCheckBox( "Convert to wide format (experimental feature)", self) self.optionWide.setCheckState(Qt.CheckState.Unchecked) # if none or all are selected, export all # if one or more are selected, export selective self.optionAll = QComboBox(self) self.optionAll.insertItems(0, [ 'All nodes (faster for large datasets, ordered by internal ID)', 'Selected nodes (ordered like shown in nodes view)' ]) if self.mainWindow.tree.noneOrAllSelected(): self.optionAll.setCurrentIndex(0) else: self.optionAll.setCurrentIndex(1) layout = self.layout() row = layout.rowCount() layout.addWidget(QLabel('Options'), row, 0) options = QHBoxLayout() options.addWidget(self.optionBOM) options.addWidget(self.optionLinebreaks) options.addWidget(QLabel('Separator')) options.addWidget(self.optionSeparator) options.addStretch(1) layout.addLayout(options, row, 1, 1, 2) layout.addWidget(QLabel('Post processing'), row + 1, 0) layout.addWidget(self.optionWide, row + 1, 1, 1, 2) layout.addWidget(QLabel('Export mode'), row + 2, 0) layout.addWidget(self.optionAll, row + 2, 1, 1, 2) self.setLayout(layout) if self.exec_(): if os.path.isfile(self.selectedFiles()[0]): os.remove(self.selectedFiles()[0]) output = open(self.selectedFiles()[0], 'w', newline='', encoding='utf8') if self.optionBOM.isChecked() and not self.optionWide.isChecked(): output.write('\ufeff') try: if self.optionAll.currentIndex() == 0: self.exportAllNodes(output) else: self.exportSelectedNodes(output) finally: output.close() if self.optionWide.isChecked(): self.convertToWideFormat(self.selectedFiles()[0]) def exportSelectedNodes(self, output): progress = ProgressBar("Exporting data...", self.mainWindow) #indexes = self.mainWindow.tree.selectionModel().selectedRows() #if child nodes should be exported as well, uncomment this line an comment the previous one indexes = self.mainWindow.tree.selectedIndexesAndChildren() indexes = list(indexes) progress.setMaximum(len(indexes)) try: delimiter = self.optionSeparator.currentText() delimiter = delimiter.encode('utf-8').decode('unicode_escape') writer = csv.writer(output, delimiter=delimiter, quotechar='"', quoting=csv.QUOTE_ALL, doublequote=True, lineterminator='\r\n') #headers row = [ str(val) for val in self.mainWindow.tree.treemodel.getRowHeader() ] if self.optionLinebreaks.isChecked(): row = [ val.replace('\n', ' ').replace('\r', ' ') for val in row ] writer.writerow(row) #rows for no in range(len(indexes)): if progress.wasCanceled: break row = [ str(val) for val in self.mainWindow.tree.treemodel.getRowData(indexes[no]) ] if self.optionLinebreaks.isChecked(): row = [ val.replace('\n', ' ').replace('\r', ' ') for val in row ] writer.writerow(row) progress.step() finally: progress.close() def exportAllNodes(self, output): progress = ProgressBar("Exporting data...", self.mainWindow) progress.setMaximum(Node.query.count()) try: delimiter = self.optionSeparator.currentText() delimiter = delimiter.encode('utf-8').decode('unicode_escape') writer = csv.writer(output, delimiter=delimiter, quotechar='"', quoting=csv.QUOTE_ALL, doublequote=True, lineterminator='\r\n') #headers row = [ "level", "id", "parent_id", "object_id", "object_type", "query_status", "query_time", "query_type" ] for key in self.mainWindow.tree.treemodel.customcolumns: row.append(key) if self.optionLinebreaks.isChecked(): row = [ val.replace('\n', ' ').replace('\r', ' ') for val in row ] writer.writerow(row) #rows page = 0 while True: allnodes = Node.query.offset(page * 5000).limit(5000) if allnodes.count() == 0: break for node in allnodes: if progress.wasCanceled: break row = [ node.level, node.id, node.parent_id, node.objectid, node.objecttype, node.querystatus, node.querytime, node.querytype ] for key in self.mainWindow.tree.treemodel.customcolumns: row.append(node.getResponseValue(key)) if self.optionLinebreaks.isChecked(): row = [ str(val).replace('\n', ' ').replace('\r', ' ') for val in row ] writer.writerow(row) # step the Bar progress.step() if progress.wasCanceled: break else: page += 1 finally: progress.close() def convertToWideFormat(self, filename): progress = ProgressBar("Converting data...", self.mainWindow) try: #Separate levels def flattenTable(fulltable, levelcol, idcol, parentidcol, countchildren, removeempty): fulltable[[levelcol]] = fulltable[[levelcol]].astype(int) levels = dict(list(fulltable.groupby(levelcol))) minlevel = fulltable.level.min() for level, data in sorted(levels.items()): #First level is the starting point for the following merges if level == minlevel: #data = data[[idcol,'object_id','object_type']] data = data.add_prefix('level_{}-'.format(level)) flattable = data else: #Aggregate object types and join them for col_countchildren in countchildren: children = data[parentidcol].groupby( [data[parentidcol], data[col_countchildren]]).count() children = children.unstack(col_countchildren) children['total'] = children.sum(axis=1) children = children.add_prefix( 'level_{}-children-{}-'.format( level - 1, col_countchildren)) leftkey = 'level_{}-id'.format(level - 1) flattable = merge(flattable, children, how='left', left_on=leftkey, right_index=True) flattable[children.columns.values.tolist( )] = flattable[children.columns.values.tolist( )].fillna(0).astype(int) #Join data data['childnumber'] = data.groupby( parentidcol).cumcount() leftkey = 'level_{}-{}'.format(level - 1, idcol) rightkey = 'level_{}-{}'.format(level, parentidcol) data = data.drop([levelcol], axis=1) data = data.add_prefix('level_{}-'.format(level)) flattable = merge(flattable, data, how="outer", left_on=leftkey, right_on=rightkey) if removeempty: flattable = flattable.dropna(axis=1, how='all') return flattable try: #delimiter delimiter = self.optionSeparator.currentText() delimiter = delimiter.encode('utf-8').decode('unicode_escape') #open data = read_csv(filename, sep=delimiter, encoding='utf-8', dtype=str) #convert newdata = flattenTable( data, 'level', 'id', 'parent_id', ['object_type', 'query_status', 'query_type'], False) #save outfile = open(filename, 'w', newline='', encoding='utf8') try: if self.optionBOM.isChecked(): outfile.write('\ufeff') #UTF8 BOM newdata.to_csv(outfile, sep=delimiter, index=False, encoding="utf-8") finally: outfile.close() except Exception as e: self.mainWindow.logmessage(e) finally: progress.close()
class SerialDeviceGui(QWidget): def __init__(self, gui_parent, name="Default"): super().__init__() self.name = name self.serial = None self.gui_parent = gui_parent self.layout = QGridLayout() self._setup() self.setLayout(self.layout) def remove(self): self.gui_parent.remove_device(self) def read(self): if self.serial: if self.serial.in_waiting > 0: return self.serial.read(self.serial.in_waiting).decode( self.encoding, errors='ignore') def write(self, bytes): if self.serial: self.serial.write(bytes) def apply(self): self.name = self.name_entry.text() self.gui_parent.update_device_list() if self.baudrate_entry_checkbox.isChecked(): baudrate = int(self.baudrate_entry_standard.currentText()) else: baudrate = self.baudrate_entry_manual.value() if self.location_entry_checkbox.isChecked(): location = self.location_entry_existing.currentText().split()[0] else: location = self.location_entry_manual.text() stopbits = int(self.stopbits_entry.currentText()) self.encoding = self.encoding_entry.currentText() if self.serial: self.serial.close() self.serial = serial.Serial(location, baudrate, stopbits=stopbits) def update_locations(self): devices = list_ports.comports(True) devices = [str(d) for d in devices] self.location_entry_existing.clear() self.location_entry_existing.addItems(devices) def update_location_existing(self): if self.location_entry_checkbox.isChecked(): self.location_entry.setCurrentWidget(self.location_entry_existing) else: self.location_entry_manual.setText( self.location_entry_existing.currentText()) self.location_entry.setCurrentWidget(self.location_entry_manual) def update_baudrate_standard(self): if self.baudrate_entry_checkbox.isChecked(): self.baudrate_entry.setCurrentWidget(self.baudrate_entry_standard) else: self.baudrate_entry_manual.setValue( int(self.baudrate_entry_standard.currentText())) self.baudrate_entry.setCurrentWidget(self.baudrate_entry_manual) def _setup(self): self.name_entry = QLineEdit() self.name_entry.setText(self.name) self.location_entry = QStackedWidget() self.location_entry.setFixedHeight(25) # FIXME: set policy not size self.location_entry_existing = QComboBox() self.location_entry_manual = QLineEdit() self.location_entry.addWidget(self.location_entry_existing) self.location_entry.addWidget(self.location_entry_manual) self.location_entry_checkbox = QCheckBox("Existing") self.location_entry_checkbox.setCheckState(Qt.Checked) self.location_entry_checkbox.stateChanged.connect( self.update_location_existing) location_entry_refresh = QPushButton("Refresh") location_entry_refresh.clicked.connect(self.update_locations) self.baudrate_entry = QStackedWidget() self.baudrate_entry.setFixedHeight(25) # FIXME: set policy not size self.baudrate_entry_standard = QComboBox() self.baudrate_entry_manual = QSpinBox() self.baudrate_entry_manual.setRange(0, 16000000) self.baudrate_entry.addWidget(self.baudrate_entry_standard) self.baudrate_entry.addWidget(self.baudrate_entry_manual) self.baudrate_entry_standard.addItems( [str(s) for s in STANDARD_BAUDRATES]) self.baudrate_entry_checkbox = QCheckBox("Standard Rate") self.baudrate_entry_checkbox.setCheckState(Qt.Checked) self.baudrate_entry_checkbox.stateChanged.connect( self.update_baudrate_standard) self.encoding_entry = QComboBox() self.encoding_entry.addItems(ENCODINGS) self.stopbits_entry = QComboBox() self.stopbits_entry.addItems([str(s) for s in STOPBITS]) apply_button = QPushButton("Apply") apply_button.clicked.connect(self.apply) remove_button = QPushButton("Remove") remove_button.clicked.connect(self.remove) n = 0 self.layout.addWidget(QLabel("name:"), n, 0, 1, 1) self.layout.addWidget(self.name_entry, n, 1, 1, -1) n += 1 self.layout.addWidget(QLabel("location:"), n, 0, 1, 1) self.layout.addWidget(self.location_entry, n, 1, 1, 1) self.layout.addWidget(self.location_entry_checkbox, n, 2, 1, 1) self.layout.addWidget(location_entry_refresh, n, 3, 1, 1) n += 1 self.layout.addWidget(QLabel("baudrate:"), n, 0, 1, 1) self.layout.addWidget(self.baudrate_entry, n, 1, 1, 1) self.layout.addWidget(self.baudrate_entry_checkbox, n, 2, 1, -1) n += 1 self.layout.addWidget(QLabel("encoding:"), n, 0, 1, 1) self.layout.addWidget(self.encoding_entry, n, 1, 1, -1) n += 1 self.layout.addWidget(QLabel("stopbits:"), n, 0, 1, 1) self.layout.addWidget(self.stopbits_entry, n, 1, 1, -1) n += 1 self.layout.addWidget(apply_button, n, 0, 1, -1) n += 1 self.layout.addWidget(remove_button, n, 0, 1, -1) n += 1 self.layout.addWidget(QLabel(), n, 0, -1, -1) self.update_baudrate_standard() self.update_location_existing()
def searchPeople(self): value = self.searchPeopleEntry.text() if value == "": QMessageBox.information(self, "Warning", "Search string cannot be empty") self.funcDisplayPeople() else: # Erase search entry self.searchPeopleEntry.setText("") try: query = "SELECT * FROM people WHERE " \ "person_id LIKE ? " \ "OR person_first_name LIKE ?" \ "OR person_last_name LIKE ?" \ "OR person_title LIKE ?" \ "OR person_phone LIKE ?" \ "OR person_email LIKE ?" \ "OR person_location LIKE ?" \ "OR person_empl_type LIKE ?" results = db.cur.execute(query, ( '%' + value + '%', '%' + value + '%', '%' + value + '%', '%' + value + '%', '%' + value + '%', '%' + value + '%', '%' + value + '%', '%' + value + '%', )).fetchall() if results == []: QMessageBox.information(self, "Info", "Nothing was found") self.displayPeople() else: for i in reversed(range(self.peopleTable.rowCount())): self.peopleTable.removeRow(i) for row_data in results: row_number = self.peopleTable.rowCount() self.peopleTable.insertRow(row_number) # Add checkboxes to the table qwidget = QWidget() checkbox = QCheckBox() checkbox.setCheckState(Qt.Unchecked) qhboxlayout = QHBoxLayout(qwidget) qhboxlayout.addWidget(checkbox) qhboxlayout.setAlignment(Qt.AlignCenter) self.peopleTable.setCellWidget(row_number, 0, qwidget) self.peopleTable.setItem(row_number, 0, QTableWidgetItem(row_number)) # Add photo photos_thumbnails to the table thumbWidget = QWidget() pic = QPixmap( "assets/media/people-media/photos_thumbnails/01Aug2020_18h01mtrtgzteuzuspxrp_thumbnail.png" ) thumbLabel = QLabel() thumbLabel.setPixmap(pic) thumbLayout = QHBoxLayout(thumbWidget) thumbLayout.addWidget(thumbLabel) self.peopleTable.setCellWidget(row_number, 1, thumbWidget) self.peopleTable.setItem(row_number, 0, QTableWidgetItem(row_number)) for column_number, data in enumerate(row_data, start=2): if column_number == 2: self.peopleTable.setItem( row_number, column_number, QTableWidgetItem("PRN#" + str(data))) else: self.peopleTable.setItem( row_number, column_number, QTableWidgetItem(str(data))) except: QMessageBox.information(self, "Info", "Cannot access database")
class MemDumpWindow(QWidget): kill_signal = Signal(bool) def __init__(self, qmp, base=0, max=constants['block_size']): super().__init__() self.flag = False self.threshold = 2048 # number of resident bytes self.qmp = qmp self.init_ui() self.baseAddress = base self.maxAddress = self.baseAddress self.delta = 4 # adds a small buffer area for scrolling action to happen self.sem = QSemaphore(1) # semaphore for controlling access to the enabling / disabling of the scroll listening self.pos = self.chr_display.verticalScrollBar().value() self.highlight_sem = QSemaphore(1) # semaphore for controlling access to highlighting state self.is_highlighted = False self.highlight_addr = 0 self.endian = Endian.little self.endian_sem = QSemaphore(1) self.hash = randint(0, 0xfffffffffffffff) icon = QIcon('package/icons/nasa.png') self.setWindowIcon(icon) self.max_size = 0xfffffffffffffff self.qmp.pmem.connect(self.update_text) self.grab_data(val=self.baseAddress, size=min(max, constants['block_size'] + base)-self.baseAddress) self.t = MyThread(self) self.t.timing_signal.connect(lambda:self.grab_data(val=self.baseAddress, size=self.maxAddress-self.baseAddress, grouping=self.grouping.currentText(), refresh=True)) self.qmp.stateChanged.connect(self.t.halt) self.t.running = self.qmp.running self.t.start() self.show() def init_ui(self): self.hbox = QHBoxLayout() # holds widgets for refresh button, desired address, and size to grab self.vbox = QVBoxLayout() # main container self.lower_hbox = QSplitter() # holds memory views self.lower_container = QHBoxLayout() # holds lower_hbox and the endian_vbox self.endian_vbox = QVBoxLayout() self.hbox.addWidget(QLabel('Address:')) self.address = QLineEdit() self.hbox.addWidget(self.address) self.hbox.addWidget(QLabel('Size:')) self.size = QLineEdit() self.hbox.addWidget(self.size) self.hbox.addWidget(QLabel('Grouping:')) self.grouping = QComboBox() self.grouping.addItems(['1','2','4','8']) self.hbox.addWidget(self.grouping) self.search = QPushButton('Search') self.search.clicked.connect(lambda:self.find(self.address.text(), constants['block_size'])) self.hbox.addWidget(self.search) self.refresh = QPushButton('Refresh') self.refresh.clicked.connect(lambda:self.grab_data(val=self.address.text(), size=self.size.text(), grouping=self.grouping.currentText(), refresh=True)) self.hbox.addWidget(self.refresh) self.save = QPushButton('Save') self.save.clicked.connect(lambda: self.save_to_file()) self.disable_save(self.qmp.running) self.qmp.stateChanged.connect(self.disable_save) self.hbox.addWidget(self.save) self.auto_refresh = QCheckBox('Auto Refresh') self.auto_refresh.setCheckState(Qt.CheckState.Checked) self.auto_refresh.stateChanged.connect(self.auto_refresh_check) self.hbox.addWidget(self.auto_refresh) self.vbox.addLayout(self.hbox) # textbox for addresses self.addresses = QTextEdit() self.addresses.setReadOnly(True) self.addresses.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.addresses.setLineWrapMode(QTextEdit.NoWrap) self.addresses.setCurrentFont(QFont('Courier New')) self.addresses.setGeometry(0,0,150,500) self.lower_hbox.addWidget(self.addresses) # textbox for hex display of memory self.mem_display = QTextEdit() self.mem_display.setReadOnly(True) self.mem_display.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.mem_display.setLineWrapMode(QTextEdit.NoWrap) self.mem_display.setCurrentFont(QFont('Courier New')) self.mem_display.setGeometry(0,0,600,500) self.lower_hbox.addWidget(self.mem_display) # textbox for char display of memory self.chr_display = QTextEdit() self.chr_display.setReadOnly(True) self.chr_display.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn) self.chr_display.setLineWrapMode(QTextEdit.NoWrap) self.chr_display.setCurrentFont(QFont('Courier New')) self.mem_display.setGeometry(0,0,400,500) self.lower_hbox.addWidget(self.chr_display) self.lower_container.addWidget(self.lower_hbox) self.mem_display.verticalScrollBar().valueChanged.connect(self.addresses.verticalScrollBar().setValue) #synchronizes addresses's scroll bar to mem_display's self.addresses.verticalScrollBar().valueChanged.connect(self.mem_display.verticalScrollBar().setValue) #synchronizes mem_display's scroll to addresses's, allowing for searching for addresses to scrol mem_display to the desired point self.chr_display.verticalScrollBar().valueChanged.connect(self.mem_display.verticalScrollBar().setValue) self.mem_display.verticalScrollBar().valueChanged.connect(self.chr_display.verticalScrollBar().setValue) self.chr_display.verticalScrollBar().valueChanged.connect(self.handle_scroll) # allows us to do scrolling # setting up endiannes selection buttons self.little = QRadioButton("Little Endian") self.little.click() self.little.clicked.connect(lambda:self.change_endian(Endian.little)) self.big = QRadioButton("Big Endian") self.big.clicked.connect(lambda:self.change_endian(Endian.big)) self.endian_vbox.addWidget(self.little) self.endian_vbox.addWidget(self.big) self.endian_vbox.addSpacing(400) self.lower_container.addLayout(self.endian_vbox) self.vbox.addLayout(self.lower_container) self.vbox.setSpacing(10) self.setLayout(self.vbox) self.setWindowTitle("Memory Dump") self.setGeometry(100, 100, 1550, 500) def disable_save(self, val): self.save.setEnabled(not val) def save_to_file(self): try: filename = QFileDialog().getSaveFileName(self, 'Save', '.', options=QFileDialog.DontUseNativeDialog) except Exception as e: return if filename[0] == '': return args = { 'val': self.baseAddress, 'size': self.maxAddress - self.baseAddress, 'filename': filename[0] } self.qmp.command('pmemsave', args=args) def auto_refresh_check(self, value): if self.auto_refresh.checkState() == Qt.CheckState.Checked and not self.t.isRunning(): self.t = MyThread(self) self.t.timing_signal.connect(lambda:self.grab_data(val=self.baseAddress, size=self.maxAddress-self.baseAddress, grouping=self.grouping.currentText(), refresh=True)) self.t.start() elif self.auto_refresh.checkState() == Qt.CheckState.Unchecked: self.kill_signal.emit(True) def closeEvent(self, event): self.kill_signal.emit(True) self.qmp.pmem.disconnect(self.update_text) while True: if self.sem.tryAcquire(1, 1): break self.sem.release(10) event.accept() def update_text(self, value): if not value or value['hash'] != self.hash: # semaphore must be held before entering this function return byte = value['vals'] if self.refresh: self.clear_highlight() self.addresses.clear() # clearing to refresh data, other regions will be refilled through scrolling self.mem_display.clear() self.chr_display.clear() s = [''] * ceil((len(byte) / (16))) # hex representation of memory addresses = '' # addresses count = self.baseAddress # keeps track of each 16 addresses if self.pos == self.max: # scrolling down count = self.maxAddress self.maxAddress = max(count + (len(byte)), self.maxAddress) first = True chars = [''] * len(s) # char represenation of memory index = 0 self.endian_sem.acquire() nums = '' for tup in byte: b = tup['val'] if count % 16 == 0: if first: addresses += f'0x{count:08x}' first = False else: addresses += f'\n0x{count:08x}' index += 1 count += 1 if self.endian == Endian.big: if tup['ismapped']: nums = f'{b:02x}' + nums chars[index] += f'{char_convert(b):3}' else: nums = '**' + nums chars[index] += f'{".":3}' elif self.endian == Endian.little: if tup['ismapped']: nums += f'{b:02x}' chars[index] = f'{char_convert(b):3}' + chars[index] else: nums = '**' + nums chars[index] = f'{".":3}' + chars[index] if count % self.group == 0: if self.endian == Endian.big: s[index] += nums + ' ' elif self.endian == Endian.little: s[index] = nums + ' ' + s[index] nums = '' #print(f'"{s[index]}"') self.endian_sem.release() s = '\n'.join(s) chars = '\n'.join(chars) scroll_goto = self.pos if self.pos > self.max - self.delta: # scrolling down self.addresses.append(addresses) self.mem_display.append(s) self.chr_display.append(chars) if self.flag: self.flag = False scroll_goto = (1 - constants['block_size'] / self.threshold) * self.max else: scroll_goto = self.max elif self.pos < self.min + self.delta: # scrolling up addr_cur = self.addresses.textCursor() mem_cur = self.mem_display.textCursor() chr_cur = self.chr_display.textCursor() addr_cur.setPosition(0) mem_cur.setPosition(0) chr_cur.setPosition(0) self.addresses.setTextCursor(addr_cur) self.mem_display.setTextCursor(mem_cur) self.chr_display.setTextCursor(chr_cur) self.addresses.insertPlainText(addresses + '\n') self.mem_display.insertPlainText(s + '\n') self.chr_display.insertPlainText(chars + '\n') if self.flag: self.flag = False scroll_goto = (constants['block_size'] / self.threshold) * self.max else: scroll_goto = self.chr_display.verticalScrollBar().maximum() - self.max else: self.addresses.setPlainText(addresses) self.mem_display.setPlainText(s) self.chr_display.setPlainText(chars) self.highlight_sem.acquire() if self.is_highlighted: self.highlight_sem.release() self.highlight(self.highlight_addr, self.group) else: self.highlight_sem.release() self.chr_display.verticalScrollBar().setValue(scroll_goto) self.chr_display.verticalScrollBar().valueChanged.connect(self.handle_scroll) self.sem.release() def grab_data(self, val=0, size=constants['block_size'], grouping=1, refresh=False): if val == None: val = 0 if size == None: size = 1024 if type(val) == str: try: val = int(val, 0) except Exception: val = 0 if type(size) == str: try: size = int(size, 0) except Exception: size = constants['block_size'] if type(grouping) == str: try: grouping = int(grouping, 0) except: grouping = 1 if grouping not in [1, 2, 4, 8]: grouping = 1 if val < 0: val = 0 if val >= self.max_size: return if size < 0: size = constants['block_size'] if size > self.threshold: size = self.threshold self.sem.acquire() val = val - (val % 16) if val < self.baseAddress or refresh: self.baseAddress = val if size % 16 != 0: size = size + (16 - (size % 16)) if val + size > self.max_size: size = self.max_size - val try: self.chr_display.verticalScrollBar().valueChanged.disconnect(self.handle_scroll) except: pass self.pos = self.chr_display.verticalScrollBar().value() self.max = self.chr_display.verticalScrollBar().maximum() self.min = self.chr_display.verticalScrollBar().minimum() self.group = grouping self.refresh = refresh if refresh: self.maxAddress = self.baseAddress self.highlight_sem.acquire() if self.is_highlighted and self.highlight_addr not in range(val, val + size): self.is_highlighted = False self.pos = 0 self.highlight_sem.release() args = { 'addr': val, 'size': size, 'hash': self.hash, 'grouping': 1 } self.qmp.command('get-pmem', args=args) def find(self, addr, size): try: addr = int(addr, 0) except ValueError as e: print(e) return if self.baseAddress <= addr and addr <= self.maxAddress: group = self.grouping.currentText() try: group = int(group, 0) if group not in [1, 2, 4, 8]: group = 1 except: group = 1 self.highlight(addr, group) else: self.highlight_sem.acquire() self.is_highlighted = True self.highlight_addr = addr self.highlight_sem.release() self.grab_data(val=addr, size=size, refresh=True ) def clear_highlight(self): fmt = QTextCharFormat() fmt.setFont('Courier New') # clearing past highlights addr_cur = self.addresses.textCursor() # getting cursors mem_cur = self.mem_display.textCursor() chr_cur = self.chr_display.textCursor() addr_cur.select(QTextCursor.Document) # selecting entire document mem_cur.select(QTextCursor.Document) chr_cur.select(QTextCursor.Document) addr_cur.setCharFormat(fmt) # adding format mem_cur.setCharFormat(fmt) chr_cur.setCharFormat(fmt) def highlight(self, addr, group): self.clear_highlight() # adding new highlights fmt = QTextCharFormat() fmt.setBackground(Qt.cyan) fmt.setFont('Courier New') addr_block = self.addresses.document().findBlockByLineNumber((addr - self.baseAddress) // 16) # gets linenos mem_block = self.mem_display.document().findBlockByLineNumber((addr - self.baseAddress) // 16) chr_block = self.chr_display.document().findBlockByLineNumber((addr - self.baseAddress) // 16) addr_cur = self.addresses.textCursor() # getting cursors mem_cur = self.mem_display.textCursor() chr_cur = self.chr_display.textCursor() char_offset = 0 mem_offset = 0 self.endian_sem.acquire() if self.endian == Endian.big: mem_offset = ((addr % 16) // group) * (2 * group + 1) char_offset = (addr % 16) * 3 elif self.endian == Endian.little: mem_offset = (((16 / group) - 1 )* (2 * group + 1)) - ((addr % 16) // group) * (2 * group + 1) char_offset = (15*3) - ((addr % 16) * 3) self.endian_sem.release() addr_cur.setPosition(addr_block.position()) # getting positions mem_cur.setPosition(mem_block.position() + mem_offset) # gives character offset within 16 byte line chr_cur.setPosition(chr_block.position() + char_offset) # sets position of char chr_text = self.chr_display.toPlainText() if chr_text[chr_cur.position()] == '\\' and chr_cur.position() + 1 < len(chr_text) and chr_text[chr_cur.position() + 1] in ['0', 'n', 't']: chr_cur.setPosition(chr_cur.position() + 2, mode=QTextCursor.KeepAnchor) else: chr_cur.setPosition(chr_cur.position() + 1, mode=QTextCursor.KeepAnchor) addr_cur.select(QTextCursor.LineUnderCursor) # selects whole line mem_cur.select(QTextCursor.WordUnderCursor) # selects just one word addr_cur.setCharFormat(fmt) # setting format mem_cur.setCharFormat(fmt) chr_cur.setCharFormat(fmt) self.addresses.setTextCursor(addr_cur) self.mem_display.setTextCursor(mem_cur) self.chr_display.setTextCursor(chr_cur) self.highlight_sem.acquire() self.is_highlighted = True self.highlight_addr = addr self.highlight_sem.release() def handle_scroll(self): if self.baseAddress > 0 and self.chr_display.verticalScrollBar().value() < self.chr_display.verticalScrollBar().minimum() + self.delta: size = constants['block_size'] if self.maxAddress - self.baseAddress >= self.threshold: self.flag = True self.grab_data(val=self.baseAddress - constants['block_size'], size=self.threshold, refresh=True, grouping=self.grouping.currentText()) return if self.baseAddress < size: size = self.baseAddress self.grab_data(val=self.baseAddress-size, size=size, grouping=self.grouping.currentText()) elif self.chr_display.verticalScrollBar().value() > self.chr_display.verticalScrollBar().maximum() - self.delta and self.maxAddress <= self.max_size: if self.maxAddress - self.baseAddress >= self.threshold: self.flag = True self.grab_data(val=self.baseAddress + constants['block_size'], size=self.threshold, refresh=True, grouping=self.grouping.currentText()) else: self.grab_data(val=self.maxAddress, grouping=self.grouping.currentText()) def change_endian(self, endian): self.endian_sem.acquire() if endian == Endian.little: self.endian = endian elif endian == Endian.big: self.endian = endian self.endian_sem.release()