Esempio n. 1
0
    def __init__(self, parent=None):
        super(QMainWindow,self).__init__()
        self.setAttribute(QtCore.Qt.WA_DeleteOnClose)

        # initialize the FilterTreeBuilder class with the filter directory and
        # the filter file as parameters:         
        # read directory with filterDesigns and construct filter tree from it
        self.ftb = FilterTreeBuilder('filter_design', 'filter_list.txt', comment_char='#')
        self._construct_UI()
Esempio n. 2
0
    def __init__(self, parent=None):
        super(QMainWindow,self).__init__()
        self.setAttribute(QtCore.Qt.WA_DeleteOnClose)

        # create clipboard instance that can be accessed from other modules
        fb.clipboard = QApplication.clipboard()

        # initialize the FilterTreeBuilder class: 
        # read config file and construct filter tree from it
        self.ftb = FilterTreeBuilder()
        self._construct_UI()
Esempio n. 3
0
    def __init__(self, parent=None):
        super(QMainWindow, self).__init__()
        self.setAttribute(QtCore.Qt.WA_DeleteOnClose)

        # create clipboard instance that can be accessed from other modules
        fb.clipboard = QApplication.clipboard()

        # initialize the FilterTreeBuilder class with the filter directory and
        # the filter file as parameters:
        # read directory with filterDesigns and construct filter tree from it
        self.ftb = FilterTreeBuilder('filter_design',
                                     'filter_list.txt',
                                     comment_char='#')
        self._construct_UI()
Esempio n. 4
0
    def __init__(self, DEBUG=False):
        super(InputFilter, self).__init__()
        self.DEBUG = DEBUG
        # initialize the FilterTreeBuilder class with the filter directory and
        # the filter file
        self.ftb = FilterTreeBuilder('filter_design', 'filter_list.txt',
                                     comment_char='#', DEBUG=DEBUG)

        self.filter_initialized = False
        self.dm_last = '' # design method from last call

        self.initUI()

        self.setResponseType() # first time initialization
Esempio n. 5
0
class InputFilter(QtGui.QWidget):
    """
    Construct combo boxes for selecting the filter, consisting of:
      - Response Type (LP, HP, Hilbert, ...)
      - Filter Type (IIR, FIR, CIC ...)
      - DesignMethod (Butterworth, ...)
    """

    sigSpecsChanged = pyqtSignal()

    def __init__(self, DEBUG=False):
        super(InputFilter, self).__init__()
        self.DEBUG = DEBUG
        # initialize the FilterTreeBuilder class with the filter directory and
        # the filter file
        self.ftb = FilterTreeBuilder('filter_design', 'filter_list.txt',
                                     comment_char='#', DEBUG=DEBUG)

        self.filter_initialized = False
        self.dm_last = '' # design method from last call

        self.initUI()

        self.setResponseType() # first time initialization


    def initUI(self):
        """
        Initialize UI with comboboxes for selecting filter
        """
#-----------------------------------------------------------------------------
#        see filterbroker.py for structure and content of "filterTree" dict
#-----------------------------------------------------------------------------

        #----------------------------------------------------------------------
        # Create combo boxes
        # - cmbResponseType for selecting response type rt (LP, HP, ...)
		# - cmbFilterType for selection of filter type (IIR, FIR, ...)
		# - cmbDesignMethod for selection of design method (Chebychev, ...)
		# and populate them from the "filterTree" dict either directly or by
		# calling setResponseType() :

        self.cmbResponseType = QtGui.QComboBox(self)
        self.cmbResponseType.setToolTip("Select filter response type.")
        self.cmbFilterType = QtGui.QComboBox(self)
        self.cmbFilterType.setToolTip("Select the kind of filter (recursive, transversal, ...).")
        self.cmbDesignMethod = QtGui.QComboBox(self)
        self.cmbDesignMethod.setToolTip("Select the actual filter design method.")

        # Adapt combobox size dynamically to largest element
        self.cmbResponseType.setSizeAdjustPolicy(QtGui.QComboBox.AdjustToContents)
        self.cmbFilterType.setSizeAdjustPolicy(QtGui.QComboBox.AdjustToContents)
        self.cmbDesignMethod.setSizeAdjustPolicy(QtGui.QComboBox.AdjustToContents)

        # Translate short response type ("LP") to displayed names ("Lowpass")
        # (correspondence is defined in filterbroker.py) and populate combo box:
        for rt in fb.fil_tree:
            self.cmbResponseType.addItem(rc.rt_names[rt], rt)
        idx = self.cmbResponseType.findData('LP') # find index for 'LP'

        if idx == -1: # Key 'LP' does not exist, use first entry instead
            idx = 0

        self.cmbResponseType.setCurrentIndex(idx) # set initial index

        #----------------------------------------------------------------------
        # LAYOUT
        #----------------------------------------------------------------------
        # see Summerfield p. 278
        self.layHDynWdg = QtGui.QHBoxLayout() # for additional dynamic subwidgets
        self.frmDynWdg = QtGui.QFrame() # collect subwidgets in frame (no border)
        self.frmDynWdg.setObjectName("wdg_frmDynWdg")
        self.frmDynWdg.setSizePolicy(QtGui.QSizePolicy.MinimumExpanding, QtGui.QSizePolicy.Minimum)

        #Debugging: enable next line to show border of frmDnyWdg
        #self.frmDynWdg.setFrameStyle(QtGui.QFrame.StyledPanel|QtGui.QFrame.Raised)

        self.frmDynWdg.setLayout(self.layHDynWdg)

        layHStdWdg = QtGui.QHBoxLayout() # container for standard subwidgets

        spacer = QtGui.QSpacerItem(1, 0, QtGui.QSizePolicy.Expanding,
                                         QtGui.QSizePolicy.Fixed)

        layHStdWdg.addWidget(self.cmbResponseType)# QtCore.Qt.AlignLeft)

        layHStdWdg.addItem(spacer)

        layHStdWdg.addWidget(self.cmbFilterType)

        layHStdWdg.addItem(spacer)

        layHStdWdg.addWidget(self.cmbDesignMethod)

        # stack standard + dynamic subwidgets vertically:
        layVAllWdg = QtGui.QVBoxLayout()

        layVAllWdg.addLayout(layHStdWdg)
        layVAllWdg.addWidget(self.frmDynWdg)


        self.frmMain = QtGui.QFrame()
        self.frmMain.setFrameStyle(QtGui.QFrame.StyledPanel|QtGui.QFrame.Sunken)
        self.frmMain.setLayout(layVAllWdg)

        layHMain = QtGui.QHBoxLayout()
        layHMain.addWidget(self.frmMain)
        layHMain.setContentsMargins(0, 0, 0, 0)

        self.setLayout(layHMain)
#        layHMain.setSizeConstraint(QtGui.QLayout.SetFixedSize)

        #------------------------------------------------------------
        # SIGNALS & SLOTS
        #------------------------------------------------------------
        # Connect comboBoxes and setters:
        self.cmbResponseType.activated.connect(self.setResponseType) # 'LP'
        self.cmbResponseType.activated.connect(self.sigSpecsChanged.emit)
        self.cmbFilterType.activated.connect(self.setFilterType) #'IIR'
        self.cmbFilterType.activated.connect(self.sigSpecsChanged.emit)
        self.cmbDesignMethod.activated.connect(self.setDesignMethod) #'cheby1'
        self.cmbDesignMethod.activated.connect(self.sigSpecsChanged.emit)
        #------------------------------------------------------------


#------------------------------------------------------------------------------
    def loadEntries(self):
        """
        Reload comboboxes from filter dictionary to update changed settings
        e.g. by loading filter design
        """
        idx_rt = self.cmbResponseType.findData(fb.fil[0]['rt']) # find index for 'LP'
        self.cmbResponseType.setCurrentIndex(idx_rt)
        self.setResponseType()


#------------------------------------------------------------------------------
    def setResponseType(self):
        """
        Triggered when cmbResponseType (LP, HP, ...) is changed:
        Copy selection to self.rt and fb.fil[0] and reconstruct filter type combo

        If previous filter type (FIR, IIR, ...) exists for new rt, set the
        filter type combo box to the old setting
        """
        print("InputFilter.setResponseType triggered")
        # cmbBox.currentText() shows full text ('Lowpass'),
        # itemData contains abbreviation ('LP')
        rt_idx = self.cmbResponseType.currentIndex()
        self.rt = self.cmbResponseType.itemData(rt_idx)

        # In Python 3, python objects are automatically converted to QVariant
        # when stored as "data" e.g. in a QComboBox and converted back when
        # retrieving. In Python 2, QVariant is returned when data is retrieved.
        # This is first converted from the QVariant container format to a
        # QString, next to a "normal" non-unicode string
        if not isinstance(self.rt, str):
            self.rt = str(self.rt.toString()) # Why is QString -> str necessary?
        fb.fil[0]['rt'] = self.rt # copy selected rt setting to filter dict

        # Get list of available filter types for new rt
        ft_list = list(fb.fil_tree[self.rt].keys()) # explicit list() needed for Py3

        # Rebuild filter type combobox entries for new rt setting
        self.cmbFilterType.clear()
        self.cmbFilterType.addItems(ft_list)

        # Is last filter type (e.g. IIR) in list for new rt?
        # And has the widget been initialized?
        if fb.fil[0]['ft'] in ft_list and self.filter_initialized:
            ft_idx = self.cmbFilterType.findText(fb.fil[0]['ft'])
            self.cmbFilterType.setCurrentIndex(ft_idx) # yes, set same ft as before
        else:
            self.cmbFilterType.setCurrentIndex(0)     # no, set index 0

        self.setFilterType()

#------------------------------------------------------------------------------
    def setFilterType(self):
        """"
        Triggered when cmbFilterType (IIR, FIR, ...) is changed:
        Copy selected setting to self.ft and (re)construct design method combo,
        adding displayed text (e.g. "Chebychev 1") and hidden data (e.g. "cheby1")
        """
        # cmbBox.currentText() has full text ('IIR'),
        # itemData only abbreviation ('IIR') which is the same in this case

        self.ft = str(self.cmbFilterType.currentText())
        fb.fil[0]['ft'] = self.ft

        # Rebuild design method combobox entries for new ft setting:
        # The combobox is populated with the "long name", the internal name
        # is stored in comboBox.itemData
        self.cmbDesignMethod.clear()

        for dm in fb.fil_tree[self.rt][self.ft]:
            self.cmbDesignMethod.addItem(fb.dm_names[dm], dm)

        # get list of available design methods for new ft
        dm_list = fb.fil_tree[self.rt][self.ft].keys()
        if self.DEBUG:
            print("dm_list", dm_list)
            print(fb.fil[0]['dm'])

        # Is previous design method (e.g. ellip) in list for new ft?
        # And has the widget been initialized?
        if fb.fil[0]['dm'] in dm_list and self.filter_initialized:
            # yes, set same dm as before, don't call setDesignMethod
            dm_idx = self.cmbDesignMethod.findText(fb.dm_names[fb.fil[0]['dm']])
            if self.DEBUG: 
                print("dm_idx", dm_idx)
            self.cmbDesignMethod.setCurrentIndex(dm_idx)
        else:
            self.cmbDesignMethod.setCurrentIndex(0)     # no, set index 0

        self.setDesignMethod()


#------------------------------------------------------------------------------
    def setDesignMethod(self):
        """
        Triggered when cmbDesignMethod (cheby1, ...) is changed:
        Instantiate (new) filter object
        """
        dm_idx = self.cmbDesignMethod.currentIndex()
        dm = self.cmbDesignMethod.itemData(dm_idx)
        if not isinstance(dm, str):
            dm = str(dm.toString()) # see explanation in setResponseType()
        fb.fil[0]['dm'] = dm

        # Check whether setDesignMethod has been called for the first time
        # (= no filter object exists, AttributeError is raised). If not, check
        # whether the design method has been changed. In both cases,
        # a (new) filter object is instantiated
        try: # has a filter object been instantiated yet?
            if dm not in fb.filObj.name: # Yes (if no error occurs), check name
                fb.filObj = self.ftb.objectWizzard(dm)
        except AttributeError as e: # No, create a filter instance
            fb.filObj = self.ftb.objectWizzard(dm)

        # Check whether new design method also provides the old filter order
        # method. If yes, don't change it, else set first available
        # filter order method
        if fb.fil[0]['fo'] not in fb.fil_tree[self.rt][self.ft][dm].keys():
            fb.fil[0].update({'fo':{}})
            fb.fil[0]['fo'] = fb.fil_tree[self.rt][self.ft][dm].keys()[0]

        if self.DEBUG:
            print("=== InputFilter.setDesignMethod ===")
            print("selFilter:", fb.fil[0])
            print("filterTree[dm] = ", fb.fil_tree[self.rt][self.ft][dm])
            print("filterTree[dm].keys() = ", fb.fil_tree[self.rt][self.ft]\
                                                            [dm].keys())

        self.filter_initialized = True

        self._update_dyn_widgets() # check for new subwidgets and update if needed

#        self.sigSpecsChanged.emit() # -> input_widgets


#------------------------------------------------------------------------------
    def _update_dyn_widgets(self):
        """
        Delete dynamically (i.e. within filter design routine) created subwidgets
        and create new ones, depending on requirements of filter design algorithm


        This does NOT work when the subwidgets to be deleted and created are
        identical, as the deletion is only performed when the current scope has
        been left (?)! Hence, it is necessary to skip this method when the new
        design method is the same as the old one.
        """
# TODO: see https://www.commandprompt.com/community/pyqt/x3410.htm

        if fb.fil[0]['dm'] != self.dm_last:

            # Find "old" dyn. subwidgets and delete them:
            widgetList = self.frmDynWdg.findChildren(
                (QtGui.QComboBox, QtGui.QLineEdit, QtGui.QLabel, QtGui.QWidget))
    #       widgetListNames = [w.objectName() for w in widgetList]

            for w in widgetList:
                self.layHDynWdg.removeWidget(w)   # remove widget from layout
                w.deleteLater()             # tell Qt to delete object when the
                                            # method has completed
#                del w                       # not really needed?

            # Try to create "new" dyn. subwidgets:
            if hasattr(fb.filObj, 'wdg'):
                try:
                    if 'sf' in fb.filObj.wdg:
                        a = getattr(fb.filObj, fb.filObj.wdg['sf'])
                        self.layHDynWdg.addWidget(a, stretch=1)
                        self.layHDynWdg.setContentsMargins(0, 0, 0, 0)
                        self.frmDynWdg.setVisible(a != None)

                except AttributeError as e:
                    print("sf.updateWidgets:", e)
                    self.frmDynWdg.setVisible(False)
            else:
                self.frmDynWdg.setVisible(False)

        self.dm_last = fb.fil[0]['dm']