def _update_win_fft(self): """ Update window type for FirWin """ self.alg = str(self.cmb_firwin_alg.currentText()) self.fir_window_name = qget_cmb_box(self.cmb_firwin_win, data=False) self.win = calc_window_function(self.win_dict, self.fir_window_name, N=self.N, sym=True) n_par = self.win_dict['n_par'] self.lblWinPar1.setVisible(n_par > 0) self.ledWinPar1.setVisible(n_par > 0) self.lblWinPar2.setVisible(n_par > 1) self.ledWinPar2.setVisible(n_par > 1) if n_par > 0: self.lblWinPar1.setText( to_html(self.win_dict['par'][0]['name'] + " =", frmt='bi')) self.ledWinPar1.setText(str(self.win_dict['par'][0]['val'])) self.ledWinPar1.setToolTip(self.win_dict['par'][0]['tooltip']) if n_par > 1: self.lblWinPar2.setText( to_html(self.win_dict['par'][1]['name'] + " =", frmt='bi')) self.ledWinPar2.setText(str(self.win_dict['par'][1]['val'])) self.ledWinPar2.setToolTip(self.win_dict['par'][1]['tooltip']) # sig_tx -> select_filter -> filter_specs self.sig_tx.emit({'sender': __name__, 'filt_changed': 'firwin'})
def update_freq_units(self): """ Update labels referrring to frequency specs """ if fb.fil[0]['freq_specs_unit'] == 'k': f_unit = '' t_unit = '' self.lblFreq1.setText(self.txtFreq1_k) self.lblFreq2.setText(self.txtFreq2_k) else: f_unit = fb.fil[0]['plt_fUnit'] t_unit = fb.fil[0]['plt_tUnit'].replace(r"$\mu$", "μ") self.lblFreq1.setText(self.txtFreq1_f) self.lblFreq2.setText(self.txtFreq2_f) if f_unit in {"f_S", "f_Ny"}: unit_frmt = "i" # italic else: unit_frmt = None # don't print units like kHz in italic self.lblFreqUnit1.setText(to_html(f_unit, frmt=unit_frmt)) self.lblFreqUnit2.setText(to_html(f_unit, frmt=unit_frmt)) self.lbl_TU1.setText(to_html(t_unit, frmt=unit_frmt)) self.lbl_TU2.setText(to_html(t_unit, frmt=unit_frmt))
def _update_noi(self): """ Update type + value + label for self.noi for noise""" self.noise = qget_cmb_box(self.cmbNoise, data=False).lower() self.lblNoi.setVisible(self.noise != 'none') self.ledNoi.setVisible(self.noise != 'none') if self.noise != 'none': self.noi = safe_eval(self.ledNoi.text(), 0, return_type='float', sign='poszero') self.ledNoi.setText(str(self.noi)) if self.noise == 'gauss': self.lblNoi.setText(to_html("σ =", frmt='bi')) self.ledNoi.setToolTip( "<span>Standard deviation of statistical process," "noise power is <i>P</i> = σ<sup>2</sup></span>") elif self.noise == 'uniform': self.lblNoi.setText(to_html("Δ =", frmt='bi')) self.ledNoi.setToolTip( "<span>Interval size for uniformly distributed process " "(e.g. quantization step size for quantization noise), " "centered around 0. Noise power is " "<i>P</i> = Δ<sup>2</sup>/12.</span>") elif self.noise == 'prbs': self.lblNoi.setText(to_html("A =", frmt='bi')) self.ledNoi.setToolTip( "<span>Amplitude of bipolar Pseudorandom Binary Sequence. " "Noise power is <i>P</i> = A<sup>2</sup>.</span>") self.sig_tx.emit({'sender': __name__, 'ui_changed': 'noi'})
def update_UI(self, new_labels=()): """ Called from filter_specs.update_UI() and target_specs.update_UI() Set labels and get corresponding values from filter dictionary. When number of entries has changed, the layout of subwidget is rebuilt, using - `self.qlabels`, a list with references to existing QLabel widgets, - `new_labels`, a list of strings from the filter_dict for the current filter design - 'num_new_labels`, their number - `self.n_cur_labels`, the number of currently visible labels / qlineedit fields """ self.update_f_unit() state = new_labels[0] new_labels = new_labels[1:] num_new_labels = len(new_labels) # hide / show labels / create new subwidgets if neccessary: self._show_entries(num_new_labels) # W_lbl = max([self.qfm.width(l) for l in new_labels]) # max. label width in pixel # ---------------------------- logging ----------------------------- logger.debug("update_UI: {0}-{1}-{2}".format(fb.fil[0]['rt'], fb.fil[0]['fc'], fb.fil[0]['fo'])) f_range = " (0 < <i>f</i> < <i>f<sub>S </sub></i>/2)" for i in range(num_new_labels): # Update ALL labels and corresponding values if fb.fil[0]['freq_specs_unit'] in {"f_S", "f_Ny"}: self.qlabels[i].setText(to_html(new_labels[i], frmt='bi')) else: # convert 'F' to 'f' for frequencies in Hz self.qlabels[i].setText( to_html(new_labels[i][0].lower() + new_labels[i][1:], frmt='bi')) self.qlineedit[i].setText(str(fb.fil[0][new_labels[i]])) self.qlineedit[i].setObjectName(new_labels[i]) # update ID qstyle_widget(self.qlineedit[i], state) if "sb" in new_labels[i].lower(): self.qlineedit[i].setToolTip( "<span>Corner frequency for (this) stop band" + f_range + ".</span>") elif "pb" in new_labels[i].lower(): self.qlineedit[i].setToolTip( "<span>Corner frequency for (this) pass band" + f_range + ".</span>") else: self.qlineedit[i].setToolTip( "<span>Corner frequency for (this) band" + f_range + ".</span>") self.n_cur_labels = num_new_labels # update number of currently visible labels self.sort_dict_freqs( ) # sort frequency entries in dictionary and update display
def _update_win_fft(self, arg=None, emit=True): """ Update window type for FFT with different arguments: - signal-slot connection to combo-box -> index (int), absorbed by `arg` emit is not set -> emit=True - called by _read_param() -> empty -> emit=True - called by update_N(emit=False) """ if not isinstance(emit, bool): logger.error("update win: emit={0}".format(emit)) self.window_name = qget_cmb_box(self.cmb_win_fft, data=False) self.win = calc_window_function(self.win_dict, self.window_name, N=self.N, sym=False) n_par = self.win_dict['n_par'] self.lblWinPar1.setVisible(n_par > 0) self.ledWinPar1.setVisible(n_par > 0) self.lblWinPar2.setVisible(n_par > 1) self.ledWinPar2.setVisible(n_par > 1) if n_par > 0: self.lblWinPar1.setText( to_html(self.win_dict['par'][0]['name'] + " =", frmt='bi')) self.ledWinPar1.setText(str(self.win_dict['par'][0]['val'])) self.ledWinPar1.setToolTip(self.win_dict['par'][0]['tooltip']) if n_par > 1: self.lblWinPar2.setText( to_html(self.win_dict['par'][1]['name'] + " =", frmt='bi')) self.ledWinPar2.setText(str(self.win_dict['par'][1]['val'])) self.ledWinPar2.setToolTip(self.win_dict['par'][1]['tooltip']) self.nenbw = self.N * np.sum(np.square(self.win)) / (np.square( np.sum(self.win))) self.cgain = np.sum(self.win) / self.N # coherent gain self.win /= self.cgain # correct gain for periodic signals # only emit a signal for local triggers to prevent infinite loop: # - signal-slot connection passes a bool or an integer # - local function calls don't pass anything if emit is True: self.sig_tx.emit({'sender': __name__, 'ui_changed': 'win'}) # ... but always notify the FFT widget via sig_tx_fft self.sig_tx_fft.emit({'sender': __name__, 'view_changed': 'win'})
def _show_entries(self, num_new_labels): """ - check whether enough subwidgets (QLabel und QLineEdit) exist for the the required number of `num_new_labels`: - create new ones if required - initialize them with dummy information - install eventFilter for new QLineEdit widgets so that the filter dict is updated automatically when a QLineEdit field has been edited. - if enough subwidgets exist already, make enough of them visible to show all spec fields """ num_tot_labels = len( self.qlabels) # number of existing labels (vis. + invis.) if num_tot_labels < num_new_labels: # new widgets need to be generated for i in range(num_tot_labels, num_new_labels): self.qlabels.append(QLabel(self)) self.qlabels[i].setText(to_html("dummy", frmt='bi')) self.qlineedit.append(QLineEdit("")) self.qlineedit[i].setObjectName("dummy") self.qlineedit[i].installEventFilter(self) # filter events # first entry is title self.layGSpecs.addWidget(self.qlabels[i], i + 1, 0) self.layGSpecs.addWidget(self.qlineedit[i], i + 1, 1) else: # make the right number of widgets visible for i in range(self.n_cur_labels, num_new_labels): self.qlabels[i].show() self.qlineedit[i].show()
def _construct_UI(self): # ===================================================================== # Controls # ===================================================================== self.butLoad = PushButton(self, icon=QIcon(':/file.svg'), checkable=False) # self.butLoad.setIconSize(q_icon_size) self.butLoad.setToolTip("Load data from file.") self.butLoad.setEnabled(False) self.lbl_info = QLabel(to_html(" coming soon ...", frmt="b")) # ---------------------------------------------------------------------- # Main Widget # ---------------------------------------------------------------------- layH_io_par = QHBoxLayout() layH_io_par.addWidget(self.butLoad) layH_io_par.addWidget(self.lbl_info) layV_io = QVBoxLayout() layV_io.addLayout(layH_io_par) layH_io = QHBoxLayout() layH_io.addLayout(layV_io) layH_io.addStretch(10) self.wdg_top = QWidget(self) self.wdg_top.setLayout(layH_io) self.wdg_top.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum)
def update_f_unit(self): """ Set label for frequency unit according to selected unit. """ unit = fb.fil[0]['freq_specs_unit'] if unit in {"f_S", "f_Ny"}: unit_frmt = 'bi' else: unit_frmt = 'b' self.lblUnit.setText(" in " + to_html(unit, frmt=unit_frmt))
def _update_noi(self): """ Update type + value + label for self.noi for noise""" self.noise = qget_cmb_box(self.cmbNoise) self.lblNoi.setVisible(self.noise != 'none') self.ledNoi.setVisible(self.noise != 'none') if self.noise != 'none': self.noi = safe_eval(self.ledNoi.text(), 0, return_type='cmplx') self.ledNoi.setText(str(self.noi)) if self.noise == 'gauss': self.lblNoi.setText(to_html(" σ =", frmt='bi')) self.ledNoi.setToolTip( "<span>Standard deviation of statistical process," "noise power is <i>P</i> = σ<sup>2</sup></span>") elif self.noise == 'uniform': self.lblNoi.setText(to_html(" Δ =", frmt='bi')) self.ledNoi.setToolTip( "<span>Interval size for uniformly distributed process (e.g. " "quantization step size for quantization noise), centered around 0. " "Noise power is <i>P</i> = Δ<sup>2</sup>/12.</span>") elif self.noise == 'prbs': self.lblNoi.setText(to_html(" A =", frmt='bi')) self.ledNoi.setToolTip( "<span>Amplitude of bipolar Pseudorandom Binary Sequence. " "Noise power is <i>P</i> = A<sup>2</sup>.</span>") elif self.noise == 'mls': self.lblNoi.setText(to_html(" A =", frmt='bi')) self.ledNoi.setToolTip( "<span>Amplitude of Maximum Length Sequence. " "Noise power is <i>P</i> = A<sup>2</sup>.</span>") elif self.noise == 'brownian': self.lblNoi.setText(to_html(" σ =", frmt='bi')) self.ledNoi.setToolTip( "<span>Standard deviation of the Gaussian process " "that is cumulated.</span>") self.emit({'ui_changed': 'noi'})
def update_UI(self, new_labels=()): """ Called from filter_specs.update_UI() and target_specs.update_UI(). Set labels and get corresponding values from filter dictionary. When number of entries has changed, the layout of subwidget is rebuilt, using - `self.qlabels`, a list with references to existing QLabel widgets, - `new_labels`, a list of strings from the filter_dict for the current filter design - 'num_new_labels`, their number - `self.n_cur_labels`, the number of currently visible labels / qlineedit fields """ state = new_labels[0] new_labels = new_labels[1:] # W_lbl = max([self.qfm.width(l) for l in new_labels]) # max. label width in pixel num_new_labels = len(new_labels) if num_new_labels < self.n_cur_labels: # less new labels/qlineedit fields than before self._hide_entries(num_new_labels) elif num_new_labels > self.n_cur_labels: # more new labels, create / show new ones self._show_entries(num_new_labels) tool_tipp_sb = "Min. attenuation resp. maximum level in (this) stop band" for i in range(num_new_labels): # Update ALL labels and corresponding values self.qlabels[i].setText(to_html(new_labels[i], frmt='bi')) self.qlineedit[i].setText(str(fb.fil[0][new_labels[i]])) self.qlineedit[i].setObjectName(new_labels[i]) # update ID if "sb" in new_labels[i].lower(): self.qlineedit[i].setToolTip("<span>" + tool_tipp_sb + " (> 0).</span>") elif "pb" in new_labels[i].lower(): self.qlineedit[i].setToolTip( "<span>Maximum ripple (> 0) in (this) pass band.<span/>" ) qstyle_widget(self.qlineedit[i], state) self.n_cur_labels = num_new_labels # update number of currently visible labels self.load_dict( ) # display rounded filter dict entries in selected unit
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 update_UI(self, new_labels=[]): """ Called from filter_specs.update_UI() Set labels and get corresponding values from filter dictionary. When number of entries has changed, the layout of subwidget is rebuilt, using - `self.qlabels`, a list with references to existing QLabel widgets, - `new_labels`, a list of strings from the filter_dict for the current filter design - 'num_new_labels`, their number - `self.n_cur_labels`, the number of currently visible labels / qlineedit fields """ state = new_labels[0] new_labels = new_labels[1:] num_new_labels = len(new_labels) # less new labels/qlineedit fields than before if num_new_labels < self.n_cur_labels: self._hide_entries(num_new_labels) # more new labels than before, create / show new ones elif num_new_labels > self.n_cur_labels: self._show_entries(num_new_labels) for i in range(num_new_labels): # Update ALL labels and corresponding values self.qlabels[i].setText(to_html(new_labels[i], frmt='bi')) self.qlineedit[i].setText(str(fb.fil[0][new_labels[i]])) self.qlineedit[i].setObjectName(new_labels[i]) # update ID self.qlineedit[i].setToolTip( "<span>Relative weight (importance) for approximating this band.</span>") qstyle_widget(self.qlineedit[i], state) self.n_cur_labels = num_new_labels # update number of currently visible labels self.load_dict() # display rounded filter dict entries
def _construct_UI(self): # ----------- --------------------------------------------------- # Run control widgets # --------------------------------------------------------------- # self.but_auto_run = QPushButtonRT(text=to_html("Auto", frmt="b"), margin=0) self.but_auto_run = QPushButton(" Auto", self) self.but_auto_run.setObjectName("but_auto_run") self.but_auto_run.setToolTip( "<span>Update response automatically when " "parameters have been changed.</span>") # self.but_auto_run.setMaximumWidth(qtext_width(text=" Auto ")) self.but_auto_run.setCheckable(True) self.but_auto_run.setChecked(True) but_height = self.but_auto_run.sizeHint().height() self.but_run = QPushButton(self) self.but_run.setIcon(QIcon(":/play.svg")) self.but_run.setIconSize(QSize(but_height, but_height)) self.but_run.setFixedSize(QSize(2 * but_height, but_height)) self.but_run.setToolTip("Run simulation") self.but_run.setEnabled(True) self.cmb_sim_select = QComboBox(self) self.cmb_sim_select.addItems(["Float", "Fixpoint"]) qset_cmb_box(self.cmb_sim_select, "Float") self.cmb_sim_select.setToolTip("<span>Simulate floating-point or " "fixpoint response.</span>") self.lbl_N_points = QLabel(to_html("N", frmt='bi') + " =", self) self.led_N_points = QLineEdit(self) self.led_N_points.setText(str(self.N)) self.led_N_points.setToolTip( "<span>Last data point. " "<i>N</i> = 0 tries to choose for you.</span>") self.led_N_points.setMaximumWidth(qtext_width(N_x=8)) self.lbl_N_start = QLabel(to_html("N_0", frmt='bi') + " =", self) self.led_N_start = QLineEdit(self) self.led_N_start.setText(str(self.N_start)) self.led_N_start.setToolTip("<span>First point to plot.</span>") self.led_N_start.setMaximumWidth(qtext_width(N_x=8)) self.lbl_N_frame = QLabel(to_html("ΔN", frmt='bi') + " =", self) self.led_N_frame = QLineEdit(self) self.led_N_frame.setText(str(self.N_frame)) self.led_N_frame.setToolTip( "<span>Frame length; longer frames calculate faster but calculation cannot " "be stopped so quickly. " "<i>ΔN</i> = 0 calculates all samples in one frame.</span>") self.led_N_frame.setMaximumWidth(qtext_width(N_x=8)) self.prg_wdg = QProgressBar(self) self.prg_wdg.setFixedHeight(but_height) self.prg_wdg.setFixedWidth(qtext_width(N_x=6)) self.prg_wdg.setMinimum(0) self.prg_wdg.setValue(0) self.but_toggle_stim_options = PushButton(" Stimuli ", checked=True) self.but_toggle_stim_options.setObjectName("but_stim_options") self.but_toggle_stim_options.setToolTip( "<span>Show / hide stimulus options.</span>") self.lbl_stim_cmplx_warn = QLabel(self) self.lbl_stim_cmplx_warn = QLabel(to_html("Cmplx!", frmt='b'), self) self.lbl_stim_cmplx_warn.setToolTip( '<span>Signal is complex valued; ' 'single-sided and H<sub>id</sub> spectra may be wrong.</span>') self.lbl_stim_cmplx_warn.setStyleSheet("background-color : yellow;" "border : 1px solid grey") self.but_fft_wdg = QPushButton(self) self.but_fft_wdg.setIcon(QIcon(":/fft.svg")) self.but_fft_wdg.setIconSize(QSize(but_height, but_height)) self.but_fft_wdg.setFixedSize(QSize(int(1.5 * but_height), but_height)) self.but_fft_wdg.setToolTip( '<span>Show / hide FFT widget (select window type ' ' and display its properties).</span>') self.but_fft_wdg.setCheckable(True) self.but_fft_wdg.setChecked(False) self.qfft_win_select = QFFTWinSelector(self, self.win_dict) self.but_fx_scale = PushButton(" FX:Int ") self.but_fx_scale.setObjectName("but_fx_scale") self.but_fx_scale.setToolTip( "<span>Display data with integer (fixpoint) scale.</span>") self.but_fx_range = PushButton(" FX:Range") self.but_fx_range.setObjectName("but_fx_limits") self.but_fx_range.setToolTip( "<span>Display limits of fixpoint range.</span>") layH_ctrl_run = QHBoxLayout() layH_ctrl_run.addWidget(self.but_auto_run) layH_ctrl_run.addWidget(self.but_run) layH_ctrl_run.addWidget(self.cmb_sim_select) layH_ctrl_run.addSpacing(10) layH_ctrl_run.addWidget(self.lbl_N_start) layH_ctrl_run.addWidget(self.led_N_start) layH_ctrl_run.addWidget(self.lbl_N_points) layH_ctrl_run.addWidget(self.led_N_points) layH_ctrl_run.addWidget(self.lbl_N_frame) layH_ctrl_run.addWidget(self.led_N_frame) layH_ctrl_run.addWidget(self.prg_wdg) layH_ctrl_run.addSpacing(20) layH_ctrl_run.addWidget(self.but_toggle_stim_options) layH_ctrl_run.addSpacing(5) layH_ctrl_run.addWidget(self.lbl_stim_cmplx_warn) layH_ctrl_run.addSpacing(20) layH_ctrl_run.addWidget(self.but_fft_wdg) layH_ctrl_run.addWidget(self.qfft_win_select) layH_ctrl_run.addSpacing(20) layH_ctrl_run.addWidget(self.but_fx_scale) layH_ctrl_run.addWidget(self.but_fx_range) layH_ctrl_run.addStretch(10) # layH_ctrl_run.setContentsMargins(*params['wdg_margins']) self.wdg_ctrl_run = QWidget(self) self.wdg_ctrl_run.setLayout(layH_ctrl_run) # --- end of run control ---------------------------------------- # ----------- --------------------------------------------------- # Controls for time domain # --------------------------------------------------------------- self.lbl_plt_time_stim = QLabel(to_html("Stim. x", frmt='bi'), self) self.cmb_plt_time_stim = QComboBox(self) qcmb_box_populate(self.cmb_plt_time_stim, self.plot_styles_list, self.plt_time_stim) self.cmb_plt_time_stim.setToolTip( "<span>Plot style for stimulus.</span>") self.lbl_plt_time_stmq = QLabel( to_html(" Fixp. Stim. x_Q", frmt='bi'), self) self.cmb_plt_time_stmq = QComboBox(self) qcmb_box_populate(self.cmb_plt_time_stmq, self.plot_styles_list, self.plt_time_stmq) self.cmb_plt_time_stmq.setToolTip( "<span>Plot style for <em>fixpoint</em> " "(quantized) stimulus.</span>") lbl_plt_time_resp = QLabel(to_html(" Resp. y", frmt='bi'), self) self.cmb_plt_time_resp = QComboBox(self) qcmb_box_populate(self.cmb_plt_time_resp, self.plot_styles_list, self.plt_time_resp) self.cmb_plt_time_resp.setToolTip( "<span>Plot style for response.</span>") self.lbl_win_time = QLabel(to_html(" Win", frmt='bi'), self) self.chk_win_time = QCheckBox(self) self.chk_win_time.setObjectName("chk_win_time") self.chk_win_time.setToolTip( '<span>Plot FFT windowing function.</span>') self.chk_win_time.setChecked(False) line1 = QVLine() line2 = QVLine(width=5) self.but_log_time = PushButton(" dB") self.but_log_time.setObjectName("but_log_time") self.but_log_time.setToolTip( "<span>Logarithmic scale for y-axis.</span>") lbl_plt_time_spgr = QLabel(to_html("Spectrogram", frmt='bi'), self) self.cmb_plt_time_spgr = QComboBox(self) qcmb_box_populate(self.cmb_plt_time_spgr, self.cmb_time_spgr_items, self.plt_time_spgr) spgr_en = self.plt_time_spgr != "none" self.cmb_mode_spgr_time = QComboBox(self) qcmb_box_populate(self.cmb_mode_spgr_time, self.cmb_mode_spgr_time_items, self.mode_spgr_time) self.cmb_mode_spgr_time.setVisible(spgr_en) self.lbl_byfs_spgr_time = QLabel(to_html(" per f_S", frmt='b'), self) self.lbl_byfs_spgr_time.setVisible(spgr_en) self.chk_byfs_spgr_time = QCheckBox(self) self.chk_byfs_spgr_time.setObjectName("chk_log_spgr") self.chk_byfs_spgr_time.setToolTip("<span>Display spectral density " "i.e. scale by f_S</span>") self.chk_byfs_spgr_time.setChecked(True) self.chk_byfs_spgr_time.setVisible(spgr_en) self.but_log_spgr_time = QPushButton("dB") self.but_log_spgr_time.setMaximumWidth(qtext_width(text=" dB")) self.but_log_spgr_time.setObjectName("but_log_spgr") self.but_log_spgr_time.setToolTip( "<span>Logarithmic scale for spectrogram.</span>") self.but_log_spgr_time.setCheckable(True) self.but_log_spgr_time.setChecked(True) self.but_log_spgr_time.setVisible(spgr_en) self.lbl_time_nfft_spgr = QLabel(to_html(" N_FFT =", frmt='bi'), self) self.lbl_time_nfft_spgr.setVisible(spgr_en) self.led_time_nfft_spgr = QLineEdit(self) self.led_time_nfft_spgr.setText(str(self.time_nfft_spgr)) self.led_time_nfft_spgr.setToolTip("<span>Number of FFT points per " "spectrogram segment.</span>") self.led_time_nfft_spgr.setVisible(spgr_en) self.lbl_time_ovlp_spgr = QLabel(to_html(" N_OVLP =", frmt='bi'), self) self.lbl_time_ovlp_spgr.setVisible(spgr_en) self.led_time_ovlp_spgr = QLineEdit(self) self.led_time_ovlp_spgr.setText(str(self.time_ovlp_spgr)) self.led_time_ovlp_spgr.setToolTip( "<span>Number of overlap data points " "between spectrogram segments.</span>") self.led_time_ovlp_spgr.setVisible(spgr_en) self.lbl_log_bottom_time = QLabel(to_html("min =", frmt='bi'), self) self.led_log_bottom_time = QLineEdit(self) self.led_log_bottom_time.setText(str(self.bottom_t)) self.led_log_bottom_time.setMaximumWidth(qtext_width(N_x=8)) self.led_log_bottom_time.setToolTip( "<span>Minimum display value for time and spectrogram plots with log. scale." "</span>") self.lbl_log_bottom_time.setVisible( self.but_log_time.isChecked() or (spgr_en and self.but_log_spgr_time.isChecked())) self.led_log_bottom_time.setVisible( self.lbl_log_bottom_time.isVisible()) # self.lbl_colorbar_time = QLabel(to_html(" Col.bar", frmt='b'), self) # self.lbl_colorbar_time.setVisible(spgr_en) # self.chk_colorbar_time = QCheckBox(self) # self.chk_colorbar_time.setObjectName("chk_colorbar_time") # self.chk_colorbar_time.setToolTip("<span>Enable colorbar</span>") # self.chk_colorbar_time.setChecked(True) # self.chk_colorbar_time.setVisible(spgr_en) layH_ctrl_time = QHBoxLayout() layH_ctrl_time.addWidget(self.lbl_plt_time_stim) layH_ctrl_time.addWidget(self.cmb_plt_time_stim) # layH_ctrl_time.addWidget(self.lbl_plt_time_stmq) layH_ctrl_time.addWidget(self.cmb_plt_time_stmq) # layH_ctrl_time.addWidget(lbl_plt_time_resp) layH_ctrl_time.addWidget(self.cmb_plt_time_resp) # layH_ctrl_time.addWidget(self.lbl_win_time) layH_ctrl_time.addWidget(self.chk_win_time) layH_ctrl_time.addSpacing(5) layH_ctrl_time.addWidget(line1) layH_ctrl_time.addSpacing(5) # layH_ctrl_time.addWidget(self.lbl_log_bottom_time) layH_ctrl_time.addWidget(self.led_log_bottom_time) layH_ctrl_time.addWidget(self.but_log_time) layH_ctrl_time.addSpacing(5) layH_ctrl_time.addWidget(line2) layH_ctrl_time.addSpacing(5) # layH_ctrl_time.addWidget(lbl_plt_time_spgr) layH_ctrl_time.addWidget(self.cmb_plt_time_spgr) layH_ctrl_time.addWidget(self.cmb_mode_spgr_time) layH_ctrl_time.addWidget(self.lbl_byfs_spgr_time) layH_ctrl_time.addWidget(self.chk_byfs_spgr_time) layH_ctrl_time.addWidget(self.but_log_spgr_time) layH_ctrl_time.addWidget(self.lbl_time_nfft_spgr) layH_ctrl_time.addWidget(self.led_time_nfft_spgr) layH_ctrl_time.addWidget(self.lbl_time_ovlp_spgr) layH_ctrl_time.addWidget(self.led_time_ovlp_spgr) layH_ctrl_time.addStretch(10) # layH_ctrl_time.setContentsMargins(*params['wdg_margins']) self.wdg_ctrl_time = QWidget(self) self.wdg_ctrl_time.setLayout(layH_ctrl_time) # ---- end time domain ------------------ # --------------------------------------------------------------- # Controls for frequency domain # --------------------------------------------------------------- self.lbl_plt_freq_stim = QLabel(to_html("Stimulus X", frmt='bi'), self) self.cmb_plt_freq_stim = QComboBox(self) qcmb_box_populate(self.cmb_plt_freq_stim, self.plot_styles_list, self.plt_freq_stim) self.cmb_plt_freq_stim.setToolTip( "<span>Plot style for stimulus.</span>") self.lbl_plt_freq_stmq = QLabel( to_html(" Fixp. Stim. X_Q", frmt='bi'), self) self.cmb_plt_freq_stmq = QComboBox(self) qcmb_box_populate(self.cmb_plt_freq_stmq, self.plot_styles_list, self.plt_freq_stmq) self.cmb_plt_freq_stmq.setToolTip( "<span>Plot style for <em>fixpoint</em> (quantized) stimulus.</span>" ) lbl_plt_freq_resp = QLabel(to_html(" Response Y", frmt='bi'), self) self.cmb_plt_freq_resp = QComboBox(self) qcmb_box_populate(self.cmb_plt_freq_resp, self.plot_styles_list, self.plt_freq_resp) self.cmb_plt_freq_resp.setToolTip( "<span>Plot style for response.</span>") self.but_log_freq = QPushButton("dB") self.but_log_freq.setMaximumWidth(qtext_width(" dB")) self.but_log_freq.setObjectName(".but_log_freq") self.but_log_freq.setToolTip( "<span>Logarithmic scale for y-axis.</span>") self.but_log_freq.setCheckable(True) self.but_log_freq.setChecked(True) self.lbl_log_bottom_freq = QLabel(to_html("min =", frmt='bi'), self) self.lbl_log_bottom_freq.setVisible(self.but_log_freq.isChecked()) self.led_log_bottom_freq = QLineEdit(self) self.led_log_bottom_freq.setText(str(self.bottom_f)) self.led_log_bottom_freq.setMaximumWidth(qtext_width(N_x=8)) self.led_log_bottom_freq.setToolTip( "<span>Minimum display value for log. scale.</span>") self.led_log_bottom_freq.setVisible(self.but_log_freq.isChecked()) if not self.but_log_freq.isChecked(): self.bottom_f = 0 self.cmb_freq_display = QComboBox(self) qcmb_box_populate(self.cmb_freq_display, self.cmb_freq_display_items, self.cmb_freq_display_item) self.cmb_freq_display.setObjectName("cmb_re_im_freq") self.but_Hf = QPushButtonRT(self, to_html("H_id", frmt="bi"), margin=5) self.but_Hf.setObjectName("chk_Hf") self.but_Hf.setToolTip( "<span>Show ideal frequency response, calculated " "from the filter coefficients.</span>") self.but_Hf.setChecked(False) self.but_Hf.setCheckable(True) self.but_freq_norm_impz = QPushButtonRT( text="<b><i>E<sub>X</sub></i> = 1</b>", margin=5) self.but_freq_norm_impz.setToolTip( "<span>Normalize the FFT of the stimulus with <i>N<sub>FFT</sub></i> for " "<i>E<sub>X</sub></i> = 1. For a dirac pulse, this yields " "|<i>Y(f)</i>| = |<i>H(f)</i>|. DC and Noise need to be " "turned off, window should be <b>Rectangular</b>.</span>") self.but_freq_norm_impz.setCheckable(True) self.but_freq_norm_impz.setChecked(True) self.but_freq_norm_impz.setObjectName("freq_norm_impz") self.but_freq_show_info = QPushButton("Info", self) self.but_freq_show_info.setMaximumWidth(qtext_width(" Info ")) self.but_freq_show_info.setObjectName("but_show_info_freq") self.but_freq_show_info.setToolTip( "<span>Show signal power in legend.</span>") self.but_freq_show_info.setCheckable(True) self.but_freq_show_info.setChecked(False) layH_ctrl_freq = QHBoxLayout() layH_ctrl_freq.addWidget(self.lbl_plt_freq_stim) layH_ctrl_freq.addWidget(self.cmb_plt_freq_stim) # layH_ctrl_freq.addWidget(self.lbl_plt_freq_stmq) layH_ctrl_freq.addWidget(self.cmb_plt_freq_stmq) # layH_ctrl_freq.addWidget(lbl_plt_freq_resp) layH_ctrl_freq.addWidget(self.cmb_plt_freq_resp) # layH_ctrl_freq.addSpacing(5) layH_ctrl_freq.addWidget(self.but_Hf) layH_ctrl_freq.addStretch(1) # layH_ctrl_freq.addWidget(self.lbl_log_bottom_freq) layH_ctrl_freq.addWidget(self.led_log_bottom_freq) layH_ctrl_freq.addWidget(self.but_log_freq) layH_ctrl_freq.addStretch(1) layH_ctrl_freq.addWidget(self.cmb_freq_display) layH_ctrl_freq.addStretch(1) layH_ctrl_freq.addWidget(self.but_freq_norm_impz) layH_ctrl_freq.addStretch(1) layH_ctrl_freq.addWidget(self.but_freq_show_info) layH_ctrl_freq.addStretch(10) # layH_ctrl_freq.setContentsMargins(*params['wdg_margins']) self.wdg_ctrl_freq = QWidget(self) self.wdg_ctrl_freq.setLayout(layH_ctrl_freq) # ---- end Frequency Domain ------------------ # ---------------------------------------------------------------------- # GLOBAL SIGNALS & SLOTs # ---------------------------------------------------------------------- # connect FFT widget to qfft_selector and vice versa and to and signals upstream: self.fft_widget.sig_tx.connect(self.process_sig_rx) self.qfft_win_select.sig_tx.connect(self.process_sig_rx) # connect process_sig_rx output to both FFT widgets self.sig_tx_fft.connect(self.fft_widget.sig_rx) self.sig_tx_fft.connect(self.qfft_win_select.sig_rx) # ---------------------------------------------------------------------- # LOCAL SIGNALS & SLOTs # ---------------------------------------------------------------------- # --- run control --- self.led_N_start.editingFinished.connect(self.update_N) self.led_N_points.editingFinished.connect(self.update_N) self.led_N_frame.editingFinished.connect(self.update_N) self.but_fft_wdg.clicked.connect(self.toggle_fft_wdg)
def _construct_UI(self): # ----------- --------------------------------------------------- # Run control widgets # --------------------------------------------------------------- self.chk_auto_run = QCheckBox("Auto", self) self.chk_auto_run.setObjectName("chk_auto_run") self.chk_auto_run.setToolTip("<span>Update response automatically when " "parameters have been changed.</span>") self.chk_auto_run.setChecked(True) self.but_run = QPushButton(self) self.but_run.setText("RUN") self.but_run.setToolTip("Run simulation") self.but_run.setEnabled(not self.chk_auto_run.isChecked()) self.cmb_sim_select = QComboBox(self) self.cmb_sim_select.addItems(["Float","Fixpoint"]) qset_cmb_box(self.cmb_sim_select, "Float") self.cmb_sim_select.setToolTip("<span>Simulate floating-point or fixpoint response." "</span>") self.lbl_N_points = QLabel(to_html("N", frmt='bi') + " =", self) self.led_N_points = QLineEdit(self) self.led_N_points.setText(str(self.N)) self.led_N_points.setToolTip("<span>Number of displayed data points. " "<i>N</i> = 0 tries to choose for you.</span>") self.lbl_N_start = QLabel(to_html("N_0", frmt='bi') + " =", self) self.led_N_start = QLineEdit(self) self.led_N_start.setText(str(self.N_start)) self.led_N_start.setToolTip("<span>First point to plot.</span>") self.chk_fx_scale = QCheckBox("Int. scale", self) self.chk_fx_scale.setObjectName("chk_fx_scale") self.chk_fx_scale.setToolTip("<span>Display data with integer (fixpoint) scale.</span>") self.chk_fx_scale.setChecked(False) self.chk_stim_options = QCheckBox("Stim. Options", self) self.chk_stim_options.setObjectName("chk_stim_options") self.chk_stim_options.setToolTip("<span>Show stimulus options.</span>") self.chk_stim_options.setChecked(True) self.but_fft_win = QPushButton(self) self.but_fft_win.setText("WIN FFT") self.but_fft_win.setToolTip('<span> time and frequency response of FFT Window ' '(can be modified in the "Frequency" tab)</span>') self.but_fft_win.setCheckable(True) self.but_fft_win.setChecked(False) layH_ctrl_run = QHBoxLayout() layH_ctrl_run.addWidget(self.but_run) #layH_ctrl_run.addWidget(self.lbl_sim_select) layH_ctrl_run.addWidget(self.cmb_sim_select) layH_ctrl_run.addWidget(self.chk_auto_run) layH_ctrl_run.addStretch(1) layH_ctrl_run.addWidget(self.lbl_N_start) layH_ctrl_run.addWidget(self.led_N_start) layH_ctrl_run.addStretch(1) layH_ctrl_run.addWidget(self.lbl_N_points) layH_ctrl_run.addWidget(self.led_N_points) layH_ctrl_run.addStretch(2) layH_ctrl_run.addWidget(self.chk_fx_scale) layH_ctrl_run.addStretch(2) layH_ctrl_run.addWidget(self.chk_stim_options) layH_ctrl_run.addStretch(2) layH_ctrl_run.addWidget(self.but_fft_win) layH_ctrl_run.addStretch(10) #layH_ctrl_run.setContentsMargins(*params['wdg_margins']) self.wdg_ctrl_run = QWidget(self) self.wdg_ctrl_run.setLayout(layH_ctrl_run) # --- end of run control ---------------------------------------- # ----------- --------------------------------------------------- # Controls for time domain # --------------------------------------------------------------- plot_styles_list = ["None","Dots","Line","Line*","Stem","Stem*","Step","Step*"] lbl_plt_time_title = QLabel("<b>View:</b>", self) self.lbl_plt_time_stim = QLabel(to_html("Stimulus x", frmt='bi'), self) self.cmb_plt_time_stim = QComboBox(self) self.cmb_plt_time_stim.addItems(plot_styles_list) qset_cmb_box(self.cmb_plt_time_stim, self.plt_time_stim) self.cmb_plt_time_stim.setToolTip("<span>Plot style for stimulus.</span>") self.lbl_plt_time_stmq = QLabel(to_html(" Fixp. Stim. x_Q", frmt='bi'), self) self.cmb_plt_time_stmq = QComboBox(self) self.cmb_plt_time_stmq.addItems(plot_styles_list) qset_cmb_box(self.cmb_plt_time_stmq, self.plt_time_stmq) self.cmb_plt_time_stmq.setToolTip("<span>Plot style for <em>fixpoint</em> (quantized) stimulus.</span>") lbl_plt_time_resp = QLabel(to_html(" Response y", frmt='bi'), self) self.cmb_plt_time_resp = QComboBox(self) self.cmb_plt_time_resp.addItems(plot_styles_list) qset_cmb_box(self.cmb_plt_time_resp, self.plt_time_resp) self.cmb_plt_time_resp.setToolTip("<span>Plot style for response.</span>") lbl_win_time = QLabel(to_html(" FFT Window", frmt='bi'), self) self.chk_win_time = QCheckBox(self) self.chk_win_time.setObjectName("chk_win_time") self.chk_win_time.setToolTip('<span>Show FFT windowing function (can be modified in the "Frequency" tab).</span>') self.chk_win_time.setChecked(False) lbl_log_time = QLabel(to_html("dB", frmt='b'), self) self.chk_log_time = QCheckBox(self) self.chk_log_time.setObjectName("chk_log_time") self.chk_log_time.setToolTip("<span>Logarithmic scale for y-axis.</span>") self.chk_log_time.setChecked(False) self.lbl_log_bottom_time = QLabel(to_html("min =", frmt='bi'), self) self.lbl_log_bottom_time.setVisible(True) self.led_log_bottom_time = QLineEdit(self) self.led_log_bottom_time.setText(str(self.bottom_t)) self.led_log_bottom_time.setToolTip("<span>Minimum display value for time " "and spectrogram plots with log. scale.</span>") self.led_log_bottom_time.setVisible(True) lbl_plt_time_spgr = QLabel(to_html(" Spectrogram", frmt='bi'), self) self.cmb_plt_time_spgr = QComboBox(self) self.cmb_plt_time_spgr.addItems(["None", "x[n]", "x_q[n]", "y[n]"]) qset_cmb_box(self.cmb_plt_time_spgr, self.plt_time_spgr) self.cmb_plt_time_spgr.setToolTip("<span>Show Spectrogram for selected signal.</span>") spgr_en = self.plt_time_spgr != "None" self.lbl_log_spgr_time = QLabel(to_html(" dB", frmt='b'), self) self.lbl_log_spgr_time.setVisible(spgr_en) self.chk_log_spgr_time = QCheckBox(self) self.chk_log_spgr_time.setObjectName("chk_log_spgr") self.chk_log_spgr_time.setToolTip("<span>Logarithmic scale for spectrogram.</span>") self.chk_log_spgr_time.setChecked(True) self.chk_log_spgr_time.setVisible(spgr_en) self.lbl_nfft_spgr_time = QLabel(to_html(" N_FFT =", frmt='bi'), self) self.lbl_nfft_spgr_time.setVisible(spgr_en) self.led_nfft_spgr_time = QLineEdit(self) self.led_nfft_spgr_time.setText(str(self.nfft_spgr_time)) self.led_nfft_spgr_time.setToolTip("<span>Number of FFT points per spectrogram segment.</span>") self.led_nfft_spgr_time.setVisible(spgr_en) self.lbl_ovlp_spgr_time = QLabel(to_html(" N_OVLP =", frmt='bi'), self) self.lbl_ovlp_spgr_time.setVisible(spgr_en) self.led_ovlp_spgr_time = QLineEdit(self) self.led_ovlp_spgr_time.setText(str(self.ovlp_spgr_time)) self.led_ovlp_spgr_time.setToolTip("<span>Number of overlap data points between spectrogram segments.</span>") self.led_ovlp_spgr_time.setVisible(spgr_en) self.lbl_mode_spgr_time = QLabel(to_html(" Mode", frmt='bi'), self) self.lbl_mode_spgr_time.setVisible(spgr_en) self.cmb_mode_spgr_time = QComboBox(self) spgr_modes = [("PSD","psd"), ("Mag.","magnitude"),\ ("Angle","angle"), ("Phase","phase")] for i in spgr_modes: self.cmb_mode_spgr_time.addItem(*i) qset_cmb_box(self.cmb_mode_spgr_time, self.mode_spgr_time, data=True) self.cmb_mode_spgr_time.setToolTip("<span>Spectrogram display mode.</span>") self.cmb_mode_spgr_time.setVisible(spgr_en) self.lbl_byfs_spgr_time = QLabel(to_html(" per f_S", frmt='b'), self) self.lbl_byfs_spgr_time.setVisible(spgr_en) self.chk_byfs_spgr_time = QCheckBox(self) self.chk_byfs_spgr_time.setObjectName("chk_log_spgr") self.chk_byfs_spgr_time.setToolTip("<span>Display spectral density i.e. scale by f_S</span>") self.chk_byfs_spgr_time.setChecked(True) self.chk_byfs_spgr_time.setVisible(spgr_en) # self.lbl_colorbar_time = QLabel(to_html(" Col.bar", frmt='b'), self) # self.lbl_colorbar_time.setVisible(spgr_en) # self.chk_colorbar_time = QCheckBox(self) # self.chk_colorbar_time.setObjectName("chk_colorbar_time") # self.chk_colorbar_time.setToolTip("<span>Enable colorbar</span>") # self.chk_colorbar_time.setChecked(True) # self.chk_colorbar_time.setVisible(spgr_en) self.chk_fx_limits = QCheckBox("Min/max.", self) self.chk_fx_limits.setObjectName("chk_fx_limits") self.chk_fx_limits.setToolTip("<span>Display limits of fixpoint range.</span>") self.chk_fx_limits.setChecked(False) layH_ctrl_time = QHBoxLayout() layH_ctrl_time.addWidget(lbl_plt_time_title) layH_ctrl_time.addStretch(1) layH_ctrl_time.addWidget(self.lbl_plt_time_stim) layH_ctrl_time.addWidget(self.cmb_plt_time_stim) # layH_ctrl_time.addWidget(self.lbl_plt_time_stmq) layH_ctrl_time.addWidget(self.cmb_plt_time_stmq) # layH_ctrl_time.addWidget(lbl_plt_time_resp) layH_ctrl_time.addWidget(self.cmb_plt_time_resp) # layH_ctrl_time.addWidget(lbl_win_time) layH_ctrl_time.addWidget(self.chk_win_time) layH_ctrl_time.addStretch(1) layH_ctrl_time.addWidget(lbl_log_time) layH_ctrl_time.addWidget(self.chk_log_time) layH_ctrl_time.addWidget(self.lbl_log_bottom_time) layH_ctrl_time.addWidget(self.led_log_bottom_time) # layH_ctrl_time.addStretch(1) # layH_ctrl_time.addWidget(lbl_plt_time_spgr) layH_ctrl_time.addWidget(self.cmb_plt_time_spgr) layH_ctrl_time.addWidget(self.lbl_log_spgr_time) layH_ctrl_time.addWidget(self.chk_log_spgr_time) layH_ctrl_time.addWidget(self.lbl_nfft_spgr_time) layH_ctrl_time.addWidget(self.led_nfft_spgr_time) layH_ctrl_time.addWidget(self.lbl_ovlp_spgr_time) layH_ctrl_time.addWidget(self.led_ovlp_spgr_time) layH_ctrl_time.addWidget(self.lbl_mode_spgr_time) layH_ctrl_time.addWidget(self.cmb_mode_spgr_time) layH_ctrl_time.addWidget(self.lbl_byfs_spgr_time) layH_ctrl_time.addWidget(self.chk_byfs_spgr_time) layH_ctrl_time.addStretch(2) layH_ctrl_time.addWidget(self.chk_fx_limits) layH_ctrl_time.addStretch(10) #layH_ctrl_time.setContentsMargins(*params['wdg_margins']) self.wdg_ctrl_time = QWidget(self) self.wdg_ctrl_time.setLayout(layH_ctrl_time) # ---- end time domain ------------------ # --------------------------------------------------------------- # Controls for frequency domain # --------------------------------------------------------------- lbl_plt_freq_title = QLabel("<b>View:</b>", self) self.lbl_plt_freq_stim = QLabel(to_html("Stimulus X", frmt='bi'), self) self.cmb_plt_freq_stim = QComboBox(self) self.cmb_plt_freq_stim.addItems(plot_styles_list) qset_cmb_box(self.cmb_plt_freq_stim, self.plt_freq_stim) self.cmb_plt_freq_stim.setToolTip("<span>Plot style for stimulus.</span>") self.lbl_plt_freq_stmq = QLabel(to_html(" Fixp. Stim. X_Q", frmt='bi'), self) self.cmb_plt_freq_stmq = QComboBox(self) self.cmb_plt_freq_stmq.addItems(plot_styles_list) qset_cmb_box(self.cmb_plt_freq_stmq, self.plt_freq_stmq) self.cmb_plt_freq_stmq.setToolTip("<span>Plot style for <em>fixpoint</em> (quantized) stimulus.</span>") lbl_plt_freq_resp = QLabel(to_html(" Response Y", frmt='bi'), self) self.cmb_plt_freq_resp = QComboBox(self) self.cmb_plt_freq_resp.addItems(plot_styles_list) qset_cmb_box(self.cmb_plt_freq_resp, self.plt_freq_resp) self.cmb_plt_freq_resp.setToolTip("<span>Plot style for response.</span>") lbl_log_freq = QLabel(to_html("dB", frmt='b'), self) self.chk_log_freq = QCheckBox(self) self.chk_log_freq.setObjectName("chk_log_freq") self.chk_log_freq.setToolTip("<span>Logarithmic scale for y-axis.</span>") self.chk_log_freq.setChecked(True) self.lbl_log_bottom_freq = QLabel(to_html("min =", frmt='bi'), self) self.lbl_log_bottom_freq.setVisible(self.chk_log_freq.isChecked()) self.led_log_bottom_freq = QLineEdit(self) self.led_log_bottom_freq.setText(str(self.bottom_f)) self.led_log_bottom_freq.setToolTip("<span>Minimum display value for log. scale.</span>") self.led_log_bottom_freq.setVisible(self.chk_log_freq.isChecked()) if not self.chk_log_freq.isChecked(): self.bottom_f = 0 lbl_re_im_freq = QLabel(to_html("Re / Im", frmt='b'), self) self.chk_re_im_freq = QCheckBox(self) self.chk_re_im_freq.setObjectName("chk_re_im_freq") self.chk_re_im_freq.setToolTip("<span>Show real and imaginary part of spectrum</span>") self.chk_re_im_freq.setChecked(False) self.lbl_win_fft = QLabel(to_html("Window", frmt='bi'), self) self.cmb_win_fft = QComboBox(self) self.cmb_win_fft.addItems(get_window_names()) self.cmb_win_fft.setToolTip("FFT window type.") qset_cmb_box(self.cmb_win_fft, self.window_name) self.cmb_win_fft_variant = QComboBox(self) self.cmb_win_fft_variant.setToolTip("FFT window variant.") self.cmb_win_fft_variant.setVisible(False) self.lblWinPar1 = QLabel("Param1") self.ledWinPar1 = QLineEdit(self) self.ledWinPar1.setText("1") self.ledWinPar1.setObjectName("ledWinPar1") self.lblWinPar2 = QLabel("Param2") self.ledWinPar2 = QLineEdit(self) self.ledWinPar2.setText("2") self.ledWinPar2.setObjectName("ledWinPar2") self.chk_Hf = QCheckBox(self) self.chk_Hf.setObjectName("chk_Hf") self.chk_Hf.setToolTip("<span>Show ideal frequency response, calculated " "from the filter coefficients.</span>") self.chk_Hf.setChecked(False) self.chk_Hf_lbl = QLabel(to_html("H_id (f)", frmt="bi"), self) lbl_show_info_freq = QLabel(to_html("Info", frmt='b'), self) self.chk_show_info_freq = QCheckBox(self) self.chk_show_info_freq.setObjectName("chk_show_info_freq") self.chk_show_info_freq.setToolTip("<span>Show infos about signal power " "and window properties.</span>") self.chk_show_info_freq.setChecked(False) layH_ctrl_freq = QHBoxLayout() layH_ctrl_freq.addWidget(lbl_plt_freq_title) layH_ctrl_freq.addStretch(1) layH_ctrl_freq.addWidget(self.lbl_plt_freq_stim) layH_ctrl_freq.addWidget(self.cmb_plt_freq_stim) # layH_ctrl_freq.addWidget(self.lbl_plt_freq_stmq) layH_ctrl_freq.addWidget(self.cmb_plt_freq_stmq) # layH_ctrl_freq.addWidget(lbl_plt_freq_resp) layH_ctrl_freq.addWidget(self.cmb_plt_freq_resp) # layH_ctrl_freq.addWidget(self.chk_Hf_lbl) layH_ctrl_freq.addWidget(self.chk_Hf) layH_ctrl_freq.addStretch(1) layH_ctrl_freq.addWidget(lbl_log_freq) layH_ctrl_freq.addWidget(self.chk_log_freq) layH_ctrl_freq.addWidget(self.lbl_log_bottom_freq) layH_ctrl_freq.addWidget(self.led_log_bottom_freq) layH_ctrl_freq.addStretch(1) layH_ctrl_freq.addWidget(lbl_re_im_freq) layH_ctrl_freq.addWidget(self.chk_re_im_freq) layH_ctrl_freq.addStretch(2) layH_ctrl_freq.addWidget(self.lbl_win_fft) layH_ctrl_freq.addWidget(self.cmb_win_fft) layH_ctrl_freq.addWidget(self.cmb_win_fft_variant) layH_ctrl_freq.addWidget(self.lblWinPar1) layH_ctrl_freq.addWidget(self.ledWinPar1) layH_ctrl_freq.addWidget(self.lblWinPar2) layH_ctrl_freq.addWidget(self.ledWinPar2) layH_ctrl_freq.addStretch(1) layH_ctrl_freq.addWidget(lbl_show_info_freq) layH_ctrl_freq.addWidget(self.chk_show_info_freq) layH_ctrl_freq.addStretch(10) #layH_ctrl_freq.setContentsMargins(*params['wdg_margins']) self.wdg_ctrl_freq = QWidget(self) self.wdg_ctrl_freq.setLayout(layH_ctrl_freq) # ---- end Frequency Domain ------------------ # --------------------------------------------------------------- # Controls for stimuli # --------------------------------------------------------------- lbl_title_stim = QLabel("<b>Stimulus:</b>", self) self.lblStimulus = QLabel(to_html("Type", frmt='bi'), self) self.cmbStimulus = QComboBox(self) self.cmbStimulus.addItems(["None","Impulse","Step","StepErr","Cos","Sine", "Chirp", "Triang","Saw","Rect","Comb","AM","PM / FM","Formula"]) self.cmbStimulus.setToolTip("Stimulus type.") qset_cmb_box(self.cmbStimulus, self.stim) self.chk_stim_bl = QCheckBox("BL", self) self.chk_stim_bl.setToolTip("<span>The signal is bandlimited to the Nyquist frequency " "to avoid aliasing. However, it is much slower to generate " "than the regular version.</span>") self.chk_stim_bl.setChecked(True) self.chk_stim_bl.setObjectName("stim_bl") self.cmbChirpMethod = QComboBox(self) for t in [("Lin","Linear"),("Square","Quadratic"),("Log", "Logarithmic"), ("Hyper", "Hyperbolic")]: self.cmbChirpMethod.addItem(*t) qset_cmb_box(self.cmbChirpMethod, self.chirp_method, data=False) self.chk_scale_impz_f = QCheckBox("Scale", self) self.chk_scale_impz_f.setToolTip("<span>Scale the FFT of the impulse response with <i>N<sub>FFT</sub></i> " "so that it has the same magnitude as |H(f)|. DC and Noise need to be " "turned off.</span>") self.chk_scale_impz_f.setChecked(True) self.chk_scale_impz_f.setObjectName("scale_impz_f") self.lblDC = QLabel(to_html("DC =", frmt='bi'), self) self.ledDC = QLineEdit(self) self.ledDC.setText(str(self.DC)) self.ledDC.setToolTip("DC Level") self.ledDC.setObjectName("stimDC") layHCmbStim = QHBoxLayout() layHCmbStim.addWidget(self.cmbStimulus) layHCmbStim.addWidget(self.chk_stim_bl) layHCmbStim.addWidget(self.chk_scale_impz_f) layHCmbStim.addWidget(self.cmbChirpMethod) #---------------------------------------------- self.lblAmp1 = QLabel(to_html(" A_1", frmt='bi') + " =", self) self.ledAmp1 = QLineEdit(self) self.ledAmp1.setText(str(self.A1)) self.ledAmp1.setToolTip("Stimulus amplitude, complex values like 3j - 1 are allowed") self.ledAmp1.setObjectName("stimAmp1") self.lblAmp2 = QLabel(to_html(" A_2", frmt='bi') + " =", self) self.ledAmp2 = QLineEdit(self) self.ledAmp2.setText(str(self.A2)) self.ledAmp2.setToolTip("Stimulus amplitude 2, complex values like 3j - 1 are allowed") self.ledAmp2.setObjectName("stimAmp2") #---------------------------------------------- self.lblPhi1 = QLabel(to_html(" φ_1", frmt='bi') + " =", self) self.ledPhi1 = QLineEdit(self) self.ledPhi1.setText(str(self.phi1)) self.ledPhi1.setToolTip("Stimulus phase") self.ledPhi1.setObjectName("stimPhi1") self.lblPhU1 = QLabel(to_html("°", frmt='b'), self) self.lblPhi2 = QLabel(to_html(" φ_2", frmt='bi') + " =", self) self.ledPhi2 = QLineEdit(self) self.ledPhi2.setText(str(self.phi2)) self.ledPhi2.setToolTip("Stimulus phase 2") self.ledPhi2.setObjectName("stimPhi2") self.lblPhU2 = QLabel(to_html("°", frmt='b'), self) #---------------------------------------------- self.lblFreq1 = QLabel(to_html(" f_1", frmt='bi') + " =", self) self.ledFreq1 = QLineEdit(self) self.ledFreq1.setText(str(self.f1)) self.ledFreq1.setToolTip("Stimulus frequency 1") self.ledFreq1.setObjectName("stimFreq1") self.lblFreqUnit1 = QLabel("f_S", self) self.lblFreq2 = QLabel(to_html(" f_2", frmt='bi') + " =", self) self.ledFreq2 = QLineEdit(self) self.ledFreq2.setText(str(self.f2)) self.ledFreq2.setToolTip("Stimulus frequency 2") self.ledFreq2.setObjectName("stimFreq2") self.lblFreqUnit2 = QLabel("f_S", self) #---------------------------------------------- self.lblNoise = QLabel(to_html(" Noise", frmt='bi'), self) self.cmbNoise = QComboBox(self) self.cmbNoise.addItems(["None","Gauss","Uniform","PRBS"]) self.cmbNoise.setToolTip("Type of additive noise.") qset_cmb_box(self.cmbNoise, self.noise) self.lblNoi = QLabel("not initialized", self) self.ledNoi = QLineEdit(self) self.ledNoi.setText(str(self.noi)) self.ledNoi.setToolTip("not initialized") self.ledNoi.setObjectName("stimNoi") layGStim = QGridLayout() layGStim.addWidget(self.lblStimulus, 0, 0) layGStim.addWidget(self.lblDC, 1, 0) layGStim.addLayout(layHCmbStim, 0, 1) layGStim.addWidget(self.ledDC, 1, 1) layGStim.addWidget(self.lblAmp1, 0, 2) layGStim.addWidget(self.lblAmp2, 1, 2) layGStim.addWidget(self.ledAmp1, 0, 3) layGStim.addWidget(self.ledAmp2, 1, 3) layGStim.addWidget(self.lblPhi1, 0, 4) layGStim.addWidget(self.lblPhi2, 1, 4) layGStim.addWidget(self.ledPhi1, 0, 5) layGStim.addWidget(self.ledPhi2, 1, 5) layGStim.addWidget(self.lblPhU1, 0, 6) layGStim.addWidget(self.lblPhU2, 1, 6) layGStim.addWidget(self.lblFreq1, 0, 7) layGStim.addWidget(self.lblFreq2, 1, 7) layGStim.addWidget(self.ledFreq1, 0, 8) layGStim.addWidget(self.ledFreq2, 1, 8) layGStim.addWidget(self.lblFreqUnit1, 0, 9) layGStim.addWidget(self.lblFreqUnit2, 1, 9) layGStim.addWidget(self.lblNoise, 0, 10) layGStim.addWidget(self.lblNoi, 1, 10) layGStim.addWidget(self.cmbNoise, 0, 11) layGStim.addWidget(self.ledNoi, 1, 11) #---------------------------------------------- self.lblStimFormula = QLabel(to_html("x =", frmt='bi'), self) self.ledStimFormula = QLineEdit(self) self.ledStimFormula.setText(str(self.stim_formula)) self.ledStimFormula.setToolTip("<span>Enter formula for stimulus in numexpr syntax" "</span>") self.ledStimFormula.setObjectName("stimFormula") layH_ctrl_stim_formula = QHBoxLayout() layH_ctrl_stim_formula.addWidget(self.lblStimFormula) layH_ctrl_stim_formula.addWidget(self.ledStimFormula,10) #---------------------------------------------- #layG_ctrl_stim = QGridLayout() layH_ctrl_stim_par = QHBoxLayout() layH_ctrl_stim_par.addLayout(layGStim) layV_ctrl_stim = QVBoxLayout() layV_ctrl_stim.addLayout(layH_ctrl_stim_par) layV_ctrl_stim.addLayout(layH_ctrl_stim_formula) layH_ctrl_stim = QHBoxLayout() layH_ctrl_stim.addWidget(lbl_title_stim) layH_ctrl_stim.addStretch(1) layH_ctrl_stim.addLayout(layV_ctrl_stim) layH_ctrl_stim.addStretch(10) self.wdg_ctrl_stim = QWidget(self) self.wdg_ctrl_stim.setLayout(layH_ctrl_stim) # --------- end stimuli --------------------------------- # frequency widgets require special handling as they are scaled with f_s self.ledFreq1.installEventFilter(self) self.ledFreq2.installEventFilter(self) #---------------------------------------------------------------------- # LOCAL SIGNALS & SLOTs #---------------------------------------------------------------------- # --- run control --- self.led_N_start.editingFinished.connect(self.update_N) self.led_N_points.editingFinished.connect(self.update_N) # --- frequency control --- # careful! currentIndexChanged passes the current index to _update_win_fft self.cmb_win_fft.currentIndexChanged.connect(self._update_win_fft) self.ledWinPar1.editingFinished.connect(self._read_param1) self.ledWinPar2.editingFinished.connect(self._read_param2) # --- stimulus control --- self.chk_stim_options.clicked.connect(self._show_stim_options) self.chk_stim_bl.clicked.connect(self._enable_stim_widgets) self.cmbStimulus.currentIndexChanged.connect(self._enable_stim_widgets) self.cmbNoise.currentIndexChanged.connect(self._update_noi) self.ledNoi.editingFinished.connect(self._update_noi) self.ledAmp1.editingFinished.connect(self._update_amp1) self.ledAmp2.editingFinished.connect(self._update_amp2) self.ledPhi1.editingFinished.connect(self._update_phi1) self.ledPhi2.editingFinished.connect(self._update_phi2) self.cmbChirpMethod.currentIndexChanged.connect(self._update_chirp_method) self.ledDC.editingFinished.connect(self._update_DC) self.ledStimFormula.editingFinished.connect(self._update_stim_formula)
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)
def write(self, msg): if not self.signalsBlocked(): msg = to_html(msg, frmt='log') self.messageWritten.emit(msg)
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): # ----------- --------------------------------------------------- # Run control widgets # --------------------------------------------------------------- self.chk_auto_run = QCheckBox("Auto", self) self.chk_auto_run.setObjectName("chk_auto_run") self.chk_auto_run.setToolTip( "<span>Update response automatically when " "parameters have been changed.</span>") self.chk_auto_run.setChecked(True) self.but_run = QPushButton(self) self.but_run.setText("RUN") self.but_run.setToolTip("Run simulation") self.but_run.setEnabled(not self.chk_auto_run.isChecked()) self.cmb_sim_select = QComboBox(self) self.cmb_sim_select.addItems(["Float", "Fixpoint"]) qset_cmb_box(self.cmb_sim_select, "Float") self.cmb_sim_select.setToolTip( "<span>Simulate floating-point or fixpoint response." "</span>") self.lbl_N_points = QLabel(to_html("N", frmt='bi') + " =", self) self.led_N_points = QLineEdit(self) self.led_N_points.setText(str(self.N)) self.led_N_points.setToolTip( "<span>Number of displayed data points. " "<i>N</i> = 0 tries to choose for you.</span>") self.lbl_N_start = QLabel(to_html("N_0", frmt='bi') + " =", self) self.led_N_start = QLineEdit(self) self.led_N_start.setText(str(self.N_start)) self.led_N_start.setToolTip("<span>First point to plot.</span>") self.chk_fx_scale = QCheckBox("Int. scale", self) self.chk_fx_scale.setObjectName("chk_fx_scale") self.chk_fx_scale.setToolTip( "<span>Display data with integer (fixpoint) scale.</span>") self.chk_fx_scale.setChecked(False) self.chk_stim_options = QCheckBox("Stim. Options", self) self.chk_stim_options.setObjectName("chk_stim_options") self.chk_stim_options.setToolTip("<span>Show stimulus options.</span>") self.chk_stim_options.setChecked(True) self.but_fft_win = QPushButton(self) self.but_fft_win.setText("WIN FFT") self.but_fft_win.setToolTip( "Show time and frequency response of FFT Window") self.but_fft_win.setCheckable(True) self.but_fft_win.setChecked(False) layH_ctrl_run = QHBoxLayout() layH_ctrl_run.addWidget(self.but_run) #layH_ctrl_run.addWidget(self.lbl_sim_select) layH_ctrl_run.addWidget(self.cmb_sim_select) layH_ctrl_run.addWidget(self.chk_auto_run) layH_ctrl_run.addStretch(1) layH_ctrl_run.addWidget(self.lbl_N_start) layH_ctrl_run.addWidget(self.led_N_start) layH_ctrl_run.addStretch(1) layH_ctrl_run.addWidget(self.lbl_N_points) layH_ctrl_run.addWidget(self.led_N_points) layH_ctrl_run.addStretch(2) layH_ctrl_run.addWidget(self.chk_fx_scale) layH_ctrl_run.addStretch(2) layH_ctrl_run.addWidget(self.chk_stim_options) layH_ctrl_run.addStretch(2) layH_ctrl_run.addWidget(self.but_fft_win) layH_ctrl_run.addStretch(10) #layH_ctrl_run.setContentsMargins(*params['wdg_margins']) self.wdg_ctrl_run = QWidget(self) self.wdg_ctrl_run.setLayout(layH_ctrl_run) # --- end of run control ---------------------------------------- # ----------- --------------------------------------------------- # Controls for time domain # --------------------------------------------------------------- plot_styles_list = [ "None", "Dots", "Line", "Line*", "Stem", "Stem*", "Step", "Step*" ] lbl_plt_time_title = QLabel("<b>View:</b>", self) lbl_plt_time_resp = QLabel("Response " + to_html("y", frmt='bi'), self) self.cmb_plt_time_resp = QComboBox(self) self.cmb_plt_time_resp.addItems(plot_styles_list) qset_cmb_box(self.cmb_plt_time_resp, self.plt_time_resp) self.cmb_plt_time_resp.setToolTip( "<span>Plot style for response.</span>") self.lbl_plt_time_stim = QLabel("Stimulus " + to_html("x", frmt='bi'), self) self.cmb_plt_time_stim = QComboBox(self) self.cmb_plt_time_stim.addItems(plot_styles_list) qset_cmb_box(self.cmb_plt_time_stim, self.plt_time_stim) self.cmb_plt_time_stim.setToolTip( "<span>Plot style for stimulus.</span>") self.lbl_plt_time_stmq = QLabel( "Fixp. Stim. " + to_html("x_Q", frmt='bi'), self) self.cmb_plt_time_stmq = QComboBox(self) self.cmb_plt_time_stmq.addItems(plot_styles_list) qset_cmb_box(self.cmb_plt_time_stmq, self.plt_time_stmq) self.cmb_plt_time_stmq.setToolTip( "<span>Plot style for <em>fixpoint</em> (quantized) stimulus.</span>" ) self.chk_log_time = QCheckBox("dB : min.", self) self.chk_log_time.setObjectName("chk_log_time") self.chk_log_time.setToolTip( "<span>Logarithmic scale for y-axis.</span>") self.chk_log_time.setChecked(False) self.led_log_bottom_time = QLineEdit(self) self.led_log_bottom_time.setText(str(self.bottom_t)) self.led_log_bottom_time.setToolTip( "<span>Minimum display value for log. scale.</span>") self.led_log_bottom_time.setVisible(self.chk_log_time.isChecked()) if not self.chk_log_time.isChecked(): self.chk_log_time.setText("dB") self.bottom_t = 0 self.chk_win_time = QCheckBox("FFT Window", self) self.chk_win_time.setObjectName("chk_win_time") self.chk_win_time.setToolTip( "<span>Show FFT windowing function.</span>") self.chk_win_time.setChecked(False) self.chk_fx_limits = QCheckBox("Min/max.", self) self.chk_fx_limits.setObjectName("chk_fx_limits") self.chk_fx_limits.setToolTip( "<span>Display limits of fixpoint range.</span>") self.chk_fx_limits.setChecked(False) layH_ctrl_time = QHBoxLayout() layH_ctrl_time.addWidget(lbl_plt_time_title) layH_ctrl_time.addStretch(1) layH_ctrl_time.addWidget(lbl_plt_time_resp) layH_ctrl_time.addWidget(self.cmb_plt_time_resp) layH_ctrl_time.addStretch(1) layH_ctrl_time.addWidget(self.lbl_plt_time_stim) layH_ctrl_time.addWidget(self.cmb_plt_time_stim) layH_ctrl_time.addStretch(1) layH_ctrl_time.addWidget(self.lbl_plt_time_stmq) layH_ctrl_time.addWidget(self.cmb_plt_time_stmq) layH_ctrl_time.addStretch(2) layH_ctrl_time.addWidget(self.chk_log_time) layH_ctrl_time.addWidget(self.led_log_bottom_time) layH_ctrl_time.addStretch(1) layH_ctrl_time.addWidget(self.chk_win_time) layH_ctrl_time.addStretch(2) layH_ctrl_time.addWidget(self.chk_fx_limits) layH_ctrl_time.addStretch(10) #layH_ctrl_time.setContentsMargins(*params['wdg_margins']) self.wdg_ctrl_time = QWidget(self) self.wdg_ctrl_time.setLayout(layH_ctrl_time) # ---- end time domain ------------------ # --------------------------------------------------------------- # Controls for frequency domain # --------------------------------------------------------------- lbl_plt_freq_title = QLabel("<b>View:</b>", self) lbl_plt_freq_resp = QLabel("Response " + to_html("Y", frmt='bi'), self) self.cmb_plt_freq_resp = QComboBox(self) self.cmb_plt_freq_resp.addItems(plot_styles_list) qset_cmb_box(self.cmb_plt_freq_resp, self.plt_freq_resp) self.cmb_plt_freq_resp.setToolTip( "<span>Plot style for response.</span>") self.lbl_plt_freq_stim = QLabel("Stimulus " + to_html("X", frmt='bi'), self) self.cmb_plt_freq_stim = QComboBox(self) self.cmb_plt_freq_stim.addItems(plot_styles_list) qset_cmb_box(self.cmb_plt_freq_stim, self.plt_freq_stim) self.cmb_plt_freq_stim.setToolTip( "<span>Plot style for stimulus.</span>") self.lbl_plt_freq_stmq = QLabel( "Fixp. Stim. " + to_html("X_Q", frmt='bi'), self) self.cmb_plt_freq_stmq = QComboBox(self) self.cmb_plt_freq_stmq.addItems(plot_styles_list) qset_cmb_box(self.cmb_plt_freq_stmq, self.plt_freq_stmq) self.cmb_plt_freq_stmq.setToolTip( "<span>Plot style for <em>fixpoint</em> (quantized) stimulus.</span>" ) self.chk_log_freq = QCheckBox("dB : min.", self) self.chk_log_freq.setObjectName("chk_log_freq") self.chk_log_freq.setToolTip( "<span>Logarithmic scale for y-axis.</span>") self.chk_log_freq.setChecked(True) self.led_log_bottom_freq = QLineEdit(self) self.led_log_bottom_freq.setText(str(self.bottom_f)) self.led_log_bottom_freq.setToolTip( "<span>Minimum display value for log. scale.</span>") self.led_log_bottom_freq.setVisible(self.chk_log_freq.isChecked()) if not self.chk_log_freq.isChecked(): self.chk_log_freq.setText("dB") self.bottom_f = 0 self.lbl_win_fft = QLabel("Window: ", self) self.cmb_win_fft = QComboBox(self) self.cmb_win_fft.addItems(get_window_names()) self.cmb_win_fft.setToolTip("FFT window type.") qset_cmb_box(self.cmb_win_fft, self.window_name) self.cmb_win_fft_variant = QComboBox(self) self.cmb_win_fft_variant.setToolTip("FFT window variant.") self.cmb_win_fft_variant.setVisible(False) self.lblWinPar1 = QLabel("Param1") self.ledWinPar1 = QLineEdit(self) self.ledWinPar1.setText("1") self.ledWinPar1.setObjectName("ledWinPar1") self.lblWinPar2 = QLabel("Param2") self.ledWinPar2 = QLineEdit(self) self.ledWinPar2.setText("2") self.ledWinPar2.setObjectName("ledWinPar2") self.chk_Hf = QCheckBox(self) self.chk_Hf.setObjectName("chk_Hf") self.chk_Hf.setToolTip( "<span>Show ideal frequency response, calculated " "from the filter coefficients.</span>") self.chk_Hf.setChecked(False) self.chk_Hf_lbl = QLabel(to_html("H_id (f)", frmt="bi"), self) layH_ctrl_freq = QHBoxLayout() layH_ctrl_freq.addWidget(lbl_plt_freq_title) layH_ctrl_freq.addStretch(1) layH_ctrl_freq.addWidget(lbl_plt_freq_resp) layH_ctrl_freq.addWidget(self.cmb_plt_freq_resp) layH_ctrl_freq.addStretch(1) layH_ctrl_freq.addWidget(self.lbl_plt_freq_stim) layH_ctrl_freq.addWidget(self.cmb_plt_freq_stim) layH_ctrl_freq.addStretch(1) layH_ctrl_freq.addWidget(self.lbl_plt_freq_stmq) layH_ctrl_freq.addWidget(self.cmb_plt_freq_stmq) layH_ctrl_freq.addStretch(2) layH_ctrl_freq.addWidget(self.chk_log_freq) layH_ctrl_freq.addWidget(self.led_log_bottom_freq) layH_ctrl_freq.addStretch(2) layH_ctrl_freq.addWidget(self.lbl_win_fft) layH_ctrl_freq.addWidget(self.cmb_win_fft) layH_ctrl_freq.addWidget(self.cmb_win_fft_variant) layH_ctrl_freq.addWidget(self.lblWinPar1) layH_ctrl_freq.addWidget(self.ledWinPar1) layH_ctrl_freq.addWidget(self.lblWinPar2) layH_ctrl_freq.addWidget(self.ledWinPar2) layH_ctrl_freq.addStretch(2) layH_ctrl_freq.addWidget(self.chk_Hf) layH_ctrl_freq.addWidget(self.chk_Hf_lbl) layH_ctrl_freq.addStretch(10) #layH_ctrl_freq.setContentsMargins(*params['wdg_margins']) self.wdg_ctrl_freq = QWidget(self) self.wdg_ctrl_freq.setLayout(layH_ctrl_freq) # ---- end Frequency Domain ------------------ # --------------------------------------------------------------- # Controls for stimuli # --------------------------------------------------------------- lbl_title_stim = QLabel("<b>Stimulus:</b>", self) self.lblStimulus = QLabel(to_html("Shape ", frmt='bi'), self) self.cmbStimulus = QComboBox(self) self.cmbStimulus.addItems([ "None", "Pulse", "Step", "StepErr", "Cos", "Sine", "Triang", "Saw", "Rect", "Comb", "AM", "FM", "PM" ]) self.cmbStimulus.setToolTip("Stimulus type.") qset_cmb_box(self.cmbStimulus, self.stim) self.chk_stim_bl = QCheckBox("BL", self) self.chk_stim_bl.setToolTip( "<span>The signal is bandlimited to the Nyquist frequency " "to avoid aliasing. However, it is much slower to generate " "than the regular version.</span>") self.chk_stim_bl.setChecked(True) self.chk_stim_bl.setObjectName("stim_bl") self.chk_scale_impz_f = QCheckBox("Scale", self) self.chk_scale_impz_f.setToolTip( "<span>Scale the FFT of the impulse response with <i>N<sub>FFT</sub></i> " "so that it has the same magnitude as |H(f)|. DC and Noise need to be " "turned off.</span>") self.chk_scale_impz_f.setChecked(True) self.chk_scale_impz_f.setObjectName("scale_impz_f") self.lblDC = QLabel(to_html("DC =", frmt='bi'), self) self.ledDC = QLineEdit(self) self.ledDC.setText(str(self.DC)) self.ledDC.setToolTip("DC Level") self.ledDC.setObjectName("stimDC") layHCmbStim = QHBoxLayout() layHCmbStim.addWidget(self.cmbStimulus) layHCmbStim.addWidget(self.chk_stim_bl) layHCmbStim.addWidget(self.chk_scale_impz_f) layVlblCmbDC = QVBoxLayout() layVlblCmbDC.addWidget(self.lblStimulus) layVlblCmbDC.addWidget(self.lblDC) #layVlblAmp.setAlignment(Qt.AlignTop) layVCmbDC = QVBoxLayout() layVCmbDC.addLayout(layHCmbStim) layVCmbDC.addWidget(self.ledDC) #---------------------------------------------- self.lblAmp1 = QLabel(to_html("A_1", frmt='bi') + " =", self) self.ledAmp1 = QLineEdit(self) self.ledAmp1.setText(str(self.A1)) self.ledAmp1.setToolTip("Stimulus amplitude") self.ledAmp1.setObjectName("stimAmp1") self.lblAmp2 = QLabel(to_html("A_2", frmt='bi') + " =", self) self.ledAmp2 = QLineEdit(self) self.ledAmp2.setText(str(self.A2)) self.ledAmp2.setToolTip("Stimulus amplitude 2") self.ledAmp2.setObjectName("stimAmp2") layVlblAmp = QVBoxLayout() layVlblAmp.addWidget(self.lblAmp1) layVlblAmp.addWidget(self.lblAmp2) #layVlblAmp.setAlignment(Qt.AlignTop) # labels are aligned incorrectly layVledAmp = QVBoxLayout() layVledAmp.addWidget(self.ledAmp1) layVledAmp.addWidget(self.ledAmp2) #layVledAmp.setAlignment(Qt.AlignTop) #---------------------------------------------- self.lblPhi1 = QLabel(to_html("φ_1", frmt='bi') + " =", self) self.ledPhi1 = QLineEdit(self) self.ledPhi1.setText(str(self.phi1)) self.ledPhi1.setToolTip("Stimulus phase") self.ledPhi1.setObjectName("stimPhi1") self.lblPhU1 = QLabel(to_html("°", frmt='b'), self) self.lblPhi2 = QLabel(to_html("φ_2", frmt='bi') + " =", self) self.ledPhi2 = QLineEdit(self) self.ledPhi2.setText(str(self.phi2)) self.ledPhi2.setToolTip("Stimulus phase 2") self.ledPhi2.setObjectName("stimPhi2") self.lblPhU2 = QLabel(to_html("°", frmt='b'), self) layVlblPhi = QVBoxLayout() layVlblPhi.addWidget(self.lblPhi1) layVlblPhi.addWidget(self.lblPhi2) layVledPhi = QVBoxLayout() layVledPhi.addWidget(self.ledPhi1) layVledPhi.addWidget(self.ledPhi2) layVlblPhU = QVBoxLayout() layVlblPhU.addWidget(self.lblPhU1) layVlblPhU.addWidget(self.lblPhU2) #---------------------------------------------- self.lblFreq1 = QLabel(to_html("f_1", frmt='bi') + " =", self) self.ledFreq1 = QLineEdit(self) self.ledFreq1.setText(str(self.f1)) self.ledFreq1.setToolTip("Stimulus frequency 1") self.ledFreq1.setObjectName("stimFreq1") self.lblFreqUnit1 = QLabel("f_S", self) self.lblFreq2 = QLabel(to_html("f_2", frmt='bi') + " =", self) self.ledFreq2 = QLineEdit(self) self.ledFreq2.setText(str(self.f2)) self.ledFreq2.setToolTip("Stimulus frequency 2") self.ledFreq2.setObjectName("stimFreq2") self.lblFreqUnit2 = QLabel("f_S", self) layVlblfreq = QVBoxLayout() layVlblfreq.addWidget(self.lblFreq1) layVlblfreq.addWidget(self.lblFreq2) layVledfreq = QVBoxLayout() layVledfreq.addWidget(self.ledFreq1) layVledfreq.addWidget(self.ledFreq2) layVlblfreqU = QVBoxLayout() layVlblfreqU.addWidget(self.lblFreqUnit1) layVlblfreqU.addWidget(self.lblFreqUnit2) #---------------------------------------------- self.lblNoise = QLabel(to_html("Noise: ", frmt='bi'), self) self.cmbNoise = QComboBox(self) self.cmbNoise.addItems(["None", "Gauss", "Uniform", "PRBS"]) self.cmbNoise.setToolTip("Type of additive noise.") qset_cmb_box(self.cmbNoise, self.noise) self.lblNoi = QLabel("not initialized", self) self.ledNoi = QLineEdit(self) self.ledNoi.setText(str(self.noi)) self.ledNoi.setToolTip("not initialized") self.ledNoi.setObjectName("stimNoi") layVlblNoi = QVBoxLayout() layVlblNoi.addWidget(self.lblNoise) layVlblNoi.addWidget(self.lblNoi) layVcmbledNoi = QVBoxLayout() layVcmbledNoi.addWidget(self.cmbNoise) layVcmbledNoi.addWidget(self.ledNoi) #---------------------------------------------- #layG_ctrl_stim = QGridLayout() layH_ctrl_stim = QHBoxLayout() layH_ctrl_stim.addWidget(lbl_title_stim) layH_ctrl_stim.addStretch(1) layH_ctrl_stim.addLayout(layVlblCmbDC) layH_ctrl_stim.addLayout(layVCmbDC) layH_ctrl_stim.addStretch(1) layH_ctrl_stim.addLayout(layVlblAmp) layH_ctrl_stim.addLayout(layVledAmp) layH_ctrl_stim.addLayout(layVlblPhi) layH_ctrl_stim.addLayout(layVledPhi) layH_ctrl_stim.addLayout(layVlblPhU) layH_ctrl_stim.addStretch(1) layH_ctrl_stim.addLayout(layVlblfreq) layH_ctrl_stim.addLayout(layVledfreq) layH_ctrl_stim.addLayout(layVlblfreqU) layH_ctrl_stim.addStretch(1) layH_ctrl_stim.addLayout(layVlblNoi) layH_ctrl_stim.addLayout(layVcmbledNoi) layH_ctrl_stim.addStretch(10) self.wdg_ctrl_stim = QWidget(self) self.wdg_ctrl_stim.setLayout(layH_ctrl_stim) # --------- end stimuli --------------------------------- # frequency widgets require special handling as they are scaled with f_s self.ledFreq1.installEventFilter(self) self.ledFreq2.installEventFilter(self) #---------------------------------------------------------------------- # LOCAL SIGNALS & SLOTs #---------------------------------------------------------------------- # --- run control --- self.led_N_start.editingFinished.connect(self.update_N) self.led_N_points.editingFinished.connect(self.update_N) # --- frequency control --- # careful! currentIndexChanged passes the current index to _update_win_fft self.cmb_win_fft.currentIndexChanged.connect(self._update_win_fft) self.ledWinPar1.editingFinished.connect(self._read_param1) self.ledWinPar2.editingFinished.connect(self._read_param2) # --- stimulus control --- self.chk_stim_options.clicked.connect(self._show_stim_options) self.chk_stim_bl.clicked.connect(self._enable_stim_widgets) self.cmbStimulus.currentIndexChanged.connect(self._enable_stim_widgets) self.cmbNoise.currentIndexChanged.connect(self._update_noi) self.ledNoi.editingFinished.connect(self._update_noi) self.ledAmp1.editingFinished.connect(self._update_amp1) self.ledAmp2.editingFinished.connect(self._update_amp2) self.ledPhi1.editingFinished.connect(self._update_phi1) self.ledPhi2.editingFinished.connect(self._update_phi2) self.ledDC.editingFinished.connect(self._update_DC)
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: - 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): # ===================================================================== # Controls for stimuli # ===================================================================== self.cmbStimulus = QComboBox(self) qcmb_box_populate(self.cmbStimulus, self.cmb_stim_items, self.cmb_stim_item) self.lblStimPar1 = QLabel(to_html("α =", frmt='b'), self) self.ledStimPar1 = QLineEdit(self) self.ledStimPar1.setText("0.5") self.ledStimPar1.setToolTip("Duty Cycle, 0 ... 1") self.ledStimPar1.setObjectName("ledStimPar1") self.but_stim_bl = QPushButton(self) self.but_stim_bl.setText("BL") self.but_stim_bl.setToolTip( "<span>Bandlimit the signal to the Nyquist " "frequency to avoid aliasing. However, this is much slower " "to calculate especially for a large number of points.</span>") self.but_stim_bl.setMaximumWidth(qtext_width(text="BL ")) self.but_stim_bl.setCheckable(True) self.but_stim_bl.setChecked(True) self.but_stim_bl.setObjectName("stim_bl") # ------------------------------------- self.cmbChirpType = QComboBox(self) qcmb_box_populate(self.cmbChirpType, self.cmb_stim_chirp_items, self.chirp_type) self.cmbImpulseType = QComboBox(self) qcmb_box_populate(self.cmbImpulseType, self.cmb_stim_impulse_items, self.impulse_type) self.cmbSinusoidType = QComboBox(self) qcmb_box_populate(self.cmbSinusoidType, self.cmb_stim_sinusoid_items, self.sinusoid_type) self.cmbPeriodicType = QComboBox(self) qcmb_box_populate(self.cmbPeriodicType, self.cmb_stim_periodic_items, self.cmb_stim_periodic_item) self.cmbModulationType = QComboBox(self) for t in [("AM", "am"), ("PM / FM", "pmfm")]: # text, data self.cmbModulationType.addItem(*t) qset_cmb_box(self.cmbModulationType, self.modulation_type, data=True) # ------------------------------------- self.chk_step_err = QPushButton("Error", self) self.chk_step_err.setToolTip( "<span>Display the step response error.</span>") self.chk_step_err.setMaximumWidth(qtext_width(text="Error ")) self.chk_step_err.setCheckable(True) self.chk_step_err.setChecked(False) self.chk_step_err.setObjectName("stim_step_err") layHCmbStim = QHBoxLayout() layHCmbStim.addWidget(self.cmbStimulus) layHCmbStim.addWidget(self.cmbImpulseType) layHCmbStim.addWidget(self.cmbSinusoidType) layHCmbStim.addWidget(self.cmbChirpType) layHCmbStim.addWidget(self.cmbPeriodicType) layHCmbStim.addWidget(self.cmbModulationType) layHCmbStim.addWidget(self.but_stim_bl) layHCmbStim.addWidget(self.lblStimPar1) layHCmbStim.addWidget(self.ledStimPar1) layHCmbStim.addWidget(self.chk_step_err) self.lblDC = QLabel(to_html("DC =", frmt='bi'), self) self.ledDC = QLineEdit(self) self.ledDC.setText(str(self.DC)) self.ledDC.setToolTip("DC Level") self.ledDC.setObjectName("stimDC") layHStimDC = QHBoxLayout() layHStimDC.addWidget(self.lblDC) layHStimDC.addWidget(self.ledDC) # ====================================================================== self.lblAmp1 = QLabel(to_html(" A_1", frmt='bi') + " =", self) self.ledAmp1 = QLineEdit(self) self.ledAmp1.setText(str(self.A1)) self.ledAmp1.setToolTip( "Stimulus amplitude, complex values like 3j - 1 are allowed") self.ledAmp1.setObjectName("stimAmp1") self.lblAmp2 = QLabel(to_html(" A_2", frmt='bi') + " =", self) self.ledAmp2 = QLineEdit(self) self.ledAmp2.setText(str(self.A2)) self.ledAmp2.setToolTip( "Stimulus amplitude 2, complex values like 3j - 1 are allowed") self.ledAmp2.setObjectName("stimAmp2") # ---------------------------------------------- self.lblPhi1 = QLabel(to_html(" φ_1", frmt='bi') + " =", self) self.ledPhi1 = QLineEdit(self) self.ledPhi1.setText(str(self.phi1)) self.ledPhi1.setToolTip("Stimulus phase") self.ledPhi1.setObjectName("stimPhi1") self.lblPhU1 = QLabel(to_html("°", frmt='b'), self) self.lblPhi2 = QLabel(to_html(" φ_2", frmt='bi') + " =", self) self.ledPhi2 = QLineEdit(self) self.ledPhi2.setText(str(self.phi2)) self.ledPhi2.setToolTip("Stimulus phase 2") self.ledPhi2.setObjectName("stimPhi2") self.lblPhU2 = QLabel(to_html("°", frmt='b'), self) # ---------------------------------------------- self.lbl_T1 = QLabel(to_html(" T_1", frmt='bi') + " =", self) self.led_T1 = QLineEdit(self) self.led_T1.setText(str(self.T1)) self.led_T1.setToolTip("Time shift") self.led_T1.setObjectName("stimT1") self.lbl_TU1 = QLabel(to_html("T_S", frmt='b'), self) self.lbl_T2 = QLabel(to_html(" T_2", frmt='bi') + " =", self) self.led_T2 = QLineEdit(self) self.led_T2.setText(str(self.T2)) self.led_T2.setToolTip("Time shift 2") self.led_T2.setObjectName("stimT2") self.lbl_TU2 = QLabel(to_html("T_S", frmt='b'), self) # --------------------------------------------- self.lbl_TW1 = QLabel( to_html(" ΔT_1", frmt='bi') + " =", self) self.led_TW1 = QLineEdit(self) self.led_TW1.setText(str(self.TW1)) self.led_TW1.setToolTip("Time width") self.led_TW1.setObjectName("stimTW1") self.lbl_TWU1 = QLabel(to_html("T_S", frmt='b'), self) self.lbl_TW2 = QLabel( to_html(" ΔT_2", frmt='bi') + " =", self) self.led_TW2 = QLineEdit(self) self.led_TW2.setText(str(self.TW2)) self.led_TW2.setToolTip("Time width 2") self.led_TW2.setObjectName("stimTW2") self.lbl_TWU2 = QLabel(to_html("T_S", frmt='b'), self) # ---------------------------------------------- self.txtFreq1_f = to_html(" f_1", frmt='bi') + " =" self.txtFreq1_k = to_html(" k_1", frmt='bi') + " =" self.lblFreq1 = QLabel(self.txtFreq1_f, self) self.ledFreq1 = QLineEdit(self) self.ledFreq1.setText(str(self.f1)) self.ledFreq1.setToolTip("Stimulus frequency") self.ledFreq1.setObjectName("stimFreq1") self.lblFreqUnit1 = QLabel("f_S", self) self.txtFreq2_f = to_html(" f_2", frmt='bi') + " =" self.txtFreq2_k = to_html(" k_2", frmt='bi') + " =" self.lblFreq2 = QLabel(self.txtFreq2_f, self) self.ledFreq2 = QLineEdit(self) self.ledFreq2.setText(str(self.f2)) self.ledFreq2.setToolTip("Stimulus frequency 2") self.ledFreq2.setObjectName("stimFreq2") self.lblFreqUnit2 = QLabel("f_S", self) # ---------------------------------------------- self.lbl_BW1 = QLabel( to_html(self.tr(" BW_1"), frmt='bi') + " =", self) self.led_BW1 = QLineEdit(self) self.led_BW1.setText(str(self.BW1)) self.led_BW1.setToolTip(self.tr("Relative bandwidth")) self.led_BW1.setObjectName("stimBW1") self.lbl_BW2 = QLabel( to_html(self.tr(" BW_2"), frmt='bi') + " =", self) self.led_BW2 = QLineEdit(self) self.led_BW2.setText(str(self.BW2)) self.led_BW2.setToolTip(self.tr("Relative bandwidth 2")) self.led_BW2.setObjectName("stimBW2") # ---------------------------------------------- self.lblNoise = QLabel(to_html(" Noise", frmt='bi'), self) self.cmbNoise = QComboBox(self) qcmb_box_populate(self.cmbNoise, self.cmb_stim_noise_items, self.noise) self.lblNoi = QLabel("not initialized", self) self.ledNoi = QLineEdit(self) self.ledNoi.setText(str(self.noi)) self.ledNoi.setToolTip("not initialized") self.ledNoi.setObjectName("stimNoi") layGStim = QGridLayout() layGStim.addLayout(layHCmbStim, 0, 1) layGStim.addLayout(layHStimDC, 1, 1) layGStim.addWidget(self.lblAmp1, 0, 2) layGStim.addWidget(self.lblAmp2, 1, 2) layGStim.addWidget(self.ledAmp1, 0, 3) layGStim.addWidget(self.ledAmp2, 1, 3) layGStim.addWidget(self.lblPhi1, 0, 4) layGStim.addWidget(self.lblPhi2, 1, 4) layGStim.addWidget(self.ledPhi1, 0, 5) layGStim.addWidget(self.ledPhi2, 1, 5) layGStim.addWidget(self.lblPhU1, 0, 6) layGStim.addWidget(self.lblPhU2, 1, 6) layGStim.addWidget(self.lbl_T1, 0, 7) layGStim.addWidget(self.lbl_T2, 1, 7) layGStim.addWidget(self.led_T1, 0, 8) layGStim.addWidget(self.led_T2, 1, 8) layGStim.addWidget(self.lbl_TU1, 0, 9) layGStim.addWidget(self.lbl_TU2, 1, 9) layGStim.addWidget(self.lbl_TW1, 0, 10) layGStim.addWidget(self.lbl_TW2, 1, 10) layGStim.addWidget(self.led_TW1, 0, 11) layGStim.addWidget(self.led_TW2, 1, 11) layGStim.addWidget(self.lbl_TWU1, 0, 12) layGStim.addWidget(self.lbl_TWU2, 1, 12) layGStim.addWidget(self.lblFreq1, 0, 13) layGStim.addWidget(self.lblFreq2, 1, 13) layGStim.addWidget(self.ledFreq1, 0, 14) layGStim.addWidget(self.ledFreq2, 1, 14) layGStim.addWidget(self.lblFreqUnit1, 0, 15) layGStim.addWidget(self.lblFreqUnit2, 1, 15) layGStim.addWidget(self.lbl_BW1, 0, 16) layGStim.addWidget(self.lbl_BW2, 1, 16) layGStim.addWidget(self.led_BW1, 0, 17) layGStim.addWidget(self.led_BW2, 1, 17) layGStim.addWidget(self.lblNoise, 0, 18) layGStim.addWidget(self.lblNoi, 1, 18) layGStim.addWidget(self.cmbNoise, 0, 19) layGStim.addWidget(self.ledNoi, 1, 19) # ---------------------------------------------- self.lblStimFormula = QLabel(to_html("x =", frmt='bi'), self) self.ledStimFormula = QLineEdit(self) self.ledStimFormula.setText(str(self.stim_formula)) self.ledStimFormula.setToolTip( "<span>Enter formula for stimulus in numexpr syntax.</span>") self.ledStimFormula.setObjectName("stimFormula") layH_stim_formula = QHBoxLayout() layH_stim_formula.addWidget(self.lblStimFormula) layH_stim_formula.addWidget(self.ledStimFormula, 10) # ---------------------------------------------------------------------- # Main Widget # ---------------------------------------------------------------------- layH_stim_par = QHBoxLayout() layH_stim_par.addLayout(layGStim) layV_stim = QVBoxLayout() layV_stim.addLayout(layH_stim_par) layV_stim.addLayout(layH_stim_formula) layH_stim = QHBoxLayout() layH_stim.addLayout(layV_stim) layH_stim.addStretch(10) self.wdg_stim = QWidget(self) self.wdg_stim.setLayout(layH_stim) self.wdg_stim.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum) # ---------------------------------------------------------------------- # Event Filter # ---------------------------------------------------------------------- # frequency related widgets are scaled with f_s, requiring special handling self.ledFreq1.installEventFilter(self) self.ledFreq2.installEventFilter(self) self.led_T1.installEventFilter(self) self.led_T2.installEventFilter(self) self.led_TW1.installEventFilter(self) self.led_TW2.installEventFilter(self) # ---------------------------------------------------------------------- # GLOBAL SIGNALS & SLOTs # ---------------------------------------------------------------------- self.sig_rx.connect(self.process_sig_rx) # ---------------------------------------------------------------------- # LOCAL SIGNALS & SLOTs # ---------------------------------------------------------------------- # --- stimulus control --- self.but_stim_bl.clicked.connect(self._enable_stim_widgets) self.chk_step_err.clicked.connect(self._enable_stim_widgets) self.cmbStimulus.currentIndexChanged.connect(self._enable_stim_widgets) self.cmbNoise.currentIndexChanged.connect(self._update_noi) self.ledNoi.editingFinished.connect(self._update_noi) self.ledAmp1.editingFinished.connect(self._update_amp1) self.ledAmp2.editingFinished.connect(self._update_amp2) self.ledPhi1.editingFinished.connect(self._update_phi1) self.ledPhi2.editingFinished.connect(self._update_phi2) self.led_BW1.editingFinished.connect(self._update_BW1) self.led_BW2.editingFinished.connect(self._update_BW2) self.cmbImpulseType.currentIndexChanged.connect( self._update_impulse_type) self.cmbSinusoidType.currentIndexChanged.connect( self._update_sinusoid_type) self.cmbChirpType.currentIndexChanged.connect(self._update_chirp_type) self.cmbPeriodicType.currentIndexChanged.connect( self._update_periodic_type) self.cmbModulationType.currentIndexChanged.connect( self._update_modulation_type) self.ledDC.editingFinished.connect(self._update_DC) self.ledStimFormula.editingFinished.connect(self._update_stim_formula) self.ledStimPar1.editingFinished.connect(self._update_stim_par1)
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 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 """ 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): """ 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)
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)