def init_reference_clock_setup_widget(self): """Initialize the reference clock selection stuff. This method initializes the reference clock selection radio buttons, and triggers the initialization of the manual reference clock setup stage. There are two choices at this level: synchronize and manual setup. """ # Reference clock selection (synchronize vs manual setup). reference_clock_selection_widget = QGroupBox('Reference clock setup:') # Big text label showing the currently set up reference clock. self.reference_datetime_label = QLabel('PLACEHOLDER') self.reference_datetime_label.setAlignment(Qt.AlignCenter) font = self.reference_datetime_label.font() font.setPointSize(self.REFERENCE_CLOCK_POINT_SIZE) self.reference_datetime_label.setFont(font) # Chooser radio buttons and the button group. synchronize_radiobutton = QRadioButton('Synchronize') synchronize_radiobutton.setChecked(True) synchronize_button = QPushButton('Synchronize') manual_setup_radiobutton = QRadioButton('Manual setup') reference_clock_setup_button_group = QButtonGroup() reference_clock_setup_button_group.addButton(synchronize_radiobutton) reference_clock_setup_button_group.addButton(manual_setup_radiobutton) reference_clock_selection_row_widget = QWidget() reference_clock_selection_row_widget.setLayout(QHBoxLayout()) reference_clock_selection_row_widget.layout().addWidget(synchronize_radiobutton) reference_clock_selection_row_widget.layout().addWidget(synchronize_button) reference_clock_selection_row_widget.layout().addWidget(manual_setup_radiobutton) reference_clock_selection_widget.setLayout(QVBoxLayout()) reference_clock_selection_widget.layout().addWidget(self.reference_datetime_label) reference_clock_selection_widget.layout().addWidget(reference_clock_selection_row_widget) # The latter choice, that expands to more choices. reference_clock_manual_setup_widget = self.init_reference_clock_manual_setup_widget() # Top-level widgets. reference_clock_setup_widget = QWidget() reference_clock_setup_widget.setLayout(QVBoxLayout()) reference_clock_setup_widget.layout().addWidget(reference_clock_selection_widget) reference_clock_setup_widget.layout().addWidget(reference_clock_manual_setup_widget) # Signals/slots plumbing. synchronize_radiobutton.toggled.connect(synchronize_button.setEnabled) manual_setup_radiobutton.toggled.connect(reference_clock_manual_setup_widget.setEnabled) synchronize_button.clicked.connect(self.time_synchronizer.show) self.time_synchronizer.clicked.connect(self.handle_time_synchronizer_done) # Set default state. synchronize_radiobutton.click() reference_clock_manual_setup_widget.setEnabled(False) return reference_clock_setup_widget
def _init_mode_picker(self, layout): image_button = QRadioButton('Images') video_button = QRadioButton('Video') self.mode_button_group.addButton(image_button) self.mode_button_group.addButton(video_button) image_button.clicked.connect(lambda: self.trigger_set_mode('images')) video_button.clicked.connect(lambda: self.trigger_set_mode('video')) layout.addWidget(image_button) layout.addWidget(video_button) image_button.click()
class AxisSettings(QWidget): def __init__(self, unit=None, parent=None): super(AxisSettings, self).__init__(parent) self._auto_radiobutton = QRadioButton('Automatic', self) self._fix_radiobutton = QRadioButton('Fixed', self) self._button_group = QButtonGroup() self._button_group.addButton(self._auto_radiobutton) self._button_group.addButton(self._fix_radiobutton) self.upper_layout = QHBoxLayout() self.upper_layout.addWidget(self._auto_radiobutton) self._from_lineedit = QLineEdit() self._from_lineedit.setFixedWidth(_LINEEDIT_WIDTH) self._from_lineedit.setValidator(QDoubleValidator()) self._from_lineedit.setAlignment(Qt.AlignRight) self._to_label = QLabel('to') self._to_lineedit = QLineEdit() self._to_lineedit.setFixedWidth(_LINEEDIT_WIDTH) self._to_lineedit.setValidator(QDoubleValidator()) self._to_lineedit.setAlignment(Qt.AlignRight) self._unit_label = QLabel(unit) if unit else None self.lower_layout = QHBoxLayout() self.lower_layout.addWidget(self._fix_radiobutton) self.lower_layout.addWidget(self._from_lineedit) self.lower_layout.addWidget(self._to_label) self.lower_layout.addWidget(self._to_lineedit) if self._unit_label: self.lower_layout.addWidget(self._unit_label) def set_values(self, fix, from_value, to_value): self._from_lineedit.setText(str(from_value)) self._to_lineedit.setText(str(to_value)) if fix: self._fix_radiobutton.click() else: self._auto_radiobutton.click() @property def fix_enabled(self): return self._fix_radiobutton.isChecked() @property def from_value(self): return float(self._from_lineedit.text()) @property def to_value(self): return float(self._to_lineedit.text())
def init_clock_selection_widget(self): """Initialize the clock selection stuff. This method initializes the clock selection radio buttons, and triggers the initialization of the reference clock selection stage. There are two choices at this level: wall clock and reference clocks. """ # Clock selection (wall clock vs reference clock). clock_selection_widget = QGroupBox('Use clock:') # Chooser radio buttons and the button group. wall_clock_radiobutton = QRadioButton('Wall clock') self.reference_clock_radiobutton = QRadioButton('Reference clock') clock_source_button_group = QButtonGroup() clock_source_button_group.addButton(wall_clock_radiobutton) clock_source_button_group.addButton(self.reference_clock_radiobutton) clock_selection_widget.setLayout(QHBoxLayout()) clock_selection_widget.layout().addWidget(wall_clock_radiobutton) clock_selection_widget.layout().addWidget(self.reference_clock_radiobutton) # The latter choice, that expands to more choices. reference_clock_setup_widget = self.init_reference_clock_setup_widget() # Top-level widgets. self.setLayout(QVBoxLayout()) self.layout().addWidget(clock_selection_widget) self.layout().addWidget(reference_clock_setup_widget) # Signals/slots plumbing. self.reference_clock_radiobutton.toggled.connect(reference_clock_setup_widget.setEnabled) self.reference_clock_radiobutton.toggled.connect(self.toggle_reference_clock_setup) # Set default state. wall_clock_radiobutton.click() reference_clock_setup_widget.setEnabled(False)
class PlotTab(TraceDocks): ## The constructor # @param parent parent for this widget def __init__(self,parent): super(PlotTab, self).__init__(parent,'Plot Tab') self.tabName = 'PlotTab' self.parent = parent self.logger.logEvent('Creating Tab now: '+ self.tabName) Globals.dockDict['dockStart'].createPlotButt.clicked.connect(self.createPlot) # Create necessary variables self.snifferConfig.configFilterState = 'Local' self.snifferConfig.configCurrentTheme = 'Dark' self.snifferConfig.parseConfigFromFile() self.writePayload = PayloadData() self.snifferPayload = PayloadData() self.singleShotTime = 0 self.end_time = 0 self.start_time = 0 #self.snifferConfigData = self.parent.snifferConfigData #self.failCnt = self.parent.failCnt self.purge = 0 #self.measurementIsRunning = self.parent.measurementIsRunning ## Create Layout for this Tab def setPlotTabLayout(self): # Create Plot Tab --------------------### # Create Layouts self.VLayout = QVBoxLayout() self.H1layout = QHBoxLayout() self.H1layout.setSpacing(15) self.H11layout = QHBoxLayout() self.H2layout = QHBoxLayout() self.V11layout = QVBoxLayout() self.V12layout = QVBoxLayout() self.V21layout = QVBoxLayout() self.V23layout = QVBoxLayout() self.V22layout = QVBoxLayout() #------------------------------------ # Create Widgets for H1layout # Create Browser self.plotter = SniffPlot(self.snifferConfig) self.rangeslider = QRangeSlider(self) self.filterGroup = QButtonGroup() self.localFilterRadio = QRadioButton('Local',self) self.globalFilterRadio = QRadioButton('Global', self) self.configureFilterButt = QPushButton('Configure Filter') self.createPlotButt = QPushButton('Create Plot') self.exportPlotButt = QPushButton('Export Plot') # We need to sync the UI before connecting any slots in order to prevent accidental stateChanges. self.syncUiToConfig() self.configureFilterButt.clicked.connect(self.configureFilter) self.createPlotButt.clicked.connect(self.createPlot) self.exportPlotButt.clicked.connect(self.exportPlot) self.localFilterRadio.clicked.connect(self.localRadioSelected) self.globalFilterRadio.clicked.connect(self.globalRadioSelected) self.H11layout.addWidget(self.localFilterRadio) self.H11layout.addWidget(self.globalFilterRadio) self.H11layout.addWidget(self.createPlotButt) self.H11layout.addWidget(self.exportPlotButt) self.V12layout.addLayout(self.H11layout) self.V12layout.addWidget(self.configureFilterButt) self.H1layout.addLayout(self.V11layout) self.H1layout.addStretch() self.H1layout.addLayout(self.V12layout) self.plotWindowStart=QDoubleSpinBox(self) self.plotWindowEnd=QDoubleSpinBox(self) self.plotWindowResetStart=QPushButton(self) self.plotWindowResetEnd=QPushButton(self) self.plotWindowResetStart.pressed.connect(self.plotter.resetStart) self.plotWindowResetEnd.pressed.connect(self.plotter.resetEnd) self.plotWindowResetStart.setText("R") self.plotWindowResetEnd.setText("R") self.plotWindowStart.setSuffix("ms") self.plotWindowEnd.setSuffix("ms") self.plotWindowStartLabel=QLabel(self) self.plotWindowDurationLabel=QLabel(self) self.plotWindowEndLabel=QLabel(self) self.applyRange=QPushButton(None) self.applyRange.setText("Apply Range") self.H2layout.addLayout(self.V21layout) self.H2layout.addWidget(self.plotWindowResetStart) self.H2layout.addStretch() self.H2layout.addLayout(self.V22layout) self.H2layout.addStretch() self.H2layout.addWidget(self.plotWindowResetEnd) self.H2layout.addLayout(self.V23layout) self.V21layout.addWidget(self.plotWindowStart) self.V21layout.addWidget(self.plotWindowStartLabel) self.V22layout.addWidget(self.applyRange) self.V22layout.addWidget(self.plotWindowDurationLabel) self.V23layout.addWidget(self.plotWindowEnd) self.V23layout.addWidget(self.plotWindowEndLabel) #------------------------------------ self.VLayout.addLayout(self.H1layout) self.VLayout.addWidget(self.plotter) self.VLayout.addWidget(self.rangeslider) self.VLayout.addLayout(self.H2layout) self.applyRange.pressed.connect(self.plotter.applyRange) self.plotter.setScrollbar(self.rangeslider) self.plotter.setWindowSpinner(self.plotWindowStart,self.plotWindowEnd) self.plotter.setRangeLabels(self.plotWindowStartLabel,self.plotWindowEndLabel,self.plotWindowDurationLabel) self.dockContents.setLayout(self.VLayout) ## Get Task name from Task-ID def getTaskName(self,taskid): return "Task-"+str(taskid) ### Export plot to PNG image def exportPlot(self): # Create dummy SniffPlot with light Theme self.plotterExport = SniffPlot(self.snifferConfig) self.plotterExport.setStyleSheet("background-color: rgb(255, 255, 255);") self.plotterExport.setOverrideStyle("Light") self.plotterExport.endTime=self.plotter.endTime self.plotterExport.endTime_=self.plotter.endTime_ self.plotterExport.startTime=self.plotter.startTime self.plotterExport.startTime_=self.plotter.startTime_ self.plotterExport.data=self.plotter.data self.plotterExport.ntask=self.plotter.ntask self.plotterExport.plotStart=self.plotter.plotStart self.plotterExport.plotEnd=self.plotter.plotEnd self.plotterExport.taskcols=self.plotter.taskcols self.plotterExport.resize(1050,750) # Create image to fit Plot pixmap=QtGui.QPixmap(self.plotterExport.size()); # Render Widget to QPixMap and safe file self.plotterExport.render(pixmap) filename, ok = QFileDialog.getSaveFileName(self, 'Save Plot', 'Plot.png', 'PNG files (*.png)') if filename and ok: pixmap.save(filename); del self.plotterExport del pixmap ## Generate actual plot def displayFunction(self,timerValueInMs_extern,payloadList): knownTasks={} #All known tasks which will be displayed in the plot readyTasks={} #Saves the ready-state of a task dataFrame=[] filteredPayloads = [] eventWidth=1 #Width of an displayed Event in ms overflowCounter=0 #Counts how often the tickOverflowValue is surpassed tickOverflow = int(Globals.dockDict['dockConfig'].snifferConfig.configMaxTickCountVal) #value of tick-overflow in normal ticks timerValueInMs=1/timerValueInMs_extern previousElementTickCount=self.getTickCount(payloadList[0].payloadHead) #Reads the start Time previousElement=payloadList[0] print('I have Payloads len:' + str(len(payloadList))) print('I have filtered len:' + str(len(filteredPayloads))) self.task_state_changes=defaultdict(list) self.end_time=0 self.start_time=None for element in payloadList: #for each element in the payload list if element.payloadHead.informationID is 148: continue if element.payloadHead.informationID is 149: continue if element.payloadHead.informationID is 150: continue if hasattr(element, 'payloadHead'):# and hasattr(element,"data1"): if previousElementTickCount-self.getTickCount(element.payloadHead)==int(Globals.dockDict['dockConfig'].snifferConfig.configMaxTickCountVal): #Checks for overflow overflowCounter = overflowCounter+1 previousElementTickCount=self.getTickCount(element.payloadHead) previousElement=element #rememver previousElement if element.payloadHead.informationID is 44: continue #get Data from element infoid=Globals.tspDict[element.payloadHead.informationID][0] timestamp=self.getTickCount(element.payloadHead)+\ overflowCounter*tickOverflow+\ self.getTimerValue(element.payloadHead)*timerValueInMs #skip Ticks if infoid=='ID_TASK_INCREMENT_TICK': continue #Task state from InfoID state2str={ 'ID_TASK_SWITCHED_OUT': "waiting", 'ID_MOVED_TASK_TO_READY_STATE': "ready", 'ID_TASK_SWITCHED_IN': "running" } #update task state and timestamp if infoid in ['ID_TASK_SWITCHED_OUT', 'ID_MOVED_TASK_TO_READY_STATE', 'ID_TASK_SWITCHED_IN']: task_id=element.data1 self.task_state_changes[task_id].append({"time":timestamp,"state":state2str[infoid]}) else: self.task_state_changes[99999].append({"time":timestamp,"state":infoid}) if timestamp>self.end_time: self.end_time=timestamp if self.start_time is None or timestamp<self.start_time: self.start_time=timestamp #save data and send to Plotter self.task_state_changes=dict(self.task_state_changes) self.plotter.update_data(self.task_state_changes,self.end_time,self.start_time) ## Handler for "Create Plot" button def createPlot(self): if(len(Globals.payloadList) == 0): self.displayException('The PayloadList is empty. Run a measurement?') return self.displayFunction(timerValueInMs_extern = int(Globals.dockDict['dockConfig'].snifferConfig.configTickToMsLine),payloadList = Globals.payloadList) ## Enable all buttons def disableButtons(self): self.saveMeasButt.setEnabled(False) self.openMeasButt.setEnabled(False) print('Disable TabStart Buttons') ## Disable all buttons def enableButtons(self): self.saveMeasButt.setEnabled(True) self.openMeasButt.setEnabled(True) print('Enable TabStart Buttons') ## Display status message def displayStatusMessage(self,myMessage): self.statusBox.setText('Message: ' + myMessage) ## Change waitForReset state def waitResetCheckChanged(self): self.snifferConfig.configWaitResetCheck ^= 1 self.logger.logEvent('changed Wait for Reset Checkbox to - '+ str(self.snifferConfig.configWaitResetCheck)) ## Select local Filter def localRadioSelected(self): self.snifferConfig.configFilterState = 'Local' self.logger.logEvent('changed Filter Radio to - '+ str(self.snifferConfig.configFilterState)) ## Select global Filter def globalRadioSelected(self): self.snifferConfig.configFilterState = 'Global' self.logger.logEvent('changed Filter Radio to - '+ str(self.snifferConfig.configFilterState)) ## Get TickCount from Header def getTickCount(self,payloadHeader): return payloadHeader.tickCountHigh << 8 | payloadHeader.tickCountLow ## Get TimerValue from Hader def getTimerValue(self,payloadHeader): if Globals.dockDict['dockConfig'].snifferConfig.configUpDownState == 'Up': return payloadHeader.timerByteHigh << 8 | payloadHeader.timerByteLow elif Globals.dockDict['dockConfig'].snifferConfig.configUpDownState == 'Down': return int(Globals.dockDict['dockConfig'].snifferConfig.configMaxTickCountVal) - (payloadHeader.timerByteHigh << 8 | payloadHeader.timerByteLow) else: self.logger.logEvent('Error in getTimerValue in PlotTab') return 0 # --- MANDATORY UI FUNCTIONS --- # # -------------------------------# ## Read out all components of snifferConfig and set the UI elements according to # the saved values. def syncUiToConfig(self): if self.snifferConfig.configFilterState == 'Local': self.localFilterRadio.click() elif self.snifferConfig.configFilterState == 'Global': self.globalFilterRadio.click() else: print('Error, neither local nor global in config') ## Open the correct filter based on the radioButton. If the Global-filter is checked # we assign its calledby variable in order to execute the right callback after the filter is saved. def configureFilter(self): if self.localFilterRadio.isChecked(): self.snifferFilter.show() elif self.globalFilterRadio.isChecked(): print('stump implementation for global filter') else: print('neither radios checked. Error!') ## CB: // Updates the UI-contents with after filtering has taken place. # This function should not be called by the tab itself, but by the filter # @param filteredIDs the IDs that are to be kept in the payloadList (obsolete) # @param filteredPayloads the new payloadList, which only contains the payloads filtered by the SnifferFilter def filterUpdated(self, filteredIDs, filteredPayloads): print('we arrive from SnifferFilter') if(len(Globals.payloadList) == 0): self.displayException('The PayloadList is empty. Run a measurement?') return self.displayFunction(timerValueInMs_extern = int(Globals.dockDict['dockConfig'].snifferConfig.configTickToMsLine),payloadList = filteredPayloads)
class RequestsOperations(QWidget): def __init__(self, parent): super().__init__(parent) self.initUI() self.__ops = [] def initUI(self): self.layout = QFormLayout() self.layout.setFieldGrowthPolicy(QFormLayout.ExpandingFieldsGrow) self.layout.setLabelAlignment(Qt.AlignLeft) self.layout.setFormAlignment(Qt.AlignLeft | Qt.AlignTop) twoListsOfSets = QWidget() twoListsOfSets.setLayout(QHBoxLayout()) twoListsOfSets.layout().setContentsMargins(5, 10, 5, 5) twoListsOfSets.layout().setSpacing(0) effect = QGraphicsDropShadowEffect() effect.setBlurRadius(10) effect.setColor(QColor(0, 0, 0, 160)) effect.setOffset(0.0) self.requestList = QListView() self.requestList.setSpacing(3) self.requestList.setAutoFillBackground(True) self.requestList.setGraphicsEffect(effect) self.requestList.setFrameStyle(QFrame.NoFrame) self.requestList.viewport().setAutoFillBackground(False) self.requestList.setFlow(QListView.LeftToRight) self.requestList.setWrapping(True) self.requestList.setResizeMode(QListView.Adjust) self.requestList.setUniformItemSizes(True) self.requestsModel = QStandardItemModel() self.requestList.setModel(self.requestsModel) effect = QGraphicsDropShadowEffect() effect.setBlurRadius(10) effect.setColor(QColor(0, 0, 0, 160)) effect.setOffset(0.0) self.requestList2 = QListView() self.requestList2.setSpacing(3) self.requestList2.setAutoFillBackground(True) self.requestList2.setGraphicsEffect(effect) self.requestList2.setFrameStyle(QFrame.NoFrame) self.requestList2.viewport().setAutoFillBackground(False) self.requestList2.setFlow(QListView.LeftToRight) self.requestList2.setWrapping(True) self.requestList2.setResizeMode(QListView.Adjust) self.requestList2.setUniformItemSizes(True) self.requestsModel2 = QStandardItemModel() self.requestList2.setModel(self.requestsModel2) twoListsOfSets.layout().addWidget(self.requestList) twoListsOfSets.layout().addWidget(self.requestList2) self.layout.addRow("SETS", twoListsOfSets) self.layout.addRow(HorizontalLine(self)) self.operationSelection = QGroupBox() self.operationSelection.setFlat(True) self.operationSelection.setLayout(QVBoxLayout()) self.buttonIntersection = QRadioButton("Intersection") self.operationSelection.layout().addWidget(self.buttonIntersection) self.buttonIntersection.clicked.connect( self.__disableSecondRequestList) self.buttonIntersection.click() self.buttonUnion = QRadioButton("Union") self.operationSelection.layout().addWidget(self.buttonUnion) self.buttonUnion.clicked.connect(self.__disableSecondRequestList) self.buttonDiff = QRadioButton("Difference") self.operationSelection.layout().addWidget(self.buttonDiff) self.buttonDiff.clicked.connect(self.__enableSecondRequestList) self.layout.addRow("OPERATION", self.operationSelection) self.buttonApplyWidget = QWidget() self.buttonApplyWidget.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred) self.buttonApplyLayout = QHBoxLayout() self.buttonApplyLayout.setContentsMargins(0, 0, 0, 0) self.buttonApplyWidget.setLayout(self.buttonApplyLayout) self.buttonApply = QPushButton("Apply") self.buttonApply.clicked.connect(self.__applyOp) self.operationSelection.layout().addWidget(self.buttonApply) self.buttonApplyLayout.addWidget(self.buttonApply, alignment=Qt.AlignRight) self.layout.addRow("", self.buttonApplyWidget) self.layout.addRow(HorizontalLine(self)) self.layout.addRow("RESULTS", None) self.resultingSets = QTableView() self.resultingSets.horizontalHeader().setSectionResizeMode( QHeaderView.Stretch) self.resultingSets.verticalHeader().setSectionResizeMode( QHeaderView.ResizeToContents) self.resultingSets.setModel(OperationsTableModel()) self.layout.addRow(self.resultingSets) self.layout.addRow(HorizontalLine(self)) self.outputSetSelection = QComboBox() self.outputSetSelection.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Fixed) self.layout.addRow("OUTPUT SET", self.outputSetSelection) self.setLayout(self.layout) def outputSet(self): return self.outputSetSelection.currentText() def setOutputSet(self, outputSetName): self.outputSetSelection.setCurrentText(outputSetName) @property def ops(self): return copy.deepcopy(self.__ops) def __applyOp(self): includedSets = [ self.requestsModel.item(i).text() for i in range(self.requestsModel.rowCount()) if self.requestsModel.item(i).data(Qt.CheckStateRole) == QVariant( Qt.Checked) ] if self.buttonUnion.isChecked(): if len(includedSets) > 1: opName = SetNameManagement.getUniqueSetName() self.addOp(OverpassUnion(opName), includedSets) logging.info("Union created.") else: logging.error("The union must have at least two sets.") elif self.buttonIntersection.isChecked(): if len(includedSets) > 1: opName = SetNameManagement.getUniqueSetName() self.addOp(OverpassIntersection(opName), includedSets) logging.info("Intersection created.") else: logging.error("The intersection must have at least two sets.") elif self.buttonDiff.isChecked(): excludedSets = [ self.requestsModel2.item(i).text() for i in range(self.requestsModel2.rowCount()) if self.requestsModel2.item(i).data(Qt.CheckStateRole) == QVariant(Qt.Checked) ] if len(includedSets) == 1 and len(excludedSets) > 0: opName = SetNameManagement.getUniqueSetName() self.addOp(OverpassDiff(includedSets[0], opName), excludedSets) logging.info("Difference created.") else: logging.error( "The difference must have only one set selected in the first list and at least one in the other." ) logging.debug("LINE") def addOp(self, op, sets=None): SetNameManagement.assign(op.name) self.__ops.append(op) if sets is not None: op.addSets(sets) self.resultingSets.model().addOp(op.name, op) self.addRequest(op.name) self.cleanRequestList() def __enableSecondRequestList(self): self.requestList2.show() def __disableSecondRequestList(self): self.requestList2.hide() def addRequest(self, name): self.requestsModel.beginInsertRows(QModelIndex(), self.requestsModel.rowCount(), self.requestsModel.rowCount()) item = QStandardItem(name) item.setFlags(Qt.ItemIsUserCheckable | Qt.ItemIsEnabled) item.setData(QVariant(Qt.Unchecked), Qt.CheckStateRole) self.requestsModel.appendRow(item) self.requestsModel.endInsertRows() self.requestsModel2.beginInsertRows(QModelIndex(), self.requestsModel2.rowCount(), self.requestsModel2.rowCount()) item = QStandardItem(name) item.setFlags(Qt.ItemIsUserCheckable | Qt.ItemIsEnabled) item.setData(QVariant(Qt.Unchecked), Qt.CheckStateRole) self.requestsModel2.appendRow(item) self.requestsModel2.endInsertRows() self.outputSetSelection.addItem(name) def removeSetAndDependencies(self, setName): removeList = [setName] for set in removeList: logging.info("Removing set '{}'.".format(set)) removeList.extend( [i for i in self.__removeSet(set) if i not in removeList]) logging.debug("LINE") def __removeSet(self, setName): dependencies = [] for op in self.__ops: op.removeSet(setName) if not op.isValid(): dependencies.append(op.name) for i in range(self.requestsModel.rowCount()): if self.requestsModel.item(i).text() == setName: self.requestsModel.beginRemoveRows(QModelIndex(), i, i) self.requestsModel.removeRow(i) self.requestsModel.endInsertRows() self.requestsModel2.beginRemoveRows(QModelIndex(), i, i) self.requestsModel2.removeRow(i) self.requestsModel2.endInsertRows() self.outputSetSelection.removeItem(i) break for op in self.__ops: if op.name == setName: self.resultingSets.model().removeOp(setName) self.__ops.remove(op) break SetNameManagement.releaseName(setName) return dependencies def reset(self): while len(self.ops) > 0: self.removeSetAndDependencies(self.ops[0].name) def cleanRequestList(self): for i in range(self.requestsModel.rowCount()): self.requestsModel.item(i).setData(QVariant(Qt.Unchecked), Qt.CheckStateRole) self.requestsModel2.item(i).setData(QVariant(Qt.Unchecked), Qt.CheckStateRole) def keyPressEvent(self, event): if event.key() == Qt.Key_Backspace and self.resultingSets.hasFocus(): advice = "Are you sure?\nAll sets containing this one will be deleted if they are no longer valid" reply = QMessageBox.question(self, "Remove request operation", advice) if reply == QMessageBox.Yes: select = self.resultingSets.selectionModel() while len(select.selectedRows()) > 0: self.removeSetAndDependencies( self.resultingSets.model().getOpByIndex( select.selectedRows()[0].row())) event.accept()
class MainWindow(QMainWindow): """ Represents main window that extends QMainWindow and that is used for interaction with user. """ def __init__(self, faces_number, draw_rectangles, parent=None): """Initializes main window. :param self: self :param faces_number: number of expected faces in frame :param draw_rectangles: indicator whether rectangles that bound detected faces should be drawn :param parent: parent of window """ super(MainWindow, self).__init__(parent) self.setWindowTitle("FaceSnap") self.setWindowIcon(QIcon("stickers/icon.png")) self.faces_number = faces_number self.draw_rectangles = draw_rectangles self.file_name = "" self.chosen_filter = "" self.processing = False self.layout = QVBoxLayout() # layout for the central widget widget = QWidget(self) # central widget widget.setLayout(self.layout) self.setGeometry(0, 0, 650, 550) self.center_on_screen() self.existing_video_layout = QHBoxLayout() # layout for existing video self.existing_video_widget = QWidget() self.existing_video_widget.setLayout(self.existing_video_layout) self.cam_video_layout = QHBoxLayout() # layout for recorder video self.cam_video_widget = QWidget() self.cam_video_widget.setLayout(self.cam_video_layout) self.choice_group = QButtonGroup( widget) # radio button group for input file choice self.filter_group = QButtonGroup( widget) # radio button group for filter choice self.existing_video_radio = QRadioButton("Choose existing video") self.existing_video_button = QPushButton("Choose video file") self.cam_video_radio = QRadioButton("Capture video with camera") self.cam_video_button = QPushButton("Record video") self.mask_button = QRadioButton() self.cat_button = QRadioButton() self.ears_button = QRadioButton() self.flowers_button = QRadioButton() self.mustache_button = QRadioButton() self.glasses_button = QRadioButton() self.mouse_button = QRadioButton() self.pirate_button = QRadioButton() self.rainbow_button = QRadioButton() self.init_video_choice() self.init_filter_choice() self.process_button = QPushButton("Process video") self.process_button.clicked.connect(self.process_chosen_video) self.layout.addWidget(QWidget()) self.layout.addWidget(QWidget()) self.layout.addWidget(QWidget()) self.layout.addWidget(self.process_button) self.layout.addWidget(QWidget()) self.status = QStatusBar() self.layout.addWidget(self.status) self.setCentralWidget(widget) def center_on_screen(self): """Centers window on screen. :param self: self """ resolution = QDesktopWidget().screenGeometry() self.move( (resolution.width() / 2) - (self.frameSize().width() / 2), (resolution.height() / 4 + 20) - (self.frameSize().height() / 2)) def init_video_choice(self): """Initializes radio button group for video choice. :param self: self """ self.cam_video_radio.clicked.connect(self.cam_video_chosen) self.choice_group.addButton(self.cam_video_radio) self.existing_video_radio.clicked.connect(self.existing_video_chosen) self.choice_group.addButton(self.existing_video_radio) self.existing_video_button.clicked.connect(self.open_file) self.existing_video_layout.addWidget(self.existing_video_radio) self.existing_video_layout.addWidget(self.existing_video_button) self.cam_video_button.clicked.connect(self.record_video) self.cam_video_layout.addWidget(self.cam_video_radio) self.cam_video_layout.addWidget(self.cam_video_button) self.layout.addWidget(self.existing_video_widget) self.layout.addWidget(self.cam_video_widget) self.existing_video_radio.click() def init_filter_choice(self): """Initializes radio button group for filter choice. :param self: self """ self.layout.addWidget(QWidget()) self.layout.addWidget(QWidget()) sticker_rows = QVBoxLayout() first_row_layout = QHBoxLayout() first_row_widget = QWidget() first_row_widget.setLayout(first_row_layout) second_row_layout = QHBoxLayout() second_row_widget = QWidget() second_row_widget.setLayout(second_row_layout) third_row_layout = QHBoxLayout() third_row_widget = QWidget() third_row_widget.setLayout(third_row_layout) sticker_rows.addWidget(first_row_widget) sticker_rows.addWidget(second_row_widget) sticker_rows.addWidget(third_row_widget) filter_widget = QWidget() filter_widget.setLayout(sticker_rows) self.init_first_row_filters(first_row_layout) self.init_second_row_filters(second_row_layout) self.init_third_row_filters(third_row_layout) self.layout.addWidget(filter_widget) def init_first_row_filters(self, first_row_layout): """Initializes first row of radio button group for filter choice. :param self: self :param first_row_layout: layout for first row of filters """ self.mask_button.clicked.connect(self.filter_chosen) self.filter_group.addButton(self.mask_button) self.mask_button.setIcon(QIcon(stickers.mask_sticker())) first_row_layout.addWidget(self.mask_button) # add mask to widget first_row_layout.addWidget(QWidget()) # add empty space self.cat_button.clicked.connect(self.filter_chosen) self.filter_group.addButton(self.cat_button) self.cat_button.setIcon(QIcon(stickers.cat_sticker())) first_row_layout.addWidget(self.cat_button) # add cat to widget first_row_layout.addWidget(QWidget()) # add empty space self.ears_button.clicked.connect(self.filter_chosen) self.filter_group.addButton(self.ears_button) self.ears_button.setIcon(QIcon(stickers.ears_sticker())) first_row_layout.addWidget(self.ears_button) # add ears to widget def init_second_row_filters(self, second_row_layout): """Initializes second row of radio button group for filter choice. :param self: self :param second_row_layout: layout for second row of filters """ self.flowers_button.clicked.connect(self.filter_chosen) self.filter_group.addButton(self.flowers_button) self.flowers_button.setIcon(QIcon(stickers.flowers_sticker())) second_row_layout.addWidget( self.flowers_button) # add flowers to widget second_row_layout.addWidget(QWidget()) # add empty space self.mustache_button.clicked.connect(self.filter_chosen) self.filter_group.addButton(self.mustache_button) self.mustache_button.setIcon(QIcon(stickers.mustache_sticker())) second_row_layout.addWidget( self.mustache_button) # add mustache to widget second_row_layout.addWidget(QWidget()) # add empty space self.glasses_button.clicked.connect(self.filter_chosen) self.filter_group.addButton(self.glasses_button) self.glasses_button.setIcon(QIcon(stickers.glasses_sticker())) second_row_layout.addWidget( self.glasses_button) # add glasses to widget def init_third_row_filters(self, third_row_layout): """Initializes third row of radio button group for filter choice. :param self: self :param third_row_layout: layout for third row of filters """ self.mouse_button.clicked.connect(self.filter_chosen) self.filter_group.addButton(self.mouse_button) self.mouse_button.setIcon(QIcon(stickers.mouse_sticker())) third_row_layout.addWidget(self.mouse_button) # add mouse to wiget third_row_layout.addWidget(QWidget()) # add empty space self.pirate_button.clicked.connect(self.filter_chosen) self.filter_group.addButton(self.pirate_button) self.pirate_button.setIcon(QIcon(stickers.pirate_sticker())) third_row_layout.addWidget(self.pirate_button) # add pirate to widget third_row_layout.addWidget(QWidget()) # add empty space self.rainbow_button.clicked.connect(self.filter_chosen) self.filter_group.addButton(self.rainbow_button) self.rainbow_button.setIcon(QIcon(stickers.rainbow_sticker())) third_row_layout.addWidget( self.rainbow_button) # add rainbow to widget def filter_chosen(self): """Detects which filter is chosen. :param self: self """ if self.mask_button.isChecked(): self.chosen_filter = "mask" elif self.cat_button.isChecked(): self.chosen_filter = "cat" elif self.ears_button.isChecked(): self.chosen_filter = "ears" elif self.flowers_button.isChecked(): self.chosen_filter = "flowers" elif self.mustache_button.isChecked(): self.chosen_filter = "mustache" elif self.glasses_button.isChecked(): self.chosen_filter = "glasses" elif self.mouse_button.isChecked(): self.chosen_filter = "mouse" elif self.pirate_button.isChecked(): self.chosen_filter = "pirate" elif self.rainbow_button.isChecked(): self.chosen_filter = "rainbow" else: self.chosen_filter = "" def process_chosen_video(self): """Starts processing chosen video and informs user about process success. :param self: self """ if self.file_name == "": print("Video for processing is not chosen!") self.status.showMessage("Video for processing is not chosen!") else: if self.processing: self.status.showMessage("Processing video in progress!") else: self.processing = True self.status.showMessage("Processing video in progress!") if process_video(self.file_name, self.faces_number, self.draw_rectangles, self.chosen_filter, self): self.status.showMessage("Processing video is successful!") self.processing = False else: self.status.showMessage("Error opening video!") self.processing = False def existing_video_chosen(self): """Disables cam video button and enables existing video button. :param self: self """ self.cam_video_button.setEnabled(False) self.existing_video_button.setEnabled(True) def cam_video_chosen(self): """Enables cam video button and disables existing video button. :param self: self """ self.cam_video_button.setEnabled(True) self.existing_video_button.setEnabled(False) def open_file(self): """Opens dialog for file choice. :param self: self """ self.file_name, _ = QFileDialog.getOpenFileName( self, "Open Video", QDir.homePath()) if self.file_name != "": print(self.file_name) self.status.showMessage("Video successfully chosen!") def record_video(self): """Opens dialog for directory choice where file is saved. :param self: self """ self.file_name = str( QFileDialog.getExistingDirectory( self, "Select Directory Where Video Will Be Saved", QDir.homePath())) if self.file_name != '': self.file_name += "/output_video.avi" print(self.file_name) self.file_name = record_from_camera(self.file_name, self) self.status.showMessage("Video successfully recorded!")
def __types_block(self, name): """ Makes block for twilight data selection: [radio buttons: {none, scrape, import}] [browse button (for import), path (for import)] Label not included (combo box contains) :param name: of type of data :return: widget of block, button group of radio buttons, line edit of path """ layout = QVBoxLayout() top_row_layout = QHBoxLayout() button_group = QButtonGroup() # radio buttons button_group.setExclusive(True) none_button = QRadioButton("None") scrape_button = QRadioButton("Scrape") import_button = QRadioButton("Import") button_group.addButton(none_button, 1) # need 1-index because 0 means not found button_group.addButton(scrape_button, 2) button_group.addButton(import_button, 3) top_row_layout.addWidget(none_button) top_row_layout.addWidget(scrape_button) top_row_layout.addWidget(import_button) top_row_layout.addStretch() button_group.buttonClicked.connect( lambda current: self.update_combo_label_clicked(current)) self.combo_box.setCurrentIndex(self.types.index(name)) if name in {"Sun", "Moon", "Nautical" }: # default setting for Paul Revere Battalion slides scrape_button.setChecked(True) scrape_button.click() else: none_button.setChecked(True) none_button.click() top_row = QWidget() top_row.setLayout(top_row_layout) bottom_row_layout = QHBoxLayout() button = QPushButton("Browse") # browse button abbrev_path = QLineEdit() # line for import path full_path = MutableString("") bottom_row_layout.addWidget(button) bottom_row_layout.addWidget(abbrev_path) button.clicked.connect(lambda: self.set_path(abbrev_path, full_path)) abbrev_path.textEdited.connect( lambda: self.set_path(abbrev_path, full_path, abbrev_path.text())) bottom_row = QWidget() bottom_row.setLayout(bottom_row_layout) layout.addWidget(top_row) layout.addWidget(bottom_row) out = QWidget() out.setLayout(layout) layout.setContentsMargins(0, 0, 0, 0) layout.setSpacing(0) top_row_layout.setContentsMargins(0, 0, 5, 0) bottom_row_layout.setContentsMargins(0, 0, 0, 0) bottom_row_layout.setSpacing(5) return out, button, button_group, abbrev_path, full_path
class LayoutPlugin(MainWindowPlugin): def __init__(self, main_window, announces, api): super().__init__(main_window, announces, api) self.topology_ratio = QRadioButton('拓扑布局', main_window) self.physical_ratio = QRadioButton('物理布局', main_window) self.group_box = QButtonGroup(main_window) self.group_box.addButton(self.topology_ratio) self.group_box.addButton(self.physical_ratio) self.group_box.buttonClicked.connect(self.buttonClickedSlot) tool_bar = QToolBar(main_window) tool_bar.setWindowTitle('位置工具栏') tool_bar.addWidget(self.topology_ratio) tool_bar.addWidget(self.physical_ratio) main_window.addToolBar(Qt.TopToolBarArea, tool_bar) self.topology_layout = None self.last_clicked_ratio = None self.pixmap = QPixmap(BACKGROUND_MAP_IMAGE) announces['playSteps'].append(self.playSteps) announces['sceneNodeMoved'].append(self.sceneNodeMoved) def playSteps(self, steps): if self.group_box.checkedButton() is None: # 设置默认模式 self.topology_layout = self._getTopologyLayout() self.topology_ratio.click( ) # 导致 self.buttonClickedSlot(self.topology_ratio) elif self.group_box.checkedButton() is self.physical_ratio: # 物理位置图 self.buttonClickedSlot(self.physical_ratio) # 重新加载位置图, 以更新位置信息 def buttonClickedSlot(self, ratio): if (ratio is self.topology_ratio) and (ratio is self.last_clicked_ratio): self.topology_layout = self._getTopologyLayout() # 多次点击, 重新计算位置 self.api['Scene.setBackgroundPixmap'](self.getBackgroundPixmap()) self.api['Scene.setLayout'](self.getLayout()) self.last_clicked_ratio = ratio def sceneNodeMoved(self, node_id, pos): if self.group_box.checkedButton() is self.topology_ratio: self.topology_layout[node_id] = pos # 拓扑图模式下修改缓存的位置信息 elif self.group_box.checkedButton() is self.physical_ratio: icn_node = self.api['Sim.node'](node_id) icn_node.pos = pos # 物理图模式下修改节点实际位置 self.announces['playSteps'](0) else: # 没有模式被设置 pass # ------------------------------------------------------------------------- def getLayout(self): if self.group_box.checkedButton() is self.topology_ratio: return self.topology_layout elif self.group_box.checkedButton() is self.physical_ratio: return self._getPhysicalLayout() else: # 没有模式被设置 pass def getBackgroundPixmap(self): if self.group_box.checkedButton() is self.topology_ratio: return None elif self.group_box.checkedButton() is self.physical_ratio: return self.pixmap else: # 没有模式被设置 pass # ------------------------------------------------------------------------- def _getPhysicalLayout(self) -> dict: graph = self.api['Sim.graph']() layout = {} for node_id in graph: icn_node = self.api['Sim.node'](node_id) layout[node_id] = getattr(icn_node, 'pos', (0, 0)) return layout def _getTopologyLayout(self) -> dict: graph = self.api['Sim.graph']() layout = networkx.spring_layout(graph, scale=300, iterations=50) # scale 单位pix # FIXME spring_layout 中, 利用已有pos迭代, 会出现扭曲. 参数: pos= self.topology_layout return layout
class MainWindow(QMainWindow): def __init__(self, *args, **kwargs): QMainWindow.__init__(self, *args, **kwargs) self.extension = '.jpg' self.image_width, self.image_height = 1280, 720 # self.image_width, self.image_height = 640, 360 # Widget de Imagen. self.image_widget = ImageWidget(self.image_width, self.image_height) # Widget de seleccion de tracker. self.tracker_combobox = ComboBoxWidget('./config/tracker_list.txt') self.tracker_groupBox = self.create_groupBox_from_widget('Tracker', self.tracker_combobox) # Widget de seleccion de clase. self.class_list = ListWidget('./config/class_list.txt') self.class_groupBox = self.create_groupBox_from_widget('Classes', self.class_list) # Botones de acciones. self.radio_track = QRadioButton(utils.MODE_DICT[utils.MODE_TRACK]) self.radio_rtrack = QRadioButton(utils.MODE_DICT[utils.MODE_RTRACK]) self.radio_copy = QRadioButton(utils.MODE_DICT[utils.MODE_COPYBBOX]) self.radio_empty = QRadioButton(utils.MODE_DICT[utils.MODE_EMPTY]) self.radio_nothing = QRadioButton(utils.MODE_DICT[utils.MODE_NOTHING]) self.group_box = self.create_button_group() # Botones de ejecucion. self.button_prev = QPushButton('Prev') self.button_next = QPushButton('Next') self.button_run = QPushButton('Run') self.button_stop = QPushButton('Stop') # Folder reader. self.folder_reader = FolderReader() # Exportar txt a xml. self.xml_creator = XMLCreator('./imagen', self.extension) # Main controller. self.controller = Controller(self, self.extension) self.controller.set_classes(self.class_list.get_items()) # Shortcuts. self.shortcut_next = QShortcut(QKeySequence('D'), self) self.shortcut_prev = QShortcut(QKeySequence('A'), self) self.shortcut_1 = QShortcut(QKeySequence('1'), self) self.shortcut_2 = QShortcut(QKeySequence('2'), self) self.shortcut_3 = QShortcut(QKeySequence('3'), self) self.shortcut_4 = QShortcut(QKeySequence('4'), self) self.shortcut_5 = QShortcut(QKeySequence('5'), self) self.shortcut_6 = QShortcut(QKeySequence('6'), self) self.shortcut_7 = QShortcut(QKeySequence('7'), self) self.shortcut_8 = QShortcut(QKeySequence('8'), self) self.shortcut_9 = QShortcut(QKeySequence('9'), self) self.setup_ui() self.setup_signals() def setup_signals(self): # Mode signals. self.radio_track.clicked.connect(self.controller.update_mode_to_track) self.radio_rtrack.clicked.connect(self.controller.update_mode_to_rtrack) self.radio_copy.clicked.connect(self.controller.update_mode_to_copybbox) self.radio_empty.clicked.connect(self.controller.update_mode_to_empty) self.radio_nothing.clicked.connect(self.controller.update_mode_to_nothing) # Class selection signals. self.class_list.currentTextChanged.connect(self.controller.set_current_class) self.controller.change_color_index.connect(self.image_widget.update_current_color_index) # Tracker selection signals. self.tracker_combobox.currentTextChanged.connect(self.controller.set_tracker_name) # Get BBoxes. self.button_next.clicked.connect(self.controller.request_next) self.button_prev.clicked.connect(self.controller.request_prev) self.button_run.clicked.connect(self.controller.run_tracking) self.button_stop.clicked.connect(self.controller.stop_tracking) self.controller.request_bboxes.connect(self.image_widget.emit_rectangles) self.controller.request_and_init_bboxes.connect(self.image_widget.emit_rectangles_and_init) self.image_widget.rectangles_signal.connect(self.controller.process_rectangles) # Update image. self.controller.update_filename.connect(self.image_widget.set_image_file) # Update bboxes. self.controller.rectangles_signal.connect(self.image_widget.receive_rectangles) # Remove bbox. self.controller.remove_rectangle_signal.connect(self.image_widget.remove_rectangle_slot) self.image_widget.rectangle_removed_signal.connect(self.controller.remove_rectangle_slot) # Run button timer self.controller.run_timer.timeout.connect(self.controller.request_next) # Folder change self.controller.update_image_folder.connect(self.select_folder) # Shortcuts self.shortcut_next.activated.connect(self.controller.request_next) self.shortcut_prev.activated.connect(self.controller.request_prev) self.shortcut_1.activated.connect(self.class_list.set_row_1) self.shortcut_2.activated.connect(self.class_list.set_row_2) self.shortcut_3.activated.connect(self.class_list.set_row_3) self.shortcut_4.activated.connect(self.class_list.set_row_4) self.shortcut_5.activated.connect(self.class_list.set_row_5) self.shortcut_6.activated.connect(self.class_list.set_row_6) self.shortcut_7.activated.connect(self.class_list.set_row_7) self.shortcut_8.activated.connect(self.class_list.set_row_8) self.shortcut_9.activated.connect(self.class_list.set_row_9) # Set mode self.radio_track.click() # Set current class self.controller.set_current_class(self.class_list.currentItem().text()) # Initialize first image self.image_widget.set_image_file(self.controller.get_current_frame()) # Update bbox if saved self.controller.send_saved_bboxes() # Update tracker name self.controller.set_tracker_name(self.tracker_combobox.currentText()) def setup_ui(self): main_widget = QWidget() self.setCentralWidget(main_widget) main_layout = QHBoxLayout() option_widget_layout = QVBoxLayout() option_widget_layout.addWidget(self.group_box) option_widget_layout.addWidget(self.tracker_groupBox) option_widget_layout.addWidget(self.class_groupBox) grid_button_layout = QGridLayout() grid_button_layout.addWidget(self.button_prev, 0, 0) grid_button_layout.addWidget(self.button_next, 0, 1) grid_button_layout.addWidget(self.button_run, 1, 0) grid_button_layout.addWidget(self.button_stop, 1, 1) option_widget_layout.addLayout(grid_button_layout) main_layout.addWidget(self.image_widget) main_layout.addLayout(option_widget_layout) self.centralWidget().setLayout(main_layout) # Menubar folder_action = QAction('Select Folder', self) folder_action.triggered.connect(self.controller.select_folder) export_action = QAction('Export', self) export_action.triggered.connect(self.xml_creator.export_txt_to_xml) menubar = self.menuBar() file_menu = menubar.addMenu('&File') file_menu.addAction(folder_action) file_menu.addAction(export_action) self.statusBar().showMessage('') def create_button_group(self): group_box = QGroupBox('Modo') self.radio_track.setChecked(True) vbox = QVBoxLayout() vbox.addWidget(self.radio_track) vbox.addWidget(self.radio_rtrack) vbox.addWidget(self.radio_copy) vbox.addWidget(self.radio_empty) vbox.addWidget(self.radio_nothing) vbox.addStretch(1) group_box.setLayout(vbox) return group_box def create_groupBox_from_widget(self, name, widget): group_box = QGroupBox(name) vbox = QVBoxLayout() vbox.addWidget(widget) group_box.setLayout(vbox) return group_box @pyqtSlot(str) def select_folder(self, folder): self.xml_creator.set_folder_path(folder)
class Button_Node(Node): def __init__(self, main_obg, parametrs=[ '0', 'Вкл', '50', '50', '1', '1', '0', '1', 'выкл', '1', 'Кнопка', 'None', '0' ]): super().__init__(main_obg, parametrs[10], int(parametrs[2]), int(parametrs[3])) self.main_window_obg = main_obg self.index_comand = parametrs[4] self.first_comand = parametrs[5] # Первая команда self.second_comand = parametrs[6] # Вторая команда self.btn_flag = True # Отправка первой или второй команды self.parametr_btn = False # наличие второй команды self.btn_name = parametrs[1] self.two_btn_name = parametrs[8] self.size_big_btn = float(parametrs[7]) self.mode = int( parametrs[9] ) # тип кнопки 1 - одна команда 2 - две попеременно 3 - две "нажал отпустил" self.key_state = bool(int(parametrs[12])) self.key_btn = int(parametrs[11]) if parametrs[11] != 'None' else None self.key_flag = False # |--------------------------------------------| обьявление виджетов self.big_btn = QPushButton(self.btn_name, self.main_window_obg) self.big_btn.clicked.connect(self.enter_comand) self.big_btn.pressed.connect(self.enter_comand_for_3_mode) self.text_set2 = QLabel(self.main_window_obg) self.text_set2.setText('Имя кнопки 1:') self.input_line2 = QLineEdit(self.btn_name, self.main_window_obg) self.input_line2.textChanged.connect(self.change_btn_name_1) self.input_line2.resize(60, 23) self.text_set3 = QLabel(self.main_window_obg) self.text_set3.setText('Индекс:') self.input_line3 = QLineEdit(self.index_comand, self.main_window_obg) self.input_line3.textChanged.connect(self.change_index) self.input_line3.resize(60, 23) self.text_set4 = QLabel(self.main_window_obg) self.text_set4.setText('Команда 1:') self.input_line4 = QLineEdit(self.first_comand, self.main_window_obg) self.input_line4.textChanged.connect(self.change_first_parametr) self.input_line4.resize(60, 23) self.text_set5 = QLabel(self.main_window_obg) self.text_set5.setText('Размер:') self.input_line5 = QLineEdit(str(self.size_big_btn), self.main_window_obg) self.input_line5.editingFinished.connect(self.change_size_big_btn) self.input_line5.resize(60, 23) self.rb_group = QButtonGroup(self.main_window_obg) self.rb1 = QRadioButton("Один сигнал", self.main_window_obg) self.rb1.move(50, 50) if self.mode == 1: self.rb1.click() self.rb1.clicked.connect(self.update_type) self.rb2 = QRadioButton("Два сигнала попеременно", self.main_window_obg) self.rb2.move(80, 50) if self.mode == 2: self.rb2.click() self.rb2.clicked.connect(self.update_type) self.rb3 = QRadioButton('Два сигнала "нажал-отпустил"', self.main_window_obg) self.rb3.move(120, 50) if self.mode == 3: self.rb3.click() self.rb3.clicked.connect(self.update_type) self.rb_group.addButton(self.rb1) self.rb_group.addButton(self.rb2) self.rb_group.addButton(self.rb3) self.text_set7 = QLabel(self.main_window_obg) self.text_set7.setText('Команда 2:') self.input_line7 = QLineEdit(self.second_comand, self.main_window_obg) self.input_line7.textChanged.connect(self.change_second_parametr) self.input_line7.resize(60, 23) self.text_set8 = QLabel(self.main_window_obg) self.text_set8.setText('Имя кнопки 2:') self.input_line8 = QLineEdit(self.two_btn_name, self.main_window_obg) self.input_line8.textChanged.connect(self.change_btn_name_2) self.input_line8.resize(60, 23) self.key_chekBox = QCheckBox('Использовать клавиши', self.main_window_obg) self.key_chekBox.stateChanged.connect(self.change_key_state) if self.key_state: self.key_chekBox.click() self.lit = QLabel(self.main_window_obg) if self.key_btn != None: self.lit.setText(chr(self.key_btn)) # |--------------------------------------------| # Список всех виджетов нода и их относительных координат self.arr_of_elem.extend([(self.big_btn, 0, 21), (self.text_set2, 0, 78), (self.input_line2, 84, 76), (self.text_set3, 0, 102), (self.input_line3, 46, 100), (self.text_set4, 0, 128), (self.input_line4, 66, 125), (self.text_set5, 0, 152), (self.input_line5, 50, 150), (self.rb1, 0, 170), (self.rb2, 0, 190), (self.rb3, 0, 210), (self.text_set7, 0, 232), (self.input_line7, 66, 230), (self.text_set8, 0, 257), (self.input_line8, 84, 255), (self.key_chekBox, 0, 280), (self.lit, 0, 50)]) # Список всех виджетов настроек self.elems_of_settings = [ self.text_set1, self.input_line1, self.text_set2, self.input_line2, self.input_line3, self.text_set3, self.text_set4, self.input_line4, self.text_set5, self.input_line5, self.rb1, self.rb2, self.rb3, self.text_set7, self.input_line7, self.text_set8, self.input_line8, self.key_chekBox, self.delete_btn, self.copy_btn ] # Список дополнительных настроек self.additional_widgets = [ self.text_set7, self.input_line7, self.text_set8, self.input_line8 ] for elem in self.elems_of_settings: elem.hide() self.big_btn.resize(int(100 * self.size_big_btn), int(30 * self.size_big_btn)) self.ubdate_cord(self.x, self.y) self.update_type() for elem in self.additional_widgets: elem.hide() self.change_key_state(None, self.key_btn) def del_widgets(self): if self.delete: for elem in self.arr_of_elem: elem[0].deleteLater() self.delete = False def parametrs_return(self): return [ '0', self.btn_name, str(self.x), str(self.y), self.index_comand, self.first_comand, self.second_comand, str(self.size_big_btn), self.two_btn_name, str(self.mode), self.name, str(self.key_btn), str(int(self.key_state)) ] def enter_comand(self): global ser if self.mode == 2: comand = self.left_com + self.index_comand + \ self.middle_com + self.first_comand + self.right_com if self.btn_flag else \ self.left_com + self.index_comand + \ self.middle_com + self.second_comand + self.right_com print('2', comand) if self.btn_flag: ser.write(comand.encode()) self.big_btn.setText(self.btn_name) self.btn_flag = False else: ser.write(comand.encode()) self.big_btn.setText(self.two_btn_name) self.btn_flag = True elif self.mode == 1: comand = self.left_com + self.index_comand + \ self.middle_com + self.first_comand + self.right_com self.big_btn.setText(self.btn_name) ser.write(comand.encode()) print(comand) elif self.mode == 3: comand = self.left_com + self.index_comand + \ self.middle_com + self.first_comand + self.right_com self.big_btn.setText(self.btn_name) ser.write(comand.encode()) print(comand) def enter_comand_for_3_mode(self): global ser if self.mode == 3: comand = self.left_com + self.index_comand + \ self.middle_com + self.second_comand + self.right_com self.big_btn.setText(self.two_btn_name) ser.write(comand.encode()) print(comand) def change_btn_name_1(self): self.big_btn.setText(self.input_line2.text()) self.btn_name = self.input_line2.text() self.big_btn.resize(self.big_btn.sizeHint()) def change_btn_name_2(self): self.two_btn_name = self.input_line8.text() def change_index(self): self.index_comand = self.input_line3.text() def change_parametr_btn(self): self.parametr_btn = not self.parametr_btn if self.parametr_btn: for elem in [self.text_set2]: elem.show() else: for elem in [self.text_set2]: elem.hide() def change_first_parametr(self): self.first_comand = self.input_line4.text() def change_second_parametr(self): self.second_comand = self.input_line7.text() def change_size_big_btn(self): self.size_big_btn = float(self.input_line5.text()) self.big_btn.resize(int(100 * self.size_big_btn), int(30 * self.size_big_btn)) def change_key_state(self, data, key=None, released=False): # self.key_state = not self.key_state try: if self.key_chekBox.isChecked() and key == None: self.key_state = True self.key_flag = True self.key_chekBox.setText('Нажмите на клавишу') elif key != None and self.key_flag: self.key_chekBox.setText('Нажата клавиша:' + chr(key)) self.lit.setText(chr(key)) #self.lit.resize(self.lit.sizeHint()) self.btn_flag = True self.key_btn = key self.key_flag = False elif self.key_btn == key and data != None: if self.mode == 3 and released: self.enter_comand() elif self.mode == 3 and not released: self.enter_comand_for_3_mode() elif not released: self.big_btn.click() elif not self.key_chekBox.isChecked(): self.key_btn = key self.lit.setText('') self.key_state = False self.key_chekBox.setText('Использовать клавиши') except Exception: pass def update_type(self): if self.rb1.isChecked(): self.mode = 1 self.big_btn.setCheckable(False) for elem in self.additional_widgets: elem.hide() elif self.rb2.isChecked(): self.mode = 2 self.big_btn.setCheckable(True) for elem in self.additional_widgets: elem.show() elif self.rb3.isChecked(): self.mode = 3 self.big_btn.setCheckable(False) for elem in self.additional_widgets: elem.show() def open_setings(self): if self.flag: self.settings_btn.setText('▼') self.flag = False for elem in self.elems_of_settings: elem.show() if self.mode == 1: for elem in self.additional_widgets: elem.hide() self.big_btn.resize(100, 30) self.lit.hide() else: self.settings_btn.setText('▲') self.flag = True for elem in self.elems_of_settings: elem.hide() self.big_btn.resize(int(100 * self.size_big_btn), int(30 * self.size_big_btn)) self.lit.show() def is_keyword(self): return True if self.key_state else False
class ReferenceClock(QWidget): """Race Info Setup This widget allows the user to name the race, and jot down various notes about the race. """ REFERENCE_CLOCK_POINT_SIZE = 24 def __init__(self, modeldb, parent=None): """Initialize the ReferenceClock instance.""" super().__init__(parent=parent) self.modeldb = modeldb # Cache this. We use it so often. self.race_table_model = self.modeldb.race_table_model # Time selection/synchronization modal window, shown when synchronize_button is clicked. self.time_synchronizer = TimeSynchronizer() self.time_synchronizer.setWindowModality(Qt.ApplicationModal) # There are some widgets we want to access outside of initialization, so we save them off # into "self". However, pylint is getting confused and thinks some of them are possibly # never initialized. Therefore, initialize every widget that we want to save to "None" here. # (Initialization will take care of giving them proper values after this.) self.reference_clock_radiobutton = None self.reference_datetime_label = None self.datetime_datetimeedit = None # Initialize our whole hierarchical mess of widgets. self.init_clock_selection_widget() # Force update widget contents. self.dataChanged(QModelIndex(), QModelIndex(), [Qt.DisplayRole]) # Signals/slots plumbing. self.race_table_model.dataChanged.connect(self.dataChanged) def init_clock_selection_widget(self): """Initialize the clock selection stuff. This method initializes the clock selection radio buttons, and triggers the initialization of the reference clock selection stage. There are two choices at this level: wall clock and reference clocks. """ # Clock selection (wall clock vs reference clock). clock_selection_widget = QGroupBox('Use clock:') # Chooser radio buttons and the button group. wall_clock_radiobutton = QRadioButton('Wall clock') self.reference_clock_radiobutton = QRadioButton('Reference clock') clock_source_button_group = QButtonGroup() clock_source_button_group.addButton(wall_clock_radiobutton) clock_source_button_group.addButton(self.reference_clock_radiobutton) clock_selection_widget.setLayout(QHBoxLayout()) clock_selection_widget.layout().addWidget(wall_clock_radiobutton) clock_selection_widget.layout().addWidget(self.reference_clock_radiobutton) # The latter choice, that expands to more choices. reference_clock_setup_widget = self.init_reference_clock_setup_widget() # Top-level widgets. self.setLayout(QVBoxLayout()) self.layout().addWidget(clock_selection_widget) self.layout().addWidget(reference_clock_setup_widget) # Signals/slots plumbing. self.reference_clock_radiobutton.toggled.connect(reference_clock_setup_widget.setEnabled) self.reference_clock_radiobutton.toggled.connect(self.toggle_reference_clock_setup) # Set default state. wall_clock_radiobutton.click() reference_clock_setup_widget.setEnabled(False) def init_reference_clock_setup_widget(self): """Initialize the reference clock selection stuff. This method initializes the reference clock selection radio buttons, and triggers the initialization of the manual reference clock setup stage. There are two choices at this level: synchronize and manual setup. """ # Reference clock selection (synchronize vs manual setup). reference_clock_selection_widget = QGroupBox('Reference clock setup:') # Big text label showing the currently set up reference clock. self.reference_datetime_label = QLabel('PLACEHOLDER') self.reference_datetime_label.setAlignment(Qt.AlignCenter) font = self.reference_datetime_label.font() font.setPointSize(self.REFERENCE_CLOCK_POINT_SIZE) self.reference_datetime_label.setFont(font) # Chooser radio buttons and the button group. synchronize_radiobutton = QRadioButton('Synchronize') synchronize_radiobutton.setChecked(True) synchronize_button = QPushButton('Synchronize') manual_setup_radiobutton = QRadioButton('Manual setup') reference_clock_setup_button_group = QButtonGroup() reference_clock_setup_button_group.addButton(synchronize_radiobutton) reference_clock_setup_button_group.addButton(manual_setup_radiobutton) reference_clock_selection_row_widget = QWidget() reference_clock_selection_row_widget.setLayout(QHBoxLayout()) reference_clock_selection_row_widget.layout().addWidget(synchronize_radiobutton) reference_clock_selection_row_widget.layout().addWidget(synchronize_button) reference_clock_selection_row_widget.layout().addWidget(manual_setup_radiobutton) reference_clock_selection_widget.setLayout(QVBoxLayout()) reference_clock_selection_widget.layout().addWidget(self.reference_datetime_label) reference_clock_selection_widget.layout().addWidget(reference_clock_selection_row_widget) # The latter choice, that expands to more choices. reference_clock_manual_setup_widget = self.init_reference_clock_manual_setup_widget() # Top-level widgets. reference_clock_setup_widget = QWidget() reference_clock_setup_widget.setLayout(QVBoxLayout()) reference_clock_setup_widget.layout().addWidget(reference_clock_selection_widget) reference_clock_setup_widget.layout().addWidget(reference_clock_manual_setup_widget) # Signals/slots plumbing. synchronize_radiobutton.toggled.connect(synchronize_button.setEnabled) manual_setup_radiobutton.toggled.connect(reference_clock_manual_setup_widget.setEnabled) synchronize_button.clicked.connect(self.time_synchronizer.show) self.time_synchronizer.clicked.connect(self.handle_time_synchronizer_done) # Set default state. synchronize_radiobutton.click() reference_clock_manual_setup_widget.setEnabled(False) return reference_clock_setup_widget def init_reference_clock_manual_setup_widget(self): """Initialize the manual reference clock setup stuff. This method initializes the manual reference clock setup stuff. """ # Reference clock manual setup widget. reference_clock_maual_selection_widget = QGroupBox('Reference clock manual setup:') self.datetime_datetimeedit = QDateTimeEdit() self.datetime_datetimeedit.setDisplayFormat('yyyy-MM-dd @ h:mm:ss.zzz') self.datetime_datetimeedit.setCalendarPopup(True) date_today_button = QPushButton('Today') date_selection_widget = QWidget() date_selection_widget.setLayout(QHBoxLayout()) date_selection_widget.layout().addWidget(self.datetime_datetimeedit) date_selection_widget.layout().addWidget(date_today_button) set_reference_clock_button = QPushButton('Set Reference Clock') # Top-level widgets. reference_clock_maual_selection_widget.setLayout(QVBoxLayout()) reference_clock_maual_selection_widget.layout().addWidget(date_selection_widget) reference_clock_maual_selection_widget.layout().addWidget(set_reference_clock_button) # Signals/slots plumbing. date_today_button.clicked.connect( lambda: self.datetime_datetimeedit.setDateTime(QDateTime(QDate.currentDate()))) set_reference_clock_button.clicked.connect(self.handle_manual_reference_clock_setup_done) return reference_clock_maual_selection_widget def dataChanged(self, top_left, bottom_right, roles): #pylint: disable=invalid-name """Respond to a RaceTableModel data change by updating input widgets with current values.""" del top_left, bottom_right, roles if self.race_table_model.reference_clock_is_enabled(): self.reference_clock_radiobutton.click() # If there's a reference datetime set up, populate the controls with it. if self.race_table_model.reference_clock_has_datetime(): reference_datetime = self.race_table_model.get_reference_clock_datetime() # Make our own combined string, because I haven't found a QDateTime format that I like. # Guess I'll keep looking...this looks really hokey. datetime_string = reference_datetime.toString(defaults.REFERENCE_CLOCK_DATETIME_FORMAT) self.reference_datetime_label.setText(datetime_string) else: # Otherwise, just use the race day's date, time zero. reference_datetime = QDateTime(QDate.currentDate()) self.reference_datetime_label.setText('Reference clock not set up') self.datetime_datetimeedit.setDateTime(reference_datetime) def toggle_reference_clock_setup(self, enable): """Toggle reference clock enable/disable. Not relevant if there is no reference clock datetime set up. """ if not self.race_table_model.reference_clock_has_datetime(): return old_reference_datetime = self.race_table_model.get_reference_clock_datetime() if enable: self.race_table_model.enable_reference_clock() else: self.race_table_model.disable_reference_clock() new_reference_datetime = self.race_table_model.get_reference_clock_datetime() self.change_reference_datetime(old_reference_datetime, new_reference_datetime) def handle_time_synchronizer_done(self, time): """Commit the time selection to the model.""" self.time_synchronizer.hide() # When synchronizing, use the current date as the date. date = QDate.currentDate() old_reference_datetime = self.race_table_model.get_reference_clock_datetime() self.race_table_model.set_reference_clock_datetime(QDateTime(date, time)) self.race_table_model.enable_reference_clock() new_reference_datetime = self.race_table_model.get_reference_clock_datetime() self.change_reference_datetime(old_reference_datetime, new_reference_datetime) def handle_manual_reference_clock_setup_done(self): """Commit the reference datetime in the database.""" old_reference_datetime = self.race_table_model.get_reference_clock_datetime() self.race_table_model.set_reference_clock_datetime(self.datetime_datetimeedit.dateTime()) self.race_table_model.enable_reference_clock() new_reference_datetime = self.race_table_model.get_reference_clock_datetime() self.change_reference_datetime(old_reference_datetime, new_reference_datetime) def change_reference_datetime(self, old_datetime, new_datetime): """Applies the new datetime as the reference datetime. Note that we also need the old datetime in order to adjust all existing time deltas to the new datetime. """ if old_datetime == new_datetime: return self.race_table_model.change_reference_clock_datetime(old_datetime, new_datetime)
class Palette(QLabel): recolor_signal = pyqtSignal(object, object) def __init__(self, parent, main): QLabel.__init__(self) self.parent = parent self.main = main self.all_values = {} pixmap = QPixmap('images/red-blue.png') self.setPixmap(pixmap) self.settings_widget = QWidget(flags=Qt.WindowStaysOnTopHint) self.settings_widget.setWindowIcon(QIcon('images/logo.ico')) self.settings_widget.setFixedSize(350, 150) self.min = None self.max = None self.settings_widget.setWindowTitle(_('Palette settings')) self.layout = QGridLayout(self.settings_widget) self.auto_radiobtn = QRadioButton( _('Auto palette for all visible tracks')) self.auto_state = True self.fixed_radiobtn = QRadioButton( _('Fixed palette for all visible tracks')) self.max_label = QLabel(_('Max')) self.min_label = QLabel(_('Min')) self.max_value = QLineEdit() self.min_value = QLineEdit() self.update_border_btn = QPushButton(_('Update')) self.line = QFrame() self.line.setFrameShape(QFrame.HLine) self.auto_label = QLabel(_('Auto')) self.all_visible_label = QLabel(_('(all visible)')) self.ok_btn = QPushButton('Ok') self.cancel_btn = QPushButton(_('Cancel')) self.apply_btn = QPushButton(_('Apply')) self.layout.addWidget(self.auto_radiobtn, 0, 0, 1, 4) self.layout.addWidget(self.fixed_radiobtn, 1, 0, 1, 4) self.layout.addWidget(self.min_label, 2, 0, 1, 1) self.layout.addWidget(self.min_value, 2, 1, 1, 1) self.layout.addWidget(self.max_label, 2, 2, 1, 1) self.layout.addWidget(self.max_value, 2, 3, 1, 1) self.layout.addWidget(self.update_border_btn, 2, 4, 1, 1) self.layout.addWidget(self.ok_btn, 3, 1, 1, 2, alignment=Qt.AlignRight) self.layout.addWidget(self.cancel_btn, 3, 3, 1, 1) self.layout.addWidget(self.apply_btn, 3, 4, 1, 1) self.min_value.textChanged.connect( lambda val: self.min_value_changed(val)) self.max_value.textChanged.connect( lambda val: self.max_value_changed(val)) self.update_border_btn.clicked.connect(lambda: self.define_borders()) self.auto_radiobtn.clicked.connect(lambda: self.auto_state_changed(1)) self.fixed_radiobtn.clicked.connect(lambda: self.auto_state_changed(0)) self.auto_radiobtn.click() self.ok_btn.clicked.connect(lambda: self.ok_clicked()) self.cancel_btn.clicked.connect(lambda: self.cancel_clicked()) self.apply_btn.clicked.connect(lambda: self.apply_clicked()) self.main.signal_language_changed.connect(lambda: self.retranslate()) def retranslate(self): self.settings_widget.setWindowTitle(_('Palette settings')) self.max_label.setText(_('Max')) self.min_label.setText(_('Min')) self.update_border_btn.setText(_('Update')) self.auto_label.setText(_('Auto')) self.all_visible_label.setText(_('(all visible)')) self.ok_btn.setText('Ok') self.cancel_btn.setText(_('Cancel')) self.apply_btn.setText(_('Apply')) def set_values(self, arr=None, min=None, max=None): if arr is None: arr = np.array(()) for value in self.all_values.values(): arr = np.hstack((arr, value)) if len(arr) == 0: for i in range(6): grad_tic = QLabel('') grad_tic.setStyleSheet( 'QLabel { background-color : rgb(127, 127, 127); color: white}' ) self.parent.layout.addWidget(grad_tic, i + 1, 1, 1, 1) return if not min and not max: gradient_tick_lst = [ np.percentile(arr, 100), np.percentile(arr, 80), np.percentile(arr, 60), np.percentile(arr, 40), np.percentile(arr, 20), np.percentile(arr, 0) ] self.min = np.amin(arr) self.max = np.amax(arr) else: gradient_tick_lst = np.ogrid[max:min:6j] self.min = min self.max = max for i, g in enumerate(gradient_tick_lst): grad_tic = QLabel('{}'.format(int(g))) if i == 0: grad_tic.setAlignment(Qt.AlignTop) elif i == 5: grad_tic.setAlignment(Qt.AlignBottom) grad_tic.setStyleSheet( 'QLabel { background-color : rgb(127, 127, 127); color: white}' ) self.parent.layout.addWidget(grad_tic, i + 1, 1, 1, 1) def mouseDoubleClickEvent(self, event): if self.parent.three_d_plot.cut_widget.isVisible(): self.parent.three_d_plot.cut_widget.activateWindow() return pos = event.globalPos() self.settings_widget.setGeometry(pos.x(), pos.y(), 300, 150) self.settings_widget.show() def min_value_changed(self, val): try: self.min = float(val.replace(',', '.')) except ValueError: pass def max_value_changed(self, val): try: self.max = float(val.replace(',', '.')) except ValueError: pass def define_borders(self): arr = np.array(()) for value in self.all_values.values(): arr = np.hstack((arr, value)) if len(arr) == 0: show_info(_('Border info'), _('No borders')) return self.min_value.setText(str(int(np.amin(arr)))) self.max_value.setText(str(int(np.amax(arr)) + 1)) self.min = np.amin(arr) self.max = np.amax(arr) def auto_state_changed(self, id): if id == 1: self.max_label.setEnabled(False) self.min_label.setEnabled(False) self.max_value.setEnabled(False) self.min_value.setEnabled(False) self.update_border_btn.setEnabled(False) else: self.max_label.setEnabled(True) self.min_label.setEnabled(True) self.max_value.setEnabled(True) self.min_value.setEnabled(True) self.update_border_btn.setEnabled(True) def ok_clicked(self): self.apply_clicked() self.settings_widget.close() def cancel_clicked(self): if self.auto_state: self.auto_radiobtn.click() else: self.fixed_radiobtn.click() self.settings_widget.close() def apply_clicked(self): self.auto_state = True if self.auto_radiobtn.isChecked() else False if self.auto_state: self.set_values() self.recolor_signal.emit(self.min, self.max) else: if len(self.min_value.text()) == 0 or len( self.max_value.text()) == 0: show_error(_('Border error'), _('Please fill Max, Min values or\nchoose Auto.')) return if float(self.min_value.text()) > float(self.max_value.text()): show_error(_('Border error'), _('Max must be more than Min')) return self.set_values(min=float(self.min_value.text()), max=float(self.max_value.text())) self.recolor_signal.emit(self.min, self.max)
def _select(self, radio_button: W.QRadioButton): radio_button.click()
class Slider_Node(Node): def __init__( self, main_obg, parametrs=['1', 'Слайдер', '50', '50', '10', 1, 1, '', '0', '100']): super().__init__(main_obg, parametrs[1], int(parametrs[2]), int(parametrs[3])) self.index_comand = parametrs[4] self.size_slider = float(parametrs[5]) self.mode = int(parametrs[6]) # тип слайдера self.value_sld = 0 self.binding = int(parametrs[7]) if parametrs[7] != '' else '' self.min = int(parametrs[8]) self.max = int(parametrs[9]) # |--------------------------------------------| обьявление виджетов self.sld = QSlider(Qt.Horizontal, self.main_window_obg) self.sld.setFocusPolicy(Qt.NoFocus) self.sld.setGeometry(30, 40, 100, 30) self.sld.valueChanged[int].connect(self.changeValue) self.sld.sliderReleased.connect(self.enter_comand) self.sld.setMinimum(self.min) self.sld.setMaximum(self.max) self.sld.resize(int(100 * self.size_slider), 30) self.text_set2 = QLabel(self.main_window_obg) self.text_set2.setText('None') self.text_set3 = QLabel(self.main_window_obg) self.text_set3.setText('Индекс:') self.input_line3 = QLineEdit(self.index_comand, self.main_window_obg) self.input_line3.textChanged.connect(self.change_index) self.input_line3.resize(60, 23) self.text_set5 = QLabel(self.main_window_obg) self.text_set5.setText('Размер:') self.input_line5 = QLineEdit(str(self.size_slider), self.main_window_obg) self.input_line5.editingFinished.connect(self.change_size_sld) self.input_line5.resize(60, 23) self.text_set4 = QLabel(self.main_window_obg) self.text_set4.setText('Минимум:') self.input_line4 = QLineEdit(str(self.min), self.main_window_obg) self.input_line4.textChanged.connect(self.change_minimum) self.input_line4.resize(60, 23) self.text_set6 = QLabel(self.main_window_obg) self.text_set6.setText('Максимум:') self.input_line6 = QLineEdit(str(self.max), self.main_window_obg) self.input_line6.textChanged.connect(self.change_maximum) self.input_line6.resize(60, 23) self.text_set7 = QLabel(self.main_window_obg) self.text_set7.setText('Привязка:') self.input_line7 = QLineEdit(str(self.binding), self.main_window_obg) self.input_line7.textChanged.connect(self.change_binding) self.input_line7.resize(60, 23) self.rb_group = QButtonGroup(self.main_window_obg) self.rb1 = QRadioButton("Отправка при отпуске", self.main_window_obg) self.rb1.move(50, 50) if self.mode == 1: self.rb1.click() self.rb1.clicked.connect(self.update_type) self.rb2 = QRadioButton("Отправка при изменении", self.main_window_obg) self.rb2.move(80, 50) if self.mode == 2: self.rb2.click() self.rb2.clicked.connect(self.update_type) self.rb_group.addButton(self.rb1) self.rb_group.addButton(self.rb2) # |--------------------------------------------| # Список всех виджетов нода и их относительных координат self.arr_of_elem.extend([(self.text_set2, 0, 50), (self.sld, 0, 21), (self.text_set3, 0, 76), (self.input_line3, 46, 75), (self.text_set4, 0, 102), (self.input_line4, 63, 100), (self.text_set6, 0, 127), (self.input_line6, 63, 125), (self.text_set5, 0, 152), (self.input_line5, 50, 150), (self.text_set7, 0, 177), (self.input_line7, 63, 175), (self.rb1, 0, 195), (self.rb2, 0, 215)]) # Список всех виджетов настроек self.elems_of_settings = [ self.text_set1, self.input_line1, self.input_line3, self.text_set3, self.text_set5, self.input_line5, self.rb1, self.rb2, self.text_set4, self.text_set6, self.input_line4, self.input_line6, self.text_set7, self.input_line7, self.delete_btn, self.copy_btn ] # Список дополнительных настроек for elem in self.elems_of_settings: elem.hide() # self.big_btn.resize(int(100 * self.size_big_btn), int(30 * self.size_big_btn)) self.ubdate_cord(self.x, self.y) def del_widgets(self): if self.delete: for elem in self.arr_of_elem: elem[0].deleteLater() self.delete = False def parametrs_return(self): return [ '1', self.name, str(self.x), str(self.y), self.index_comand, str(self.size_slider), str(self.mode), str(self.binding), str(self.min), str(self.max) ] def enter_comand(self): if self.mode == 1: global ser comand = self.left_com + self.index_comand + \ self.middle_com + str(self.value_sld) + self.right_com ser.write(comand.encode()) if self.binding != '': try: self.sld.setValue(int(self.binding)) comand = self.left_com + self.index_comand + \ self.middle_com + str(self.value_sld) + self.right_com ser.write(comand.encode()) except ValueError: pass def change_index(self): self.index_comand = self.input_line3.text() def change_size_sld(self): try: self.size_slider = float(self.input_line5.text()) self.sld.resize(int(100 * self.size_slider), 30) except ValueError: pass def change_binding(self): self.binding = self.input_line7.text() def changeValue(self, value='X_X'): global ser self.value_sld = value self.text_set2.setText(str(value)) self.text_set2.resize(self.text_set2.sizeHint()) if self.mode == 2: comand = self.left_com + self.index_comand + \ self.middle_com + str(self.value_sld) + self.right_com ser.write(comand.encode()) def change_maximum(self): try: self.max = int(self.input_line6.text()) self.sld.setMaximum(self.max) except ValueError: pass def change_minimum(self): try: self.min = int(self.input_line6.text()) self.sld.setMinimum(self.min) except ValueError: pass def update_type(self): if self.rb1.isChecked(): self.mode = 1 elif self.rb2.isChecked(): self.mode = 2 def open_setings(self): if self.flag: self.settings_btn.setText('▼') self.flag = False for elem in self.elems_of_settings: elem.show() self.text_set2.hide() else: self.settings_btn.setText('▲') self.flag = True for elem in self.elems_of_settings: elem.hide() self.text_set2.show() def is_keyword(self): return False
class MyWindow(QWidget): def __init__(self): super().__init__() Fixed = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) #... self.updateButton = QPushButton('Set') self.updateButton.clicked.connect(self.OnUpdate) #Связываем сигнал со слотом; self.updateButton.setEnabled(False) #... self.insertButton = QPushButton('Add') self.insertButton.clicked.connect(self.OnInsert) #... self.deleteButton = QPushButton('Del') self.deleteButton.clicked.connect(self.OnDelete) #... self.spinRowID = QSpinBox() self.spinRowID.lineEdit().setReadOnly(True) self.spinRowID.valueChanged.connect(self.OnRowChanged) self.spinRowID.setSizePolicy(Fixed) #... self.editName = QLineEdit() #... self.vbox = QVBoxLayout() self.is_female = QRadioButton('FEMALE'); self.is_male = QRadioButton('MALE'); self.is_male.click() self.vbox.addWidget(self.is_female) self.vbox.addWidget(self.is_male) self.vbox.setDirection(QVBoxLayout.LeftToRight) #Задаем направление компоновки; self.chckSex = QGroupBox() self.chckSex.setLayout(self.vbox) #... self.listAge = QComboBox() self.listAge.setSizePolicy(Fixed) #Устанавливаем фиксированный размер виджета; for i in range(16, 31): self.listAge.addItem(str(i), i) #... self.editCity = QLineEdit() #... self.view = View(self) self.view.clicked.connect(self.OnViewClicked) self.view.sortByColumn(0, Qt.AscendingOrder) #Используем компоновщики для позиционирования виджетов: self.lay2 = QGridLayout() self.lay2.addWidget(self.updateButton, 0, 0) self.lay2.addWidget(self.insertButton, 1, 0) self.lay2.addWidget(self.deleteButton, 2, 0) self.lay2.addWidget(self.spinRowID, 0, 1) self.lay2.addWidget(self.editName, 0, 2) self.lay2.addWidget(self.listAge, 0, 3) self.lay2.addWidget(self.chckSex, 0, 4) self.lay2.addWidget(self.editCity, 0, 5) #... self.lay1 = QGridLayout(self) self.lay1.addLayout(self.lay2, 0, 0) self.lay1.addWidget(self.view, 1, 0) self.setGeometry(0, 0, 800, 500) self.setWindowTitle('Test Application') self.show() def update(self): temp = self.view.getDataByID(self.spinRowID.value()) if not temp: self.updateButton.setEnabled(False) return self.updateButton.setEnabled(True) self.editName.setText(temp[1]) if temp[2] == 'F': self.is_female.click() else: self.is_male.click() self.listAge.setCurrentText(str(temp[3])) self.editCity.setText(temp[4]) self.repaint() def record(self): rec = [self.editName.text()] rec.append(1 if self.is_male.isChecked() else 0) rec.append(int(self.listAge.currentText())) rec.append(self.editCity.text()) return tuple(rec) def OnViewClicked(self, index): temp = self.view.getRowData(index.row()) self.spinRowID.setValue(temp[0]) def OnRowChanged(self, rowid): self.update() def OnUpdate(self): rec = self.record() self.view.updateRow(self.spinRowID.value(), rec) self.update() def OnInsert(self): rec = self.record() self.view.insertRow(rec) self.update() def OnDelete(self): self.view.removeRow(self.spinRowID.value()) self.update()
class ConfigTab(TraceDocks): ## The constructor # initialize the super-class, assign a name and first configItems def __init__(self,parent): super(ConfigTab, self).__init__(parent,'ConfigTab') self.tabName = 'ConfigTab' self.logger.logEvent('Creating Tab now: '+ self.tabName) # Set a couple of default-values, in case the configParser does not work self.snifferConfig.configBaud = 1000000 self.snifferConfig.configCom = 'COM4' self.snifferConfig.configMode = 'Singleshot' self.snifferConfig.configParity = 'None' self.snifferConfig.configStopBits = 0 self.snifferConfig.configTimeBytes = 2 self.snifferConfig.configTrigger = 'Start' self.snifferConfig.configLogCheck = 0 self.snifferConfig.configIncTimeCheck = 0 self.snifferConfig.configTickToMsLine = 1000 self.snifferConfig.configSingleDurLine = 3000 self.snifferConfig.configMaxTickCountVal = 65536 self.snifferConfig.configUpDownState = 'Up' self.snifferConfig.configCurrentTheme = 'Dark' # By parsing the config now, we assure that we re-load everything # the way we left it self.snifferConfig.parseConfigFromFile() # Create necessary Lists self.COMList = OsSniffer.OS_SerialPortList() self.BAUDList = ['110','300','600','1200','2400','4800','9600','14400','19200','38400','57600','115200','128000','256000','921600','1000000','2000000'] self.STOPList = ['0','1','2'] self.PARITYList = ['None','Even','Odd'] self.MODEList = ['Singleshot','Continuous','Trigger'] self.TRIGGERList = [] for triggers in Globals.tspDict.items(): self.TRIGGERList.append(triggers[1][0]) self.INACTIVEList = ['INACTIVE'] # We need a list for the items and one for the actual Values ## Create the visible UI def setConfigTabLayout(self): # Create Configurations Tab --------------------### # Create Layouts self.Vlayout = QVBoxLayout() self.H1layout = QHBoxLayout() self.H1layout.setSpacing(10) self.H1SubV1Layout = QVBoxLayout() self.H1SubV1H1Layout = QHBoxLayout() self.H1SubV1H2Layout = QHBoxLayout() self.H1SubV1H3Layout = QHBoxLayout() self.H1SubV1H4Layout = QHBoxLayout() self.H1SubV1H5Layout = QHBoxLayout() self.H1SubV2Layout = QVBoxLayout() self.H1SubV2H1Layout = QHBoxLayout() self.H1SubV2H2Layout = QHBoxLayout() self.H1SubV2H3Layout = QHBoxLayout() self.H1SubV2H4Layout = QHBoxLayout() self.H1SubV2H5Layout = QHBoxLayout() self.H1SubV2H6Layout = QHBoxLayout() self.H1SubV2H7Layout = QHBoxLayout() self.H1SubV2H8Layout = QHBoxLayout() #------------------------------------ # Create Widgets TextBox #------------------------------------ # First Buttons self.saveLogButt = QPushButton('Save Logfile') self.saveConfigButt = QPushButton('Save Configuration') self.toggleThemeButt = QPushButton('Toggle Theme') self.refreshComButt = QPushButton('Refresh COM') # Then Checkbox and Comboboxes self.saveLogCheck = QCheckBox('Activate Logging') self.saveIncTimeCheck = QCheckBox('Save Inc_Tick Data') self.labelSerial = QLabel('Serial Configuration') self.labelCOM = QLabel('COM-PORT') self.labelBAUD = QLabel('BAUD-RATE') self.labelSTOP= QLabel('STOP-BITS') self.labelPARITY= QLabel('PARITY') self.labelMeasure = QLabel('Measurement Configuration') self.labelMODE = QLabel('MEASUREMENT MODE') self.labelSINGLETIME = QLabel('MEASUREMENT TIME') self.labelTRIGGER = QLabel('TRIGGER TYPE') self.labelRATIO = QLabel('TICK TO MS RATIO') self.labelMaxTickCount = QLabel('MAX TICKOUT VAL') self.labelUpDownCount = QLabel('SELECT UP OR DOWN COUNTER') self.inputSingleDurBox = QLineEdit() self.inputSingleDurBox.setText('Duration(ticks)') #self.inputSingleDurBox.setMaximumWidth(20) self.inputTickToMsBox = QLineEdit() self.inputTickToMsBox.setText('Set Ticks to Ms Ratio') #self.inputTickToMsBox.setMaximumWidth(200) self.inputMaxTickCount = QLineEdit() self.inputMaxTickCount.setText('Set Maximum Tickcount Val') self.comboMODE = QComboBox() self.comboMODE.addItems(self.MODEList) self.comboCOM = QComboBox() self.comboCOM.setSizeAdjustPolicy(QComboBox.AdjustToContents) self.comboCOM.addItems(self.COMList) self.comboBAUD = QComboBox() self.comboBAUD.addItems(self.BAUDList) self.comboBAUD.setEditable(True) self.comboSTOP = QComboBox() self.comboSTOP.addItems(self.STOPList) self.comboPARITY = QComboBox() self.comboPARITY.addItems(self.PARITYList) self.comboTRIGGER = QComboBox() self.comboTRIGGER.addItems(self.TRIGGERList) self.upCountRadio = QRadioButton('Up',self) self.downCountRadio = QRadioButton('Down', self) # We need to sync the UI before connecting any slots in order to prevent accidental stateChanges. self.syncUiToConfig() #--- SIGNAL/SLOT CONNECTIONS ---# # Button Signal/Slot connections self.saveLogButt.clicked.connect(self.saveLog) for keys, values in dockDict.items(): # We need to connect EVERY tab in order to save the ConfigurationData self.saveConfigButt.clicked.connect(values.snifferConfig.saveConfigToFile) self.saveConfigButt.clicked.connect(self.snifferConfig.saveConfigToFile) self.toggleThemeButt.clicked.connect(self.toggleTheme) self.refreshComButt.clicked.connect(self.refreshCom) # Checkbox Signal/Slot connections self.saveLogCheck.stateChanged.connect(self.checkSaveLogChanged) self.saveIncTimeCheck.stateChanged.connect(self.checkSaveInctimeChanged) # Lineedit Signal/Slot connections self.inputSingleDurBox.textChanged.connect(self.lineSingleDurChanged) self.inputTickToMsBox.textChanged.connect(self.lineTickToMsChanged) self.inputMaxTickCount.textChanged.connect(self.lineMaxTickCountChanged) # Combobox Signal/Slot connections self.comboMODE.currentIndexChanged[int].connect(self.comboModeChanged) self.comboCOM.currentIndexChanged[int].connect(self.comboComChanged) self.comboBAUD.currentIndexChanged[int].connect(self.comboBaudChanged) self.comboBAUD.currentTextChanged.connect(self.comboBaudChanged) self.comboSTOP.currentIndexChanged[int].connect(self.comboStopBitsChanged) self.comboPARITY.currentIndexChanged[int].connect(self.comboParityChanged) self.comboTRIGGER.currentIndexChanged[int].connect(self.comboTriggerChanged) # Radio button connections self.upCountRadio.clicked.connect(self.upCountRadioSelected) self.downCountRadio.clicked.connect(self.downCountRadioSelected) # Add the Widgets to the corresponding Layouts self.H1SubV1H1Layout.addWidget(self.labelCOM) self.H1SubV1H1Layout.addWidget(self.refreshComButt) self.H1SubV1H1Layout.addWidget(self.comboCOM) self.H1SubV1H2Layout.addWidget(self.labelBAUD) self.H1SubV1H2Layout.addWidget(self.comboBAUD) self.H1SubV1H3Layout.addWidget(self.labelSTOP) self.H1SubV1H3Layout.addWidget(self.comboSTOP) self.H1SubV1H4Layout.addWidget(self.labelPARITY) self.H1SubV1H4Layout.addWidget(self.comboPARITY) self.H1SubV1Layout.addWidget(self.labelSerial) self.H1SubV1Layout.addLayout(self.H1SubV1H1Layout) self.H1SubV1Layout.addLayout(self.H1SubV1H2Layout) self.H1SubV1Layout.addLayout(self.H1SubV1H3Layout) self.H1SubV1Layout.addLayout(self.H1SubV1H4Layout) self.H1SubV1Layout.addStretch() self.H1SubV2H1Layout.addWidget(self.labelMODE) self.H1SubV2H1Layout.addWidget(self.comboMODE) self.H1SubV2H2Layout.addWidget(self.labelSINGLETIME) self.H1SubV2H2Layout.addWidget(self.inputSingleDurBox) self.H1SubV2H3Layout.addWidget(self.labelTRIGGER) self.H1SubV2H3Layout.addWidget(self.comboTRIGGER) self.H1SubV2H5Layout.addWidget(self.saveIncTimeCheck) self.H1SubV2H5Layout.addWidget(self.saveLogCheck) self.H1SubV2H5Layout.addWidget(self.saveLogButt) self.H1SubV2H5Layout.addWidget(self.toggleThemeButt) self.H1SubV2H6Layout.addWidget(self.labelRATIO) self.H1SubV2H6Layout.addWidget(self.inputTickToMsBox) self.H1SubV2H7Layout.addWidget(self.labelMaxTickCount) self.H1SubV2H7Layout.addWidget(self.inputMaxTickCount) self.H1SubV2H8Layout.addWidget(self.labelUpDownCount) self.H1SubV2H8Layout.addWidget(self.upCountRadio) self.H1SubV2H8Layout.addWidget(self.downCountRadio) self.H1SubV2Layout.addWidget(self.labelMeasure) self.H1SubV2Layout.addLayout(self.H1SubV2H1Layout) self.H1SubV2Layout.addLayout(self.H1SubV2H2Layout) self.H1SubV2Layout.addLayout(self.H1SubV2H3Layout) self.H1SubV2Layout.addLayout(self.H1SubV2H4Layout) self.H1SubV2Layout.addLayout(self.H1SubV2H5Layout) self.H1SubV2Layout.addLayout(self.H1SubV2H6Layout) self.H1SubV2Layout.addLayout(self.H1SubV2H7Layout) self.H1SubV2Layout.addLayout(self.H1SubV2H8Layout) self.H1SubV2Layout.addStretch() self.H1layout.addLayout(self.H1SubV1Layout) self.H1layout.addStretch() self.H1layout.addLayout(self.H1SubV2Layout) self.Vlayout.addLayout(self.H1layout) self.Vlayout.addStretch() self.Vlayout.addWidget(self.saveConfigButt) self.dockContents.setLayout(self.Vlayout) # -- ! We need callbacks to update the actual Values ! --# #---CREATE COMBOBOX Callbacks---# ## CB: comboCOM // Serial COM-Port def comboComChanged(self): self.snifferConfig.configCom = self.COMList[self.comboCOM.currentIndex()] self.logger.logEvent('changed COM-Port to - '+ self.snifferConfig.configCom) ## CB: comboBAUD // Serial BAUD-Rate def comboBaudChanged(self): self.snifferConfig.configBaud = self.comboBAUD.currentText() self.logger.logEvent('changed BAUD-Rate to - '+ self.snifferConfig.configBaud) ## CB: comboSTOP // Serial STOP-bit count def comboStopBitsChanged(self): self.snifferConfig.configStopBits = self.STOPList[self.comboSTOP.currentIndex()] self.logger.logEvent('changed STOP-Bits to - '+ self.snifferConfig.configStopBits) ## CB: comboPARTIY // Serial Parity-bit (odd/even/none) def comboParityChanged(self): self.snifferConfig.configParity = self.PARITYList[self.comboPARITY.currentIndex()] self.logger.logEvent('changed PARITY to - '+ self.snifferConfig.configParity) ## CB: comboMODE // Measurement mode def comboModeChanged(self): # Check which box is checked in order to show the user the necessary info self.snifferConfig.configMode = self.MODEList[self.comboMODE.currentIndex()] if self.snifferConfig.configMode == self.MODEList[0]: self.inputSingleDurBox.show() self.labelSINGLETIME.show() self.comboTRIGGER.hide() self.labelTRIGGER.hide() if self.snifferConfig.configMode == self.MODEList[1]: self.inputSingleDurBox.hide() self.labelSINGLETIME.hide() self.comboTRIGGER.hide() self.labelTRIGGER.hide() if self.snifferConfig.configMode == self.MODEList[2]: self.inputSingleDurBox.show() self.labelSINGLETIME.show() self.comboTRIGGER.show() self.labelTRIGGER.show() self.logger.logEvent('changed Measurement-mode to - '+ self.snifferConfig.configMode) ## CB: comboTRIGGER // the Trigger the measurement waits for (only in TRIGGER-measmode) def comboTriggerChanged(self): self.snifferConfig.configTrigger = self.TRIGGERList[self.comboTRIGGER.currentIndex()] self.logger.logEvent('changed TriggerType to - '+ self.snifferConfig.configTrigger) #---CREATE THEME Callbacks---# ## CB: Toggles the theme between dark and light mode # @details This happens by calling the appropriate function of the parent (QMainwindow), so that the theme # is changed globally def toggleTheme(self): if(self.snifferConfig.configCurrentTheme == 'Light'): self.parent.loadTheme('Dark') #self.parent.tabStart.startStopAnalyzingButt.setStyleSheet('QPushButton:focus {border: 2px solid; border-color: limegreen; background-color: #31363b; border-radius:100px}') else: self.parent.loadTheme('Light') #self.parent.tabStart.startStopAnalyzingButt.setStyleSheet('QPushButton:focus {border: 2px solid; border-color: limegreen; background-color: white; border-radius:100px}') #self.parent.setStartStopButtonStyle() #---CREATE CHECKBOX Callbacks---# ## CB: Handle the SaveLog checkbox event (Toggle) def checkSaveLogChanged(self): self.snifferConfig.configLogCheck ^= 1 if(self.snifferConfig.configLogCheck == 1): self.logger.enableLogs() else: self.logger.disableLogs() self.logger.logEvent('changed LogCheckbox to - '+ str(self.snifferConfig.configLogCheck)) ## CB: Handle the SaveInctime checkbox event (Toggle) def checkSaveInctimeChanged(self): self.snifferConfig.configIncTimeCheck ^= 1 self.logger.logEvent('changed Save Time-Increment Checkbox to - '+ str(self.snifferConfig.configIncTimeCheck)) #---CREATE LINEEDIT Callbacks---# ## CB: Handle the SingleDur lineedit callback (adjust singleshot duration) def lineSingleDurChanged(self): self.snifferConfig.configSingleDurLine = self.inputSingleDurBox.text() self.logger.logEvent('changed Singleshot Duration to - '+ str(self.snifferConfig.configSingleDurLine)) ## CB: Handle the TickToMs lineedit callback (adjust ticks per ms) def lineTickToMsChanged(self): self.snifferConfig.configTickToMsLine = self.inputTickToMsBox.text() self.logger.logEvent('changed Tick To Ms Ratio to - '+ str(self.snifferConfig.configTickToMsLine)) ## CB: Handle the MaxTickCount lineedit callback (adjust maximum tickcount value) def lineMaxTickCountChanged(self): self.snifferConfig.configMaxTickCountVal = self.inputMaxTickCount.text() self.logger.logEvent('changed Max Tickcount Value to - '+ str(self.snifferConfig.configTickToMsLine)) #---CREATE PUSHBUTTON Callbacks---# ## CB: Handle the refreshCOM pushbutton callback (refresh all com-ports) def refreshCom(self): self.COMList = OsSniffer.OS_SerialPortList() self.comboCOM.clear() self.comboCOM.addItems(self.COMList) self.snifferConfig.configCom = self.COMList[self.comboCOM.currentIndex()] #---CREATE RADIO Callbacks---# ## Select upCount def upCountRadioSelected(self): self.snifferConfig.configUpDownState = 'Up' self.logger.logEvent('changed Up/Down Radio to - '+ str(self.snifferConfig.configUpDownState)) ## Select downCount def downCountRadioSelected(self): self.snifferConfig.configUpDownState = 'Down' self.logger.logEvent('changed Up/Down Radio to - '+ str(self.snifferConfig.configUpDownState)) #---CONTENT FUNCTIONS---# ## CB: Saves all logs saved in the logList to a output-file def saveLog(self): print('Trying to save logs') if(len(snifferLogList) == 0): self.displayException('Global Logging List empty. Did you enable the checkbox?') else: self.saveLogDirectory, self.purge = QFileDialog.getSaveFileName(self, 'Save File', '', 'Logfile (*.slog)') print(self.saveLogDirectory) self.logFile = open(self.saveLogDirectory,'a+') for logTuple in snifferLogList: self.logFile.write(str(logTuple[0])+', '+str(logTuple[1])+'\n') self.logFile.close() # --- MANDATORY UI FUNCTIONS --- # # -------------------------------# ## Read out all components of snifferConfig and set the UI elements according to # the saved values. def syncUiToConfig(self): self.inputSingleDurBox.setText(str(self.snifferConfig.configSingleDurLine)) self.inputTickToMsBox.setText(str(self.snifferConfig.configTickToMsLine)) self.inputMaxTickCount.setText(str(self.snifferConfig.configMaxTickCountVal)) self.saveLogCheck.setChecked(self.snifferConfig.configLogCheck) self.saveIncTimeCheck.setChecked(self.snifferConfig.configIncTimeCheck) if self.snifferConfig.configUpDownState == 'Up': self.upCountRadio.click() elif self.snifferConfig.configUpDownState == 'Down': self.downCountRadio.click() else: print('Error, neither up nor down in config') try: self.comboCOM.setCurrentIndex(self.COMList.index(self.snifferConfig.configCom)) except Exception as valException: print('Exception when syncing UI in Configtab: comboCOM - snifferConfig Error') self.comboCOM.setCurrentIndex(0) try: self.comboMODE.setCurrentIndex(self.MODEList.index(self.snifferConfig.configMode)) except Exception as valException: print('Exception when syncing UI in Configtab: comboMODE - snifferConfig Error') self.comboMODE.setCurrentIndex(0) try: self.comboBAUD.setCurrentIndex(self.BAUDList.index(str(self.snifferConfig.configBaud))) except Exception as valException: print('Exception when syncing UI in Configtab: comboBAUD - snifferConfig Error') self.comboBAUD.setCurrentIndex(0) try: self.comboPARITY.setCurrentIndex(self.PARITYList.index(self.snifferConfig.configParity)) except Exception as valException: print('Exception when syncing UI in Configtab: comboPARITY - snifferConfig Error') self.comboPARITY.setCurrentIndex(0) try: self.comboSTOP.setCurrentIndex(self.STOPList.index(str(self.snifferConfig.configStopBits))) except Exception as valException: print('Exception when syncing UI in Configtab: comboSTOP - snifferConfig Error') self.comboSTOP.setCurrentIndex(0) try: self.comboTRIGGER.setCurrentIndex(self.TRIGGERList.index(self.snifferConfig.configTrigger.upper())) except Exception as valException: print('Exception when syncing UI in Configtab: comboTRIGGER - snifferConfig Error') self.comboTRIGGER.setCurrentIndex(0)