Пример #1
0
class FormTabWidget(QWidget):
    def __init__(self, datalist, comment="", parent=None):
        QWidget.__init__(self, parent)
        layout = QHBoxLayout()
        self.contentsWidget = QListWidget()
        self.contentsWidget.setViewMode(QListView.ListMode)
        self.contentsWidget.setMovement(QListView.Static)
        self.contentsWidget.setMaximumWidth(128)

        self.pagesWidget = QStackedWidget()
        layout.addWidget(self.contentsWidget)
        layout.addWidget(self.pagesWidget)
        self.setLayout(layout)
        self.widgetlist = []

        for elem in datalist:
            if len(elem) == 4:
                data, title, comment, icon = elem
            else:
                data, title, comment = elem
                icon = None

            if len(data[0]) == 3:
                widget = FormComboWidget(data, comment=comment, parent=self)
            else:
                widget = FormWidget(data, comment=comment, parent=self)
            #index = self.tabwidget.addTab(widget, title)
            #self.tabwidget.setTabToolTip(index, comment)
            self.pagesWidget.addWidget(widget)
            contentItem = QListWidgetItem(self.contentsWidget)
            if icon:
                contentItem.setIcon(icon)
            contentItem.setText(title)
            contentItem.setToolTip(comment)
            contentItem.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled)
            self.contentsWidget.addItem(contentItem)
            self.widgetlist.append(widget)

        self.contentsWidget.currentRowChanged.connect(self.changePage)

    def changePage(self, current):
        if current != -1:
            self.pagesWidget.setCurrentIndex(current)

    def setup(self):
        for widget in self.widgetlist:
            widget.setup()

    def get(self):
        return [ widget.get() for widget in self.widgetlist]
Пример #2
0
class MiniCalculation(QDialog):
    AppName = u"迷你计算器"

    def __init__(self, parent=None):
        super(MiniCalculation, self).__init__(parent)
        self.btnHelpState = False
        self.setWindowTitle(MiniCalculation.AppName)
        self.txtBrower = QTextBrowser()
        self.txtLine = QLineEdit()
        self.txtLine.setPlaceholderText(u"请输入表达式,按回车结束...")

        self.btnCal = QPushButton(u"计算")
        self.btnClear = QPushButton(u"清空")
        self.btnHelp = QPushButton(u"特殊函数表>>")
        self.btnHelp.setCheckable(True)
        self.btnHelp.setChecked(True)

        mathList = [s for s in dir(math) if not s.startswith("__")]
        self.listWidget = QListWidget()
        self.listWidget.addItems(mathList)
        for i in range(len(mathList)):
            item = self.listWidget.item(i)
            strFun = item.text() + '.__doc__'
            item.setToolTip(eval(str(strFun)))
        self.listWidget.setMaximumWidth(100)

        midLay = QHBoxLayout()
        midLay.addWidget(self.btnCal)
        midLay.addWidget(self.btnClear)
        midLay.addStretch()
        midLay.addWidget(self.btnHelp)

        bottomLay = QHBoxLayout()
        bottomLay.addWidget(self.txtBrower)
        bottomLay.addWidget(self.listWidget)

        lay = QVBoxLayout()
        lay.addWidget(self.txtLine)
        lay.addItem(midLay)
        lay.addItem(bottomLay)

        self.resize(450, 300)
        self.setLayout(lay)
        self.updateUI()

        self.btnCal.clicked.connect(self.btnCalClicked)
        self.btnClear.clicked.connect(self.txtLine.clear)
        self.btnClear.clicked.connect(self.txtBrower.clear)
        self.btnHelp.clicked.connect(self.updateUI)
        self.listWidget.itemDoubleClicked.connect(self.listItemDoubleClicked)

    def updateUI(self):
        state = not self.btnHelp.isChecked()
        self.listWidget.setHidden(state)
        text = u"特殊函数表>>" if state else u"特殊函数表<<"
        self.btnHelp.setText(text)

    def btnCalClicked(self):
        try:
            txt = str(self.txtLine.text())
            self.txtBrower.append("%s = <b>%s</b>" % (txt, eval(txt)))
        except UnicodeEncodeError:
            QMessageBox.warning(self,u"QData -- 迷你计算机",
                    u"表达式中存在中文或全角字符\n",
                    QMessageBox.Ok)
        except:
            self.txtBrower.append("<font color=red>%s <b>is invalid</b>" % txt)

    def listItemDoubleClicked(self):
        item = self.listWidget.currentItem()
        self.txtLine.insert(item.text())
        self.txtLine.setFocus()
Пример #3
0
class ConfigDialog(QDialog):
    def __init__(self, parent=None):
        QDialog.__init__(self, parent)

        self.contents_widget = QListWidget()
        self.contents_widget.setMovement(QListView.Static)
        self.contents_widget.setMinimumWidth(120)
        self.contents_widget.setMaximumWidth(120)
        self.contents_widget.setSpacing(1)

        bbox = QDialogButtonBox(QDialogButtonBox.Ok|QDialogButtonBox.Apply
                                     |QDialogButtonBox.Cancel)
        self.apply_btn = bbox.button(QDialogButtonBox.Apply)
        self.connect(bbox, SIGNAL("accepted()"), SLOT("accept()"))
        self.connect(bbox, SIGNAL("rejected()"), SLOT("reject()"))
        self.connect(bbox, SIGNAL("clicked(QAbstractButton*)"),
                     self.button_clicked)

        self.pages_widget = QStackedWidget()
        self.connect(self.pages_widget, SIGNAL("currentChanged(int)"),
                     self.current_page_changed)

        self.connect(self.contents_widget, SIGNAL("currentRowChanged(int)"),
                     self.pages_widget.setCurrentIndex)
        self.contents_widget.setCurrentRow(0)

        hlayout = QHBoxLayout()
        hlayout.addWidget(self.contents_widget)
        hlayout.addWidget(self.pages_widget)
        hlayout.setStretch(1,1)

        btnlayout = QHBoxLayout()
        btnlayout.addStretch(1)
        btnlayout.addWidget(bbox)

        vlayout = QVBoxLayout()
        vlayout.addLayout(hlayout)
        vlayout.addLayout(btnlayout)

        self.setLayout(vlayout)

        self.setWindowTitle("Preferences")
        self.setWindowIcon(get_icon("configure.png"))
        
    def get_current_index(self):
        """Return current page index"""
        return self.contents_widget.currentRow()
        
    def set_current_index(self, index):
        """Set current page index"""
        self.contents_widget.setCurrentRow(index)
        
    def accept(self):
        """Reimplement Qt method"""
        for index in range(self.pages_widget.count()):
            configpage = self.pages_widget.widget(index)
            if not configpage.is_valid():
                return
            configpage.apply_changes()
        QDialog.accept(self)
        
    def button_clicked(self, button):
        if button is self.apply_btn:
            # Apply button was clicked
            configpage = self.pages_widget.currentWidget()
            if not configpage.is_valid():
                return
            configpage.apply_changes()
            
    def current_page_changed(self, index):
        widget = self.pages_widget.widget(index)
        self.apply_btn.setVisible(widget.apply_callback is not None)
        self.apply_btn.setEnabled(widget.is_modified)
        
    def add_page(self, widget):
        self.connect(self, SIGNAL('check_settings()'), widget.check_settings)
        self.connect(widget, SIGNAL('show_this_page()'),
                     lambda row=self.contents_widget.count():
                     self.contents_widget.setCurrentRow(row))
        self.connect(widget, SIGNAL("apply_button_enabled(bool)"),
                     self.apply_btn.setEnabled)
        self.pages_widget.addWidget(widget)
        item = QListWidgetItem(self.contents_widget)
        item.setIcon(widget.get_icon())
        item.setText(widget.get_name())
        item.setFlags(Qt.ItemIsSelectable|Qt.ItemIsEnabled)
        item.setSizeHint(QSize(0, 25))
        
    def check_all_settings(self):
        """This method is called to check all configuration page settings
        after configuration dialog has been shown"""
        self.emit(SIGNAL('check_settings()'))
Пример #4
0
class MainWindow(QMainWindow):
    """The main window widget for the program.

    """

    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)

        #### 1 CREATE AND INITIALIZE DATA STRUCTURES ####

        self.xLabel = None
        self.xSelection = DEFAULTX
        self.xSelection_old = None
        self.xArray = None

        self.yLabel = None
        self.ySelection = DEFAULTY
        self.ySelection_old = None

        self.yArray = None

        self.filename = None

        self.tdms_file_object = None

        self.channel_registry = {}

        # Y selector on Left
        self.ySelector = QListWidget()
        ySelectorLabel = QLabel("y axis channel")
        self.ySelector.setMaximumWidth(ySelectorLabel.sizeHint().width())

        # File name and plot in the middle
        self.sourceFileName = QLabel("None")
        self.sourceFileName.setSizePolicy(QSizePolicy.Expanding,
                                          QSizePolicy.Fixed)
        sourceFileLabel = QLabel("current file")
        sourceFileLabel.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)

        # Matplotlib canvas
        fig = Figure(dpi=100)
        self.canvas = FigureCanvas(fig)
        self.canvas.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        mpl_toolbar = NavigationToolbar(self.canvas, self.canvas)

        self.axes = fig.add_subplot(111)

        # X selector on bottom
        self.xSelector = QListWidget()
        self.xSelector.addItem("Time")
        self.xSelector.setFlow(0)
        xSelectorLabel = QLabel("x axis channel")
        self.xSelector.setMaximumHeight(self.xSelector.sizeHintForColumn(0))

        # Offset and parameter widgets on the right top
        self.offsetThing = OffsetWidget()
        self.attributesThing = AttributesWidget()

        # Save channel on right bottom
        self.save_chan_chkbx = QCheckBox()
        save_chan_label = QLabel("Save Channel")

        # Status bar at the bottom

        self.fileSizeLabel = QLabel("File Size: {f_size:0>7.3f} MB".format(f_size=0.0))
        self.fileSizeLabel.setFixedWidth(self.fileSizeLabel.sizeHint().width()+10)
        self.fileSizeLabel.setFrameStyle(QFrame.Panel|QFrame.Sunken)

        self.yChanLength = QLabel("Y Channel Length: {y_len:0>7.0f}".format(y_len=0.0))
        self.yChanLength.setFixedWidth(self.yChanLength.sizeHint().width()+10)
        self.yChanLength.setFrameStyle(QFrame.Panel|QFrame.Sunken)
        
        self.xChanLength = QLabel("X Channel Length: {x_len:0>7.0f}".format(x_len=0.0))
        self.xChanLength.setFixedWidth(self.xChanLength.sizeHint().width()+10)
        self.xChanLength.setFrameStyle(QFrame.Panel|QFrame.Sunken)

        status = self.statusBar()
        status.setSizeGripEnabled(False)
        status.addPermanentWidget(self.fileSizeLabel)
        status.addPermanentWidget(self.yChanLength)
        status.addPermanentWidget(self.xChanLength)

        status.showMessage("Ready", 5000)
        
        #2 Create the central widget
        self.centralWidget = QWidget()

        # Left Side
        selectorLayout = QVBoxLayout()
        #selectorLayout.addWidget(xSelectorLabel)
        #selectorLayout.addWidget(self.xSelector)
        selectorLayout.addWidget(ySelectorLabel)
        selectorLayout.addWidget(self.ySelector)
        selectorLayout.addStretch()

        # Center
        centralLayout = QVBoxLayout()
        fileNameLayout = QHBoxLayout()
        xSelectorLayout = QHBoxLayout()
        fileNameLayout.addWidget(sourceFileLabel)
        fileNameLayout.addWidget(self.sourceFileName)
        xSelectorLayout.addWidget(xSelectorLabel)
        xSelectorLayout.addWidget(self.xSelector)
        centralLayout.addLayout(fileNameLayout)
        centralLayout.addWidget(self.canvas)
        centralLayout.addWidget(mpl_toolbar)
        centralLayout.addLayout(xSelectorLayout)

        # Right bottom
        save_chan_layout = QHBoxLayout()
        save_chan_layout.addWidget(self.save_chan_chkbx)
        save_chan_layout.addWidget(save_chan_label)

        # Right Side
        rightLayout = QVBoxLayout()
        rightLayout.addWidget(self.offsetThing)
        rightLayout.addWidget(self.attributesThing)
        rightLayout.addStretch()
        rightLayout.addLayout(save_chan_layout)

        layout = QHBoxLayout()
        layout.addLayout(selectorLayout)
        layout.addLayout(centralLayout)
        layout.addLayout(rightLayout)

        self.centralWidget.setLayout(layout)
        self.setCentralWidget(self.centralWidget)

        self.resize(self.sizeHint())

        #3 Create and set up any dock windows

        #4 Create actions and insert them into menus and toolbars
        fileQuitAction = self.createAction("&Quit", self.close, "Ctrl+Q",
                                           "exit", "Close the application")
        fileOpenAction = self.createAction("&Open TDMS File", self.fileOpen,
                                           QKeySequence.Open, "fileopen",
                                           "Open an existing TDMS file")
        fileExportAction = self.createAction("&Export", self.exprtToHDF5,
                                             "Ctrl+E",
                                             tip="Export the TDMS data to HDF5")

        self.fileMenu = self.menuBar().addMenu("&File")
        self.fileMenuActions = (fileOpenAction, fileExportAction,
                                fileQuitAction)
        #self.addActions(self.fileMenu, self.fileMenuActions)

        self.xSelector.itemSelectionChanged.connect(self.make_x_selection)
        self.ySelector.itemSelectionChanged.connect(self.make_y_selection)
        self.offsetThing.new_offset.connect(self.subtract_offset)
        self.fileMenu.triggered.connect(self.update_file_menu)

        self.save_chan_chkbx.stateChanged.connect(self.toggle_save)

        #5 Read in application's settings
        settings = QSettings()

        # Restore the geometry and state of the main window from last use
        #self.restoreGeometry(settings.value("MainWindow/Geometry"))
        #self.restoreState(settings.value("MainWindow/State"))

        self.setWindowTitle("TDMS to HDF5 Converter")
        self.recentFiles = settings.value("RecentFiles")
        if not self.recentFiles:
            self.recentFiles = []

        self.update_file_menu()

    def update_ui(self):
        pass

    def initVariables(self):
        self.xLabel = None
        self.xSelection = DEFAULTX
        self.xSelection_old = None
        self.xArray = None

        self.yLabel = None
        self.ySelection = DEFAULTY
        self.ySelection_old = None

        self.yArray = None

        self.filename = None

        self.tdms_file_object = None

        self.channel_registry = {}

    def createAction(self, text, slot=None, shortcut=None, icon=None,
                     tip=None, checkable=False, signal="triggered()"):
        # Create the action
        action = QAction(text, self)
        # Give it its icon
        if icon is not None:
            action.setIcon(QIcon(":/{icon}.png".format(icon=icon)))
        # Give it its shortcut
        if shortcut is not None:
            action.setShortcut(shortcut)
        # Set up its help/tip text
        if tip is not None:
            action.setToolTip(tip)
            action.setStatusTip(tip)
        # Connect it to a signal
        if slot is not None:
            self.connect(action, SIGNAL(signal), slot)
        # Make it checkable
        if checkable:
            action.setCheckable(True)
        return action

    def addActions(self, target, actions):
        for action in actions:
            if action is None:
                target.addSeparator()
            else:
                target.addAction(action)

    def update_file_menu(self):
        self.fileMenu.clear()
        self.addActions(self.fileMenu, self.fileMenuActions[:-1])
        current = self.filename if self.filename is not None else None
        recentFiles = []
        for fname in self.recentFiles:
            if fname != current and QFile.exists(fname):
                recentFiles.append(fname)
        if recentFiles:
            self.fileMenu.addSeparator()
            for i, fname in enumerate(recentFiles):
                action = QAction("&{num} {name}".format(num=i+1, name=QFileInfo(fname).fileName()), self)
                action.setData(fname)
                action.triggered.connect(lambda: self.loadFile(fname))
                self.fileMenu.addAction(action)
        self.fileMenu.addSeparator()
        self.fileMenu.addAction(self.fileMenuActions[-1])

    def fileOpen(self): # Process 1
        self.initVariables()
        basedir = os.path.dirname(self.filename) if self.filename is not None \
          else "~/Documents/PhD/root/raw-data/sio2al149/CryoMeasurement"
        formats = "TDMS files (*.tdms)"
        fname = QFileDialog.getOpenFileName(self, "Open a TDMS File",
                                            basedir, formats)

        # Process 1.1 Collect file name
        if fname and QFile.exists(fname):
            self.loadFile(fname)

    def loadFile(self, fname): # Process 1.2 Generate TDMS file object
        self.add_recent_file(fname)
        self.tdms_file_object = TdmsFile(fname)
        self.filename = fname

         # Process 1.3 Read data into local structure
        if self.tdms_file_object:

            # Process 1.3.0 Generate group list
            group_list = self.tdms_file_object.groups()

            # Processes 1.3.1 through 1.3.3 Sort TDMS data
            for group in group_list:
                self.sortTDMSGroupData(group)

            message = "Loaded {f_name}".format(f_name=os.path.basename(fname))
            self.sourceFileName.setText(os.path.basename(fname))

            # Process 2.1 Populate channel selection lists
            self.update_selectors()

        else:
            message = "Failed to load {f_name}".format(f_name=os.path.
                                                       basename(fname))

        self.statusBar().showMessage(message, 5000)

        fsize = os.path.getsize(self.filename)
        self.fileSizeLabel.setText("File Size: {file_size:>7.3f} MB".format(file_size=fsize/1E6))
        #TODO self.updateStatus(message) # see Rapid GUI ch06.pyw

    def add_recent_file(self, fname):
        if fname is None:
            return
        if not fname in self.recentFiles:
            self.recentFiles.insert(0, fname)
            while len(self.recentFiles) > 9:
                self.recentFiles.pop()

    def sortTDMSGroupData(self, group): # Process 1.3 Sort Group data

        # Process 1.3.1 Get <Group> Channels
        group_props = self.tdms_file_object.object(group).properties

        # Process 1.3.2 Get <Group> Properties
        group_chans = self.tdms_file_object.group_channels(group)

        # Process 1.3.3 Create a new channel in the registry for each channel
        # in the group
        for chan in group_chans:
            chan_name = chan.path.split('/')[-1].strip("'")

            # Process 1.3.3.1 Generate new channel object and fill with data
            # Some of the TDMS channels were created, but never populated with
            # data. The following weeds those out.
            try:
                new_chan = Channel(chan_name,
                                device=group,
                                meas_array=chan.data)
            except TypeError:
                self.statusBar().showMessage("Channel {chan} in {dev} has no data"
                                             .format(chan=chan_name, dev=group),
                                             5000)

            try:
                new_chan.set_start_time(chan.property("wf_start_time"))

                new_chan.set_delta_time(chan.property("wf_increment"))

                new_chan.set_location('raw/{c2_name}'.format(c2_name=chan_name))

                if chan_name not in ['TCap', 'xMagnet']:
                    new_chan.set_write()

                # Some of the channel-specific properties were actually
                # saved in the group object's properties list.
                # We retrieve those here.
                # Process 1.3.3.2 Resort the group properties of TDMS ADWin
                if group == "ADWin":
                    for atr_name in ADWIN_DICT[chan_name]:
                        try:
                            new_chan.attributes[atr_name] = \
                              group_props[atr_name]
                        except KeyError:
                            #print('The key {a_name} was not found.'
                            #      .format(a_name=atr_name))
                            #print('The keys available are\n')
                            #print(group_props)
                            pass

                # Process 1.3.3.3 Add new channel to the registry
                self.channel_registry[chan_name] = new_chan

                #print('\tChannel name:\t{ch_name}'.format(ch_name=chan_name))

            except (KeyError, UnboundLocalError):
                pass
                #print('Error: Was unable to load {c3_name}'
                #      .format(c3_name=chan_name))

    def update_selectors(self):

        # Clear the selectors
        self.xSelector.clear()
        self.ySelector.clear()

        # Add the names of the channels in the registry to both selectors
        for key in self.channel_registry.keys():
            self.xSelector.addItem(key)
            self.ySelector.addItem(key)

        # Add the time "channel" to the x selector
        self.xSelector.addItem('Time')

        # Sort the lists (alphabetically) otherwise the order constantly changes
        self.xSelector.sortItems()
        self.ySelector.sortItems()

        # Set the current x selector default
        default_x_item = self.xSelector.findItems(DEFAULTX, Qt.MatchExactly)
        self.xSelector.setCurrentItem(default_x_item[0])

        # Set the current y selector default
        try:
            default_y_item = self.ySelector.findItems(DEFAULTY,
                                                      Qt.MatchExactly)
            self.ySelector.setCurrentItem(default_y_item[0])
        except IndexError:
            self.ySelector.setCurrentRow(0)

        self.xSelector.setMinimumHeight(self.xSelector.sizeHintForRow(0)*3)
        self.ySelector.setMinimumWidth(self.ySelector.sizeHintForColumn(0)+10)

    def exprtToHDF5(self): # Process 5 Save to HDF5
        fname = self.filename.split('.')[0] + '.hdf5'
        basedir = "/home/chris/Documents/PhD/root/data/sio2al149/cryo_measurement"

        if not os.path.exists(basedir):
            os.makedirs(basedir)

        formats = "TDMS files (*.hdf5 *.h5 *.he5 *.hdf)"
    
        dialog = QFileDialog()
        dialog.setFilter(formats)
        dialog.setDefaultSuffix("*.hdf5")
        dialog.selectFile(os.path.join(basedir, fname))
        dialog.setDirectory(basedir)
        if dialog.exec_():
            fname = dialog.selectedFiles()
        else:
            return

        # Process 5.1 Create HDF5 file object
        hdf5_file_object = h5py.File(fname[0])

        # Process 5.2 Create channels at their locations
        for chan in self.channel_registry:

            chan_obj = self.channel_registry[chan]
            chan_name = chan

            #print(chan, self.channel_registry[chan].location,
            #      self.channel_registry[chan].write_to_file)

            # Process 5.2.1 Write channel data
            if self.channel_registry[chan].write_to_file:

                dset = hdf5_file_object.create_dataset(chan_obj.location,
                                                            data=chan_obj.data)

            # Process 5.2.2 Write channel attributes
            for attr_name in self.channel_registry[chan].attributes:
                attr_value = self.channel_registry[chan].attributes[attr_name]

                # Convert the datetime format to a string
                if type(attr_value) is datetime:
                    attr_value = attr_value.isoformat()

                # There's currently a wierd bug when dealing with python3
                # strings.
                # This gets around that
                if type(attr_value) is str:
                    #attr_value = attr_value.encode('utf-8')
                    #attr_value = np.string_(attr_value, dtype="S10")
                    attr_value = np.string_(attr_value)

                dset.attrs.create(attr_name, attr_value)

        # Process 5.3 Write data to file
        hdf5_file_object.flush()
        hdf5_file_object.close()

    def make_x_selection(self):

        self.x_change = True

        # Get the name of the newly selected channel
        self.xSelection = self.xSelector.currentItem().text()

        # Get the axis label
        self.xLabel = self.gen_axis_label(self.xSelection)

        # If the xSelection is time, use the time data instead of measurement
        # data
        if self.xSelection == 'Time':
            try:
                self.xArray = self.channel_registry[self.ySelection].time
            except KeyError:
                self.xArray = np.array([])
        else:
            self.xArray = self.channel_registry[self.xSelection].data

        if self.yLabel:
            self.plotData()

        self.xSelection_old = self.xSelector.currentItem()

        self.x_change = False

        self.xChanLength.setText("X Channel Length: {x_len:>7.0f}".format(x_len=len(self.xArray)))

    def make_y_selection(self, offset=0.0):

        self.y_change = True

        # Get the names of the selected channels from the selectors
        try:
            self.ySelection = self.ySelector.currentItem().text()
        except AttributeError:
            self.ySelection = DEFAULTY

        # Set save channel checkbox state
        self.save_chan_chkbx.setChecked(self.channel_registry[self.ySelection]
                                        .write_to_file)

        # Get the axis label
        self.yLabel = self.gen_axis_label(self.ySelection)

        # Generate the y-channel array to be plotted
        self.yArray = self.channel_registry[self.ySelection].data - offset

        # Update the attributes view
        self.attributesThing.clear_attributes()

        self.attributesThing.select_chan(self.channel_registry[self.ySelection])

        if self.xSelection == 'Time':
            self.make_x_selection()
        else:
            self.plotData()

        self.ySelection_old = self.ySelector.currentItem()

        self.y_change = False

        self.yChanLength.setText("Y Channel Length: {y_len:>7.0f}".format(y_len=len(self.yArray)))

    def gen_axis_label(self, chan_name):

        # Generate the axis labels based on the selected channels
        # Cycle through the labes in the AXESLABELS dictionary
        for axlbl in AXESLABELS.keys():

            # Cycle through the channel names in each label's dictionary entry
            for cn in AXESLABELS[axlbl]:

                # If a channel equals one of the selections, save the label 
                if chan_name == cn:
                    label = axlbl

        return label

    def plotData(self):

        # Clear the plot
        self.axes.cla()

        # Turn on the grid
        self.axes.grid(True)

        # Set the labels
        try: 
            self.axes.set_xlabel(self.xLabel)
        except UnboundLocalError:
            self.statusBar().showMessage("Could not generate an axis label for {chan}"
                                         .format(chan=self.xSelection), 5000)
        try:
            self.axes.set_ylabel(self.yLabel)
        except UnboundLocalError:
            self.statusBar().showMessage("Could not generate an axis label for {chan}"
                                         .format(chan=self.ySelection), 5000)

        # Try plotting the data. There are still no checks in place to make sure
        # the arrays are of the same length.
        try:
            # Plot the data and label it
            self.axes.plot(self.xArray, self.yArray, label=self.ySelection)

            # Show the legend
            self.axes.legend(loc=0)

            # Draw everything
            self.canvas.draw()
        except ValueError:

            QMessageBox.warning(self, "Unequal Arrays", "{y_chan} and {x_chan} "
                                .format(y_chan=self.ySelection,
                                        x_chan=self.xSelection) + \
                                        "are not the same length!")

            if self.x_change:
                self.xSelector.setCurrentItem(self.xSelection_old)
            elif self.y_change:
                self.ySelector.setCurrentItem(self.ySelection_old)

    def subtract_offset(self):
        "Subtract the offset entered from the currently selected y channel."

        offset = self.offsetThing.offset_entry.value()

        self.make_y_selection(offset=offset)

    def toggle_save(self):

        self.channel_registry[self.ySelection].write_to_file = \
          self.save_chan_chkbx.isChecked()

    def create_new_channel(self, ch_name):
        "Create a new channel in the registry."

        #print(ch_name)
        pass

    def closeEvent(self, event):
        """Reimplementation of the close even handler.

        We have to reimplement this because not all close actions, e.g. clicking
        the X button, call the close() method.  We want to catch this so we can
        give the user the opportunity to save unsaved changes before the program
        exits.

        """
        settings = QSettings()
        #settings.setValue("MainWindow/Geometry", QVariant(
        #    self.saveGeometry()))
        #settings.setValue("MainWindow/State", QVariant(
        #    self.saveState()))
        if self.recentFiles:
            recentFiles = self.recentFiles
        else:
            recentFiles = []
        settings.setValue("RecentFiles", recentFiles)
Пример #5
0
class ConfigDialog(QDialog):
    def __init__(self, parent=None):
        QDialog.__init__(self, parent)

        self.contents_widget = QListWidget()
        self.contents_widget.setMovement(QListView.Static)
        self.contents_widget.setMinimumWidth(120)
        self.contents_widget.setMaximumWidth(120)
        self.contents_widget.setSpacing(1)

        bbox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Apply
                                | QDialogButtonBox.Cancel)
        self.apply_btn = bbox.button(QDialogButtonBox.Apply)
        self.connect(bbox, SIGNAL("accepted()"), SLOT("accept()"))
        self.connect(bbox, SIGNAL("rejected()"), SLOT("reject()"))
        self.connect(bbox, SIGNAL("clicked(QAbstractButton*)"),
                     self.button_clicked)

        self.pages_widget = QStackedWidget()
        self.connect(self.pages_widget, SIGNAL("currentChanged(int)"),
                     self.current_page_changed)

        self.connect(self.contents_widget, SIGNAL("currentRowChanged(int)"),
                     self.pages_widget.setCurrentIndex)
        self.contents_widget.setCurrentRow(0)

        hlayout = QHBoxLayout()
        hlayout.addWidget(self.contents_widget)
        hlayout.addWidget(self.pages_widget)
        hlayout.setStretch(1, 1)

        btnlayout = QHBoxLayout()
        btnlayout.addStretch(1)
        btnlayout.addWidget(bbox)

        vlayout = QVBoxLayout()
        vlayout.addLayout(hlayout)
        vlayout.addLayout(btnlayout)

        self.setLayout(vlayout)

        self.setWindowTitle("Preferences")
        self.setWindowIcon(get_icon("configure.png"))

    def get_current_index(self):
        """Return current page index"""
        return self.contents_widget.currentRow()

    def set_current_index(self, index):
        """Set current page index"""
        self.contents_widget.setCurrentRow(index)

    def accept(self):
        """Reimplement Qt method"""
        for index in range(self.pages_widget.count()):
            configpage = self.pages_widget.widget(index)
            if not configpage.is_valid():
                return
            configpage.apply_changes()
        QDialog.accept(self)

    def button_clicked(self, button):
        if button is self.apply_btn:
            # Apply button was clicked
            configpage = self.pages_widget.currentWidget()
            if not configpage.is_valid():
                return
            configpage.apply_changes()

    def current_page_changed(self, index):
        widget = self.pages_widget.widget(index)
        self.apply_btn.setVisible(widget.apply_callback is not None)
        self.apply_btn.setEnabled(widget.is_modified)

    def add_page(self, widget):
        self.connect(self, SIGNAL('check_settings()'), widget.check_settings)
        self.connect(widget,
                     SIGNAL('show_this_page()'),
                     lambda row=self.contents_widget.count(): self.
                     contents_widget.setCurrentRow(row))
        self.connect(widget, SIGNAL("apply_button_enabled(bool)"),
                     self.apply_btn.setEnabled)
        self.pages_widget.addWidget(widget)
        item = QListWidgetItem(self.contents_widget)
        item.setIcon(widget.get_icon())
        item.setText(widget.get_name())
        item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled)
        item.setSizeHint(QSize(0, 25))

    def check_all_settings(self):
        """This method is called to check all configuration page settings
        after configuration dialog has been shown"""
        self.emit(SIGNAL('check_settings()'))
Пример #6
0
class I2CWidget(QWidget):

    def __init__(self, status, actions):
        super (I2CWidget, self).__init__()
        self.status =  status
        self.actions = actions

        self.row_add_action = QAction("Add Row", self)
        self.row_add_action.triggered.connect(self.add_row)

        self.row_delete_action = QAction("Delete Row", self)
        self.row_delete_action.triggered.connect(self.remove_row)

        self.default_script_list = QListWidget()
        self.default_script_list.setMaximumWidth(150)

        self.default_script_list.itemDoubleClicked.connect(self.default_script_load_double_clicked)
        self.setWindowTitle("Standalone I2C Widget")
        layout = QHBoxLayout()
        self.load_callback = None
        self.toolbar = QToolBar()
        self.toolbar.setMaximumWidth(150)
        self.toolbar.setSizePolicy(Qt.QSizePolicy.Maximum, Qt.QSizePolicy.Maximum)

        self.tools_layout= QVBoxLayout()

        self.save_loader = SaveLoader(extensions = ["csv"],
                                      initial_file = "i2c_config_file")

        self.toolbar.setOrientation(QtCore.Qt.Vertical)
        self.toolbar.addAction(self.row_add_action)
        self.toolbar.addAction(self.row_delete_action)
        self.tools_layout.addWidget(self.toolbar)
        self.tools_layout.addWidget(QLabel("Default Scripts"))
        self.tools_layout.addWidget(self.default_script_list)
        default_script_load = QPushButton("Load")
        default_script_load.clicked.connect(self.default_script_load_clicked)
        self.tools_layout.addWidget(default_script_load)


        self.tab_view = QTabWidget()

        self.init_table = I2CTable(self.status, self.actions, loop = False)
        self.loop_table = I2CTable(self.status, self.actions, loop = True)
        self.tab_view.addTab(self.init_table, "Start")
        self.tab_view.addTab(self.loop_table, "Loop")

        self.control_view = I2CControlView(self.status, self.actions)
        self.actions.i2c_update_view.connect(self.update_i2c_transactions)

        layout.addLayout(self.tools_layout)

        io_layout = QVBoxLayout()
        io_layout.addWidget(self.save_loader)
        name_desc_layout = QHBoxLayout()
        self.config_name = QLineEdit("Name")
        self.config_name.setMinimumWidth(100)
        self.config_name.setSizePolicy(Qt.QSizePolicy.Preferred, Qt.QSizePolicy.Preferred)

        self.config_desc = QLineEdit("Description")
        name_desc_layout.addWidget(self.config_name)
        name_desc_layout.addWidget(self.config_desc)

        io_layout.addLayout(name_desc_layout)
        io_layout.addWidget(self.tab_view)

        layout.addLayout(io_layout)

        #layout.addWidget(self.tab_view)
        layout.addWidget(self.control_view)

        self.setLayout(layout)
        

        self.actions.i2c_update_read_view.connect(self.update_read_view)
        self.init_read_data = None
        self.loop_read_data = None
        self.read_timer = QTimer(self)
        self.read_timer.setInterval(SINGLE_SHOT_TIMEOUT)
        self.read_timer.setSingleShot(True)

    def get_config_name(self):
        return self.config_name.text()

    def set_config_name(self, name):
        self.config_name.setText(name)

    def get_config_description(self):
        return self.config_desc.text()

    def set_config_description(self, description):
        self.config_desc.setText(description)

    def add_row(self):
        if self.tab_view.currentWidget() is self.loop_table:
            self.actions.i2c_row_add.emit(True)
        else:
            self.actions.i2c_row_add.emit(False)

    def remove_row(self):
        if self.tab_view.currentWidget() is self.loop_table:
            self.actions.i2c_row_delete.emit(True)
        else:
            self.actions.i2c_row_delete.emit(False)

    def update_i2c_transactions(self, loop, transactions):
        if not loop:
            self.update_i2c_init_transactions(transactions)
        else:
            self.update_i2c_loop_transactions(transactions)

    def update_i2c_init_transactions(self, transactions):
        self.init_table.update_i2c_transactions(transactions)

    def update_i2c_loop_transactions(self, transactions):
        self.loop_table.update_i2c_transactions(transactions)

    def set_save_callback(self, callback):
        self.save_loader.set_save_callback(callback)

    def set_load_callback(self, callback):
        self.save_loader.set_load_callback(callback)

    def get_filename(self):
        return self.save_loader.get_filename()

    def default_script_load_clicked(self):
        item = self.default_script_list.currentItem()
        if item is not None:
            filename = os.path.join(DEFAULT_SCRIPT_PATH, str(item.text()))
            if self.load_callback is not None:
                self.load_callback(filename)
            #print "Item: %s" % filename

    def set_load_default_callback(self, callback):
        self.load_callback = callback

    def default_script_load_double_clicked(self, item):
        self.default_script_load_clicked()

    def load_default_scripts(self):
        files = os.listdir(DEFAULT_SCRIPT_PATH)
        self.default_script_list.clear()
        self.default_script_list.addItems(files)
        self.default_script_list.setCurrentRow(0)

    def singleshot_event(self):
        #print "update I2C Read: in thread: %s" % str(QThread.currentThread().objectName())

        if self.init_read_data is not None:
            self.init_table.update_read_data(self.init_read_data)
            self.init_read_data = None
        if self.loop_read_data is not None:
            self.loop_table.update_read_data(self.loop_read_data)
            self.loop_read_data = None

    def update_read_view(self, loop, read_data):
        #print "read timer active: %s" % str(self.read_timer.isActive())
        if loop:
            self.loop_read_data = read_data

        else:
            self.init_read_data = read_data

        if not self.read_timer.isActive():
            self.read_timer.singleShot(SINGLE_SHOT_TIMEOUT, self.singleshot_event)
            self.read_timer.start()
class ChatTracer(QMainWindow):
    def __init__(self):
        super(ChatTracer, self).__init__()
        self.__initGui()
        self.__initQeo()
        self.connect(self, SIGNAL("newLogMsg"), self.__appendLog)

    def __initGui(self):
        self.setWindowTitle("ChatTracer")

        g = QGridLayout()
        w = QWidget()
        w.setLayout(g)
        self.setCentralWidget(w)

        self.logWindow = QTextEdit()
        self.logWindow.setReadOnly(True)
        self.logWindow.setFocusPolicy(Qt.NoFocus)
        self.logWindow.setMinimumWidth(300)
        g.addWidget(self.logWindow, 0, 0, 3, 1)

        l = QLabel("ChatParticipants")
        g.addWidget(l, 0, 1)

        self.participants = QListWidget()
        self.participants.setMaximumWidth(250)
        self.participants.setFocusPolicy(Qt.NoFocus)
        g.addWidget(self.participants, 1, 1)

        pb = QPushButton("Refresh Participants")
        pb.clicked.connect(self.onRefreshParticipants)
        g.addWidget(pb, 2, 1)

        g.setColumnStretch(0, 3)
        g.setColumnStretch(1, 2)

        self.show()
        pb.setFocus()

    def __initQeo(self):
        self.participantReader = StateReader(
                ChatParticipant,
                onData=self.forwardData,
                onNoMoreData=lambda cls="ChatParticipant": self.forwardNoMoreData(cls),
                onDispose=self.forwardDispose)
        self.msgReader = EventReader(ChatMessage,
                onData=self.forwardData,
                onNoMoreData=lambda cls="ChatMessage": self.forwardNoMoreData(cls))

        self.connect(self, SIGNAL("onData"), self.onData)
        self.connect(self, SIGNAL("onNoMoreData"), self.onNoMoreData)
        self.connect(self, SIGNAL("onDispose"), self.onDispose)


    def closeApp(self):
        self.participantReader.close()
        self.participantReader = None
        self.msgReader.close()
        self.msgReader = None

    def __appendLog(self, msg):
        self.logWindow.append(msg)

    def __buildLogMsg(self, prefix, data):
        msg = [prefix + ": "]
        if data:
            msg.append("%s" % data.__class__.__name__)
            msg.append("{")
            for k, v in data.__dict__.iteritems():
                msg.append("%s='%s'" % (str(k), str(v)))
        msg.append("}")
        self.__appendLog(' '.join(msg))

    def forwardData(self, s):
        self.emit(SIGNAL("onData"), s)

    def forwardDispose(self, s):
        self.emit(SIGNAL("onDispose"), s)

    def forwardNoMoreData(self, s):
        self.emit(SIGNAL("onNoMoreData"), s)

    def onData(self, sample):
        self.__buildLogMsg("onData", sample)

    def onDispose(self, sample):
        print "onDispose called: %s - %s" % (sample.name, sample.room)

    def onNoMoreData(self, class_):
        self.__buildLogMsg("onNoMoreData", None)

    def onRefreshParticipants(self):
        self.participants.clear()
        for s in self.participantReader.states():
            self.participants.addItem("%s - %s - %s" % (s.name, s.room, s.state))
Пример #8
0
class LayerImportBrowser(QDialog):

    class VectorPage(QWidget):
        def __init__(self, parent=None, filters="", encodings=[]):
            QWidget.__init__(self, parent)
            self.filters = filters
            self.layerLineEdit = QLineEdit()
            self.browseToolButton = QToolButton()
            self.browseToolButton.setAutoRaise(True)
            self.browseToolButton.setIcon(QIcon(":document-open"))
            layerLabel = QLabel("&Dataset:")
            layerLabel.setBuddy(self.layerLineEdit)

            self.encodingComboBox = QComboBox()
            self.encodingComboBox.addItems(encodings)
            encodingLabel = QLabel("&Encoding:")
            encodingLabel.setBuddy(self.encodingComboBox)

            hbox = QHBoxLayout()
            hbox.addWidget(layerLabel)
            hbox.addWidget(self.layerLineEdit)
            hbox.addWidget(self.browseToolButton)
            vbox = QVBoxLayout()
            vbox.addLayout(hbox)
            hbox = QHBoxLayout()
            hbox.addWidget(encodingLabel)
            hbox.addWidget(self.encodingComboBox)
            vbox.addLayout(hbox)
            self.setLayout(vbox)
            self.encodingComboBox.setCurrentIndex(self.encodingComboBox.findText("System"))

            self.connect(self.browseToolButton,
                SIGNAL("clicked()"), self.browseToFile)
            self.connect(self.encodingComboBox,
                SIGNAL("currentIndexChanged(QString)"), self.changeEncoding)

        def browseToFile(self):
            dialog = QFileDialog(self, "manageR - Open Vector File",
                unicode(robjects.r.getwd()[0]), self.filters)
            if not dialog.exec_() == QDialog.Accepted:
                return
            files = dialog.selectedFiles()
            file = files.first().trimmed()
            self.layerLineEdit.setText(file)
            self.emit(SIGNAL("filePathChanged(QString)"), file)

        def changeEncoding(self, text):
            self.emit(SIGNAL("encodingChanged(QString)"), text)

    class RasterPage(QWidget):
        def __init__(self, parent=None, filters=""):
            QWidget.__init__(self, parent)
            self.parent = parent
            self.filters = filters
            self.layerLineEdit = QLineEdit()
            self.browseToolButton = QToolButton()
            self.browseToolButton.setAutoRaise(True)
            self.browseToolButton.setIcon(QIcon(":document-open"))
            layerLabel = QLabel("&Dataset:")
            layerLabel.setBuddy(self.layerLineEdit)

            hbox = QHBoxLayout()
            hbox.addWidget(layerLabel)
            hbox.addWidget(self.layerLineEdit)
            hbox.addWidget(self.browseToolButton)
            vbox = QVBoxLayout()
            vbox.addLayout(hbox)
            self.setLayout(vbox)

            self.connect(self.browseToolButton, SIGNAL("clicked()"), self.browseToFile)

        def browseToFile(self):
            dialog = QFileDialog(self, "manageR - Open Raster File",
                unicode(robjects.r.getwd()[0]), self.filters)
            if not dialog.exec_() == QDialog.Accepted:
                return
            files = dialog.selectedFiles()
            file = files.first().trimmed()
            self.layerLineEdit.setText(file)
            self.emit(SIGNAL("filePathChanged(QString)"), file)

    def __init__(self, parent=None, vectors="", rasters="", encodings=[]):
        QDialog.__init__(self, parent)
        self.contentsWidget = QListWidget()
        self.setWindowIcon(QIcon(":icon"))
        self.contentsWidget.setViewMode(QListView.IconMode)
        self.contentsWidget.setIconSize(QSize(76, 66))
        self.contentsWidget.setMovement(QListView.Static)
        self.contentsWidget.setMaximumWidth(106)
        self.contentsWidget.setMinimumWidth(106)
        self.contentsWidget.setMinimumHeight(220)
        self.contentsWidget.setSpacing(12)
        self.__filePath = ""
        self.__encoding = "System"
        self.__type = 0

        self.pagesWidget = QStackedWidget()
        vectorPage = self.VectorPage(self, vectors, encodings)
        self.pagesWidget.addWidget(vectorPage)
        rasterPage = self.RasterPage(self, rasters)
        self.pagesWidget.addWidget(rasterPage)

        buttons = QDialogButtonBox(QDialogButtonBox.Ok|QDialogButtonBox.Cancel,
            Qt.Horizontal, self)

        self.connect(buttons, SIGNAL("accepted()"), self.accept)
        self.connect(buttons, SIGNAL("rejected()"), self.reject)
        self.connect(vectorPage, SIGNAL("filePathChanged(QString)"), self.setFilePath)
        self.connect(vectorPage, SIGNAL("encodingChanged(QString)"), self.setEncoding)
        self.connect(rasterPage, SIGNAL("filePathChanged(QString)"), self.setFilePath)

        self.createIcons()
        self.contentsWidget.setCurrentRow(0)

        horizontalLayout = QHBoxLayout()
        horizontalLayout.addWidget(self.contentsWidget)
        horizontalLayout.addWidget(self.pagesWidget, 1)

        mainLayout = QVBoxLayout()
        mainLayout.addLayout(horizontalLayout)
        mainLayout.addStretch(1)
        mainLayout.addSpacing(12)
        mainLayout.addWidget(buttons)
        self.setLayout(mainLayout)
        self.setWindowTitle("manageR - Import Layer")

    def createIcons(self):
        vectorButton = QListWidgetItem(self.contentsWidget)
        vectorButton.setIcon(QIcon(":custom-vector.svg"))
        vectorButton.setText("Vector Layer")
        vectorButton.setTextAlignment(Qt.AlignHCenter)
        vectorButton.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled)
        rasterButton = QListWidgetItem(self.contentsWidget)
        rasterButton.setIcon(QIcon(":custom-raster.svg"))
        rasterButton.setText("Raster Layer")
        rasterButton.setTextAlignment(Qt.AlignHCenter)
        rasterButton.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled)

        self.connect(self.contentsWidget,
            SIGNAL("currentItemChanged(QListWidgetItem*, QListWidgetItem*)"),
            self.changePage)

    def changePage(self, current, previous):
        if not current:
            current = previous
        self.pagesWidget.setCurrentIndex(self.contentsWidget.row(current))

    def filePath(self):
        return self.__filePath
        
    def setFilePath(self, filePath):
        self.__filePath = filePath

    def encoding(self):
        return self.__encoding
    
    def setEncoding(self, encoding):
        self.__encoding = encoding
        
    def layerType(self):
        return self.__type
        
    def setLayerType(self, type):
        self.__type = type

    def accept(self):
        self.__type = self.pagesWidget.currentIndex()
        QDialog.accept(self)
Пример #9
0
class ChatTracer(QMainWindow):
    def __init__(self):
        super(ChatTracer, self).__init__()
        self.__initGui()
        self.__initQeo()
        self.connect(self, SIGNAL("newLogMsg"), self.__appendLog)

    def __initGui(self):
        self.setWindowTitle("ChatTracer")

        g = QGridLayout()
        w = QWidget()
        w.setLayout(g)
        self.setCentralWidget(w)

        self.logWindow = QTextEdit()
        self.logWindow.setReadOnly(True)
        self.logWindow.setFocusPolicy(Qt.NoFocus)
        self.logWindow.setMinimumWidth(300)
        g.addWidget(self.logWindow, 0, 0, 3, 1)

        l = QLabel("ChatParticipants")
        g.addWidget(l, 0, 1)

        self.participants = QListWidget()
        self.participants.setMaximumWidth(250)
        self.participants.setFocusPolicy(Qt.NoFocus)
        g.addWidget(self.participants, 1, 1)

        pb = QPushButton("Refresh Participants")
        pb.clicked.connect(self.onRefreshParticipants)
        g.addWidget(pb, 2, 1)

        g.setColumnStretch(0, 3)
        g.setColumnStretch(1, 2)

        self.show()
        pb.setFocus()

    def __initQeo(self):
        self.participantReader = StateReader(
            ChatParticipant,
            onData=self.forwardData,
            onNoMoreData=lambda cls="ChatParticipant": self.forwardNoMoreData(
                cls),
            onDispose=self.forwardDispose)
        self.msgReader = EventReader(
            ChatMessage,
            onData=self.forwardData,
            onNoMoreData=lambda cls="ChatMessage": self.forwardNoMoreData(cls))

        self.connect(self, SIGNAL("onData"), self.onData)
        self.connect(self, SIGNAL("onNoMoreData"), self.onNoMoreData)
        self.connect(self, SIGNAL("onDispose"), self.onDispose)

    def closeApp(self):
        self.participantReader.close()
        self.participantReader = None
        self.msgReader.close()
        self.msgReader = None

    def __appendLog(self, msg):
        self.logWindow.append(msg)

    def __buildLogMsg(self, prefix, data):
        msg = [prefix + ": "]
        if data:
            msg.append("%s" % data.__class__.__name__)
            msg.append("{")
            for k, v in data.__dict__.iteritems():
                msg.append("%s='%s'" % (str(k), str(v)))
        msg.append("}")
        self.__appendLog(' '.join(msg))

    def forwardData(self, s):
        self.emit(SIGNAL("onData"), s)

    def forwardDispose(self, s):
        self.emit(SIGNAL("onDispose"), s)

    def forwardNoMoreData(self, s):
        self.emit(SIGNAL("onNoMoreData"), s)

    def onData(self, sample):
        self.__buildLogMsg("onData", sample)

    def onDispose(self, sample):
        print "onDispose called: %s - %s" % (sample.name, sample.room)

    def onNoMoreData(self, class_):
        self.__buildLogMsg("onNoMoreData", None)

    def onRefreshParticipants(self):
        self.participants.clear()
        for s in self.participantReader.states():
            self.participants.addItem("%s - %s - %s" %
                                      (s.name, s.room, s.state))