def _construct_UI(self): """ Intitialize the widget, consisting of: - Matplotlib widget with NavigationToolbar - Frame with control elements """ self.cmbUnitsPhi = QComboBox(self) units = ["rad", "rad/pi", "deg"] scales = [1., 1. / np.pi, 180. / np.pi] for unit, scale in zip(units, scales): self.cmbUnitsPhi.addItem(unit, scale) self.cmbUnitsPhi.setObjectName("cmbUnitsA") self.cmbUnitsPhi.setToolTip("Set unit for phase.") self.cmbUnitsPhi.setCurrentIndex(0) self.cmbUnitsPhi.setSizeAdjustPolicy(QComboBox.AdjustToContents) self.chkWrap = QCheckBox("Wrapped Phase", self) self.chkWrap.setChecked(False) self.chkWrap.setToolTip("Plot phase wrapped to +/- pi") layHControls = QHBoxLayout() layHControls.addWidget(self.cmbUnitsPhi) layHControls.addWidget(self.chkWrap) layHControls.addStretch(10) #---------------------------------------------------------------------- # ### frmControls ### # # This widget encompasses all control subwidgets #---------------------------------------------------------------------- self.frmControls = QFrame(self) self.frmControls.setObjectName("frmControls") self.frmControls.setLayout(layHControls) #---------------------------------------------------------------------- # ### mplwidget ### # # main widget, encompassing the other widgets #---------------------------------------------------------------------- self.mplwidget = MplWidget(self) self.mplwidget.layVMainMpl.addWidget(self.frmControls) self.mplwidget.layVMainMpl.setContentsMargins(*params['wdg_margins']) self.setLayout(self.mplwidget.layVMainMpl) self.init_axes() self.draw() # initial drawing #---------------------------------------------------------------------- # GLOBAL SIGNALS & SLOTs #---------------------------------------------------------------------- self.sig_rx.connect(self.process_sig_rx) #---------------------------------------------------------------------- # LOCAL SIGNALS & SLOTs #---------------------------------------------------------------------- self.chkWrap.clicked.connect(self.draw) self.cmbUnitsPhi.currentIndexChanged.connect(self.unit_changed) self.mplwidget.mplToolbar.sig_tx.connect(self.process_sig_rx)
def main(): import sys from pyfda.libs.compat import QApplication, QFrame app = QApplication(sys.argv) # instantiate filter widget filt = Firwin() filt.construct_UI() wdg_firwin = getattr(filt, 'wdg_fil') layVDynWdg = QVBoxLayout() layVDynWdg.addWidget(wdg_firwin, stretch=1) filt.LPman(fb.fil[0]) # design a low-pass with parameters from global dict print(fb.fil[0][filt.FRMT]) # return results in default format frmMain = QFrame() frmMain.setFrameStyle(QFrame.StyledPanel | QFrame.Sunken) frmMain.setLayout(layVDynWdg) mainw = frmMain mainw.show() app.exec_()
def _construct_UI(self): """ Construct user interface """ # subwidget for Frequency Specs self.f_specs = freq_specs.FreqSpecs(self, title="Frequency") # subwidget for Amplitude Specs self.a_specs = amplitude_specs.AmplitudeSpecs(self, title="Amplitude") self.a_specs.setVisible(True) """ LAYOUT """ bfont = QFont() bfont.setBold(True) lblTitle = QLabel(self) # field for widget title lblTitle.setText(self.title) lblTitle.setFont(bfont) # lblTitle.setContentsMargins(2,2,2,2) layHTitle = QHBoxLayout() layHTitle.addWidget(lblTitle) layHTitle.setAlignment(Qt.AlignHCenter) layHSpecs = QHBoxLayout() layHSpecs.setAlignment(Qt.AlignTop) layHSpecs.addWidget(self.f_specs) # frequency specs layHSpecs.addWidget(self.a_specs) # ampltitude specs layVSpecs = QVBoxLayout() layVSpecs.addLayout(layHTitle) layVSpecs.addLayout(layHSpecs) layVSpecs.setContentsMargins(0, 6, 0, 0) # (left, top, right, bottom) # This is the top level widget, encompassing the other widgets frmMain = QFrame(self) frmMain.setLayout(layVSpecs) self.layVMain = QVBoxLayout() # Widget main layout self.layVMain.addWidget(frmMain) self.layVMain.setContentsMargins(*params['wdg_margins']) self.setLayout(self.layVMain) # ---------------------------------------------------------------------- # GLOBAL SIGNALS & SLOTs # ---------------------------------------------------------------------- # connect f_specs and a_specs subwidget to signalling self.f_specs.sig_tx.connect(self.sig_tx) # pass signal upwards self.sig_rx.connect(self.f_specs.sig_rx) # pass on received signals self.a_specs.sig_tx.connect(self.sig_tx) # pass signal upwards self.update_UI() # first time initialization
def _construct_UI(self): """ Construct User Interface """ self.layGSpecs = QGridLayout() # Sublayout for spec fields, populated # dynamically in _show_entries() title = "Weight Specifications" bfont = QFont() bfont.setBold(True) lblTitle = QLabel(self) # field for widget title lblTitle.setText(str(title)) lblTitle.setFont(bfont) lblTitle.setWordWrap(True) self.butReset = QToolButton(self) self.butReset.setText("Reset") self.butReset.setToolTip("Reset weights to 1") layHTitle = QHBoxLayout() # Layout for title and reset button layHTitle.addWidget(lblTitle) layHTitle.addWidget(self.butReset) # set the title as the first (fixed) entry in grid layout. The other # fields are added and hidden dynamically in _show_entries and _hide_entries() self.layGSpecs.addLayout(layHTitle, 0, 0, 1, 2) # This is the top level widget, encompassing the other widgets frmMain = QFrame(self) frmMain.setLayout(self.layGSpecs) self.layVMain = QVBoxLayout() # Widget main vertical layout self.layVMain.addWidget(frmMain) self.layVMain.setContentsMargins(*params['wdg_margins']) self.setLayout(self.layVMain) # - Build a list from all entries in the fil_dict dictionary starting # with "W" (= weight specifications of the current filter) # - Pass the list to setEntries which recreates the widget # ATTENTION: Entries need to be converted from QString to str for Py 2 self.n_cur_labels = 0 # number of currently visible labels / qlineedits new_labels = [str(l) for l in fb.fil[0] if l[0] == 'W'] self.update_UI(new_labels=new_labels) #---------------------------------------------------------------------- # LOCAL SIGNALS & SLOTs / EVENT FILTER #---------------------------------------------------------------------- self.butReset.clicked.connect(self._reset_weights)
def _construct_UI(self): """ Intitialize the widget, consisting of: - Matplotlib widget with NavigationToolbar - Frame with control elements """ self.chkWarnings = QCheckBox(self.tr("Verbose"), self) self.chkWarnings.setChecked(self.verbose) self.chkWarnings.setToolTip( self. tr("<span>Print messages about singular group delay and calculation times." "</span>")) self.cmbAlgorithm = QComboBox(self) qcmb_box_populate(self.cmbAlgorithm, self.cmb_algorithm_items, self.algorithm) layHControls = QHBoxLayout() layHControls.addStretch(10) layHControls.addWidget(self.chkWarnings) # layHControls.addWidget(self.chkScipy) layHControls.addWidget(self.cmbAlgorithm) # This widget encompasses all control subwidgets: self.frmControls = QFrame(self) self.frmControls.setObjectName("frmControls") self.frmControls.setLayout(layHControls) self.mplwidget = MplWidget(self) self.mplwidget.layVMainMpl.addWidget(self.frmControls) self.mplwidget.layVMainMpl.setContentsMargins(*params['mpl_margins']) self.mplwidget.mplToolbar.a_he.setEnabled(True) self.mplwidget.mplToolbar.a_he.info = "manual/plot_tau_g.html" self.setLayout(self.mplwidget.layVMainMpl) self.init_axes() self.draw() # initial drawing of tau_g # ---------------------------------------------------------------------- # GLOBAL SIGNALS & SLOTs # ---------------------------------------------------------------------- self.sig_rx.connect(self.process_sig_rx) # ---------------------------------------------------------------------- # LOCAL SIGNALS & SLOTs # ---------------------------------------------------------------------- self.mplwidget.mplToolbar.sig_tx.connect(self.process_sig_rx) self.cmbAlgorithm.currentIndexChanged.connect(self.draw)
def _construct_UI(self): """ Intitialize the user interface - """ # widget / subwindow for parameter selection self.butSave = QPushButton("Save Filter", self) self.butLoad = QPushButton("Load Filter", self) self.butAbout = QPushButton("About", self) # ============== UI Layout ===================================== bfont = QFont() bfont.setBold(True) bifont = QFont() bifont.setBold(True) bifont.setItalic(True) ifont = QFont() ifont.setItalic(True) layVIO = QVBoxLayout() layVIO.addWidget(self.butSave) # save filter dict -> various formats layVIO.addWidget(self.butLoad) # load filter dict -> various formats layVIO.addWidget(self.butAbout) # pop-up "About" window # This is the top level widget, encompassing the other widgets frmMain = QFrame(self) frmMain.setLayout(layVIO) layVMain = QVBoxLayout() layVMain.setAlignment(Qt.AlignTop) # layVMain.addLayout(layVIO) layVMain.addWidget(frmMain) layVMain.setContentsMargins(*params['wdg_margins']) self.setLayout(layVMain) #---------------------------------------------------------------------- # LOCAL SIGNALS & SLOTs #---------------------------------------------------------------------- self.butSave.clicked.connect(self.save_filter) self.butLoad.clicked.connect(self.load_filter) self.butAbout.clicked.connect(self.about_window)
def _construct_UI(self): """ Construct the User Interface """ bfont = QFont() bfont.setBold(True) lblTitle = QLabel(str(self.title), self) # field for widget title lblTitle.setFont(bfont) lblTitle.setWordWrap(True) self.lblUnit = QLabel(self) self.lblUnit.setText("in " + to_html(fb.fil[0]['freq_specs_unit'], frmt='bi')) layHTitle = QHBoxLayout() layHTitle.addWidget(lblTitle) layHTitle.addWidget(self.lblUnit) layHTitle.addStretch(1) # Create a gridLayout consisting of QLabel and QLineEdit fields # for the frequency specs: self.layGSpecs = QGridLayout() # sublayout for spec fields # set the title as the first (fixed) entry in grid layout. The other # fields are added and hidden dynamically in _show_entries and _hide_entries() self.layGSpecs.addLayout(layHTitle, 0, 0, 1, 2) self.layGSpecs.setAlignment(Qt.AlignLeft) self.frmMain = QFrame(self) self.frmMain.setLayout(self.layGSpecs) self.layVMain = QVBoxLayout() # Widget main layout self.layVMain.addWidget(self.frmMain) #, Qt.AlignLeft) self.layVMain.setContentsMargins(*params['wdg_margins']) self.setLayout(self.layVMain) self.n_cur_labels = 0 # number of currently visible labels / qlineedits #---------------------------------------------------------------------- # GLOBAL SIGNALS & SLOTs #---------------------------------------------------------------------- self.sig_rx.connect(self.process_sig_rx)
def _construct_UI(self): """ Intitialize the widget, consisting of: - top chkbox row - coefficient table - two bottom rows with action buttons """ self.bfont = QFont() self.bfont.setBold(True) self.bifont = QFont() self.bifont.setBold(True) self.bifont.setItalic(True) # q_icon_size = QSize(20, 20) # optional, size is derived from butEnable ####################################################################### # frmMain # # This frame contains all the buttons ####################################################################### # --------------------------------------------- # layHDisplay # # UI Elements for controlling the display # --------------------------------------------- self.butEnable = PushButton(self, icon=QIcon(':/circle-check.svg'), checked=True) q_icon_size = self.butEnable.iconSize() # <- uncomment this for manual sizing self.butEnable.setToolTip( "<span>Show / hide filter coefficients in an editable table." " For high order systems, table display might be slow.</span>") fix_formats = ['Dec', 'Hex', 'Bin', 'CSD'] self.cmbFormat = QComboBox(self) model = self.cmbFormat.model() item = QtGui.QStandardItem('Float') item.setData('child', Qt.AccessibleDescriptionRole) model.appendRow(item) item = QtGui.QStandardItem('Fixp.:') item.setData('parent', Qt.AccessibleDescriptionRole) item.setData(0, QtGui.QFont.Bold) item.setFlags(item.flags() & ~Qt.ItemIsEnabled) # | Qt.ItemIsSelectable)) model.appendRow(item) for idx in range(len(fix_formats)): item = QtGui.QStandardItem(fix_formats[idx]) # item.setForeground(QtGui.QColor('red')) model.appendRow(item) self.cmbFormat.insertSeparator(1) qset_cmb_box(self.cmbFormat, 'float') self.cmbFormat.setToolTip('Set the display format.') self.cmbFormat.setSizeAdjustPolicy(QComboBox.AdjustToContents) self.spnDigits = QSpinBox(self) self.spnDigits.setRange(0, 16) self.spnDigits.setValue(params['FMT_ba']) self.spnDigits.setToolTip("Number of digits to display.") self.lblDigits = QLabel("Digits", self) self.lblDigits.setFont(self.bifont) self.cmbQFrmt = QComboBox(self) q_formats = [('Norm. Frac.', 'qnfrac'), ('Integer', 'qint'), ('Fractional', 'qfrac')] for q in q_formats: self.cmbQFrmt.addItem(*q) self.lbl_W = QLabel("W = ", self) self.lbl_W.setFont(self.bifont) self.ledW = QLineEdit(self) self.ledW.setToolTip("Specify total wordlength.") self.ledW.setText("16") self.ledW.setMaxLength(2) # maximum of 2 digits self.ledW.setFixedWidth(30) # width of lineedit in points(?) layHDisplay = QHBoxLayout() layHDisplay.setAlignment(Qt.AlignLeft) layHDisplay.addWidget(self.butEnable) layHDisplay.addWidget(self.cmbFormat) layHDisplay.addWidget(self.spnDigits) layHDisplay.addWidget(self.lblDigits) layHDisplay.addWidget(self.cmbQFrmt) layHDisplay.addWidget(self.lbl_W) layHDisplay.addWidget(self.ledW) layHDisplay.addStretch() ####################################################################### # frmButtonsCoeffs # # This frame contains all buttons for manipulating coefficients ####################################################################### # ----------------------------------------------------------------- # layHButtonsCoeffs1 # # UI Elements for loading / storing / manipulating cells and rows # ----------------------------------------------------------------- self.cmbFilterType = QComboBox(self) self.cmbFilterType.setObjectName("comboFilterType") self.cmbFilterType.setToolTip( "<span>Select between IIR and FIR filter for manual entry." "Changing the type reloads the filter from the filter dict.</span>") self.cmbFilterType.addItems(["FIR", "IIR"]) self.cmbFilterType.setSizeAdjustPolicy(QComboBox.AdjustToContents) self.butAddCells = QPushButton(self) self.butAddCells.setIcon(QIcon(':/row_insert_above.svg')) self.butAddCells.setIconSize(q_icon_size) self.butAddCells.setToolTip( "<span>Select cells to insert a new cell above each selected cell. " "Use <SHIFT> or <CTRL> to select multiple cells. " "When nothing is selected, add a row at the end.</span>") self.butDelCells = QPushButton(self) self.butDelCells.setIcon(QIcon(':/row_delete.svg')) self.butDelCells.setIconSize(q_icon_size) self.butDelCells.setToolTip( "<span>Delete selected cell(s) from the table. " "Use <SHIFT> or <CTRL> to select multiple cells. " "When nothing is selected, delete the last row.</span>") self.butSave = QPushButton(self) self.butSave.setIcon(QIcon(':/upload.svg')) self.butSave.setIconSize(q_icon_size) self.butSave.setToolTip( "<span>Copy coefficient table to filter dict and update all plots" "and widgets.</span>") self.butLoad = QPushButton(self) self.butLoad.setIcon(QIcon(':/download.svg')) self.butLoad.setIconSize(q_icon_size) self.butLoad.setToolTip("Reload coefficient table from filter dict.") self.butClear = QPushButton(self) self.butClear.setIcon(QIcon(':/trash.svg')) self.butClear.setIconSize(q_icon_size) self.butClear.setToolTip("Clear all table entries.") self.butFromTable = QPushButton(self) self.butFromTable.setIconSize(q_icon_size) self.butToTable = QPushButton(self) self.butToTable.setIconSize(q_icon_size) self.but_csv_options = PushButton(self, icon=QIcon(':/settings.svg'), checked=False) self.but_csv_options.setIconSize(q_icon_size) self.but_csv_options.setToolTip( "<span>Select CSV format and whether " "to copy to/from clipboard or file.</span>") self._set_load_save_icons() # initialize icon / button settings layHButtonsCoeffs1 = QHBoxLayout() layHButtonsCoeffs1.addWidget(self.cmbFilterType) layHButtonsCoeffs1.addWidget(self.butAddCells) layHButtonsCoeffs1.addWidget(self.butDelCells) layHButtonsCoeffs1.addWidget(self.butClear) layHButtonsCoeffs1.addWidget(self.butSave) layHButtonsCoeffs1.addWidget(self.butLoad) layHButtonsCoeffs1.addWidget(self.butFromTable) layHButtonsCoeffs1.addWidget(self.butToTable) layHButtonsCoeffs1.addWidget(self.but_csv_options) layHButtonsCoeffs1.addStretch() # ---------------------------------------------------------------------- # layHButtonsCoeffs2 # # Eps / set zero settings # --------------------------------------------------------------------- self.butSetZero = QPushButton("= 0", self) self.butSetZero.setToolTip( "<span>Set selected coefficients = 0 with a magnitude < ε. " "When nothing is selected, test the whole table.</span>") self.butSetZero.setIconSize(q_icon_size) lblEps = QLabel(self) lblEps.setText("<b><i>for b, a</i> <</b>") self.ledEps = QLineEdit(self) self.ledEps.setToolTip("Specify tolerance value.") layHButtonsCoeffs2 = QHBoxLayout() layHButtonsCoeffs2.addWidget(self.butSetZero) layHButtonsCoeffs2.addWidget(lblEps) layHButtonsCoeffs2.addWidget(self.ledEps) layHButtonsCoeffs2.addStretch() # ------------------------------------------------------------------- # Now put the ButtonsCoeffs HBoxes into frmButtonsCoeffs # --------------------------------------------------------------------- layVButtonsCoeffs = QVBoxLayout() layVButtonsCoeffs.addLayout(layHButtonsCoeffs1) layVButtonsCoeffs.addLayout(layHButtonsCoeffs2) layVButtonsCoeffs.setContentsMargins(0, 5, 0, 0) # This frame encompasses all Quantization Settings self.frmButtonsCoeffs = QFrame(self) self.frmButtonsCoeffs.setLayout(layVButtonsCoeffs) # ###################################################################### # frmQSettings # # This frame contains all quantization settings # ###################################################################### # ------------------------------------------------------------------- # layHW_Scale # # QFormat and scale settings # --------------------------------------------------------------------- lbl_Q = QLabel("Q =", self) lbl_Q.setFont(self.bifont) self.ledWI = QLineEdit(self) self.ledWI.setToolTip("Specify number of integer bits.") self.ledWI.setText("0") self.ledWI.setMaxLength(2) # maximum of 2 digits self.ledWI.setFixedWidth(30) # width of lineedit in points(?) self.lblDot = QLabel(".", self) # class attribute, visibility is toggled self.lblDot.setFont(self.bfont) self.ledWF = QLineEdit(self) self.ledWF.setToolTip("Specify number of fractional bits.") self.ledWF.setText("15") self.ledWF.setMaxLength(2) # maximum of 2 digits # self.ledWF.setFixedWidth(30) # width of lineedit in points(?) self.ledWF.setMaximumWidth(30) self.lblScale = QLabel("<b><i>Scale</i> =</b>", self) self.ledScale = QLineEdit(self) self.ledScale.setToolTip( "Set the scale for converting float to fixpoint representation.") self.ledScale.setText(str(1)) self.ledScale.setEnabled(False) layHWI_WF = QHBoxLayout() layHWI_WF.addWidget(lbl_Q) layHWI_WF.addWidget(self.ledWI) layHWI_WF.addWidget(self.lblDot) layHWI_WF.addWidget(self.ledWF) layHWI_WF.addStretch() layHScale = QHBoxLayout() layHScale.addWidget(self.lblScale) layHScale.addWidget(self.ledScale) layHScale.addStretch() layHW_Scale = QHBoxLayout() layHW_Scale.addLayout(layHWI_WF) layHW_Scale.addLayout(layHScale) # ------------------------------------------------------------------- # layGQOpt # # Quantization / Overflow / MSB / LSB settings # --------------------------------------------------------------------- lblQOvfl = QLabel("Ovfl.:", self) lblQOvfl.setFont(self.bifont) lblQuant = QLabel("Quant.:", self) lblQuant.setFont(self.bifont) self.cmbQOvfl = QComboBox(self) qOvfl = ['wrap', 'sat'] self.cmbQOvfl.addItems(qOvfl) qset_cmb_box(self.cmbQOvfl, 'sat') self.cmbQOvfl.setToolTip("Select overflow behaviour.") # ComboBox size is adjusted automatically to fit the longest element self.cmbQOvfl.setSizeAdjustPolicy(QComboBox.AdjustToContents) layHQOvflOpt = QHBoxLayout() layHQOvflOpt.addWidget(lblQOvfl) layHQOvflOpt.addWidget(self.cmbQOvfl) layHQOvflOpt.addStretch() self.cmbQuant = QComboBox(self) qQuant = ['none', 'round', 'fix', 'floor'] self.cmbQuant.addItems(qQuant) qset_cmb_box(self.cmbQuant, 'round') self.cmbQuant.setToolTip("Select the kind of quantization.") self.cmbQuant.setSizeAdjustPolicy(QComboBox.AdjustToContents) layHQuantOpt = QHBoxLayout() layHQuantOpt.addWidget(lblQuant) layHQuantOpt.addWidget(self.cmbQuant) layHQuantOpt.addStretch() self.butQuant = QPushButton(self) self.butQuant.setToolTip( "<span>Quantize selected coefficients / " "whole table with specified settings.</span>") self.butQuant.setIcon(QIcon(':/quantize.svg')) self.butQuant.setIconSize(q_icon_size) self.butQuant.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) lblMSBtxt = QLabel(self) lblMSBtxt.setText("<b><i>MSB</i><sub>10</sub> =</b>") self.lblMSB = QLabel(self) layHMSB = QHBoxLayout() layHMSB.addWidget(lblMSBtxt) layHMSB.addWidget(self.lblMSB) layHMSB.addStretch() lblLSBtxt = QLabel(self) lblLSBtxt.setText("<b><i>LSB</i><sub>10</sub> =</b>") self.lblLSB = QLabel(self) layHLSB = QHBoxLayout() layHLSB.addWidget(lblLSBtxt) layHLSB.addWidget(self.lblLSB) layHLSB.addStretch() layGQOpt = QGridLayout() layGQOpt.addLayout(layHQOvflOpt, 0, 0) layGQOpt.addLayout(layHQuantOpt, 0, 1) layGQOpt.addWidget(self.butQuant, 0, 2, Qt.AlignCenter) layGQOpt.addLayout(layHMSB, 1, 0) layGQOpt.addLayout(layHLSB, 1, 1) # ------------------------------------------------------------------- # Display MAX # --------------------------------------------------------------------- lblMAXtxt = QLabel(self) lblMAXtxt.setText("<b><i>Max =</i></b>") self.lblMAX = QLabel(self) layHCoeffs_MAX = QHBoxLayout() layHCoeffs_MAX.addWidget(lblMAXtxt) layHCoeffs_MAX.addWidget(self.lblMAX) layHCoeffs_MAX.addStretch() ####################################################################### # Now put all the coefficient HBoxes into frmQSettings # --------------------------------------------------------------------- layVButtonsQ = QVBoxLayout() layVButtonsQ.addLayout(layHW_Scale) layVButtonsQ.addLayout(layGQOpt) layVButtonsQ.addLayout(layHCoeffs_MAX) layVButtonsQ.setContentsMargins(0, 0, 0, 0) # This frame encompasses all Quantization Settings self.frmQSettings = QFrame(self) self.frmQSettings.setLayout(layVButtonsQ) ####################################################################### # ######################## Main UI Layout ############################ ####################################################################### # layout for frame (UI widget) layVMainF = QVBoxLayout() layVMainF.addLayout(layHDisplay) layVMainF.addWidget(self.frmQSettings) layVMainF.addWidget(QHLine()) layVMainF.addWidget(self.frmButtonsCoeffs) # This frame encompasses all UI elements frmMain = QFrame(self) frmMain.setLayout(layVMainF) layVMain = QVBoxLayout() # the following affects only the first widget (intended here) layVMain.setAlignment(Qt.AlignTop) layVMain.addWidget(frmMain) layVMain.setContentsMargins(*params['wdg_margins']) self.setLayout(layVMain) ####################################################################### # --- set initial values from dict ------------ self.spnDigits.setValue(params['FMT_ba']) self.ledEps.setText(str(self.eps)) # ---------------------------------------------------------------------- # LOCAL SIGNALS & SLOTs # ---------------------------------------------------------------------- self.but_csv_options.clicked.connect(self._open_csv_win)
def _construct_UI(self): """ Intitialize the widget, consisting of: - Checkboxes for selecting the info to be displayed - A large text window for displaying infos about the filter design algorithm """ bfont = QFont() bfont.setBold(True) # ============== UI Layout ===================================== # widget / subwindow for filter infos self.chkFiltPerf = QCheckBox("H(f)", self) self.chkFiltPerf.setChecked(True) self.chkFiltPerf.setToolTip( "Display frequency response at test frequencies.") self.chkDocstring = QCheckBox("Doc$", self) self.chkDocstring.setChecked(False) self.chkDocstring.setToolTip( "Display docstring from python filter method.") self.chkRichText = QCheckBox("RTF", self) self.chkRichText.setChecked(HAS_DOCUTILS) self.chkRichText.setEnabled(HAS_DOCUTILS) self.chkRichText.setToolTip( "Render documentation in Rich Text Format.") self.chkFiltDict = QCheckBox("FiltDict", self) self.chkFiltDict.setToolTip("Show filter dictionary for debugging.") self.chkFiltTree = QCheckBox("FiltTree", self) self.chkFiltTree.setToolTip("Show filter tree for debugging.") self.layHChkBoxes = QHBoxLayout() self.layHChkBoxes.addWidget(self.chkFiltPerf) self.layHChkBoxes.addStretch(1) self.layHChkBoxes.addWidget(self.chkDocstring) self.layHChkBoxes.addStretch(1) self.layHChkBoxes.addWidget(self.chkRichText) self.layHChkBoxes.addStretch(1) self.layHChkBoxes.addWidget(self.chkFiltDict) self.layHChkBoxes.addStretch(1) self.layHChkBoxes.addWidget(self.chkFiltTree) self.frmMain = QFrame(self) self.frmMain.setLayout(self.layHChkBoxes) self.tblFiltPerf = QTableWidget(self) self.tblFiltPerf.setAlternatingRowColors(True) # self.tblFiltPerf.verticalHeader().setVisible(False) self.tblFiltPerf.horizontalHeader().setHighlightSections(False) self.tblFiltPerf.horizontalHeader().setFont(bfont) self.tblFiltPerf.verticalHeader().setHighlightSections(False) self.tblFiltPerf.verticalHeader().setFont(bfont) self.txtFiltInfoBox = QTextBrowser(self) self.txtFiltDict = QTextBrowser(self) self.txtFiltTree = QTextBrowser(self) layVMain = QVBoxLayout() layVMain.addWidget(self.frmMain) # layVMain.addLayout(self.layHChkBoxes) splitter = QSplitter(self) splitter.setOrientation(Qt.Vertical) splitter.addWidget(self.tblFiltPerf) splitter.addWidget(self.txtFiltInfoBox) splitter.addWidget(self.txtFiltDict) splitter.addWidget(self.txtFiltTree) # setSizes uses absolute pixel values, but can be "misused" by specifying values # that are way too large: in this case, the space is distributed according # to the _ratio_ of the values: splitter.setSizes([3000, 10000, 1000, 1000]) layVMain.addWidget(splitter) layVMain.setContentsMargins(*params['wdg_margins']) self.setLayout(layVMain) #---------------------------------------------------------------------- # GLOBAL SIGNALS & SLOTs #---------------------------------------------------------------------- self.sig_rx.connect(self.process_sig_rx) #---------------------------------------------------------------------- # LOCAL SIGNALS & SLOTs #---------------------------------------------------------------------- self.chkFiltPerf.clicked.connect(self._show_filt_perf) self.chkFiltDict.clicked.connect(self._show_filt_dict) self.chkFiltTree.clicked.connect(self._show_filt_tree) self.chkDocstring.clicked.connect(self._show_doc) self.chkRichText.clicked.connect(self._show_doc)
def _construct_UI(self): self.but_log = PushButton("dB", checked=False) self.but_log.setObjectName("but_log") self.but_log.setToolTip("Logarithmic scale") self.but_plot_in_UC = PushButton("|z| < 1 ", checked=False) self.but_plot_in_UC.setObjectName("but_plot_in_UC") self.but_plot_in_UC.setToolTip("Only plot H(z) within the unit circle") self.lblBottom = QLabel(to_html("Bottom =", frmt='bi'), self) self.ledBottom = QLineEdit(self) self.ledBottom.setObjectName("ledBottom") self.ledBottom.setText(str(self.zmin)) self.ledBottom.setToolTip("Minimum display value.") self.lblBottomdB = QLabel("dB", self) self.lblBottomdB.setVisible(self.but_log.isChecked()) self.lblTop = QLabel(to_html("Top =", frmt='bi'), self) self.ledTop = QLineEdit(self) self.ledTop.setObjectName("ledTop") self.ledTop.setText(str(self.zmax)) self.ledTop.setToolTip("Maximum display value.") self.lblTopdB = QLabel("dB", self) self.lblTopdB.setVisible(self.but_log.isChecked()) self.plt_UC = PushButton("UC", checked=True) self.plt_UC.setObjectName("plt_UC") self.plt_UC.setToolTip("Plot unit circle") self.but_PZ = PushButton("P/Z ", checked=True) self.but_PZ.setObjectName("but_PZ") self.but_PZ.setToolTip("Plot poles and zeros") self.but_Hf = PushButton("H(f) ", checked=True) self.but_Hf.setObjectName("but_Hf") self.but_Hf.setToolTip("Plot H(f) along the unit circle") modes = ['None', 'Mesh', 'Surf', 'Contour'] self.cmbMode3D = QComboBox(self) self.cmbMode3D.addItems(modes) self.cmbMode3D.setObjectName("cmbShow3D") self.cmbMode3D.setToolTip("Select 3D-plot mode.") self.cmbMode3D.setCurrentIndex(0) self.cmbMode3D.setSizeAdjustPolicy(QComboBox.AdjustToContents) self.but_colormap_r = PushButton("reverse", checked=True) self.but_colormap_r.setObjectName("but_colormap_r") self.but_colormap_r.setToolTip("reverse colormap") self.cmbColormap = QComboBox(self) self._init_cmb_colormap(cmap_init=self.cmap_default) self.cmbColormap.setToolTip("Select colormap") self.but_colbar = PushButton("Colorbar ", checked=False) self.but_colbar.setObjectName("chkColBar") self.but_colbar.setToolTip("Show colorbar") self.but_lighting = PushButton("Lighting", checked=False) self.but_lighting.setObjectName("but_lighting") self.but_lighting.setToolTip("Enable light source") self.lblAlpha = QLabel(to_html("Alpha", frmt='bi'), self) self.diaAlpha = QDial(self) self.diaAlpha.setRange(0, 10) self.diaAlpha.setValue(10) self.diaAlpha.setTracking(False) # produce less events when turning self.diaAlpha.setFixedHeight(30) self.diaAlpha.setFixedWidth(30) self.diaAlpha.setWrapping(False) self.diaAlpha.setToolTip( "<span>Set transparency for surf and contour plots.</span>") self.lblHatch = QLabel(to_html("Stride", frmt='bi'), self) self.diaHatch = QDial(self) self.diaHatch.setRange(0, 9) self.diaHatch.setValue(5) self.diaHatch.setTracking(False) # produce less events when turning self.diaHatch.setFixedHeight(30) self.diaHatch.setFixedWidth(30) self.diaHatch.setWrapping(False) self.diaHatch.setToolTip("Set line density for various plots.") self.but_contour_2d = PushButton("Contour2D ", checked=False) self.but_contour_2d.setObjectName("chkContour2D") self.but_contour_2d.setToolTip("Plot 2D-contours at z =0") # ---------------------------------------------------------------------- # LAYOUT for UI widgets # ---------------------------------------------------------------------- layGControls = QGridLayout() layGControls.addWidget(self.but_log, 0, 0) layGControls.addWidget(self.but_plot_in_UC, 1, 0) layGControls.addWidget(self.lblTop, 0, 2) layGControls.addWidget(self.ledTop, 0, 4) layGControls.addWidget(self.lblTopdB, 0, 5) layGControls.addWidget(self.lblBottom, 1, 2) layGControls.addWidget(self.ledBottom, 1, 4) layGControls.addWidget(self.lblBottomdB, 1, 5) layGControls.setColumnStretch(5, 1) layGControls.addWidget(self.plt_UC, 0, 6) layGControls.addWidget(self.but_Hf, 1, 6) layGControls.addWidget(self.but_PZ, 0, 8) layGControls.addWidget(self.cmbMode3D, 0, 10) layGControls.addWidget(self.but_contour_2d, 1, 10) layGControls.addWidget(self.cmbColormap, 0, 12, 1, 1) layGControls.addWidget(self.but_colormap_r, 1, 12) layGControls.addWidget(self.but_lighting, 0, 14) layGControls.addWidget(self.but_colbar, 1, 14) layGControls.addWidget(self.lblAlpha, 0, 15) layGControls.addWidget(self.diaAlpha, 0, 16) layGControls.addWidget(self.lblHatch, 1, 15) layGControls.addWidget(self.diaHatch, 1, 16) # This widget encompasses all control subwidgets self.frmControls = QFrame(self) self.frmControls.setObjectName("frmControls") self.frmControls.setLayout(layGControls) # ---------------------------------------------------------------------- # mplwidget # ---------------------------------------------------------------------- # This is the plot pane widget, encompassing the other widgets self.mplwidget = MplWidget(self) self.mplwidget.layVMainMpl.addWidget(self.frmControls) self.mplwidget.layVMainMpl.setContentsMargins(*params['mpl_margins']) self.mplwidget.mplToolbar.a_he.setEnabled(True) self.mplwidget.mplToolbar.a_he.info = "manual/plot_3d.html" self.setLayout(self.mplwidget.layVMainMpl) self._init_grid() # initialize grid and do initial plot # ---------------------------------------------------------------------- # GLOBAL SIGNALS & SLOTs # ---------------------------------------------------------------------- self.sig_rx.connect(self.process_sig_rx) # ---------------------------------------------------------------------- # LOCAL SIGNALS & SLOTs # ---------------------------------------------------------------------- self.but_log.clicked.connect(self._log_clicked) self.ledBottom.editingFinished.connect(self._log_clicked) self.ledTop.editingFinished.connect(self._log_clicked) self.but_plot_in_UC.clicked.connect(self._init_grid) self.plt_UC.clicked.connect(self.draw) self.but_Hf.clicked.connect(self.draw) self.but_PZ.clicked.connect(self.draw) self.cmbMode3D.currentIndexChanged.connect(self.draw) self.but_colbar.clicked.connect(self.draw) self.cmbColormap.currentIndexChanged.connect(self.draw) self.but_colormap_r.clicked.connect(self.draw) self.but_lighting.clicked.connect(self.draw) self.diaAlpha.valueChanged.connect(self.draw) self.diaHatch.valueChanged.connect(self.draw) self.but_contour_2d.clicked.connect(self.draw) self.mplwidget.mplToolbar.sig_tx.connect(self.process_sig_rx)
def _construct_UI(self): """ Intitialize the widget, consisting of: - Matplotlib widget with NavigationToolbar - Frame with control elements """ self.chkWarnings = QCheckBox(self.tr("Verbose"), self) self.chkWarnings.setChecked(self.verbose) self.chkWarnings.setToolTip(self.tr("<span>Print messages about singular group delay" "and calculation times.")) self.cmbAlgorithm = QComboBox(self) for t in [(self.tr("Auto"),"auto"),(self.tr("Scipy"),"scipy"), (self.tr("JOS"), "jos"), (self.tr("Diff"), "diff"), (self.tr("Shpak"), "shpak")]: # text, data self.cmbAlgorithm.addItem(*t) qset_cmb_box(self.cmbAlgorithm, self.algorithm,data=True) self.cmbAlgorithm.setToolTip(self.tr("<span>Select algorithm for calculating " "the group delay.</span>")) self.cmbAlgorithm.setItemData(0, self.tr("<span>Try to find best-suited algorithm." "</span>"),Qt.ToolTipRole) self.cmbAlgorithm.setItemData(1, self.tr("<span>Scipy algorithm.</span>"),Qt.ToolTipRole) self.cmbAlgorithm.setItemData(2, self.tr("<span>J.O. Smith's algorithm.</span>"),Qt.ToolTipRole) self.cmbAlgorithm.setItemData(3, self.tr("<span>Textbook-style, differentiate " "the phase.</span>"),Qt.ToolTipRole) self.cmbAlgorithm.setItemData(4, self.tr("<span>Shpak's algorithm for SOS and other " "IIR filters.</span>"),Qt.ToolTipRole) #self.chkScipy = QCheckBox("Scipy", self) #self.chkScipy.setChecked(False) #self.chkScipy.setToolTip("Use scipy group delay routine") layHControls = QHBoxLayout() layHControls.addStretch(10) layHControls.addWidget(self.chkWarnings) #layHControls.addWidget(self.chkScipy) layHControls.addWidget(self.cmbAlgorithm) # This widget encompasses all control subwidgets: self.frmControls = QFrame(self) self.frmControls.setObjectName("frmControls") self.frmControls.setLayout(layHControls) self.mplwidget = MplWidget(self) self.mplwidget.layVMainMpl.addWidget(self.frmControls) self.mplwidget.layVMainMpl.setContentsMargins(*params['wdg_margins']) self.mplwidget.mplToolbar.a_he.setEnabled(True) self.mplwidget.mplToolbar.a_he.info = "manual/plot_tau_g.html" self.setLayout(self.mplwidget.layVMainMpl) self.init_axes() self.draw() # initial drawing of tau_g #---------------------------------------------------------------------- # GLOBAL SIGNALS & SLOTs #---------------------------------------------------------------------- self.sig_rx.connect(self.process_sig_rx) #---------------------------------------------------------------------- # LOCAL SIGNALS & SLOTs #---------------------------------------------------------------------- self.mplwidget.mplToolbar.sig_tx.connect(self.process_sig_rx) self.cmbAlgorithm.currentIndexChanged.connect(self.draw)
if __name__ == '__main__': import sys from pyfda.libs.compat import QApplication # importing filterbroker initializes all its globals import pyfda.filterbroker as fb app = QApplication (sys.argv) # ellip filter widget filt = EllipZeroPhz() # instantiate filter filt.construct_UI() wdg_ma = getattr (filt, 'wdg_fil') layVDynWdg = QVBoxLayout() layVDynWdg.addWidget(wdg_ma, stretch = 1) filt.LPman(fb.fil[0]) # design a low-pass with parameters from global dict print(fb.fil[0][filt.FRMT]) # return results in default format form = QFrame() form.setFrameStyle (QFrame.StyledPanel|QFrame.Sunken) form.setLayout (layVDynWdg) form.show() app.exec_() #-----------------------------------------------------------------------------
def _construct_UI(self): """ Intitialize the widget, consisting of: - Matplotlib widget with NavigationToolbar - Frame with control elements """ self.chkHf = QCheckBox("Show |H(f)|", self) self.chkHf.setToolTip( "<span>Display |H(f)| around unit circle.</span>") self.chkHf.setEnabled(True) self.chkHfLog = QCheckBox("Log. Scale", self) self.chkHfLog.setToolTip("<span>Log. scale for |H(f)|.</span>") self.chkHfLog.setEnabled(True) self.diaRad_Hf = QDial(self) self.diaRad_Hf.setRange(2., 10.) self.diaRad_Hf.setValue(2) self.diaRad_Hf.setTracking(False) # produce less events when turning self.diaRad_Hf.setFixedHeight(30) self.diaRad_Hf.setFixedWidth(30) self.diaRad_Hf.setWrapping(False) self.diaRad_Hf.setToolTip( "<span>Set max. radius for |H(f)| plot.</span>") self.lblRad_Hf = QLabel("Radius", self) self.chkFIR_P = QCheckBox("Plot FIR Poles", self) self.chkFIR_P.setToolTip("<span>Show FIR poles at the origin.</span>") self.chkFIR_P.setChecked(True) layHControls = QHBoxLayout() layHControls.addWidget(self.chkHf) layHControls.addWidget(self.chkHfLog) layHControls.addWidget(self.diaRad_Hf) layHControls.addWidget(self.lblRad_Hf) layHControls.addStretch(10) layHControls.addWidget(self.chkFIR_P) #---------------------------------------------------------------------- # ### frmControls ### # # This widget encompasses all control subwidgets #---------------------------------------------------------------------- self.frmControls = QFrame(self) self.frmControls.setObjectName("frmControls") self.frmControls.setLayout(layHControls) #---------------------------------------------------------------------- # ### mplwidget ### # # main widget, encompassing the other widgets #---------------------------------------------------------------------- self.mplwidget = MplWidget(self) self.mplwidget.layVMainMpl.addWidget(self.frmControls) self.mplwidget.layVMainMpl.setContentsMargins(*params['wdg_margins']) self.setLayout(self.mplwidget.layVMainMpl) self.init_axes() self.draw() # calculate and draw poles and zeros #---------------------------------------------------------------------- # GLOBAL SIGNALS & SLOTs #---------------------------------------------------------------------- self.sig_rx.connect(self.process_sig_rx) #---------------------------------------------------------------------- # LOCAL SIGNALS & SLOTs #---------------------------------------------------------------------- self.mplwidget.mplToolbar.sig_tx.connect(self.process_sig_rx) self.chkHf.clicked.connect(self.draw) self.chkHfLog.clicked.connect(self.draw) self.diaRad_Hf.valueChanged.connect(self.draw) self.chkFIR_P.clicked.connect(self.draw)
def _construct_UI(self): """ Intitialize the widget, consisting of: - Checkboxes for selecting the info to be displayed - A large text window for displaying infos about the filter design algorithm """ bfont = QFont() bfont.setBold(True) # ============== UI Layout ===================================== # widget / subwindow for filter infos # self.butFiltPerf = QToolButton("H(f)", self) self.butFiltPerf = QPushButton(self) self.butFiltPerf.setText("H(f)") self.butFiltPerf.setCheckable(True) self.butFiltPerf.setChecked(True) self.butFiltPerf.setToolTip("Display frequency response at test frequencies.") self.butDebug = QPushButton(self) self.butDebug.setText("Debug") self.butDebug.setCheckable(True) self.butDebug.setChecked(False) self.butDebug.setToolTip("Show debugging options.") self.butAbout = QPushButton("About", self) # pop-up "About" window self.butSettings = QPushButton("Settings", self) # self.butSettings.setCheckable(True) self.butSettings.setChecked(False) self.butSettings.setToolTip("Display and set some settings") layHControls1 = QHBoxLayout() layHControls1.addWidget(self.butFiltPerf) layHControls1.addWidget(self.butAbout) layHControls1.addWidget(self.butSettings) layHControls1.addWidget(self.butDebug) self.butDocstring = QPushButton("Doc$", self) self.butDocstring.setCheckable(True) self.butDocstring.setChecked(False) self.butDocstring.setToolTip("Display docstring from python filter method.") self.butRichText = QPushButton("RTF", self) self.butRichText.setCheckable(HAS_DOCUTILS) self.butRichText.setChecked(HAS_DOCUTILS) self.butRichText.setEnabled(HAS_DOCUTILS) self.butRichText.setToolTip("Render documentation in Rich Text Format.") self.butFiltDict = QPushButton("FiltDict", self) self.butFiltDict.setToolTip("Show filter dictionary for debugging.") self.butFiltDict.setCheckable(True) self.butFiltDict.setChecked(False) self.butFiltTree = QPushButton("FiltTree", self) self.butFiltTree.setToolTip("Show filter tree for debugging.") self.butFiltTree.setCheckable(True) self.butFiltTree.setChecked(False) layHControls2 = QHBoxLayout() layHControls2.addWidget(self.butDocstring) # layHControls2.addStretch(1) layHControls2.addWidget(self.butRichText) # layHControls2.addStretch(1) layHControls2.addWidget(self.butFiltDict) # layHControls2.addStretch(1) layHControls2.addWidget(self.butFiltTree) self.frmControls2 = QFrame(self) self.frmControls2.setLayout(layHControls2) self.frmControls2.setVisible(self.butDebug.isChecked()) self.frmControls2.setContentsMargins(0, 0, 0, 0) lbl_settings_NFFT = QLabel(to_html("N_FFT =", frmt='bi'), self) self.led_settings_NFFT = QLineEdit(self) self.led_settings_NFFT.setText(str(params['N_FFT'])) self.led_settings_NFFT.setToolTip("<span>Number of FFT points for frequency " "domain widgets.</span>") layGSettings = QGridLayout() layGSettings.addWidget(lbl_settings_NFFT, 1, 0) layGSettings.addWidget(self.led_settings_NFFT, 1, 1) self.frmSettings = QFrame(self) self.frmSettings.setLayout(layGSettings) self.frmSettings.setVisible(self.butSettings.isChecked()) self.frmSettings.setContentsMargins(0, 0, 0, 0) layVControls = QVBoxLayout() layVControls.addLayout(layHControls1) layVControls.addWidget(self.frmControls2) layVControls.addWidget(self.frmSettings) self.frmMain = QFrame(self) self.frmMain.setLayout(layVControls) self.tblFiltPerf = QTableWidget(self) self.tblFiltPerf.setAlternatingRowColors(True) # self.tblFiltPerf.verticalHeader().setVisible(False) self.tblFiltPerf.horizontalHeader().setHighlightSections(False) self.tblFiltPerf.horizontalHeader().setFont(bfont) self.tblFiltPerf.verticalHeader().setHighlightSections(False) self.tblFiltPerf.verticalHeader().setFont(bfont) self.txtFiltInfoBox = QTextBrowser(self) self.txtFiltDict = QTextBrowser(self) self.txtFiltTree = QTextBrowser(self) layVMain = QVBoxLayout() layVMain.addWidget(self.frmMain) # layVMain.addLayout(self.layHControls) splitter = QSplitter(self) splitter.setOrientation(Qt.Vertical) splitter.addWidget(self.tblFiltPerf) splitter.addWidget(self.txtFiltInfoBox) splitter.addWidget(self.txtFiltDict) splitter.addWidget(self.txtFiltTree) # setSizes uses absolute pixel values, but can be "misused" by specifying values # that are way too large: in this case, the space is distributed according # to the _ratio_ of the values: splitter.setSizes([3000, 10000, 1000, 1000]) layVMain.addWidget(splitter) layVMain.setContentsMargins(*params['wdg_margins']) self.setLayout(layVMain) # ---------------------------------------------------------------------- # GLOBAL SIGNALS & SLOTs # ---------------------------------------------------------------------- self.sig_rx.connect(self.process_sig_rx) # ---------------------------------------------------------------------- # LOCAL SIGNALS & SLOTs # ---------------------------------------------------------------------- self.butFiltPerf.clicked.connect(self._show_filt_perf) self.butAbout.clicked.connect(self._about_window) self.butSettings.clicked.connect(self._show_settings) self.led_settings_NFFT.editingFinished.connect(self._update_settings_nfft) self.butDebug.clicked.connect(self._show_debug) self.butFiltDict.clicked.connect(self._show_filt_dict) self.butFiltTree.clicked.connect(self._show_filt_tree) self.butDocstring.clicked.connect(self._show_doc) self.butRichText.clicked.connect(self._show_doc)
def _construct_ui(self): """ Define and construct the subwidgets """ modes = ['| H |', 're{H}', 'im{H}'] self.cmbShowH = QComboBox(self) self.cmbShowH.addItems(modes) self.cmbShowH.setObjectName("cmbUnitsH") self.cmbShowH.setToolTip("Show magnitude, real / imag. part of H or H \n" "without linear phase (acausal system).") self.cmbShowH.setCurrentIndex(0) self.lblIn = QLabel(to_html("Unit:", frmt="b"), self) self.cmb_units_a = QComboBox(self) qcmb_box_populate(self.cmb_units_a, self.cmb_units_a_items, self.cmb_units_a_default) self.cmb_units_a.setObjectName("cmbUnitsA") self.lbl_log_bottom = QLabel(to_html("min =", 'bi'), self) self.led_log_bottom = QLineEdit(self) self.led_log_bottom.setText(str(self.log_bottom)) self.led_log_bottom.setMaximumWidth(qtext_width(N_x=8)) self.led_log_bottom.setToolTip( "<span>Minimum display value for dB. scale.</span>") self.lbl_log_unit = QLabel("dB", self) self.cmbShowH.setSizeAdjustPolicy(QComboBox.AdjustToContents) self.cmb_units_a.setSizeAdjustPolicy(QComboBox.AdjustToContents) self.but_zerophase = PushButton(" Zero phase ", checked=False) self.but_zerophase.setToolTip( "<span>Remove linear phase calculated from filter order.\n" "Attention: This makes no sense for a non-linear phase system!</span>") self.lblInset = QLabel(to_html("Inset", "bi"), self) self.cmbInset = QComboBox(self) self.cmbInset.addItems(['off', 'edit', 'fixed']) self.cmbInset.setObjectName("cmbInset") self.cmbInset.setToolTip("Display/edit second inset plot") self.cmbInset.setCurrentIndex(0) self.inset_idx = 0 # store previous index for comparison self.but_specs = PushButton("Specs ", checked=False) self.but_specs.setToolTip("Display filter specs as hatched regions") self.but_phase = PushButton("Phase ", checked=False) self.but_phase.setToolTip("Overlay phase") self.but_align = PushButton("Align", checked=True) self.but_align.setToolTip( "<span>Try to align gridlines for magnitude and phase " "(doesn't work in all cases).</span>") self.but_align.setVisible(self.but_phase.isChecked()) # ---------------------------------------------------------------------- # ### frmControls ### # # This widget encompasses all control subwidgets # ---------------------------------------------------------------------- layHControls = QHBoxLayout() layHControls.addWidget(self.cmbShowH) layHControls.addWidget(self.lblIn) layHControls.addWidget(self.cmb_units_a) layHControls.addStretch(1) layHControls.addWidget(self.lbl_log_bottom) layHControls.addWidget(self.led_log_bottom) layHControls.addWidget(self.lbl_log_unit) layHControls.addStretch(1) layHControls.addWidget(self.but_zerophase) layHControls.addStretch(1) layHControls.addWidget(self.lblInset) layHControls.addWidget(self.cmbInset) layHControls.addStretch(1) layHControls.addWidget(self.but_specs) layHControls.addStretch(1) layHControls.addWidget(self.but_phase) layHControls.addWidget(self.but_align) layHControls.addStretch(10) self.frmControls = QFrame(self) self.frmControls.setObjectName("frmControls") self.frmControls.setLayout(layHControls) # ---------------------------------------------------------------------- # ### mplwidget ### # # main widget, encompassing the other widgets # ---------------------------------------------------------------------- self.mplwidget = MplWidget(self) self.mplwidget.layVMainMpl.addWidget(self.frmControls) self.mplwidget.layVMainMpl.setContentsMargins(*params['mpl_margins']) self.mplwidget.mplToolbar.a_he.setEnabled(True) self.mplwidget.mplToolbar.a_he.info = "manual/plot_hf.html" self.setLayout(self.mplwidget.layVMainMpl) self.init_axes() self.draw() # calculate and draw |H(f)| # ---------------------------------------------------------------------- # GLOBAL SIGNALS & SLOTs # ---------------------------------------------------------------------- self.sig_rx.connect(self.process_sig_rx) # ---------------------------------------------------------------------- # LOCAL SIGNALS & SLOTs # ---------------------------------------------------------------------- self.cmb_units_a.currentIndexChanged.connect(self.draw) self.led_log_bottom.editingFinished.connect(self.update_view) self.cmbShowH.currentIndexChanged.connect(self.draw) self.but_zerophase.clicked.connect(self.draw) self.cmbInset.currentIndexChanged.connect(self.draw_inset) self.but_specs.clicked.connect(self.draw) self.but_phase.clicked.connect(self.draw) self.but_align.clicked.connect(self.draw) self.mplwidget.mplToolbar.sig_tx.connect(self.process_sig_rx)
def _construct_UI(self): """ Construct the User Interface """ self.layVMain = QVBoxLayout() # Widget main layout f_units = ['k', 'f_S', 'f_Ny', 'Hz', 'kHz', 'MHz', 'GHz'] self.t_units = ['', 'T_S', 'T_S', 's', 'ms', r'$\mu$s', 'ns'] bfont = QFont() bfont.setBold(True) self.lblUnits = QLabel(self) self.lblUnits.setText("Freq. Unit") self.lblUnits.setFont(bfont) self.fs_old = fb.fil[0]['f_S'] # store current sampling frequency self.lblF_S = QLabel(self) self.lblF_S.setText(to_html("f_S =", frmt='bi')) self.ledF_S = QLineEdit() self.ledF_S.setText(str(fb.fil[0]["f_S"])) self.ledF_S.setObjectName("f_S") self.ledF_S.installEventFilter(self) # filter events self.butLock = QToolButton(self) self.butLock.setIcon(QIcon(':/lock-unlocked.svg')) self.butLock.setCheckable(True) self.butLock.setChecked(False) self.butLock.setToolTip( "<span><b>Unlocked:</b> When f_S is changed, all frequency related " "widgets are updated, normalized frequencies stay the same.<br />" "<b>Locked:</b> When f_S is changed, displayed absolute frequency " "values don't change but normalized frequencies do.</span>") # self.butLock.setStyleSheet("QToolButton:checked {font-weight:bold}") layHF_S = QHBoxLayout() layHF_S.addWidget(self.ledF_S) layHF_S.addWidget(self.butLock) self.cmbUnits = QComboBox(self) self.cmbUnits.setObjectName("cmbUnits") self.cmbUnits.addItems(f_units) self.cmbUnits.setToolTip( 'Select whether frequencies are specified w.r.t. \n' 'the sampling frequency "f_S", to the Nyquist frequency \n' 'f_Ny = f_S/2 or as absolute values. "k" specifies frequencies w.r.t. f_S ' 'but plots graphs over the frequency index k.') self.cmbUnits.setCurrentIndex(1) # self.cmbUnits.setItemData(0, (0,QColor("#FF333D"),Qt.BackgroundColorRole))# # self.cmbUnits.setItemData(0, (QFont('Verdana', bold=True), Qt.FontRole) fRanges = [("0...½", "half"), ("0...1", "whole"), ("-½...½", "sym")] self.cmbFRange = QComboBox(self) self.cmbFRange.setObjectName("cmbFRange") for f in fRanges: self.cmbFRange.addItem(f[0], f[1]) self.cmbFRange.setToolTip("Select frequency range (whole or half).") self.cmbFRange.setCurrentIndex(0) # Combobox resizes with longest entry self.cmbUnits.setSizeAdjustPolicy(QComboBox.AdjustToContents) self.cmbFRange.setSizeAdjustPolicy(QComboBox.AdjustToContents) self.butSort = QToolButton(self) self.butSort.setText("Sort") self.butSort.setIcon(QIcon(':/sort-ascending.svg')) #self.butDelCells.setIconSize(q_icon_size) self.butSort.setCheckable(True) self.butSort.setChecked(True) self.butSort.setToolTip( "Sort frequencies in ascending order when pushed.") self.butSort.setStyleSheet("QToolButton:checked {font-weight:bold}") self.layHUnits = QHBoxLayout() self.layHUnits.addWidget(self.cmbUnits) self.layHUnits.addWidget(self.cmbFRange) self.layHUnits.addWidget(self.butSort) # Create a gridLayout consisting of QLabel and QLineEdit fields # for setting f_S, the units and the actual frequency specs: self.layGSpecWdg = QGridLayout() # sublayout for spec fields self.layGSpecWdg.addWidget(self.lblF_S, 1, 0) # self.layGSpecWdg.addWidget(self.ledF_S,1,1) self.layGSpecWdg.addLayout(layHF_S, 1, 1) self.layGSpecWdg.addWidget(self.lblUnits, 0, 0) self.layGSpecWdg.addLayout(self.layHUnits, 0, 1) frmMain = QFrame(self) frmMain.setLayout(self.layGSpecWdg) self.layVMain.addWidget(frmMain) self.layVMain.setContentsMargins(*params['wdg_margins']) self.setLayout(self.layVMain) #---------------------------------------------------------------------- # LOCAL SIGNALS & SLOTs #---------------------------------------------------------------------- self.cmbUnits.currentIndexChanged.connect(self.update_UI) self.butLock.clicked.connect(self._lock_freqs) self.cmbFRange.currentIndexChanged.connect(self._freq_range) self.butSort.clicked.connect(self._store_sort_flag) # ---------------------------------------------------------------------- self.update_UI() # first-time initialization
def _construct_UI(self, **kwargs): """ Construct widget from quantization dict, individual settings and the default dict below """ # default settings dict_ui = { 'wdg_name': 'ui_w', 'label': 'WI.WF', 'lbl_sep': '.', 'max_led_width': 30, 'WI': 0, 'WI_len': 2, 'tip_WI': 'Number of integer bits', 'WF': 15, 'WF_len': 2, 'tip_WF': 'Number of fractional bits', 'enabled': True, 'visible': True, 'fractional': True, 'combo_visible': False, 'combo_items': ['auto', 'full', 'man'], 'tip_combo': 'Calculate Acc. width.', 'lock_visible': False, 'tip_lock': 'Lock input/output quantization.' } #: default values if self.q_dict: dict_ui.update(self.q_dict) for k, v in kwargs.items(): if k not in dict_ui: logger.warning("Unknown key {0}".format(k)) else: dict_ui.update({k: v}) self.wdg_name = dict_ui['wdg_name'] if not dict_ui['fractional']: dict_ui['WF'] = 0 self.WI = dict_ui['WI'] self.WF = dict_ui['WF'] self.W = int(self.WI + self.WF + 1) if self.q_dict: self.q_dict.update({'WI': self.WI, 'WF': self.WF, 'W': self.W}) else: self.q_dict = {'WI': self.WI, 'WF': self.WF, 'W': self.W} lblW = QLabel(to_html(dict_ui['label'], frmt='bi'), self) self.cmbW = QComboBox(self) self.cmbW.addItems(dict_ui['combo_items']) self.cmbW.setVisible(dict_ui['combo_visible']) self.cmbW.setToolTip(dict_ui['tip_combo']) self.cmbW.setObjectName("cmbW") self.butLock = QPushButton(self) self.butLock.setCheckable(True) self.butLock.setChecked(False) self.butLock.setVisible(dict_ui['lock_visible']) self.butLock.setToolTip(dict_ui['tip_lock']) self.ledWI = QLineEdit(self) self.ledWI.setToolTip(dict_ui['tip_WI']) self.ledWI.setMaxLength(dict_ui['WI_len']) # maximum of 2 digits self.ledWI.setFixedWidth( dict_ui['max_led_width']) # width of lineedit in points self.ledWI.setObjectName("WI") lblDot = QLabel(dict_ui['lbl_sep'], self) lblDot.setVisible(dict_ui['fractional']) self.ledWF = QLineEdit(self) self.ledWF.setToolTip(dict_ui['tip_WF']) self.ledWF.setMaxLength(dict_ui['WI_len']) # maximum of 2 digits self.ledWF.setFixedWidth( dict_ui['max_led_width']) # width of lineedit in points self.ledWF.setVisible(dict_ui['fractional']) self.ledWF.setObjectName("WF") layH = QHBoxLayout() layH.addWidget(lblW) layH.addStretch() layH.addWidget(self.cmbW) layH.addWidget(self.butLock) layH.addWidget(self.ledWI) layH.addWidget(lblDot) layH.addWidget(self.ledWF) layH.setContentsMargins(0, 0, 0, 0) frmMain = QFrame(self) frmMain.setLayout(layH) layVMain = QVBoxLayout() # Widget main layout layVMain.addWidget(frmMain) layVMain.setContentsMargins(0, 5, 0, 0) # *params['wdg_margins']) self.setLayout(layVMain) # ---------------------------------------------------------------------- # INITIAL SETTINGS # ---------------------------------------------------------------------- self.ledWI.setText(qstr(dict_ui['WI'])) self.ledWF.setText(qstr(dict_ui['WF'])) frmMain.setEnabled(dict_ui['enabled']) frmMain.setVisible(dict_ui['visible']) # ---------------------------------------------------------------------- # LOCAL SIGNALS & SLOTs # ---------------------------------------------------------------------- self.ledWI.editingFinished.connect(self.ui2dict) self.ledWF.editingFinished.connect(self.ui2dict) self.butLock.clicked.connect(self.butLock_clicked) self.cmbW.currentIndexChanged.connect(self.ui2dict) # initialize button icon self.butLock_clicked(self.butLock.isChecked())
def _construct_UI(self): """ Construct the User Interface """ self.layVMain = QVBoxLayout() # Widget main layout f_units = ['f_S', 'f_Ny', 'Hz', 'kHz', 'MHz', 'GHz'] self.t_units = ['', '', 's', 'ms', r'$\mu$s', 'ns'] bfont = QFont() bfont.setBold(True) self.lblUnits=QLabel(self) self.lblUnits.setText("Freq. Unit:") self.lblUnits.setFont(bfont) self.fs_old = fb.fil[0]['f_S'] # store current sampling frequency self.ledF_S = QLineEdit() self.ledF_S.setText(str(fb.fil[0]["f_S"])) self.ledF_S.setObjectName("f_S") self.ledF_S.installEventFilter(self) # filter events self.lblF_S = QLabel(self) self.lblF_S.setText(to_html("f_S", frmt='bi')) self.cmbUnits = QComboBox(self) self.cmbUnits.setObjectName("cmbUnits") self.cmbUnits.addItems(f_units) self.cmbUnits.setToolTip( "Select whether frequencies are specified with respect to \n" "the sampling frequency f_S, to the Nyquist frequency \n" "f_Ny = f_S/2 or as absolute values.") self.cmbUnits.setCurrentIndex(0) # self.cmbUnits.setItemData(0, (0,QColor("#FF333D"),Qt.BackgroundColorRole))# # self.cmbUnits.setItemData(0, (QFont('Verdana', bold=True), Qt.FontRole) fRanges = [("0...½", "half"), ("0...1","whole"), ("-½...½", "sym")] self.cmbFRange = QComboBox(self) self.cmbFRange.setObjectName("cmbFRange") for f in fRanges: self.cmbFRange.addItem(f[0],f[1]) self.cmbFRange.setToolTip("Select frequency range (whole or half).") self.cmbFRange.setCurrentIndex(0) # Combobox resizes with longest entry self.cmbUnits.setSizeAdjustPolicy(QComboBox.AdjustToContents) self.cmbFRange.setSizeAdjustPolicy(QComboBox.AdjustToContents) self.butSort = QToolButton(self) self.butSort.setText("Sort") self.butSort.setCheckable(True) self.butSort.setChecked(True) self.butSort.setToolTip("Sort frequencies in ascending order when pushed.") self.butSort.setStyleSheet("QToolButton:checked {font-weight:bold}") self.layHUnits = QHBoxLayout() self.layHUnits.addWidget(self.cmbUnits) self.layHUnits.addWidget(self.cmbFRange) self.layHUnits.addWidget(self.butSort) # Create a gridLayout consisting of QLabel and QLineEdit fields # for setting f_S, the units and the actual frequency specs: self.layGSpecWdg = QGridLayout() # sublayout for spec fields self.layGSpecWdg.addWidget(self.lblF_S,1,0) self.layGSpecWdg.addWidget(self.ledF_S,1,1) self.layGSpecWdg.addWidget(self.lblUnits,0,0) self.layGSpecWdg.addLayout(self.layHUnits,0,1) frmMain = QFrame(self) frmMain.setLayout(self.layGSpecWdg) self.layVMain.addWidget(frmMain) self.layVMain.setContentsMargins(*params['wdg_margins']) self.setLayout(self.layVMain) #---------------------------------------------------------------------- # LOCAL SIGNALS & SLOTs #---------------------------------------------------------------------- self.cmbUnits.currentIndexChanged.connect(self.update_UI) self.cmbFRange.currentIndexChanged.connect(self._freq_range) self.butSort.clicked.connect(self._store_sort_flag) #---------------------------------------------------------------------- self.update_UI() # first-time initialization
def _construct_UI(self): """ Intitialize the widget, consisting of: - top chkbox row - coefficient table - two bottom rows with action buttons """ self.bfont = QFont() self.bfont.setBold(True) self.bifont = QFont() self.bifont.setBold(True) self.bifont.setItalic(True) # q_icon_size = QSize(20, 20) # optional, size is derived from butEnable # --------------------------------------------- # UI Elements for controlling the display # --------------------------------------------- self.butEnable = QPushButton(self) self.butEnable.setIcon(QIcon(':/circle-x.svg')) q_icon_size = self.butEnable.iconSize() # <- set this for manual icon sizing self.butEnable.setIconSize(q_icon_size) self.butEnable.setCheckable(True) self.butEnable.setChecked(True) self.butEnable.setToolTip("<span>Show / hide poles and zeros in an editable table." " For high order systems, the table display might be slow.</span>") self.cmbPZFrmt = QComboBox(self) pz_formats = [('Cartesian', 'cartesian'), ('Polar (rad)', 'polar_rad'), ('Polar (pi)', 'polar_pi'), ('Polar (°)', 'polar_deg')] # display text, data # π: u'3C0, °: u'B0, ∠: u'2220 for pz in pz_formats: self.cmbPZFrmt.addItem(*pz) self.cmbPZFrmt.setSizeAdjustPolicy(QComboBox.AdjustToContents) # self.cmbPZFrmt.setEnabled(False) self.cmbPZFrmt.setToolTip("<span>Set display format for poles and zeros to" " either cartesian (x + jy) or polar (r * ∠ Ω)." " Type 'o' for '°', '<' for '∠' and 'pi' for 'π'.</span>") self.spnDigits = QSpinBox(self) self.spnDigits.setRange(0,16) self.spnDigits.setToolTip("Number of digits to display.") self.lblDigits = QLabel("Digits", self) self.lblDigits.setFont(self.bifont) self.cmbCausal = QComboBox(self) causal_types = ['Causal', 'Acausal', 'Anticausal'] for cs in causal_types: self.cmbCausal.addItem(cs) qset_cmb_box(self.cmbCausal, 'Causal') self.cmbCausal.setToolTip('<span>Set the system type. Not implemented yet.</span>') self.cmbCausal.setSizeAdjustPolicy(QComboBox.AdjustToContents) self.cmbCausal.setEnabled(False) layHDisplay = QHBoxLayout() layHDisplay.setAlignment(Qt.AlignLeft) layHDisplay.addWidget(self.butEnable) layHDisplay.addWidget(self.cmbPZFrmt) layHDisplay.addWidget(self.spnDigits) layHDisplay.addWidget(self.lblDigits) layHDisplay.addWidget(self.cmbCausal) layHDisplay.addStretch() # --------------------------------------------- # UI Elements for setting the gain # --------------------------------------------- self.lblNorm = QLabel(to_html("Normalize:", frmt='bi'), self) self.cmbNorm = QComboBox(self) self.cmbNorm.addItems(["None", "1", "Max"]) self.cmbNorm.setToolTip("<span>Set the gain <i>k</i> so that H(f)<sub>max</sub> is " "either 1 or the max. of the previous system.</span>") self.lblGain = QLabel(to_html("k =", frmt='bi'), self) self.ledGain = QLineEdit(self) self.ledGain.setToolTip("<span>Specify gain factor <i>k</i>" " (only possible for Normalize = 'None').</span>") self.ledGain.setText(str(1.)) self.ledGain.setObjectName("ledGain") layHGain = QHBoxLayout() layHGain.addWidget(self.lblNorm) layHGain.addWidget(self.cmbNorm) layHGain.addWidget(self.lblGain) layHGain.addWidget(self.ledGain) layHGain.addStretch() # --------------------------------------------- # UI Elements for loading / storing / manipulating cells and rows # --------------------------------------------- # self.cmbFilterType = QComboBox(self) # self.cmbFilterType.setObjectName("comboFilterType") # self.cmbFilterType.setToolTip("Select between IIR and FIR filte for manual entry.") # self.cmbFilterType.addItems(["FIR","IIR"]) # self.cmbFilterType.setSizeAdjustPolicy(QComboBox.AdjustToContents) self.butAddCells = QPushButton(self) self.butAddCells.setIcon(QIcon(':/row_insert_above.svg')) self.butAddCells.setIconSize(q_icon_size) self.butAddCells.setToolTip("<SPAN>Select cells to insert a new cell above each selected cell. " "Use <SHIFT> or <CTRL> to select multiple cells. " "When nothing is selected, add a row at the end.</SPAN>") self.butDelCells = QPushButton(self) self.butDelCells.setIcon(QIcon(':/row_delete.svg')) self.butDelCells.setIconSize(q_icon_size) self.butDelCells.setToolTip("<SPAN>Delete selected cell(s) from the table. " "Use <SHIFT> or <CTRL> to select multiple cells. " "When nothing is selected, delete the last row.</SPAN>") self.butSave = QPushButton(self) self.butSave.setIcon(QIcon(':/upload.svg')) self.butSave.setIconSize(q_icon_size) self.butSave.setToolTip("<span>Copy P/Z table to filter dict and update all plots and widgets.</span>") self.butLoad = QPushButton(self) self.butLoad.setIcon(QIcon(':/download.svg')) self.butLoad.setIconSize(q_icon_size) self.butLoad.setToolTip("Reload P/Z table from filter dict.") self.butClear = QPushButton(self) self.butClear.setIcon(QIcon(':/trash.svg')) self.butClear.setIconSize(q_icon_size) self.butClear.setToolTip("Clear all table entries.") self.butFromTable = QPushButton(self) self.butFromTable.setIconSize(q_icon_size) self.butToTable = QPushButton(self) self.butToTable.setIconSize(q_icon_size) self.but_csv_options = QPushButton(self) self.but_csv_options.setIcon(QIcon(':/settings.svg')) self.but_csv_options.setIconSize(q_icon_size) self.but_csv_options.setToolTip("<span>Select CSV format and whether " "to copy to/from clipboard or file.</span>") self.but_csv_options.setCheckable(True) self.but_csv_options.setChecked(False) self._set_load_save_icons() # initialize icon / button settings layHButtonsCoeffs1 = QHBoxLayout() # layHButtonsCoeffs1.addWidget(self.cmbFilterType) layHButtonsCoeffs1.addWidget(self.butAddCells) layHButtonsCoeffs1.addWidget(self.butDelCells) layHButtonsCoeffs1.addWidget(self.butClear) layHButtonsCoeffs1.addWidget(self.butSave) layHButtonsCoeffs1.addWidget(self.butLoad) layHButtonsCoeffs1.addWidget(self.butFromTable) layHButtonsCoeffs1.addWidget(self.butToTable) layHButtonsCoeffs1.addWidget(self.but_csv_options) layHButtonsCoeffs1.addStretch() #------------------------------------------------------------------- # Eps / set zero settings # --------------------------------------------------------------------- self.butSetZero = QPushButton("= 0", self) self.butSetZero.setToolTip("<span>Set selected poles / zeros = 0 with a magnitude < ε. " "When nothing is selected, test the whole table.</span>") self.butSetZero.setIconSize(q_icon_size) lblEps = QLabel(self) lblEps.setText("<b><i>for ε</i> <</b>") self.ledEps = QLineEdit(self) self.ledEps.setToolTip("Specify tolerance value.") layHButtonsCoeffs2 = QHBoxLayout() layHButtonsCoeffs2.addWidget(self.butSetZero) layHButtonsCoeffs2.addWidget(lblEps) layHButtonsCoeffs2.addWidget(self.ledEps) layHButtonsCoeffs2.addStretch() # ######################## Main UI Layout ############################ # layout for frame (UI widget) layVMainF = QVBoxLayout() layVMainF.addLayout(layHDisplay) layVMainF.addLayout(layHGain) layVMainF.addLayout(layHButtonsCoeffs1) layVMainF.addLayout(layHButtonsCoeffs2) # This frame encompasses all UI elements frmMain = QFrame(self) frmMain.setLayout(layVMainF) layVMain = QVBoxLayout() layVMain.setAlignment(Qt.AlignTop) # this affects only the first widget (intended here) layVMain.addWidget(frmMain) layVMain.setContentsMargins(*params['wdg_margins']) self.setLayout(layVMain) #--- set initial values from dict ------------ self.spnDigits.setValue(params['FMT_pz']) self.ledEps.setText(str(self.eps)) #---------------------------------------------------------------------- # LOCAL SIGNALS & SLOTs #---------------------------------------------------------------------- self.but_csv_options.clicked.connect(self._open_csv_win)
def _construct_UI(self): """ Construct UI with comboboxes for selecting filter: - cmbResponseType for selecting response type rt (LP, HP, ...) - cmbFilterType for selection of filter type (IIR, FIR, ...) - cmbFilterClass for selection of design design class (Chebyshev, ...) and populate them from the "filterTree" dict during the initial run. Later, calling _set_response_type() updates the three combo boxes. See filterbroker.py for structure and content of "filterTree" dict """ # ---------------------------------------------------------------------- # Combo boxes for filter selection # ---------------------------------------------------------------------- self.cmbResponseType = QComboBox(self) self.cmbResponseType.setObjectName("comboResponseType") self.cmbResponseType.setToolTip("Select filter response type.") self.cmbFilterType = QComboBox(self) self.cmbFilterType.setObjectName("comboFilterType") self.cmbFilterType.setToolTip( "<span>Choose filter type, either recursive (Infinite Impulse Response) " "or transversal (Finite Impulse Response).</span>") self.cmbFilterClass = QComboBox(self) self.cmbFilterClass.setObjectName("comboFilterClass") self.cmbFilterClass.setToolTip("Select the filter design class.") # Adapt comboboxes size dynamically to largest element self.cmbResponseType.setSizeAdjustPolicy(QComboBox.AdjustToContents) self.cmbFilterType.setSizeAdjustPolicy(QComboBox.AdjustToContents) self.cmbFilterClass.setSizeAdjustPolicy(QComboBox.AdjustToContents) # ---------------------------------------------------------------------- # Populate combo box with initial settings from fb.fil_tree # ---------------------------------------------------------------------- # Translate short response type ("LP") to displayed names ("Lowpass") # (correspondence is defined in pyfda_rc.py) and populate rt combo box # rt_list = sorted(list(fb.fil_tree.keys())) for rt in rt_list: try: self.cmbResponseType.addItem(rc.rt_names[rt], rt) except KeyError as e: logger.warning( f"KeyError: {e} has no corresponding full name in rc.rt_names." ) 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 rt = qget_cmb_box(self.cmbResponseType) for ft in fb.fil_tree[rt]: self.cmbFilterType.addItem(rc.ft_names[ft], ft) self.cmbFilterType.setCurrentIndex(0) # set initial index ft = qget_cmb_box(self.cmbFilterType) for fc in fb.fil_tree[rt][ft]: self.cmbFilterClass.addItem(fb.filter_classes[fc]['name'], fc) self.cmbFilterClass.setCurrentIndex(0) # set initial index # ---------------------------------------------------------------------- # Layout for Filter Type Subwidgets # ---------------------------------------------------------------------- layHFilWdg = QHBoxLayout() # container for filter subwidgets layHFilWdg.addWidget(self.cmbResponseType) # LP, HP, BP, etc. layHFilWdg.addStretch() layHFilWdg.addWidget(self.cmbFilterType) # FIR, IIR layHFilWdg.addStretch() layHFilWdg.addWidget(self.cmbFilterClass) # bessel, elliptic, etc. # ---------------------------------------------------------------------- # Layout for dynamic filter subwidgets (empty frame) # ---------------------------------------------------------------------- # see Summerfield p. 278 self.layHDynWdg = QHBoxLayout() # for additional dynamic subwidgets # ---------------------------------------------------------------------- # Filter Order Subwidgets # ---------------------------------------------------------------------- self.lblOrder = QLabel("<b>Order:</b>") self.chkMinOrder = QCheckBox("Minimum", self) self.chkMinOrder.setToolTip( "<span>Minimum filter order / # of taps is determined automatically.</span>" ) self.lblOrderN = QLabel("<b><i>N =</i></b>") self.ledOrderN = QLineEdit(str(fb.fil[0]['N']), self) self.ledOrderN.setToolTip("Filter order (# of taps - 1).") # -------------------------------------------------- # Layout for filter order subwidgets # -------------------------------------------------- layHOrdWdg = QHBoxLayout() layHOrdWdg.addWidget(self.lblOrder) layHOrdWdg.addWidget(self.chkMinOrder) layHOrdWdg.addStretch() layHOrdWdg.addWidget(self.lblOrderN) layHOrdWdg.addWidget(self.ledOrderN) # ---------------------------------------------------------------------- # OVERALL LAYOUT (stack standard + dynamic subwidgets vertically) # ---------------------------------------------------------------------- self.layVAllWdg = QVBoxLayout() self.layVAllWdg.addLayout(layHFilWdg) self.layVAllWdg.addLayout(self.layHDynWdg) self.layVAllWdg.addLayout(layHOrdWdg) # ============================================================================== frmMain = QFrame(self) frmMain.setLayout(self.layVAllWdg) layHMain = QHBoxLayout() layHMain.addWidget(frmMain) layHMain.setContentsMargins(*rc.params['wdg_margins']) self.setLayout(layHMain) # ============================================================================== # ------------------------------------------------------------ # SIGNALS & SLOTS # ------------------------------------------------------------ # Connect comboBoxes and setters, propgate change events hierarchically # through all widget methods and emit 'filt_changed' in the end. self.cmbResponseType.currentIndexChanged.connect( lambda: self._set_response_type(enb_signal=True)) # 'LP' self.cmbFilterType.currentIndexChanged.connect( lambda: self._set_filter_type(enb_signal=True)) # 'IIR' self.cmbFilterClass.currentIndexChanged.connect( lambda: self._set_design_method(enb_signal=True)) # 'cheby1' self.chkMinOrder.clicked.connect( lambda: self._set_filter_order(enb_signal=True)) # Min. Order self.ledOrderN.editingFinished.connect( lambda: self._set_filter_order(enb_signal=True)) # Manual Order
def _construct_UI(self): """ Intitialize the main GUI, consisting of: - A combo box to select the filter topology and an image of the topology - The input quantizer - The UI of the fixpoint filter widget - Simulation and export buttons """ #------------------------------------------------------------------------------ # Define frame and layout for the dynamically updated filter widget # The actual filter widget is instantiated in self.set_fixp_widget() later on self.layH_fx_wdg = QHBoxLayout() #self.layH_fx_wdg.setContentsMargins(*params['wdg_margins']) frmHDL_wdg = QFrame(self) frmHDL_wdg.setLayout(self.layH_fx_wdg) #frmHDL_wdg.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum) #------------------------------------------------------------------------------ # Initialize fixpoint filter combobox, title and description #------------------------------------------------------------------------------ self.cmb_wdg_fixp = QComboBox(self) self.cmb_wdg_fixp.setSizeAdjustPolicy(QComboBox.AdjustToContents) self.lblTitle = QLabel("not set", self) self.lblTitle.setWordWrap(True) self.lblTitle.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) layHTitle = QHBoxLayout() layHTitle.addWidget(self.cmb_wdg_fixp) layHTitle.addWidget(self.lblTitle) self.frmTitle = QFrame(self) self.frmTitle.setLayout(layHTitle) self.frmTitle.setContentsMargins(*params['wdg_margins']) #------------------------------------------------------------------------------ # Input and Output Quantizer #------------------------------------------------------------------------------ # - instantiate widgets for input and output quantizer # - pass the quantization (sub-?) dictionary to the constructor #------------------------------------------------------------------------------ self.wdg_w_input = UI_W(self, q_dict=fb.fil[0]['fxqc']['QI'], id='w_input', label='', lock_visible=True) self.wdg_w_input.sig_tx.connect(self.process_sig_rx) cmb_q = ['round', 'floor', 'fix'] self.wdg_w_output = UI_W(self, q_dict=fb.fil[0]['fxqc']['QO'], id='w_output', label='') self.wdg_w_output.sig_tx.connect(self.process_sig_rx) self.wdg_q_output = UI_Q( self, q_dict=fb.fil[0]['fxqc']['QO'], id='q_output', label='Output Format <i>Q<sub>Y </sub></i>:', cmb_q=cmb_q, cmb_ov=['wrap', 'sat']) self.wdg_q_output.sig_tx.connect(self.sig_rx) if HAS_DS: cmb_q.append('dsm') self.wdg_q_input = UI_Q( self, q_dict=fb.fil[0]['fxqc']['QI'], id='q_input', label='Input Format <i>Q<sub>X </sub></i>:', cmb_q=cmb_q) self.wdg_q_input.sig_tx.connect(self.sig_rx) # Layout and frame for input quantization layVQiWdg = QVBoxLayout() layVQiWdg.addWidget(self.wdg_q_input) layVQiWdg.addWidget(self.wdg_w_input) frmQiWdg = QFrame(self) #frmBtns.setFrameStyle(QFrame.StyledPanel|QFrame.Sunken) frmQiWdg.setLayout(layVQiWdg) frmQiWdg.setContentsMargins(*params['wdg_margins']) # Layout and frame for output quantization layVQoWdg = QVBoxLayout() layVQoWdg.addWidget(self.wdg_q_output) layVQoWdg.addWidget(self.wdg_w_output) frmQoWdg = QFrame(self) #frmBtns.setFrameStyle(QFrame.StyledPanel|QFrame.Sunken) frmQoWdg.setLayout(layVQoWdg) frmQoWdg.setContentsMargins(*params['wdg_margins']) #------------------------------------------------------------------------------ # Dynamically updated image of filter topology #------------------------------------------------------------------------------ # label is a placeholder for image self.lbl_fixp_img = QLabel("img not set", self) #self.lbl_fixp_img.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum) self.embed_fixp_img(self.no_fx_filter_img) layHImg = QHBoxLayout() layHImg.setContentsMargins(0, 0, 0, 0) layHImg.addWidget(self.lbl_fixp_img) #, Qt.AlignCenter) self.frmImg = QFrame(self) self.frmImg.setLayout(layHImg) self.frmImg.setContentsMargins(*params['wdg_margins']) self.resize_img() #------------------------------------------------------------------------------ # Simulation and export Buttons #------------------------------------------------------------------------------ self.butExportHDL = QPushButton(self) self.butExportHDL.setToolTip( "Export fixpoint filter in Verilog format.") self.butExportHDL.setText("Create HDL") self.butSimHDL = QPushButton(self) self.butSimHDL.setToolTip("Start migen fixpoint simulation.") self.butSimHDL.setText("Sim. HDL") self.butSimFxPy = QPushButton(self) self.butSimFxPy.setToolTip("Simulate filter with fixpoint effects.") self.butSimFxPy.setText("Sim. FixPy") self.layHHdlBtns = QHBoxLayout() self.layHHdlBtns.addWidget(self.butSimFxPy) self.layHHdlBtns.addWidget(self.butSimHDL) self.layHHdlBtns.addWidget(self.butExportHDL) # This frame encompasses the HDL buttons sim and convert frmHdlBtns = QFrame(self) #frmBtns.setFrameStyle(QFrame.StyledPanel|QFrame.Sunken) frmHdlBtns.setLayout(self.layHHdlBtns) frmHdlBtns.setContentsMargins(*params['wdg_margins']) # ------------------------------------------------------------------- # Top level layout # ------------------------------------------------------------------- splitter = QSplitter(self) splitter.setOrientation(Qt.Vertical) splitter.addWidget(frmHDL_wdg) splitter.addWidget(frmQoWdg) splitter.addWidget(self.frmImg) # setSizes uses absolute pixel values, but can be "misused" by specifying values # that are way too large: in this case, the space is distributed according # to the _ratio_ of the values: splitter.setSizes([3000, 3000, 5000]) layVMain = QVBoxLayout() layVMain.addWidget(self.frmTitle) layVMain.addWidget(frmHdlBtns) layVMain.addWidget(frmQiWdg) layVMain.addWidget(splitter) layVMain.addStretch() layVMain.setContentsMargins(*params['wdg_margins']) self.setLayout(layVMain) #---------------------------------------------------------------------- # GLOBAL SIGNALS & SLOTs #---------------------------------------------------------------------- self.sig_rx.connect(self.process_sig_rx) #---------------------------------------------------------------------- # LOCAL SIGNALS & SLOTs & EVENTFILTERS #---------------------------------------------------------------------- # monitor events and generate sig_resize event when resized self.lbl_fixp_img.installEventFilter(self) # ... then redraw image when resized self.sig_resize.connect(self.resize_img) self.cmb_wdg_fixp.currentIndexChanged.connect(self._update_fixp_widget) self.butExportHDL.clicked.connect(self.exportHDL) self.butSimHDL.clicked.connect(self.fx_sim_init) #---------------------------------------------------------------------- inst_wdg_list = self._update_filter_cmb() if len(inst_wdg_list) == 0: logger.warning("No fixpoint filters found!") else: logger.debug("Imported {0:d} fixpoint filters:\n{1}".format( len(inst_wdg_list.split("\n")) - 1, inst_wdg_list)) self._update_fixp_widget()
def _construct_UI(self): """ Intitialize the widget, consisting of: - Matplotlib widget with NavigationToolbar - Frame with control elements """ self.bfont = QFont() self.bfont.setBold(True) self.qfft_win_select = QFFTWinSelector(self, self.win_dict) self.lbl_N = QLabel(to_html("N =", frmt='bi')) self.led_N = QLineEdit(self) self.led_N.setText(str(self.N_view)) self.led_N.setMaximumWidth(qtext_width(N_x=8)) self.led_N.setToolTip( "<span>Number of window data points to display.</span>") # By default, the enter key triggers the default 'dialog action' in QDialog # widgets. This activates one of the pushbuttons. self.but_log_t = QPushButton("dB", default=False, autoDefault=False) self.but_log_t.setMaximumWidth(qtext_width(" dB ")) self.but_log_t.setObjectName("chk_log_time") self.but_log_t.setCheckable(True) self.but_log_t.setChecked(False) self.but_log_t.setToolTip("Display in dB") self.led_log_bottom_t = QLineEdit(self) self.led_log_bottom_t.setVisible(self.but_log_t.isChecked()) self.led_log_bottom_t.setText(str(self.bottom_t)) self.led_log_bottom_t.setMaximumWidth(qtext_width(N_x=6)) self.led_log_bottom_t.setToolTip( "<span>Minimum display value for log. scale.</span>") self.lbl_log_bottom_t = QLabel(to_html("min =", frmt='bi'), self) self.lbl_log_bottom_t.setVisible(self.but_log_t.isChecked()) self.but_norm_f = QPushButton("Max=1", default=False, autoDefault=False) self.but_norm_f.setCheckable(True) self.but_norm_f.setChecked(True) self.but_norm_f.setMaximumWidth(qtext_width(text=" Max=1 ")) self.but_norm_f.setToolTip( "Normalize window spectrum for a maximum of 1.") self.but_half_f = QPushButton("0...½", default=False, autoDefault=False) self.but_half_f.setCheckable(True) self.but_half_f.setChecked(True) self.but_half_f.setMaximumWidth(qtext_width(text=" 0...½ ")) self.but_half_f.setToolTip( "Display window spectrum in the range 0 ... 0.5 f_S.") # By default, the enter key triggers the default 'dialog action' in QDialog # widgets. This activates one of the pushbuttons. self.but_log_f = QPushButton("dB", default=False, autoDefault=False) self.but_log_f.setMaximumWidth(qtext_width(" dB ")) self.but_log_f.setObjectName("chk_log_freq") self.but_log_f.setToolTip("<span>Display in dB.</span>") self.but_log_f.setCheckable(True) self.but_log_f.setChecked(True) self.lbl_log_bottom_f = QLabel(to_html("min =", frmt='bi'), self) self.lbl_log_bottom_f.setVisible(self.but_log_f.isChecked()) self.led_log_bottom_f = QLineEdit(self) self.led_log_bottom_f.setVisible(self.but_log_t.isChecked()) self.led_log_bottom_f.setText(str(self.bottom_f)) self.led_log_bottom_f.setMaximumWidth(qtext_width(N_x=6)) self.led_log_bottom_f.setToolTip( "<span>Minimum display value for log. scale.</span>") # ---------------------------------------------------------------------- # ### frmControls ### # # This widget encompasses all control subwidgets # ---------------------------------------------------------------------- layH_win_select = QHBoxLayout() layH_win_select.addWidget(self.qfft_win_select) layH_win_select.setContentsMargins(0, 0, 0, 0) layH_win_select.addStretch(1) frmQFFT = QFrame(self) frmQFFT.setObjectName("frmQFFT") frmQFFT.setLayout(layH_win_select) hline = QHLine() layHControls = QHBoxLayout() layHControls.addWidget(self.lbl_N) layHControls.addWidget(self.led_N) layHControls.addStretch(1) layHControls.addWidget(self.lbl_log_bottom_t) layHControls.addWidget(self.led_log_bottom_t) layHControls.addWidget(self.but_log_t) layHControls.addStretch(5) layHControls.addWidget(QVLine(width=2)) layHControls.addStretch(5) layHControls.addWidget(self.but_norm_f) layHControls.addStretch(1) layHControls.addWidget(self.but_half_f) layHControls.addStretch(1) layHControls.addWidget(self.lbl_log_bottom_f) layHControls.addWidget(self.led_log_bottom_f) layHControls.addWidget(self.but_log_f) layVControls = QVBoxLayout() layVControls.addWidget(frmQFFT) layVControls.addWidget(hline) layVControls.addLayout(layHControls) frmControls = QFrame(self) frmControls.setObjectName("frmControls") frmControls.setLayout(layVControls) # ---------------------------------------------------------------------- # ### mplwidget ### # # Layout layVMainMpl (VBox) is defined within MplWidget, additional # widgets can be added below the matplotlib widget (here: frmControls) # # ---------------------------------------------------------------------- self.mplwidget = MplWidget(self) self.mplwidget.layVMainMpl.addWidget(frmControls) self.mplwidget.layVMainMpl.setContentsMargins(0, 0, 0, 0) # ---------------------------------------------------------------------- # ### frmInfo ### # # This widget encompasses the text info box and the table with window # parameters. # ---------------------------------------------------------------------- self.tbl_win_props = QTableWidget(self.tbl_rows, self.tbl_cols, self) self.tbl_win_props.setAlternatingRowColors(True) # Auto-resize of table can be set using the header (although it is invisible) self.tbl_win_props.verticalHeader().setSectionResizeMode( QHeaderView.Stretch) # Only the columns with data are stretched, the others are minimum size self.tbl_win_props.horizontalHeader().setSectionResizeMode( 1, QHeaderView.Stretch) self.tbl_win_props.horizontalHeader().setSectionResizeMode( 4, QHeaderView.Stretch) self.tbl_win_props.verticalHeader().setVisible(False) self.tbl_win_props.horizontalHeader().setVisible(False) self.tbl_win_props.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.MinimumExpanding) self.tbl_win_props.setFixedHeight( self.tbl_win_props.rowHeight(0) * self.tbl_rows + self.tbl_win_props.frameWidth() * 2) # self.tbl_win_props.setVerticalScrollBarPolicy( # Qt.ScrollBarAlwaysOff) # self.tbl_win_props.setHorizontalScrollBarPolicy( # Qt.ScrollBarAlwaysOff) self._construct_table(self.tbl_rows, self.tbl_cols, " ") self.txtInfoBox = QTextBrowser(self) layVInfo = QVBoxLayout(self) layVInfo.addWidget(self.tbl_win_props) layVInfo.addWidget(self.txtInfoBox) frmInfo = QFrame(self) frmInfo.setObjectName("frmInfo") frmInfo.setLayout(layVInfo) # ---------------------------------------------------------------------- # ### splitter ### # # This widget encompasses all subwidgets # ---------------------------------------------------------------------- splitter = QSplitter(self) splitter.setOrientation(Qt.Vertical) splitter.addWidget(self.mplwidget) splitter.addWidget(frmInfo) # setSizes uses absolute pixel values, but can be "misused" by # specifying values that are way too large: in this case, the space # is distributed according to the _ratio_ of the values: splitter.setSizes([3000, 800]) layVMain = QVBoxLayout() layVMain.addWidget(splitter) self.setLayout(layVMain) # ---------------------------------------------------------------------- # Set subplots # self.ax = self.mplwidget.fig.subplots(nrows=1, ncols=2) self.ax_t = self.ax[0] self.ax_f = self.ax[1] self.calc_win_draw() # initial calculation and drawing # ---------------------------------------------------------------------- # GLOBAL SIGNALS & SLOTs # ---------------------------------------------------------------------- self.sig_rx.connect(self.process_sig_rx) self.sig_rx.connect(self.qfft_win_select.sig_rx) # ---------------------------------------------------------------------- # LOCAL SIGNALS & SLOTs # ---------------------------------------------------------------------- self.but_log_f.clicked.connect(self.update_view) self.but_log_t.clicked.connect(self.update_view) self.led_log_bottom_t.editingFinished.connect(self.update_bottom) self.led_log_bottom_f.editingFinished.connect(self.update_bottom) self.led_N.editingFinished.connect(self.calc_win_draw) self.but_norm_f.clicked.connect(self.calc_win_draw) self.but_half_f.clicked.connect(self.update_view) self.mplwidget.mplToolbar.sig_tx.connect(self.process_sig_rx) self.tbl_win_props.itemClicked.connect(self._handle_item_clicked) self.qfft_win_select.sig_tx.connect(self.update_fft_win)
#------------------------------------------------------------------------------ if __name__ == '__main__': import sys from pyfda.libs.compat import QApplication, QFrame app = QApplication(sys.argv) # instantiate filter widget filt = Delay() filt.construct_UI() wdg_delay = getattr(filt, 'wdg_fil') layVDynWdg = QVBoxLayout() layVDynWdg.addWidget(wdg_delay, stretch = 1) filt.LPman(fb.fil[0]) # design a low-pass with parameters from global dict print(fb.fil[0][filt.FRMT]) # return results in default format frmMain = QFrame() frmMain.setFrameStyle(QFrame.StyledPanel|QFrame.Sunken) frmMain.setLayout(layVDynWdg) form = frmMain form.show() app.exec_() #------------------------------------------------------------------------------
def _construct_UI(self): """ Intitialize the widget, consisting of: - Matplotlib widget with NavigationToolbar - Frame with control elements """ self.bfont = QFont() self.bfont.setBold(True) self.chk_auto_N = QCheckBox(self) self.chk_auto_N.setChecked(False) self.chk_auto_N.setToolTip( "Use number of points from calling routine.") self.lbl_auto_N = QLabel("Auto " + to_html("N", frmt='i')) self.led_N = QLineEdit(self) self.led_N.setText(str(self.N)) self.led_N.setMaximumWidth(70) self.led_N.setToolTip("<span>Number of window data points.</span>") self.chk_log_t = QCheckBox("Log", self) self.chk_log_t.setChecked(False) self.chk_log_t.setToolTip("Display in dB") self.led_log_bottom_t = QLineEdit(self) self.led_log_bottom_t.setText(str(self.bottom_t)) self.led_log_bottom_t.setMaximumWidth(50) self.led_log_bottom_t.setEnabled(self.chk_log_t.isChecked()) self.led_log_bottom_t.setToolTip( "<span>Minimum display value for log. scale.</span>") self.lbl_log_bottom_t = QLabel("dB", self) self.lbl_log_bottom_t.setEnabled(self.chk_log_t.isChecked()) self.chk_norm_f = QCheckBox("Norm", self) self.chk_norm_f.setChecked(True) self.chk_norm_f.setToolTip( "Normalize window spectrum for a maximum of 1.") self.chk_half_f = QCheckBox("Half", self) self.chk_half_f.setChecked(True) self.chk_half_f.setToolTip( "Display window spectrum in the range 0 ... 0.5 f_S.") self.chk_log_f = QCheckBox("Log", self) self.chk_log_f.setChecked(True) self.chk_log_f.setToolTip("Display in dB") self.led_log_bottom_f = QLineEdit(self) self.led_log_bottom_f.setText(str(self.bottom_f)) self.led_log_bottom_f.setMaximumWidth(50) self.led_log_bottom_f.setEnabled(self.chk_log_f.isChecked()) self.led_log_bottom_f.setToolTip( "<span>Minimum display value for log. scale.</span>") self.lbl_log_bottom_f = QLabel("dB", self) self.lbl_log_bottom_f.setEnabled(self.chk_log_f.isChecked()) layHControls = QHBoxLayout() layHControls.addWidget(self.chk_auto_N) layHControls.addWidget(self.lbl_auto_N) layHControls.addWidget(self.led_N) layHControls.addStretch(1) layHControls.addWidget(self.chk_log_t) layHControls.addWidget(self.led_log_bottom_t) layHControls.addWidget(self.lbl_log_bottom_t) layHControls.addStretch(10) layHControls.addWidget(self.chk_norm_f) layHControls.addStretch(1) layHControls.addWidget(self.chk_half_f) layHControls.addStretch(1) layHControls.addWidget(self.chk_log_f) layHControls.addWidget(self.led_log_bottom_f) layHControls.addWidget(self.lbl_log_bottom_f) self.tblWinProperties = QTableWidget(self.tbl_rows, self.tbl_cols, self) self.tblWinProperties.setAlternatingRowColors(True) self.tblWinProperties.verticalHeader().setVisible(False) self.tblWinProperties.horizontalHeader().setVisible(False) self._init_table(self.tbl_rows, self.tbl_cols, " ") self.txtInfoBox = QTextBrowser(self) #---------------------------------------------------------------------- # ### frmControls ### # # This widget encompasses all control subwidgets #---------------------------------------------------------------------- self.frmControls = QFrame(self) self.frmControls.setObjectName("frmControls") self.frmControls.setLayout(layHControls) #---------------------------------------------------------------------- # ### mplwidget ### # # main widget: Layout layVMainMpl (VBox) is defined with MplWidget, # additional widgets can be added (like self.frmControls) # The widget encompasses all other widgets. #---------------------------------------------------------------------- self.mplwidget = MplWidget(self) self.mplwidget.layVMainMpl.addWidget(self.frmControls) self.mplwidget.layVMainMpl.setContentsMargins(*params['wdg_margins']) #---------------------------------------------------------------------- # ### frmInfo ### # # This widget encompasses the text info box and the table with window # parameters. #---------------------------------------------------------------------- layVInfo = QVBoxLayout(self) layVInfo.addWidget(self.tblWinProperties) layVInfo.addWidget(self.txtInfoBox) self.frmInfo = QFrame(self) self.frmInfo.setObjectName("frmInfo") self.frmInfo.setLayout(layVInfo) #---------------------------------------------------------------------- # ### splitter ### # # This widget encompasses all control subwidgets #---------------------------------------------------------------------- splitter = QSplitter(self) splitter.setOrientation(Qt.Vertical) splitter.addWidget(self.mplwidget) splitter.addWidget(self.frmInfo) # setSizes uses absolute pixel values, but can be "misused" by specifying values # that are way too large: in this case, the space is distributed according # to the _ratio_ of the values: splitter.setSizes([3000, 1000]) layVMain = QVBoxLayout() layVMain.addWidget(splitter) self.setLayout(layVMain) #---------------------------------------------------------------------- # Set subplots # self.ax = self.mplwidget.fig.subplots(nrows=1, ncols=2) self.ax_t = self.ax[0] self.ax_f = self.ax[1] self.draw() # initial drawing #---------------------------------------------------------------------- # GLOBAL SIGNALS & SLOTs #---------------------------------------------------------------------- self.sig_rx.connect(self.process_sig_rx) #---------------------------------------------------------------------- # LOCAL SIGNALS & SLOTs #---------------------------------------------------------------------- self.chk_log_f.clicked.connect(self.update_view) self.chk_log_t.clicked.connect(self.update_view) self.led_log_bottom_t.editingFinished.connect(self.update_bottom) self.led_log_bottom_f.editingFinished.connect(self.update_bottom) self.chk_auto_N.clicked.connect(self.calc_N) self.led_N.editingFinished.connect(self.draw) self.chk_norm_f.clicked.connect(self.draw) self.chk_half_f.clicked.connect(self.update_view) self.mplwidget.mplToolbar.sig_tx.connect(self.process_sig_rx) self.tblWinProperties.itemClicked.connect(self._handle_item_clicked)
def _construct_UI(self, **kwargs): """ Construct widget """ dict_ui = { 'wdg_name': 'ui_q', 'label': '', 'label_q': 'Quant.', 'tip_q': 'Select the kind of quantization.', 'cmb_q': ['round', 'fix', 'floor'], 'cur_q': 'round', 'label_ov': 'Ovfl.', 'tip_ov': 'Select overflow behaviour.', 'cmb_ov': ['wrap', 'sat'], 'cur_ov': 'wrap', 'enabled': True, 'visible': True } #: default widget settings if 'quant' in self.q_dict and self.q_dict['quant'] in dict_ui['cmb_q']: dict_ui['cur_q'] = self.q_dict['quant'] if 'ovfl' in self.q_dict and self.q_dict['ovfl'] in dict_ui['cmb_ov']: dict_ui['cur_ov'] = self.q_dict['ovfl'] for key, val in kwargs.items(): dict_ui.update({key: val}) # dict_ui.update(map(kwargs)) # same as above? self.wdg_name = dict_ui['wdg_name'] lblQuant = QLabel(dict_ui['label_q'], self) self.cmbQuant = QComboBox(self) self.cmbQuant.addItems(dict_ui['cmb_q']) qset_cmb_box(self.cmbQuant, dict_ui['cur_q']) self.cmbQuant.setToolTip(dict_ui['tip_q']) self.cmbQuant.setObjectName('quant') lblOvfl = QLabel(dict_ui['label_ov'], self) self.cmbOvfl = QComboBox(self) self.cmbOvfl.addItems(dict_ui['cmb_ov']) qset_cmb_box(self.cmbOvfl, dict_ui['cur_ov']) self.cmbOvfl.setToolTip(dict_ui['tip_ov']) self.cmbOvfl.setObjectName('ovfl') # ComboBox size is adjusted automatically to fit the longest element self.cmbQuant.setSizeAdjustPolicy(QComboBox.AdjustToContents) self.cmbOvfl.setSizeAdjustPolicy(QComboBox.AdjustToContents) layH = QHBoxLayout() if dict_ui['label'] != "": lblW = QLabel(to_html(dict_ui['label'], frmt='bi'), self) layH.addWidget(lblW) layH.addStretch() layH.addWidget(lblOvfl) layH.addWidget(self.cmbOvfl) # layH.addStretch(1) layH.addWidget(lblQuant) layH.addWidget(self.cmbQuant) layH.setContentsMargins(0, 0, 0, 0) frmMain = QFrame(self) frmMain.setLayout(layH) layVMain = QVBoxLayout() # Widget main layout layVMain.addWidget(frmMain) layVMain.setContentsMargins(0, 0, 0, 0) # *params['wdg_margins']) self.setLayout(layVMain) # ---------------------------------------------------------------------- # INITIAL SETTINGS # ---------------------------------------------------------------------- self.ovfl = qget_cmb_box(self.cmbOvfl, data=False) self.quant = qget_cmb_box(self.cmbQuant, data=False) frmMain.setEnabled(dict_ui['enabled']) frmMain.setVisible(dict_ui['visible']) # ---------------------------------------------------------------------- # LOCAL SIGNALS & SLOTs # ---------------------------------------------------------------------- self.cmbOvfl.currentIndexChanged.connect(self.ui2dict) self.cmbQuant.currentIndexChanged.connect(self.ui2dict)
def _construct_UI(self) -> None: """ Intitialize the main GUI, consisting of: - A combo box to select the filter topology and an image of the topology - The input quantizer - The UI of the fixpoint filter widget - Simulation and export buttons """ # ------------------------------------------------------------------------------ # Define frame and layout for the dynamically updated filter widget # The actual filter widget is instantiated in self.set_fixp_widget() later on self.layH_fx_wdg = QHBoxLayout() # self.layH_fx_wdg.setContentsMargins(*params['wdg_margins']) frmHDL_wdg = QFrame(self) frmHDL_wdg.setLayout(self.layH_fx_wdg) # frmHDL_wdg.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum) # ------------------------------------------------------------------------------ # Initialize fixpoint filter combobox, title and description # ------------------------------------------------------------------------------ self.cmb_fx_wdg = QComboBox(self) self.cmb_fx_wdg.setSizeAdjustPolicy(QComboBox.AdjustToContents) self.lblTitle = QLabel("not set", self) self.lblTitle.setWordWrap(True) self.lblTitle.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) layHTitle = QHBoxLayout() layHTitle.addWidget(self.cmb_fx_wdg) layHTitle.addWidget(self.lblTitle) self.frmTitle = QFrame(self) self.frmTitle.setLayout(layHTitle) self.frmTitle.setContentsMargins(*params['wdg_margins']) # ------------------------------------------------------------------------------ # Input and Output Quantizer # ------------------------------------------------------------------------------ # - instantiate widgets for input and output quantizer # - pass the quantization (sub-?) dictionary to the constructor # ------------------------------------------------------------------------------ self.wdg_w_input = UI_W(self, q_dict=fb.fil[0]['fxqc']['QI'], wdg_name='w_input', label='', lock_visible=True) self.wdg_w_input.sig_tx.connect(self.process_sig_rx_local) cmb_q = ['round', 'floor', 'fix'] self.wdg_w_output = UI_W(self, q_dict=fb.fil[0]['fxqc']['QO'], wdg_name='w_output', label='') self.wdg_w_output.sig_tx.connect(self.process_sig_rx_local) self.wdg_q_output = UI_Q(self, q_dict=fb.fil[0]['fxqc']['QO'], wdg_name='q_output', label='Output Format <i>Q<sub>Y </sub></i>:', cmb_q=cmb_q, cmb_ov=['wrap', 'sat']) self.wdg_q_output.sig_tx.connect(self.sig_rx_local) if HAS_DS: cmb_q.append('dsm') self.wdg_q_input = UI_Q(self, q_dict=fb.fil[0]['fxqc']['QI'], wdg_name='q_input', label='Input Format <i>Q<sub>X </sub></i>:', cmb_q=cmb_q) self.wdg_q_input.sig_tx.connect(self.sig_rx_local) # Layout and frame for input quantization layVQiWdg = QVBoxLayout() layVQiWdg.addWidget(self.wdg_q_input) layVQiWdg.addWidget(self.wdg_w_input) frmQiWdg = QFrame(self) # frmBtns.setFrameStyle(QFrame.StyledPanel|QFrame.Sunken) frmQiWdg.setLayout(layVQiWdg) frmQiWdg.setContentsMargins(*params['wdg_margins']) # Layout and frame for output quantization layVQoWdg = QVBoxLayout() layVQoWdg.addWidget(self.wdg_q_output) layVQoWdg.addWidget(self.wdg_w_output) frmQoWdg = QFrame(self) # frmBtns.setFrameStyle(QFrame.StyledPanel|QFrame.Sunken) frmQoWdg.setLayout(layVQoWdg) frmQoWdg.setContentsMargins(*params['wdg_margins']) # ------------------------------------------------------------------------------ # Dynamically updated image of filter topology (label as placeholder) # ------------------------------------------------------------------------------ # allow setting background color # lbl_fixp_img_palette = QPalette() # lbl_fixp_img_palette.setColor(QPalette(window, Qt: white)) # lbl_fixp_img_palette.setBrush(self.backgroundRole(), QColor(150, 0, 0)) # lbl_fixp_img_palette.setColor(QPalette: WindowText, Qt: blue) self.lbl_fixp_img = QLabel("img not set", self) self.lbl_fixp_img.setAutoFillBackground(True) # self.lbl_fixp_img.setPalette(lbl_fixp_img_palette) # self.lbl_fixp_img.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum) self.embed_fixp_img(self.no_fx_filter_img) layHImg = QHBoxLayout() layHImg.setContentsMargins(0, 0, 0, 0) layHImg.addWidget(self.lbl_fixp_img) # , Qt.AlignCenter) self.frmImg = QFrame(self) self.frmImg.setLayout(layHImg) self.frmImg.setContentsMargins(*params['wdg_margins']) # ------------------------------------------------------------------------------ # Simulation and export Buttons # ------------------------------------------------------------------------------ self.butExportHDL = QPushButton(self) self.butExportHDL.setToolTip( "Create Verilog or VHDL netlist for fixpoint filter.") self.butExportHDL.setText("Create HDL") self.butSimFx = QPushButton(self) self.butSimFx.setToolTip("Start fixpoint simulation.") self.butSimFx.setText("Sim. FX") self.layHHdlBtns = QHBoxLayout() self.layHHdlBtns.addWidget(self.butSimFx) self.layHHdlBtns.addWidget(self.butExportHDL) # This frame encompasses the HDL buttons sim and convert frmHdlBtns = QFrame(self) # frmBtns.setFrameStyle(QFrame.StyledPanel|QFrame.Sunken) frmHdlBtns.setLayout(self.layHHdlBtns) frmHdlBtns.setContentsMargins(*params['wdg_margins']) # ------------------------------------------------------------------- # Top level layout # ------------------------------------------------------------------- splitter = QSplitter(self) splitter.setOrientation(Qt.Vertical) splitter.addWidget(frmHDL_wdg) splitter.addWidget(frmQoWdg) splitter.addWidget(self.frmImg) # setSizes uses absolute pixel values, but can be "misused" by specifying values # that are way too large: in this case, the space is distributed according # to the _ratio_ of the values: splitter.setSizes([3000, 3000, 5000]) layVMain = QVBoxLayout() layVMain.addWidget(self.frmTitle) layVMain.addWidget(frmHdlBtns) layVMain.addWidget(frmQiWdg) layVMain.addWidget(splitter) layVMain.addStretch() layVMain.setContentsMargins(*params['wdg_margins']) self.setLayout(layVMain) # ---------------------------------------------------------------------- # GLOBAL SIGNALS & SLOTs # ---------------------------------------------------------------------- self.sig_rx.connect(self.process_sig_rx) self.sig_rx_local.connect(self.process_sig_rx_local) # dynamic connection in `self._update_fixp_widget()`: # ----- # if hasattr(self.fx_filt_ui, "sig_rx"): # self.sig_rx.connect(self.fx_filt_ui.sig_rx) # if hasattr(self.fx_filt_ui, "sig_tx"): # self.fx_filt_ui.sig_tx.connect(self.sig_rx_local) # ---- # ---------------------------------------------------------------------- # LOCAL SIGNALS & SLOTs # ---------------------------------------------------------------------- self.cmb_fx_wdg.currentIndexChanged.connect(self._update_fixp_widget) self.butExportHDL.clicked.connect(self.exportHDL) self.butSimFx.clicked.connect(lambda x: self.emit({'fx_sim': 'start'}))
def _construct_UI(self): """ Construct User Interface from all input subwidgets """ self.butLoadFilt = QPushButton("LOAD FILTER", self) self.butLoadFilt.setToolTip("Load filter from disk") self.butSaveFilt = QPushButton("SAVE FILTER", self) self.butSaveFilt.setToolTip("Save filter todisk") layHButtons1 = QHBoxLayout() layHButtons1.addWidget(self.butLoadFilt) # <Load Filter> button layHButtons1.addWidget(self.butSaveFilt) # <Save Filter> button layHButtons1.setContentsMargins(*params['wdg_margins_spc']) self.butDesignFilt = QPushButton("DESIGN FILTER", self) self.butDesignFilt.setToolTip("Design filter with chosen specs") self.butQuit = QPushButton("Quit", self) self.butQuit.setToolTip("Exit pyfda tool") layHButtons2 = QHBoxLayout() layHButtons2.addWidget(self.butDesignFilt) # <Design Filter> button layHButtons2.addWidget(self.butQuit) # <Quit> button layHButtons2.setContentsMargins(*params['wdg_margins']) # Subwidget for selecting filter with response type rt (LP, ...), # filter type ft (IIR, ...) and filter class fc (cheby1, ...) self.sel_fil = select_filter.SelectFilter(self) self.sel_fil.setObjectName("select_filter") self.sel_fil.sig_tx.connect(self.sig_rx_local) # Subwidget for selecting the frequency unit and range self.f_units = freq_units.FreqUnits(self) self.f_units.setObjectName("freq_units") self.f_units.sig_tx.connect(self.sig_rx_local) # Changing the frequency unit requires re-display of frequency specs # but it does not influence the actual specs (no specsChanged ) # Activating the "Sort" button emits 'view_changed'?specs_changed'?, requiring # sorting and storing the frequency entries # Changing filter parameters / specs requires reloading of parameters # in other hierarchy levels, e.g. in the plot tabs # Subwidget for Frequency Specs self.f_specs = freq_specs.FreqSpecs(self) self.f_specs.setObjectName("freq_specs") self.f_specs.sig_tx.connect(self.sig_rx_local) self.sig_tx.connect(self.f_specs.sig_rx) # Subwidget for Amplitude Specs self.a_specs = amplitude_specs.AmplitudeSpecs(self) self.a_specs.setObjectName("amplitude_specs") self.a_specs.sig_tx.connect(self.sig_rx_local) # Subwidget for Weight Specs self.w_specs = weight_specs.WeightSpecs(self) self.w_specs.setObjectName("weight_specs") self.w_specs.sig_tx.connect(self.sig_rx_local) # Subwidget for target specs (frequency and amplitude) self.t_specs = target_specs.TargetSpecs(self, title="Target Specifications") self.t_specs.setObjectName("target_specs") self.t_specs.sig_tx.connect(self.sig_rx_local) self.sig_tx.connect(self.t_specs.sig_rx) # Subwidget for displaying infos on the design method self.lblMsg = QLabel(self) self.lblMsg.setWordWrap(True) layVMsg = QVBoxLayout() layVMsg.addWidget(self.lblMsg) self.frmMsg = QFrame(self) self.frmMsg.setLayout(layVMsg) layVFrm = QVBoxLayout() layVFrm.addWidget(self.frmMsg) layVFrm.setContentsMargins(*params['wdg_margins']) # ---------------------------------------------------------------------- # LAYOUT for input specifications and buttons # ---------------------------------------------------------------------- layVMain = QVBoxLayout(self) layVMain.addLayout(layHButtons1) # <Load> & <Save> buttons layVMain.addWidget(self.sel_fil) # Design method (IIR - ellip, ...) layVMain.addLayout(layHButtons2) # <Design> & <Quit> buttons layVMain.addWidget(self.f_units) # Frequency units layVMain.addWidget(self.t_specs) # Target specs layVMain.addWidget(self.f_specs) # Freq. specifications layVMain.addWidget(self.a_specs) # Amplitude specs layVMain.addWidget(self.w_specs) # Weight specs layVMain.addLayout(layVFrm) # Text message layVMain.addStretch() layVMain.setContentsMargins(*params['wdg_margins']) self.setLayout(layVMain) # main layout of widget # ---------------------------------------------------------------------- # GLOBAL SIGNALS & SLOTs # ---------------------------------------------------------------------- self.sig_rx.connect(self.process_sig_rx) # ---------------------------------------------------------------------- # LOCAL SIGNALS & SLOTs # ---------------------------------------------------------------------- self.sig_rx_local.connect(self.process_sig_rx_local) self.butLoadFilt.clicked.connect(lambda: load_filter(self)) self.butSaveFilt.clicked.connect(lambda: save_filter(self)) self.butDesignFilt.clicked.connect(self.start_design_filt) self.butQuit.clicked.connect(self.quit_program) # emit 'quit_program' # ---------------------------------------------------------------------- self.update_UI() # first time initialization self.start_design_filt() # design first filter using default values
def _construct_ui(self): """ Define and construct the subwidgets """ modes = ['| H |', 're{H}', 'im{H}'] self.cmbShowH = QComboBox(self) self.cmbShowH.addItems(modes) self.cmbShowH.setObjectName("cmbUnitsH") self.cmbShowH.setToolTip( "Show magnitude, real / imag. part of H or H \n" "without linear phase (acausal system).") self.cmbShowH.setCurrentIndex(0) self.lblIn = QLabel("in", self) units = ['dB', 'V', 'W', 'Auto'] self.cmbUnitsA = QComboBox(self) self.cmbUnitsA.addItems(units) self.cmbUnitsA.setObjectName("cmbUnitsA") self.cmbUnitsA.setToolTip( "<span>Set unit for y-axis:\n" "dB is attenuation (positive values), V and W are gain (less than 1).</span>" ) self.cmbUnitsA.setCurrentIndex(0) self.lbl_log_bottom = QLabel("Bottom", self) self.led_log_bottom = QLineEdit(self) self.led_log_bottom.setText(str(self.log_bottom)) self.led_log_bottom.setToolTip( "<span>Minimum display value for dB. scale.</span>") self.lbl_log_unit = QLabel("dB", self) self.cmbShowH.setSizeAdjustPolicy(QComboBox.AdjustToContents) self.cmbUnitsA.setSizeAdjustPolicy(QComboBox.AdjustToContents) self.chkZerophase = QCheckBox("Zero phase", self) self.chkZerophase.setToolTip( "<span>Remove linear phase calculated from filter order.\n" "Attention: This makes no sense for a non-linear phase system!</span>" ) self.lblInset = QLabel("Inset", self) self.cmbInset = QComboBox(self) self.cmbInset.addItems(['off', 'edit', 'fixed']) self.cmbInset.setObjectName("cmbInset") self.cmbInset.setToolTip("Display/edit second inset plot") self.cmbInset.setCurrentIndex(0) self.inset_idx = 0 # store previous index for comparison self.chkSpecs = QCheckBox("Specs", self) self.chkSpecs.setChecked(False) self.chkSpecs.setToolTip("Display filter specs as hatched regions") self.chkPhase = QCheckBox("Phase", self) self.chkPhase.setToolTip("Overlay phase") self.chkPhase.setChecked(False) self.chkAlign = QCheckBox("Align", self) self.chkAlign.setToolTip( "<span>Try to align grids for magnitude and phase " "(doesn't work in all cases).</span>") self.chkAlign.setChecked(True) self.chkAlign.setVisible(self.chkPhase.isChecked()) #---------------------------------------------------------------------- # ### frmControls ### # # This widget encompasses all control subwidgets #---------------------------------------------------------------------- layHControls = QHBoxLayout() layHControls.addStretch(10) layHControls.addWidget(self.cmbShowH) layHControls.addWidget(self.lblIn) layHControls.addWidget(self.cmbUnitsA) layHControls.addStretch(1) layHControls.addWidget(self.lbl_log_bottom) layHControls.addWidget(self.led_log_bottom) layHControls.addWidget(self.lbl_log_unit) layHControls.addStretch(1) layHControls.addWidget(self.chkZerophase) layHControls.addStretch(1) layHControls.addWidget(self.lblInset) layHControls.addWidget(self.cmbInset) layHControls.addStretch(1) layHControls.addWidget(self.chkSpecs) layHControls.addStretch(1) layHControls.addWidget(self.chkPhase) layHControls.addWidget(self.chkAlign) layHControls.addStretch(10) self.frmControls = QFrame(self) self.frmControls.setObjectName("frmControls") self.frmControls.setLayout(layHControls) #---------------------------------------------------------------------- # ### mplwidget ### # # main widget, encompassing the other widgets #---------------------------------------------------------------------- self.mplwidget = MplWidget(self) self.mplwidget.layVMainMpl.addWidget(self.frmControls) self.mplwidget.layVMainMpl.setContentsMargins(*params['wdg_margins']) self.mplwidget.mplToolbar.a_he.setEnabled(True) self.mplwidget.mplToolbar.a_he.info = "manual/plot_hf.html" self.setLayout(self.mplwidget.layVMainMpl) self.init_axes() self.draw() # calculate and draw |H(f)| #---------------------------------------------------------------------- # GLOBAL SIGNALS & SLOTs #---------------------------------------------------------------------- self.sig_rx.connect(self.process_sig_rx) #---------------------------------------------------------------------- # LOCAL SIGNALS & SLOTs #---------------------------------------------------------------------- self.cmbUnitsA.currentIndexChanged.connect(self.draw) self.led_log_bottom.editingFinished.connect(self.update_view) self.cmbShowH.currentIndexChanged.connect(self.draw) self.chkZerophase.clicked.connect(self.draw) self.cmbInset.currentIndexChanged.connect(self.draw_inset) self.chkSpecs.clicked.connect(self.draw) self.chkPhase.clicked.connect(self.draw) self.chkAlign.clicked.connect(self.draw) self.mplwidget.mplToolbar.sig_tx.connect(self.process_sig_rx)
def _construct_UI(self): """ Construct User Interface """ amp_units = ["dB", "V", "W"] bfont = QFont() bfont.setBold(True) lblTitle = QLabel(str(self.title), self) # field for widget title lblTitle.setFont(bfont) lblTitle.setWordWrap(True) lblUnits = QLabel("in", self) self.cmbUnitsA = QComboBox(self) self.cmbUnitsA.addItems(amp_units) self.cmbUnitsA.setObjectName("cmbUnitsA") self.cmbUnitsA.setToolTip( "<span>Unit for amplitude specifications:" " dB is attenuation (> 0); levels in V and W have to be < 1.</span>" ) # fit size dynamically to largest element: self.cmbUnitsA.setSizeAdjustPolicy(QComboBox.AdjustToContents) # find index for default unit from dictionary and set the unit amp_idx = self.cmbUnitsA.findData(fb.fil[0]['amp_specs_unit']) if amp_idx < 0: amp_idx = 0 self.cmbUnitsA.setCurrentIndex(amp_idx) # initialize for dBs layHTitle = QHBoxLayout() # layout for title and unit layHTitle.addWidget(lblTitle) layHTitle.addWidget(lblUnits, Qt.AlignLeft) layHTitle.addWidget(self.cmbUnitsA, Qt.AlignLeft) layHTitle.addStretch(1) self.layGSpecs = QGridLayout() # sublayout for spec fields # set the title as the first (fixed) entry in grid layout. The other # fields are added and hidden dynamically in _show_entries and _hide_entries() self.layGSpecs.addLayout(layHTitle, 0, 0, 1, 2) self.layGSpecs.setAlignment(Qt.AlignLeft) # This is the top level widget, encompassing the other widgets self.frmMain = QFrame(self) self.frmMain.setLayout(self.layGSpecs) self.layVMain = QVBoxLayout() # Widget main layout self.layVMain.addWidget(self.frmMain) self.layVMain.setContentsMargins(*params['wdg_margins']) self.setLayout(self.layVMain) self.n_cur_labels = 0 # number of currently visible labels / qlineedits # - Build a list from all entries in the fil_dict dictionary starting # with "A" (= amplitude specifications of the current filter) # - Pass the list to update_UI which recreates the widget # ATTENTION: Entries need to be converted from QString to str for Py 2 new_labels = [str(l) for l in fb.fil[0] if l[0] == 'A'] self.update_UI(new_labels=new_labels) #---------------------------------------------------------------------- # LOCAL SIGNALS & SLOTs / EVENT MONITORING #---------------------------------------------------------------------- self.cmbUnitsA.currentIndexChanged.connect(self._set_amp_unit)
def _construct_UI(self): """ Intitialize the widget, consisting of: - Matplotlib widget with NavigationToolbar - Frame with control elements """ self.lbl_overlay = QLabel(to_html("Overlay:", frmt='bi'), self) self.cmb_overlay = QComboBox(self) qcmb_box_populate( self.cmb_overlay, self.cmb_overlay_items, self.cmb_overlay_default) self.but_log = PushButton(" Log.", checked=True) self.but_log.setObjectName("but_log") self.but_log.setToolTip("<span>Log. scale for overlays.</span>") self.diaRad_Hf = QDial(self) self.diaRad_Hf.setRange(2, 10) self.diaRad_Hf.setValue(2) self.diaRad_Hf.setTracking(False) # produce less events when turning self.diaRad_Hf.setFixedHeight(30) self.diaRad_Hf.setFixedWidth(30) self.diaRad_Hf.setWrapping(False) self.diaRad_Hf.setToolTip("<span>Set max. radius for |H(f)| plot.</span>") self.lblRad_Hf = QLabel("Radius", self) self.lblBottom = QLabel(to_html("Bottom =", frmt='bi'), self) self.ledBottom = QLineEdit(self) self.ledBottom.setObjectName("ledBottom") self.ledBottom.setText(str(self.zmin)) self.ledBottom.setMaximumWidth(qtext_width(N_x=8)) self.ledBottom.setToolTip("Minimum display value.") self.lblBottomdB = QLabel("dB", self) self.lblBottomdB.setVisible(self.but_log.isChecked()) self.lblTop = QLabel(to_html("Top =", frmt='bi'), self) self.ledTop = QLineEdit(self) self.ledTop.setObjectName("ledTop") self.ledTop.setText(str(self.zmax)) self.ledTop.setToolTip("Maximum display value.") self.ledTop.setMaximumWidth(qtext_width(N_x=8)) self.lblTopdB = QLabel("dB", self) self.lblTopdB.setVisible(self.but_log.isChecked()) self.but_fir_poles = PushButton(" FIR Poles ", checked=True) self.but_fir_poles.setToolTip("<span>Show FIR poles at the origin.</span>") layHControls = QHBoxLayout() layHControls.addWidget(self.lbl_overlay) layHControls.addWidget(self.cmb_overlay) layHControls.addWidget(self.but_log) layHControls.addWidget(self.diaRad_Hf) layHControls.addWidget(self.lblRad_Hf) layHControls.addWidget(self.lblTop) layHControls.addWidget(self.ledTop) layHControls.addWidget(self.lblTopdB) layHControls.addWidget(self.lblBottom) layHControls.addWidget(self.ledBottom) layHControls.addWidget(self.lblBottomdB) layHControls.addStretch(10) layHControls.addWidget(self.but_fir_poles) # ---------------------------------------------------------------------- # ### frmControls ### # # This widget encompasses all control subwidgets # ---------------------------------------------------------------------- self.frmControls = QFrame(self) self.frmControls.setObjectName("frmControls") self.frmControls.setLayout(layHControls) # ---------------------------------------------------------------------- # ### mplwidget ### # # main widget, encompassing the other widgets # ---------------------------------------------------------------------- self.mplwidget = MplWidget(self) self.mplwidget.layVMainMpl.addWidget(self.frmControls) self.mplwidget.layVMainMpl.setContentsMargins(*params['wdg_margins']) self.mplwidget.mplToolbar.a_he.setEnabled(True) self.mplwidget.mplToolbar.a_he.info = "manual/plot_pz.html" self.setLayout(self.mplwidget.layVMainMpl) self.init_axes() self._log_clicked() # calculate and draw poles and zeros # ---------------------------------------------------------------------- # GLOBAL SIGNALS & SLOTs # ---------------------------------------------------------------------- self.sig_rx.connect(self.process_sig_rx) # ---------------------------------------------------------------------- # LOCAL SIGNALS & SLOTs # ---------------------------------------------------------------------- self.mplwidget.mplToolbar.sig_tx.connect(self.process_sig_rx) self.cmb_overlay.currentIndexChanged.connect(self.draw) self.but_log.clicked.connect(self._log_clicked) self.ledBottom.editingFinished.connect(self._log_clicked) self.ledTop.editingFinished.connect(self._log_clicked) self.diaRad_Hf.valueChanged.connect(self.draw) self.but_fir_poles.clicked.connect(self.draw)