示例#1
0
    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))
示例#4
0
    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()
示例#6
0
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()
示例#7
0
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()
示例#8
0
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)
示例#9
0
    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()