def _plot(self): """ Network performance graph """ setConfigOption('background', '#FF000000') _graph = PlotWidget() _graph.setMenuEnabled(enableMenu=False) _graph.setMouseEnabled(x=False, y=False) _graph.hideButtons() self._out_curve = _graph.getPlotItem().plot() self._inc_curve = _graph.getPlotItem().plot() self._legend = LegendItem(offset=(50, 10)) self._legend.setParentItem(_graph.getPlotItem()) self._legend.addItem(self._out_curve, self._lang.NetworkGraphOutgoing) self._legend.addItem(self._inc_curve, self._lang.NetworkGraphIncoming) self._base.net_perf_lyt.addWidget(_graph) self._menu_popup = QMenu() _action = QAction(QIcon('icon/reload.png'), self._lang.PopupReload, self._base.net_perf_box) _action.triggered.connect(self.reload) self._menu_popup.addAction(_action) self._base.net_perf_box.setContextMenuPolicy(Qt.CustomContextMenu) self._base.net_perf_box.customContextMenuRequested.connect( self._popup_show)
class Ui_plotWindow(object): def setupUi(self, plotWindow): plotWindow.setObjectName(_fromUtf8("plotWindow")) plotWindow.resize(540, 350) plotWindow.setMaximumSize(QtCore.QSize(16777215, 16777215)) self.gridLayout = QtGui.QGridLayout(plotWindow) self.gridLayout.setObjectName(_fromUtf8("gridLayout")) self.graphicsView = PlotWidget(plotWindow) self.graphicsView.hideButtons() self.graphicsView.showGrid(True, True) self.graphicsView.setMenuEnabled(False) self.graphicsView.setMouseEnabled(False, False) self.graphicsView.setFrameShadow(QtGui.QFrame.Plain) self.graphicsView.setFrameShape(QtGui.QFrame.StyledPanel) self.graphicsView.setObjectName(_fromUtf8("graphicsView")) self.gridLayout.addWidget(self.graphicsView, 0, 1, 1, 1) self.treeWidget = QtGui.QTreeWidget(plotWindow) self.treeWidget.setMaximumSize(QtCore.QSize(200, 16777215)) self.treeWidget.setHorizontalScrollBarPolicy( QtCore.Qt.ScrollBarAlwaysOff) self.treeWidget.setRootIsDecorated(False) self.treeWidget.setItemsExpandable(False) self.treeWidget.setExpandsOnDoubleClick(False) self.treeWidget.setColumnCount(3) self.treeWidget.setObjectName(_fromUtf8("treeWidget")) self.treeWidget.header().setVisible(True) self.treeWidget.header().setDefaultSectionSize(80) self.gridLayout.addWidget(self.treeWidget, 0, 0, 1, 1) self.retranslateUi(plotWindow) QtCore.QMetaObject.connectSlotsByName(plotWindow) def retranslateUi(self, plotWindow): plotWindow.setWindowTitle( QtGui.QApplication.translate("plotWindow", "Form", None, QtGui.QApplication.UnicodeUTF8)) self.treeWidget.headerItem().setText( 0, QtGui.QApplication.translate("plotWindow", "Legend", None, QtGui.QApplication.UnicodeUTF8)) self.treeWidget.headerItem().setText( 1, QtGui.QApplication.translate("plotWindow", "Name", None, QtGui.QApplication.UnicodeUTF8)) self.treeWidget.headerItem().setText( 2, QtGui.QApplication.translate("plotWindow", "Value", None, QtGui.QApplication.UnicodeUTF8))
class Ui_plotWindow(object): def setupUi(self, plotWindow): plotWindow.setObjectName(_fromUtf8("plotWindow")) plotWindow.resize(540, 350) plotWindow.setMaximumSize(QtCore.QSize(16777215, 16777215)) self.gridLayout = QtGui.QGridLayout(plotWindow) self.gridLayout.setObjectName(_fromUtf8("gridLayout")) self.graphicsView = PlotWidget(plotWindow) self.graphicsView.hideButtons() self.graphicsView.showGrid(True, True) self.graphicsView.setMenuEnabled(False) self.graphicsView.setMouseEnabled(False, False) self.graphicsView.setFrameShadow(QtGui.QFrame.Plain) self.graphicsView.setFrameShape(QtGui.QFrame.StyledPanel) self.graphicsView.setObjectName(_fromUtf8("graphicsView")) self.gridLayout.addWidget(self.graphicsView, 0, 1, 1, 1) self.treeWidget = QtGui.QTreeWidget(plotWindow) self.treeWidget.setMaximumSize(QtCore.QSize(200, 16777215)) self.treeWidget.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff) self.treeWidget.setRootIsDecorated(False) self.treeWidget.setItemsExpandable(False) self.treeWidget.setExpandsOnDoubleClick(False) self.treeWidget.setColumnCount(3) self.treeWidget.setObjectName(_fromUtf8("treeWidget")) self.treeWidget.header().setVisible(True) self.treeWidget.header().setDefaultSectionSize(80) self.gridLayout.addWidget(self.treeWidget, 0, 0, 1, 1) self.retranslateUi(plotWindow) QtCore.QMetaObject.connectSlotsByName(plotWindow) def retranslateUi(self, plotWindow): plotWindow.setWindowTitle(QtGui.QApplication.translate("plotWindow", "Form", None, QtGui.QApplication.UnicodeUTF8)) self.treeWidget.headerItem().setText(0, QtGui.QApplication.translate("plotWindow", "Legend", None, QtGui.QApplication.UnicodeUTF8)) self.treeWidget.headerItem().setText(1, QtGui.QApplication.translate("plotWindow", "Name", None, QtGui.QApplication.UnicodeUTF8)) self.treeWidget.headerItem().setText(2, QtGui.QApplication.translate("plotWindow", "Value", None, QtGui.QApplication.UnicodeUTF8))
def __init__(self, atri_plot: PlotWidget, vent_plot: PlotWidget, data_size: int): print("Graphs handler init") # noinspection PyArgumentList atri_plot.setRange(xRange=[-1, data_size], yRange=[-0.5, 5.5], padding=0) atri_plot.setLimits(xMin=-1, xMax=data_size, maxXRange=data_size + 1, yMin=-0.5, yMax=5.5) atri_plot.setMouseEnabled(x=True, y=False) atri_plot.enableAutoRange(x=False, y=True) atri_plot.setAutoVisible(x=False, y=True) atri_plot.showGrid(x=True, y=True) atri_plot.hideButtons() atri_plot.setMenuEnabled(False) atri_plot.setLabel('left', "Amplitude", units='V', **{'color': '#FFF', 'font-size': '10pt'}) atri_plot.setLabel('bottom', "Time", units='s', **{'color': '#FFF', 'font-size': '10pt'}) atri_plot.getAxis('bottom').setHeight(30) # noinspection PyArgumentList vent_plot.setRange(xRange=[-1, data_size], yRange=[-0.5, 5.5], padding=0) vent_plot.setLimits(xMin=-1, xMax=data_size, maxXRange=data_size + 1, yMin=-0.5, yMax=5.5) vent_plot.setMouseEnabled(x=True, y=False) vent_plot.enableAutoRange(x=False, y=True) vent_plot.setAutoVisible(x=False, y=True) vent_plot.showGrid(x=True, y=True) vent_plot.hideButtons() vent_plot.setMenuEnabled(False) vent_plot.setLabel('left', "Amplitude", units='V', **{'color': '#FFF', 'font-size': '10pt'}) vent_plot.setLabel('bottom', "Time", units='s', **{'color': '#FFF', 'font-size': '10pt'}) vent_plot.getAxis('bottom').setHeight(30) # Initialize graphs to 0 self._atri_data = np.zeros(data_size) self._vent_data = np.zeros(data_size) # Create new sense plots for the atrial and ventricular graphs, in blue self._atri_plot = atri_plot.plot(pen=(0, 229, 255)) self._vent_plot = vent_plot.plot(pen=(0, 229, 255)) self._plot_data()
class Window(QtGui.QWidget): # Default application settings. period = 30 analog_channel = 0 trigger_channel = 8 rate_index = 0 out_string = 'Data' directory = os.path.dirname(os.path.realpath(__file__)) + '/data' settings_port = '' # Initialization of application variables. volts = [] times = [] port_name = '' last_multiple = period time = 0 sweep = 0 reading = False def __init__(self, parent=None): super(Window, self).__init__(parent) # Replace default settings with settings from file. self.readSettings() # Initialize serial communication. self.ser = Serial() self.ser.baudrate = BAUD_RATE self.ser.timeout = TIMEOUT # Create graph for plotting data. Disable mouse by default. self.graph = PlotWidget() self.graph.hideAxis('bottom') self.graph.showAxis('bottom') self.graph.setMouseEnabled(False, False) self.graph.hideButtons() self.graph.setYRange(0, GRAPH_RANGE_Y) self.graph.setXRange(0, self.period) # Create user interface elements and connect them to corresponding functions. self.start_button = QtGui.QPushButton('Start') self.start_button.clicked.connect(self.startPlot) self.stop_button = QtGui.QPushButton('Stop') self.stop_button.clicked.connect(self.stopPlot) self.stop_button.setEnabled(False) self.stop_button.setCheckable(True) channel_label = QtGui.QLabel('Analog Channel') self.channel_box = QtGui.QSpinBox() self.channel_box.setValue(self.analog_channel) self.channel_box.valueChanged.connect(self.channel) self.channel(self.analog_channel) trigger_label = QtGui.QLabel('Trigger Channel') self.trigger_box = QtGui.QSpinBox() self.trigger_box.setValue(self.trigger_channel) self.trigger_box.valueChanged.connect(self.trigger) self.trigger(self.trigger_channel) rate_label = QtGui.QLabel('Data Acquisition Rate (Hz)') self.rate_box = QtGui.QComboBox() self.rate_box.addItems(['10', '20', '50', '100', '200', '250', '500']) self.rate_box.setCurrentIndex(self.rate_index) self.rate_box.currentIndexChanged.connect(self.refresh) self.refresh(self.rate_index) port_label = QtGui.QLabel('Serial Port') self.port_box = QtGui.QComboBox() # Find valid ports. self.refreshPorts() self.port_box.currentIndexChanged.connect(self.portChanged) # Check if previously used port is still valid. if self.settings_port != '': index = self.port_box.findText(self.settings_port) if index > -1: self.port_box.setCurrentIndex(index) else: self.port_name = '' self.refresh_button = QtGui.QPushButton('Refresh Ports') self.refresh_button.clicked.connect(self.refreshPorts) period_label = QtGui.QLabel('Graph Period (s)') self.period_box = QtGui.QSpinBox() self.period_box.setMaximum(1000000) self.period_box.setValue(self.period) self.period_box.valueChanged.connect(self.changePeriod) output_label = QtGui.QLabel('Data Output Prefix') self.output_edit = QtGui.QLineEdit() self.output_edit.setText(self.out_string) self.output_edit.editingFinished.connect(self.outputString) self.dir_button = QtGui.QPushButton('Choose Data Directory') self.dir_button.clicked.connect(self.chooseDirectory) # Add user interface elements to panel. button_box = QtGui.QVBoxLayout() button_box.addWidget(port_label) button_box.addWidget(self.port_box) button_box.addWidget(self.refresh_button) button_box.addWidget(channel_label) button_box.addWidget(self.channel_box) button_box.addWidget(trigger_label) button_box.addWidget(self.trigger_box) button_box.addWidget(rate_label) button_box.addWidget(self.rate_box) button_box.addWidget(period_label) button_box.addWidget(self.period_box) button_box.addWidget(output_label) button_box.addWidget(self.output_edit) button_box.addWidget(self.dir_button) # Displace start and stop buttons to bottom of panel. button_box.addStretch(1) button_box.addWidget(self.start_button) button_box.addWidget(self.stop_button) # Place panel on left side of application and graph on right. layout = QtGui.QHBoxLayout() layout.addLayout(button_box) layout.addWidget(self.graph, 1) self.setLayout(layout) # Create timers to control repeating functions. self.plot_timer = QtCore.QTimer(self) self.plot_timer.timeout.connect(self.plot) self.read_timer = QtCore.QTimer(self) self.read_timer.timeout.connect(self.read) self.trigger_timer = QtCore.QTimer(self) self.trigger_timer.timeout.connect(self.checkTrigger) self.trigger_timer.start() def refreshPorts(self): # Loop through com ports and try to open each. self.port_box.clear() for p in serial.tools.list_ports.comports(): try: self.openPort(p[0]) # If the port opened, add it to the list. if (self.ser.read() == READY_COMMAND): self.port_box.addItem(p[0]) except: pass if self.port_box.count() == 0: self.port_name = '' def closeEvent(self, event): # When user closes application, stop reading and save settings. if self.reading: self.stopPlot() settings = open( os.path.dirname(os.path.realpath(__file__)) + '/settings.dat', 'w+') settings.write('PORT=' + self.port_name + '\n') settings.write('ANALOG_CHANNEL=' + str(self.analog_channel) + '\n') settings.write('DATA_RATE=' + str(self.rate_index) + '\n') settings.write('PERIOD=' + str(self.period) + '\n') settings.write('PREFIX=' + self.out_string + '\n') settings.write('DIRECTORY=' + self.directory + '\n') settings.close() event.accept() def read(self): # If full transmission of 6 bytes is available, read data from arduino. #print(self.ser.inWaiting()) if (self.ser.inWaiting() >= 6): # Convert reading to voltage by using conversion factor 1 bit = 0.125 mV. volt = (4.096 * int(binascii.hexlify(self.ser.read(2)), 16) / 32768.0) #volt = 4.096*(int(self.ser.read(2).encode('hex'), 16)/32768.0) # Convert time reading from microseconds to seconds. #self.time += (int(self.ser.read(4).encode('hex'), 16)/1000000.0) self.time += (int(binascii.hexlify(self.ser.read(4)), 16) / 1000000.0) # If graph has reached edge, reset with new sweep. if (self.time > self.last_multiple): self.last_multiple += self.period self.newSweep() # Add readings to lists of readings. self.times.append(self.time) self.volts.append(volt) def plot(self): # Plot current lists of data on graph after clearing previous graph. self.graph.plot(self.times, self.volts, clear=True) def startPlot(self): if self.port_name == '': # If no ports are available, inform user and end function. warn = QtGui.QMessageBox() warn.setWindowTitle('Warning') warn.setText('No open ports.') warn.exec_() return if not self.ping(): # If currently selected port is not open, warn user and end function. warn = QtGui.QMessageBox() warn.setWindowTitle('Warning') warn.setText('Could not connect to port: ' + self.ser.port) warn.exec_() return if (self.period * int(self.rate_box.itemText(self.rate_box.currentIndex())) > 20000): # If the user chose too large of a period, inform user and end function. # This is in place to avoid memory issues caused by overly large lists of data. warn = QtGui.QMessageBox() warn.setWindowTitle('Warning') warn.setText('Period too large for current data acquisition rate.\n\n'\ 'Maximum Periods:\n'\ '10\tHz\t\t\t2,000\ts\n'\ '20\tHz\t\t\t1,000\ts\n'\ '50\tHz\t\t\t400\ts\n'\ '100\tHz\t\t\t200\ts\n'\ '200\tHz\t\t\t100\ts\n'\ '250\tHz\t\t\t80\ts\n'\ '500\tHz\t\t\t40\ts') warn.exec_() return self.reading = True # Send current pin and data rate to the arduino. self.ser.write(PIN_COMMAND) self.ser.write(bytes(str(self.analog_channel), 'utf_8')) self.ser.write(b'\n') self.ser.write(RATE_COMMAND) self.ser.write( bytes(str(int(self.rate_box.itemText(self.rate_index))), 'utf_8')) self.ser.write(b'\n') # Reset data lists and graph variables to starting values. self.volts = [] self.times = [] self.sweep = 0 self.time = 0 self.last_multiple = self.period self.graph.setXRange(0, self.period) # Disable all user interface elements that should not be changed while acquiring data. self.start_button.setEnabled(False) self.channel_box.setEnabled(False) self.trigger_box.setEnabled(False) self.rate_box.setEnabled(False) self.period_box.setEnabled(False) self.port_box.setEnabled(False) self.output_edit.setEnabled(False) self.dir_button.setEnabled(False) # Enable stop button. self.stop_button.setEnabled(True) # Tell arduino to start reading, and start the timers to read and plot data. self.ser.write(READ_COMMAND) self.ser.flushInput() # Graph updates at 50 Hz to smoothly graph while avoiding performance issues. self.plot_timer.start(20) self.read_timer.start() def stopPlot(self): # Export the current sweep to data file. self.autoExport() if self.reading: # Stop timers from reading and plotting data. #self.plot_timer.stop() #self.read_timer.stop() self.reading = False # Re-enable user interface. self.start_button.setEnabled(True) self.channel_box.setEnabled(True) self.trigger_box.setEnabled(True) self.rate_box.setEnabled(True) self.period_box.setEnabled(True) self.port_box.setEnabled(True) self.output_edit.setEnabled(True) self.dir_button.setEnabled(True) # Disable stop button. self.stop_button.setEnabled(False) # If connection was not lost, tell arduino to stop reading. try: self.ser.write(READ_COMMAND) #self.ser.write(b'\n') except: pass # Stop timers from reading and plotting data. self.plot_timer.stop() self.read_timer.stop() def channel(self, new_channel): # Controls which channel arduino should read from. self.analog_channel = new_channel def trigger(self, new_channel): # Controls which channel arduino should read trigger from. self.trigger_channel = new_channel if self.ping(): self.ser.write(TRIGGER_COMMAND) self.ser.write(bytes(self.trigger_channel)) self.ser.write(b'\n') def refresh(self, rate_index): # Controls rate arduino should read at. self.rate_index = rate_index def openPort(self, port_name): # Close current port, reinitialize to new port, and attempt to open new port. self.ser.close() self.port_name = port_name self.ser.port = port_name self.ser.open() def portChanged(self, port_index): # When new port is chosen from list, try to open it. try: name = str(self.port_box.itemText(port_index)) if self.port_name != name: self.openPort(name) except: pass def newSweep(self): # When graph reaches edge, dump data to file and reset for new sweep. self.autoExport() self.times = [] self.volts = [] self.sweep += 1 self.graph.setXRange(self.period * self.sweep, self.period * (self.sweep + 1)) def autoExport(self): # Checks specified directory for data. If it doesn't exist, it is created. dir = self.directory + '/' + self.out_string if not os.path.exists(dir): os.makedirs(dir) # Creates or opens data file corresponding to current sweep of graph. f = open( dir + '/' + self.out_string + '_' + ('%03d' % self.sweep) + '.txt', 'w') # Writes data to that file. for time, volt in zip(self.times, self.volts): f.write(str(time) + '\t' + str(volt) + '\n') f.close() def changePeriod(self, new_period): # Changes period of graph and sweep. self.period = new_period self.last_multiple = new_period self.graph.setXRange(0, new_period) def outputString(self): # Changes prefix of data files. self.out_string = str(self.output_edit.text()) def chooseDirectory(self): # Opens dialog for user to choose where to save data. new_dir = str( QtGui.QFileDialog.getExistingDirectory(self, 'Select Directory')) if (new_dir): self.directory = new_dir def readSettings(self): # Open or create settings file. path = os.path.dirname(os.path.realpath(__file__)) + '/settings.dat' if os.path.exists(path): settings = open(path, 'r+') else: settings = open(path, 'w+') # Parse through file and read settings. for line in settings.readlines(): key, value = line.split('=') value = value.rstrip() if (key == 'PORT'): self.settings_port = value elif (key == 'ANALOG_CHANNEL'): self.analog_channel = int(value) elif (key == 'DATA_RATE'): self.rate_index = int(value) elif (key == 'PERIOD'): self.period = int(value) elif (key == 'PREFIX'): self.out_string = value elif (key == 'DIRECTORY'): self.directory = value settings.close() def ping(self): # Check if arduino is still connected. try: self.ser.write(READY_COMMAND) return True except: return False def checkTrigger(self): #print(self.reading) ''' #print(self.plot_timer.timerId()) while self.reading == False and self.port_name != '': print("this stopped") #print(self.ser.inWaiting()) self.plot_timer.stop() self.read_timer.stop() self.reading = False #if self.plot_timer.timerId() == -1 and self.read_timer.timerId() == -1 and self.ser.inWaiting: # break # if not self.ser.inWaiting(): # break ''' if not self.reading and self.port_name != '' and self.ser.inWaiting( ) and not self.stop_button.isChecked(): if self.ser.read() == READ_COMMAND: self.startPlot() self.ser.flushInput()
class widget_mfi_lon_plot(QWidget): #----------------------------------------------------------------------- # DEFINE THE INITIALIZATION FUNCTION. #----------------------------------------------------------------------- def __init__(self, core): # Inherit all attributes of an instance of "QWidget". super(widget_mfi_lon_plot, self).__init__() # Store the Janus core. self.core = core # Prepare to respond to signals received from the core. self.connect(self.core, SIGNAL('janus_rset'), self.resp_rset) self.connect(self.core, SIGNAL('janus_chng_mfi'), self.resp_chng_mfi) # Initialize this widget's instance of "PlotWidget", which will # contain the plot of MFI magnetic field data. # Note. The "QGridLayout" object given to this widget as its # layout is essentially a dummy. I could have just had # this class inherit "PlotWidget", but I think that this # gives me a bit more control (and a similar structure # "janus_widget_fc_cup"). self.setLayout(QGridLayout()) self.plt = PlotWidget() self.layout().addWidget(self.plt) self.layout().setContentsMargins(0, 0, 0, 0) # Extract the individual elements of the "PlotWidget" object # (e.g., it's axes) for more convenient access later. self.vbx = self.plt.getViewBox() self.axs_x = self.plt.getAxis('bottom') self.axs_y = self.plt.getAxis('left') self.ptm = self.plt.getPlotItem() # Initialize and store the pens and fonts. self.pen_vbx = mkPen(color='k') self.pen_crv_lon = mkPen(color='#FFD700') self.fnt = self.core.app.font() # Configure the plot: disable automatic adjustments and # adjustments made by the user, change the background and # foreground colors, enable grid lines for both axes, label the # axes, adjust the tick font size, adjust the "AxisItem" sizes, # and add a margin around the entire plot. self.plt.disableAutoRange() self.plt.setMouseEnabled(False, False) self.plt.setMenuEnabled(False) self.plt.hideButtons() self.plt.setBackground('w') setConfigOption('foreground', 'k') #####self.plt.showGrid( True, True ) labelStyle = {'color': 'k'} self.axs_x.setLabel('Time [s]', **labelStyle) self.axs_y.setLabel('Azim. [deg]', **labelStyle) self.axs_x.label.setFont(self.fnt) self.axs_y.label.setFont(self.fnt) self.axs_x.setTickFont(self.fnt) self.axs_y.setTickFont(self.fnt) self.axs_x.setHeight(35) self.axs_y.setWidth(40) self.vbx.border = self.pen_vbx self.ptm.setContentsMargins(5, 5, 5, 5) # Initialize the curves that will be added to this plot. self.crv_lon = None # Populate this plot and adjust it's settings. self.make_plt() #----------------------------------------------------------------------- # DEFINE THE FUNCTION FOR POPULATING THE PLOT. #----------------------------------------------------------------------- def make_plt(self): # Reset the plot (i.e., remove all plot elements). self.rset_plt() # Establish the ranges of its time and magnetic field values. # If the core contains no data or only a single datum, # improvise (for the purpose of later establishing axis limits). if (self.core.n_mfi >= 1): # Establish the domain of the plot. t_min = min(amin(self.core.mfi_s), 0.) t_max = max(amax(self.core.mfi_s), self.core.fc_spec['dur']) # Establish the range of the plot. As part of this, # ensure that the range satisfies a minimum size and has # sufficient padding. ang_max = max(self.core.mfi_b_lon) ang_min = min(self.core.mfi_b_lon) ang_max = 5. + ang_max ang_min = -5. + ang_min d_t_0 = t_max - t_min d_t = max(1.5 + d_t_0, 3.) t_max = t_min + d_t else: t_min = 0.001 t_max = 3.500 ang_min = -360 ang_max = 360 # Set the range of the axis of each plot. self.plt.setXRange(t_min, t_max, padding=0.0) self.plt.setYRange(ang_min, ang_max, padding=0.0) # If the core contains no Wind/MFI magnetic field data, return. if (self.core.n_mfi <= 0): return # Generate and display each curve for the plot. self.crv_lon = PlotDataItem(self.core.mfi_s, self.core.mfi_b_lon, pen=self.pen_crv_lon) self.plt.addItem(self.crv_lon) #----------------------------------------------------------------------- # DEFINE THE FUNCTION FOR RESETTING THIS PLOT (CLEARING ALL ELEMENTS). #----------------------------------------------------------------------- def rset_plt(self): # Hide and remove each of this plot's elements. if (self.crv_lon is not None): self.plt.removeItem(self.crv_lon) # Permanently delete this plot's elements by setting each of the # variables that store them to "None". self.crv_lon = None #----------------------------------------------------------------------- # DEFINE THE FUNCTION FOR RESPONDING TO THE "rset" SIGNAL. #----------------------------------------------------------------------- def resp_rset(self): # Reset the plot. self.rset_plt() #----------------------------------------------------------------------- # DEFINE THE FUNCTION FOR RESPONDING TO THE "chng_mfi" SIGNAL. #----------------------------------------------------------------------- def resp_chng_mfi(self): # Regenerate the plot. self.make_plt()
class widget_mfi_lin_plot(QWidget): #----------------------------------------------------------------------- # DEFINE THE INITIALIZATION FUNCTION. #----------------------------------------------------------------------- def __init__(self, core): # Inherit all attributes of an instance of "QWidget". super(widget_mfi_lin_plot, self).__init__() # Store the Janus core. self.core = core # Prepare to respond to signals received from the core. self.connect(self.core, SIGNAL('janus_rset'), self.resp_rset) self.connect(self.core, SIGNAL('janus_chng_mfi'), self.resp_chng_mfi) # Initialize this widget's instance of "PlotWidget", which will # contain the plot of MFI magnetic field data. # Note. The "QGridLayout" object given to this widget as its # layout is essentially a dummy. I could have just had # this class inherit "PlotWidget", but I think that this # gives me a bit more control (and a similar structure # "janus_widget_fc_cup"). self.setLayout(QGridLayout()) self.plt = PlotWidget() self.layout().addWidget(self.plt) self.layout().setContentsMargins(0, 0, 0, 0) # Extract the individual elements of the "PlotWidget" object # (e.g., it's axes) for more convenient access later. self.vbx = self.plt.getViewBox() self.axs_x = self.plt.getAxis('bottom') self.axs_y = self.plt.getAxis('left') self.ptm = self.plt.getPlotItem() # Initialize and store the pens and fonts. self.pen_vbx = mkPen(color='k') self.pen_crv_m = mkPen(color='k') self.pen_crv_n = mkPen(color='k') self.pen_crv_x = mkPen(color='r') self.pen_crv_y = mkPen(color='g') self.pen_crv_z = mkPen(color='b') self.fnt = self.core.app.font() # Configure the plot: disable automatic adjustments and # adjustments made by the user, change the background and # foreground colors, enable grid lines for both axes, label the # axes, adjust the tick font size, adjust the "AxisItem" sizes, # and add a margin around the entire plot. self.plt.disableAutoRange() self.plt.setMouseEnabled(False, False) self.plt.setMenuEnabled(False) self.plt.hideButtons() self.plt.setBackground('w') setConfigOption('foreground', 'k') #####self.plt.showGrid( True, True ) labelStyle = {'color': 'k'} self.axs_x.setLabel('Time [s]', **labelStyle) self.axs_y.setLabel('Magnetic Field [nT]', **labelStyle) self.axs_x.label.setFont(self.fnt) self.axs_y.label.setFont(self.fnt) self.axs_x.setTickFont(self.fnt) self.axs_y.setTickFont(self.fnt) self.axs_x.setHeight(35) self.axs_y.setWidth(40) self.vbx.border = self.pen_vbx self.ptm.setContentsMargins(5, 5, 5, 5) # Initialize the curves that will be added to this plot. self.crv_m = None self.crv_n = None self.crv_x = None self.crv_y = None self.crv_z = None self.pl = [] # Populate this plot and adjust it's settings. self.make_plt() #----------------------------------------------------------------------- # DEFINE THE FUNCTION FOR POPULATING THE PLOT. #----------------------------------------------------------------------- def make_plt(self): # Reset the plot (i.e., remove all plot elements). self.rset_plt() # Establish the ranges of its time and magnetic field values. # If the core contains no data or only a single datum, # improvise (for the purpose of later establishing axis limits). if (self.core.n_mfi >= 1): # Establish the domain of the plot. t_min = min(amin(self.core.mfi_s), 0.) t_max = max(amax(self.core.mfi_s), self.core.fc_spec['dur']) # Establish the range of the plot. As part of this, # ensure that the range satisfies a minimum size and has # sufficient padding. b_max = amax(self.core.mfi_b) b_min = -b_max d_t_0 = t_max - t_min d_b_0 = b_max - b_min d_t = max(1.5 + d_t_0, 3.) d_b = max(1.2 * d_b_0, 5.) t_max = t_min + d_t b_min = b_min - (d_b - d_b_0) / 2. b_max = b_max + (d_b - d_b_0) / 2. else: t_min = 0.001 t_max = 3.500 b_min = -2.5 b_max = 2.5 # Set the range of the axis of each plot. self.plt.setXRange(t_min, t_max, padding=0.0) self.plt.setYRange(b_min, b_max, padding=0.0) # Set the PESA-L pen with a width corresponding to one rotation # Note: For some reason, the lines are not wide enough unless 5 # is added to the scaled width of the rotation time rot = 3.05 * self.axs_x.width() / (t_max - t_min) + 5 self.pen_pl = mkPen(color=(245, 245, 245), width=rot) # If the core contains no Wind/MFI magnetic field data, return. if (self.core.n_mfi <= 0): return # Generate and display each curve for the plot. self.crv_m = PlotDataItem(self.core.mfi_s, self.core.mfi_b, pen=self.pen_crv_m) self.crv_n = PlotDataItem(self.core.mfi_s, [-b for b in self.core.mfi_b], pen=self.pen_crv_n) self.crv_x = PlotDataItem(self.core.mfi_s, self.core.mfi_b_x, pen=self.pen_crv_x) self.crv_y = PlotDataItem(self.core.mfi_s, self.core.mfi_b_y, pen=self.pen_crv_y) self.crv_z = PlotDataItem(self.core.mfi_s, self.core.mfi_b_z, pen=self.pen_crv_z) # If PESA-L spectra were loaded, add the vertical indicators # showing their time relative to the start of the FC spectrum for n in range(len(self.core.pl_spec_arr)): time = self.core.pl_spec_arr[n]['time'][0] t_0 = self.core.fc_spec['time'] delta_t = (time - t_0).total_seconds() self.pl += [ InfiniteLine(delta_t + self.core.fc_spec['rot'] / 2., pen=self.pen_pl) ] for i in range(len(self.pl)): self.plt.addItem(self.pl[i]) self.plt.addItem(self.crv_m) self.plt.addItem(self.crv_n) self.plt.addItem(self.crv_x) self.plt.addItem(self.crv_y) self.plt.addItem(self.crv_z) #----------------------------------------------------------------------- # DEFINE THE FUNCTION FOR RESETTING THIS PLOT (CLEARING ALL ELEMENTS). #----------------------------------------------------------------------- def rset_plt(self): # Hide and remove each of this plot's elements. if (self.crv_m is not None): self.plt.removeItem(self.crv_m) if (self.crv_n is not None): self.plt.removeItem(self.crv_n) if (self.crv_x is not None): self.plt.removeItem(self.crv_x) if (self.crv_y is not None): self.plt.removeItem(self.crv_y) if (self.crv_z is not None): self.plt.removeItem(self.crv_z) if (self.pl != []): for i in range(len(self.pl)): self.plt.removeItem(self.pl[i]) # if ( self.crv_colat is not None ) : # self.plt.removeItem( self.crv_colat ) # if ( self.crv_lon is not None ) : # self.plt.removeItem( self.crv_lon ) # Permanently delete this plot's elements by setting each of the # variables that store them to "None". self.crv_m = None self.crv_n = None self.crv_x = None self.crv_y = None self.crv_z = None self.pl = [] #----------------------------------------------------------------------- # DEFINE THE FUNCTION FOR RESPONDING TO THE "rset" SIGNAL. #----------------------------------------------------------------------- def resp_rset(self): # Reset the plot. self.rset_plt() #----------------------------------------------------------------------- # DEFINE THE FUNCTION FOR RESPONDING TO THE "chng_mfi" SIGNAL. #----------------------------------------------------------------------- def resp_chng_mfi(self): # Regenerate the plot. self.make_plt()
class TabChartView(QtWidgets.QWidget): """ Виджет с графиком, стаканом и обновляющимся списком символов """ def __init__(self): super(TabChartView, self).__init__() self._setup_ui() self._controller = TabChartController(self) def _setup_ui(self): horizontal_layout = QtWidgets.QHBoxLayout(self) # list symbols area label_exchange = QtWidgets.QLabel('Exchanges') self.exchanges_combobox = QtWidgets.QComboBox() self.exchanges_combobox.setCurrentIndex(0) label_symbols = QtWidgets.QLabel('Pairs') self.pairs_combobox = QtWidgets.QComboBox() self.tickers_table = QtWidgets.QTableView() self.tickers_table.setSelectionBehavior( Qt.QAbstractItemView.SelectRows) self.tickers_table.verticalHeader().close() self.tickers_table.setSelectionMode( Qt.QAbstractItemView.SingleSelection) self.delete_ticker_button = QtWidgets.QPushButton('Delete from list') vertical_layout_1 = QtWidgets.QVBoxLayout() vertical_layout_1.addWidget(label_exchange) vertical_layout_1.addWidget(self.exchanges_combobox) vertical_layout_1.addWidget(label_symbols) vertical_layout_1.addWidget(self.pairs_combobox) vertical_layout_1.addWidget(self.tickers_table) vertical_layout_1.addWidget(self.delete_ticker_button) horizontal_layout.addLayout(vertical_layout_1, 2) # table cup area self.depth_table = QtWidgets.QTableView() self.depth_table.setSelectionMode( Qt.QAbstractItemView.SelectionMode.NoSelection) self.depth_table.horizontalHeader().setSectionResizeMode( QtWidgets.QHeaderView.Stretch) self.depth_table.verticalHeader().close() horizontal_layout.addWidget(self.depth_table, 2) # tools for chart area vertical_layout_2 = QtWidgets.QVBoxLayout() self.panel_layout = QtWidgets.QHBoxLayout() self.cross_hair_checkbox = QtWidgets.QCheckBox() self.cross_hair_checkbox.setChecked(True) self.cross_hair_checkbox.setText("Crosshair") self.panel_layout.addWidget(self.cross_hair_checkbox) self.autoscroll_checkbox = QtWidgets.QCheckBox() self.autoscroll_checkbox.setChecked(True) self.autoscroll_checkbox.setText("Auto-scroll") self.panel_layout.addWidget(self.autoscroll_checkbox) self.autoscale_checkbox = QtWidgets.QCheckBox() self.autoscale_checkbox.setChecked(True) self.autoscale_checkbox.setText("Auto-scaled") self.panel_layout.addWidget(self.autoscale_checkbox) self.timeframe_combobox = QtWidgets.QComboBox() self.panel_layout.addWidget(self.timeframe_combobox) self.chart_type_combobox = QtWidgets.QComboBox() self.panel_layout.addWidget(self.chart_type_combobox) vertical_layout_2.addLayout(self.panel_layout, 1) self.price_chart = PlotWidget() self.price_chart.setBackground("w") self.price_chart.hideButtons() self.price_chart.showGrid(True, True) self.price_chart.getPlotItem().showAxis('right') self.price_chart.getAxis('bottom').setStyle(showValues=False) self.price_chart.getAxis('left').setStyle(showValues=False) self.price_chart.getViewBox().setLimits(yMin=-1, xMin=-1) time_axis = CustomAxisItem(orientation='bottom') self.volume_chart = PlotWidget(axisItems={'bottom': time_axis}) self.volume_chart.setBackground("w") self.volume_chart.hideButtons() self.volume_chart.showGrid(True, True) self.volume_chart.getPlotItem().showAxis('right') self.volume_chart.getAxis('left').setStyle(showValues=False) self.volume_chart.getViewBox().setLimits(yMin=-1, xMin=-1) self.price_chart.setXLink(self.volume_chart) vertical_layout_2.addWidget(self.price_chart, 4) vertical_layout_2.addWidget(self.volume_chart, 1) horizontal_layout.addLayout(vertical_layout_2, 5)
def __init__(self, main_loop): # noinspection PyArgumentList super(ProgramUI, self).__init__() uic.loadUi("ui/USBIPManager.ui", self) self.show() # Setting application icon self.setWindowIcon(QIcon("icon/logo.png")) # Application main loop self.main_loop = main_loop # Getting the configuration from config.ini file self.config = config.get_config() self.cancel_process = CancelProcessButton( self.frameGeometry().width(), self.frameGeometry().height()) self.cancel_process.setParent(None) # Setting actions for main menu buttons self.auto_find_button.clicked.connect( partial(ApplicationMenu.auto_find, self)) self.add_server_button.clicked.connect( partial(ApplicationMenu.add_server, self)) self.search_all_button.clicked.connect( partial(ApplicationMenu.search_all, self)) self.connect_all_button.clicked.connect( partial(ApplicationMenu.connect_all, self)) self.disconnect_all_button.clicked.connect( partial(ApplicationMenu.disconnect_all, self, config.usbip_array)) self.settings_button.clicked.connect( partial(ApplicationMenu.settings, self)) # self.log.setContextMenuPolicy(Qt.CustomContextMenu) self.log.customContextMenuRequested.connect(self.log_context_menu) # Setting context menu for the server list box self.server_box.setContextMenuPolicy(Qt.CustomContextMenu) self.server_box.customContextMenuRequested.connect( partial(SRVArea.box_context_menu, self)) # Setting default context menu for the connected device tree box self.device_tree_menu = dict() self.device_tree_menu["menu"] = QMenu() self.device_tree_menu["action"] = dict() # Enabling data capture context action self.device_tree_menu["action"]["enable"] = \ QAction(QIcon("icon/enable.png"), _("Enable data capturing"), self) self.device_tree_menu["action"]["enable"].setEnabled(False) # Resetting data capture context action self.device_tree_menu["action"]["reset"] = \ QAction(QIcon("icon/reset.png"), _("Reset data capturing"), self) self.device_tree_menu["action"]["reset"].setEnabled(False) # Disabling data capture context action self.device_tree_menu["action"]["disable"] = \ QAction(QIcon("icon/disable.png"), _("Disable data capturing"), self) self.device_tree_menu["action"]["disable"].setEnabled(False) # self.device_box.setContextMenuPolicy(Qt.CustomContextMenu) self.device_box.customContextMenuRequested.connect( partial(DevTreeMenu.box_context_menu, self)) # Setting activity plot setConfigOption("background", "#FF000000") activity_graph = PlotWidget() activity_graph.setMenuEnabled(enableMenu=False) activity_graph.setMouseEnabled(x=False, y=False) activity_graph.showGrid(x=True, y=True) activity_graph.hideButtons() # Defining sent and received activity curves self.sent_curve = activity_graph.getPlotItem().plot() self.recv_curve = activity_graph.getPlotItem().plot() # Setting activity box layout and adding activity plot to the program window activity_layout = QGridLayout() self.activity_box.setLayout(activity_layout) activity_layout.addWidget(activity_graph) self.activity_box.setContextMenuPolicy(Qt.CustomContextMenu) self.activity_box.customContextMenuRequested.connect( partial(NetworkActivity.box_context_menu, self)) # Getting the configuration and filling the server list with the found servers SRVArea.srv_get(self) # Starting checking servers availability process self.srv_checking = self.main_loop.create_task( SRVArea.async_srv_check(self)) # Starting checking software cpu and memory usage process self.usage_checking = self.main_loop.create_task(async_sw_usage(self)) # Starting checking network activity process self.activity_checking = self.main_loop.create_task( NetworkActivity.async_get_activity(self)) if config.watchdog_enable: # Setting watchdog event handler as PyQt Object signal event_handler = ConfigWatchdog() event_handler.fileUpdated.connect(self.config_change_action) # Starting observer thread that schedules file watching and dispatches calls to event handler observer = Observer() observer.schedule(event_handler, path=path.dirname(path.abspath(__file__)), recursive=False) observer.start()