def interface(self, generic_options=None): if generic_options is None: generic_options = {} if self.options_widget is None: self.options_widget = QtGui.QWidget() vbox = QtGui.QVBoxLayout() self.options_widget.setLayout(vbox) cite = Citation(CITE_TITLE, CITE_AUTHOR, CITE_JOURNAL) vbox.addWidget(cite) self.optbox = OptionBox() self.optbox.add("Mask for registration data", DataOption(self.ivm, rois=True, data=False), key="inmask", checked=True) self.optbox.add("Mask for reference data", DataOption(self.ivm, rois=True, data=False), key="refmask", checked=True) self.optbox.add("Spline order", ChoiceOption([2, 3]), key="splineorder", checked=True) self.optbox.add("Use pre-defined configuration", ChoiceOption( ["T1_2_MNI152_2mm", "FA_2_FMRIB58_1mm"]), key="config", checked=True) vbox.addWidget(self.optbox) return self.options_widget
def init_ui(self, run_box=True): self.vbox = QtGui.QVBoxLayout() self.setLayout(self.vbox) title = TitleWidget(self, help="fsl", subtitle="%s %s" % (self.description, __version__)) self.vbox.addWidget(title) cite = Citation(*CITATIONS.get(self.prog, CITATIONS["fsl"])) self.vbox.addWidget(cite) self.options = OptionBox("%s options" % self.prog.upper()) self.vbox.addWidget(self.options) if run_box: self.run_box = RunBox(self.get_process, self.get_options) self.vbox.addWidget(self.run_box) self.vbox.addStretch(1) fsldir = FslDirWidget() self.vbox.addWidget(fsldir) fsldir.sig_changed.connect(self._fsldir_changed) self._fsldir_changed(fsldir.fsldir)
def init_ui(self): vbox = QtGui.QVBoxLayout() self.setLayout(vbox) try: proc = get_plugins("processes", "FabberProcess")[0] except: proc = None if proc is None: vbox.addWidget( QtGui.QLabel( "Fabber core library not found.\n\n You must install Fabber to use this widget" )) return title = TitleWidget(self, help="fabber-dsc", subtitle="Bayesian modelling for DSC-MRI %s" % __version__) vbox.addWidget(title) cite = Citation(FAB_CITE_TITLE, FAB_CITE_AUTHOR, FAB_CITE_JOURNAL) vbox.addWidget(cite) tabs = QtGui.QTabWidget() vbox.addWidget(tabs) self.dsc_widget = DscOptionsWidget(self.ivm) tabs.addTab(self.dsc_widget, "DSC Options") self.aif_widget = AifWidget(self.ivm) tabs.addTab(self.aif_widget, "AIF") vbox.addWidget(tabs) vbox.addWidget(RunWidget(self, save_option=True)) vbox.addStretch(1)
def __init__(self, ivm, parent, acq_options): OptionsWidget.__init__(self, ivm, parent) self.acq_options = acq_options vbox = QtWidgets.QVBoxLayout() self.setLayout(vbox) cite = Citation(FAB_CITE_TITLE, FAB_CITE_AUTHOR, FAB_CITE_JOURNAL) vbox.addWidget(cite) self._optbox = OptionBox() self._optbox.add("<b>Model options</b>") self._optbox.add("Infer constant signal offset", BoolOption(default=True), key="infer-sig0") self._optbox.add("Infer delay", BoolOption(default=True), key="infer-delay") #self._optbox.add("<b>Model fitting options</b>") #self._optbox.add("Spatial regularization", BoolOption(default=True), key="spatial") self._optbox.add("<b>Output options</b>") self._optbox.add("Output data name suffix", TextOption(), checked=True, key="output-suffix") vbox.addWidget(self._optbox) vbox.addWidget(RunWidget(self, save_option=True)) vbox.addStretch(1)
def init_ui(self): vbox = QtGui.QVBoxLayout() self.setLayout(vbox) try: self.fabber_process = get_plugins("processes", "FabberProcess")[0] except: self.fabber_process = None if self.fabber_process is None: vbox.addWidget( QtGui.QLabel( "Fabber core library not found.\n\n You must install Fabber to use this widget" )) return title = TitleWidget( self, help="cest", subtitle= "Bayesian Modelling for Chemical Exchange Saturation Transfer MRI %s" % __version__) vbox.addWidget(title) cite = Citation(CEST_CITE_TITLE, CEST_CITE_AUTHOR, CEST_CITE_JOURNAL) vbox.addWidget(cite) self.tabs = QtGui.QTabWidget() self.seqtab = SequenceOptions(self.ivm) self.tabs.addTab(self.seqtab, "Sequence") self.pooltab = PoolOptions(self.ivm) self.tabs.addTab(self.pooltab, "Pools") self.analysistab = AnalysisOptions(self.ivm) self.tabs.addTab(self.analysistab, "Analysis") self.pooltab.sig_pools_changed.connect(self.analysistab.set_pools) self.seqtab.sig_b0_changed.connect(self.pooltab.set_b0) vbox.addWidget(self.tabs) run_tabs = QtGui.QTabWidget() run_box = RunBox(self._get_process_model, self._options, title="Run model-based analysis", save_option=True) run_tabs.addTab(run_box, "Model based analysis") run_box = RunBox(self._get_process_lda, self._options_lda, title="Run Lorentzian Difference analysis", save_option=True) run_tabs.addTab(run_box, "Lorentzian Difference analysis") vbox.addWidget(run_tabs) vbox.addStretch(1) self.analysistab.set_pools(self.pooltab.pools)
def init_ui(self): vbox = QtGui.QVBoxLayout() self.setLayout(vbox) title = TitleWidget( self, help="asl", subtitle="Data processing for Arterial Spin Labelling MRI") vbox.addWidget(title) cite = Citation(FAB_CITE_TITLE, FAB_CITE_AUTHOR, FAB_CITE_JOURNAL) vbox.addWidget(cite) self.tabs = QtGui.QTabWidget() vbox.addWidget(self.tabs) self.asldata = AslImageWidget(self.ivm, parent=self) self.asldata.sig_changed.connect(self._data_changed) self.tabs.addTab(self.asldata, "ASL data") self.preproc = PreprocOptions(self.ivm) self.preproc.sig_enable_tab.connect(self._enable_tab) self.tabs.addTab(self.preproc, "Corrections") # Only add these if appropriate self._optional_tabs = { "veasl": VeaslOptions(self.ivm, self.asldata), "enable": EnableOptions(self.ivm), "deblur": DeblurOptions(), } self.structural = StructuralData(self.ivm) self.tabs.addTab(self.structural, "Structural data") self.calibration = CalibrationOptions(self.ivm) self.tabs.addTab(self.calibration, "Calibration") self.analysis = AnalysisOptions(self.ivm) self.analysis.optbox.option("wp").sig_changed.connect(self._wp_changed) self.tabs.addTab(self.analysis, "Analysis") self.output = OutputOptions() self.tabs.addTab(self.output, "Output") runbox = RunWidget(self, title="Run processing", save_option=True) runbox.sig_postrun.connect(self._postrun) vbox.addWidget(runbox) vbox.addStretch(1) fsldir_qwidgets = get_plugins("qwidgets", "FslDirWidget") if len(fsldir_qwidgets) > 0: fsldir = fsldir_qwidgets[0]() vbox.addWidget(fsldir)
def __init__(self, ivm=None): QtGui.QWidget.__init__(self) self.ivm = ivm self.vbox = QtGui.QVBoxLayout() self.setLayout(self.vbox) if hasattr(self, "CITE"): self.vbox.addWidget(Citation(*self.CITE)) self.optbox = OptionBox() self.vbox.addWidget(self.optbox) self._init_ui() self.vbox.addStretch(1)
def init_ui(self): self.vbox = QtGui.QVBoxLayout() self.setLayout(self.vbox) title = TitleWidget(self, subtitle="Plugin %s" % __version__, help="fabber") self.vbox.addWidget(title) cite = Citation(FAB_CITE_TITLE, FAB_CITE_AUTHOR, FAB_CITE_JOURNAL) self.vbox.addWidget(cite) self.options = OptionBox("Options") self.options.sig_changed.connect(self._options_changed) self.vbox.addWidget(self.options) self.warn_box = WarningBox("") self.warn_box.setVisible(False) self.vbox.addWidget(self.warn_box)
def interface(self, generic_options=None): """ :return: QWidget containing registration options """ if generic_options is None: generic_options = {} if self.options_widget is None: self.options_widget = QtGui.QWidget() vbox = QtGui.QVBoxLayout() self.options_widget.setLayout(vbox) cite = Citation(CITE_TITLE, CITE_AUTHOR, CITE_JOURNAL) vbox.addWidget(cite) self.optbox = OptionBox() self.optbox.add("Cost Model", ChoiceOption(self.cost_models, self.cost_model_options, default="normcorr"), key="cost") #self.optbox.add("Number of search stages", ChoiceOption([1, 2, 3, 4]), key="nstages") #self.optbox.option("stages").value = 2 #self.optbox.add("Final stage interpolation", ChoiceOption(["None", "Sinc", "Spline", "Nearest neighbour"], ["", "sinc_final", "spline_final", "nn_final"]), key="final") #self.optbox.add("Field of view (mm)", NumericOption(minval1, maxval=100, default=20), key="fov") self.optbox.add("Number of bins", NumericOption(intonly=True, minval=1, maxval=1000, default=256), key="bins") self.optbox.add("Degrees of freedom", ChoiceOption([6, 9, 12]), key="dof") #self.optbox.add("Scaling", NumericOption(minval=0.1, maxval=10, default=6), key="scaling") #self.optbox.add("Smoothing in cost function", NumericOption(minval=0.1, maxval=10, default=1), key="smoothing") #self.optbox.add("Scaling factor for rotation\noptimization tolerances", NumericOption(minval=0.1, maxval=10, default=1), key="rotscale") #self.optbox.add("Search on gradient images", BoolOption, key="grad") vbox.addWidget(self.optbox) return self.options_widget
def init_ui(self): layout = QtGui.QVBoxLayout() self.setLayout(layout) title = TitleWidget(self, "Supervoxel Generation", help="sv") layout.addWidget(title) cite = Citation(CITE_TITLE, CITE_AUTHOR, CITE_JOURNAL) layout.addWidget(cite) hbox = QtGui.QHBoxLayout() optbox = QtGui.QGroupBox() optbox.setTitle("Options") grid = QtGui.QGridLayout() optbox.setLayout(grid) grid.addWidget(QtGui.QLabel("Data"), 0, 0) self.ovl = OverlayCombo(self.ivm) self.ovl.currentIndexChanged.connect(self._data_changed) grid.addWidget(self.ovl, 0, 1) grid.addWidget(QtGui.QLabel("ROI"), 1, 0) self.roi = RoiCombo(self.ivm) grid.addWidget(self.roi, 1, 1) self.n_comp = NumericOption("Number of components", grid, 2, minval=1, maxval=3, default=3, intonly=True) self.compactness = NumericOption("Compactness", grid, 3, minval=0.01, maxval=1, step=0.05, default=0.1, intonly=False) self.sigma = NumericOption("Smoothing", grid, 4, minval=0, maxval=5, step=0.1, default=1, intonly=False) self.n_supervoxels = NumericOption("Number of supervoxels", grid, 5, minval=2, maxval=1000, default=20, intonly=True) grid.addWidget(QtGui.QLabel("Output name"), 6, 0) self.output_name = QtGui.QLineEdit("supervoxels") grid.addWidget(self.output_name, 6, 1) self.gen_btn = QtGui.QPushButton('Generate', self) self.gen_btn.clicked.connect(self._generate) grid.addWidget(self.gen_btn, 7, 0) hbox.addWidget(optbox) hbox.addStretch(1) layout.addLayout(hbox) layout.addStretch(1)
def init_ui(self): vbox = QtGui.QVBoxLayout() self.setLayout(vbox) vbox.addWidget(TitleWidget(self)) vbox.addWidget(Citation(*CITATIONS["fsl"])) self.data_list = FslDataListWidget(self) vbox.addWidget(self.data_list) self.data_list.sig_selected.connect(self._data_selected) hbox = QtGui.QHBoxLayout() self._load_btn = QtGui.QPushButton("Load") self._load_btn.clicked.connect(self._load) hbox.addWidget(self._load_btn) hbox.addWidget(QtGui.QLabel("Dataset name: ")) self._load_name = QtGui.QLineEdit() hbox.addWidget(self._load_name) vbox.addLayout(hbox) fsldir = FslDirWidget() vbox.addWidget(fsldir)
def init_ui(self): vbox = QtGui.QVBoxLayout() vbox.setSpacing(1) self.setLayout(vbox) vbox.addWidget(TitleWidget(self)) vbox.addWidget(Citation(*CITATIONS["fsl"])) self.atlas_list = AtlasListWidget(self, self._registry) vbox.addWidget(self.atlas_list) self.atlas_desc = AtlasDescription(self, self._registry) vbox.addWidget(self.atlas_desc) self.atlas_list.sig_selected.connect(self.atlas_desc.set_atlas) fsldir = FslDirWidget() vbox.addWidget(fsldir) # This needs to be done after creating the FslDirWidget because otherwise we may not # have picked up a previously saved FSLDIR setting and the atlas list will be empty self._registry.rescanAtlases() self.atlas_list.init_list()
def __init__(self, ivm=None): QtGui.QWidget.__init__(self) self._ivm = ivm self._poolvals_edited = False vbox = QtGui.QVBoxLayout() self.setLayout(vbox) self.optbox = OptionBox() vbox.addWidget(self.optbox) self.optbox.add("<b>Output options</b>") self.optbox.add("CEST R*", BoolOption(default=True), key="save-model-extras") self.optbox.add("Parameter maps", BoolOption(default=False), key="save-mean") #self.optbox.add("Parameter variance", BoolOption(default=False), key="var") self.optbox.add("Model fit", BoolOption(default=False), key="save-model-fit") self.optbox.add("Prefix for output", TextOption(), checked=True, key="output-prefix") self.optbox.add(" ") self.optbox.add("<b>Analysis options</b>") self.optbox.add("Spatial Regularization", BoolOption(), key="spatial") self.optbox.add("Allow uncertainty in T1/T2 values", BoolOption(), key="t12prior") self.optbox.add("Prior T1 map", DataOption(self._ivm), key="t1img", checked=True) self.optbox.add("Prior T2 map", DataOption(self._ivm), key="t2img", checked=True) self.optbox.add("Tissue PV map (GM+WM)", DataOption(self._ivm), key="pvimg", checked=True) self.optbox.option("t12prior").sig_changed.connect(self._update_ui) self.optbox.add("Use steady state solution for MT bias reduction", BoolOption(default=False), key="new-ss") self.optbox.option("new-ss").sig_changed.connect(self._update_ui) self.optbox.add("TR (s)", NumericOption(default=3.0, minval=0, maxval=5, digits=3, step=0.1), key="tr") self.optbox.add("Excitation flip angle (\N{DEGREE SIGN})", NumericOption(default=12.0, minval=0, maxval=25, digits=3, step=1.0), key="fa") self.optbox.add( "MT pool Line shape", ChoiceOption( ["None", "Gaussian", "Lorentzian", "Super Lorentzian"], ["none", "gaussian", "lorentzian", "superlorentzian"]), key="lineshape") self.alexmt_cite = Citation(ALEXMT_CITE_TITLE, ALEXMT_CITE_AUTHOR, ALEXMT_CITE_JOURNAL) vbox.addWidget(self.alexmt_cite) vbox.addStretch(1) self._update_ui()
class AnalysisOptions(QtGui.QWidget): """ Widget allowing model and output options to be changed """ def __init__(self, ivm=None): QtGui.QWidget.__init__(self) self._ivm = ivm self._poolvals_edited = False vbox = QtGui.QVBoxLayout() self.setLayout(vbox) self.optbox = OptionBox() vbox.addWidget(self.optbox) self.optbox.add("<b>Output options</b>") self.optbox.add("CEST R*", BoolOption(default=True), key="save-model-extras") self.optbox.add("Parameter maps", BoolOption(default=False), key="save-mean") #self.optbox.add("Parameter variance", BoolOption(default=False), key="var") self.optbox.add("Model fit", BoolOption(default=False), key="save-model-fit") self.optbox.add("Prefix for output", TextOption(), checked=True, key="output-prefix") self.optbox.add(" ") self.optbox.add("<b>Analysis options</b>") self.optbox.add("Spatial Regularization", BoolOption(), key="spatial") self.optbox.add("Allow uncertainty in T1/T2 values", BoolOption(), key="t12prior") self.optbox.add("Prior T1 map", DataOption(self._ivm), key="t1img", checked=True) self.optbox.add("Prior T2 map", DataOption(self._ivm), key="t2img", checked=True) self.optbox.add("Tissue PV map (GM+WM)", DataOption(self._ivm), key="pvimg", checked=True) self.optbox.option("t12prior").sig_changed.connect(self._update_ui) self.optbox.add("Use steady state solution for MT bias reduction", BoolOption(default=False), key="new-ss") self.optbox.option("new-ss").sig_changed.connect(self._update_ui) self.optbox.add("TR (s)", NumericOption(default=3.0, minval=0, maxval=5, digits=3, step=0.1), key="tr") self.optbox.add("Excitation flip angle (\N{DEGREE SIGN})", NumericOption(default=12.0, minval=0, maxval=25, digits=3, step=1.0), key="fa") self.optbox.add( "MT pool Line shape", ChoiceOption( ["None", "Gaussian", "Lorentzian", "Super Lorentzian"], ["none", "gaussian", "lorentzian", "superlorentzian"]), key="lineshape") self.alexmt_cite = Citation(ALEXMT_CITE_TITLE, ALEXMT_CITE_AUTHOR, ALEXMT_CITE_JOURNAL) vbox.addWidget(self.alexmt_cite) vbox.addStretch(1) self._update_ui() def _update_ui(self): t12prior = self.optbox.option("t12prior").value self.optbox.set_visible("t1img", t12prior) self.optbox.set_visible("t2img", t12prior) newss = self.optbox.values().get("new-ss", False) self.optbox.set_visible("tr", newss) self.optbox.set_visible("fa", newss) self.optbox.set_visible("lineshape", newss) self.alexmt_cite.setVisible(newss) def set_pools(self, pools): self.optbox.set_visible("new-ss", "MT" in [p.name for p in pools if p.enabled]) self._update_ui() def options(self): options = self.optbox.values() if options.pop("spatial", False): options["method"] = "spatialvb" options["param-spatial-priors"] = "MN+" else: options["method"] = "vb" options.pop("param-spatial-priors", None) # The new MT model is automatically triggered when the TR and FA options are given options.pop("new-ss", None) prior_num = 1 for idx in (1, 2): if "t%iimg" % idx in options: options["PSP_byname%i" % prior_num] = "T%ia" % idx options["PSP_byname%i_type" % prior_num] = "I" options["PSP_byname%i_image" % prior_num] = options.pop( "t%iimg" % idx) prior_num += 1 return options
def init_ui(self): vbox = QtGui.QVBoxLayout() self.setLayout(vbox) try: self.FabberProcess = get_plugins("processes", "FabberProcess")[0] except IndexError: self.FabberProcess = None if self.FabberProcess is None: vbox.addWidget( QtGui.QLabel( "Fabber core library not found.\n\n You must install Fabber to use this widget" )) return title = TitleWidget( self, help="fabber-dsc", subtitle="DSC modelling using the Fabber process %s" % __version__) vbox.addWidget(title) cite = Citation(FAB_CITE_TITLE, FAB_CITE_AUTHOR, FAB_CITE_JOURNAL) vbox.addWidget(cite) self.input = OptionBox("Input data") self.input.add("DCE data", DataOption(self.ivm, include_3d=False, include_4d=True), key="data") self.input.add("ROI", DataOption(self.ivm, data=False, rois=True), key="roi", checked=True) self.input.add("T1 map", DataOption(self.ivm, include_3d=True, include_4d=False), key="t1", checked=True) self.input.option("t1").sig_changed.connect(self._t1_map_changed) vbox.addWidget(self.input) self.acquisition = OptionBox("Acquisition") self.acquisition.add("Contrast agent R1 relaxivity (l/mmol s)", NumericOption(minval=0, maxval=10, default=3.7), key="r1") self.acquisition.add("Flip angle (\N{DEGREE SIGN})", NumericOption(minval=0, maxval=90, default=12), key="fa") self.acquisition.add("TR (ms)", NumericOption(minval=0, maxval=10, default=4.108), key="tr") self.acquisition.add("Time between volumes (s)", NumericOption(minval=0, maxval=30, default=12), key="delt") vbox.addWidget(self.acquisition) self.model = OptionBox("Model options") self.model.add( "Model", ChoiceOption([ "Standard Tofts model", "Extended Tofts model (ETM)", "2 Compartment exchange model", "Compartmental Tissue Update (CTU) model", "Adiabatic Approximation to Tissue Homogeneity (AATH) Model" ], ["dce_tofts", "dce_ETM", "dce_2CXM", "dce_CTU", "dce_AATH"]), key="model") self.model.add( "AIF", ChoiceOption([ "Population (Orton 2008)", "Population (Parker)", "Measured DCE signal", "Measured concentration curve" ], ["orton", "parker", "signal", "conc"]), key="aif") self.model.add("Bolus injection time (s)", NumericOption(minval=0, maxval=60, default=30), key="tinj") self.model.add("AIF data values", NumberListOption([ 0, ]), key="aif-data") self.model.add("T1 (s)", NumericOption(minval=0.0, maxval=5.0, default=1.0), key="t10") self.model.add("Allow T1 to vary", BoolOption(default=False), key="infer-t10") self.model.add("Bolus arrival time (s)", NumericOption(minval=0, maxval=2.0, default=0), key="delay") self.model.add("Allow bolus arrival time to vary", BoolOption(default=False), key="infer-delay") self.model.add("Infer kep rather than ve", BoolOption(default=False), key="infer-kep") self.model.add("Infer flow", BoolOption(default=True), key="infer-fp") self.model.add("Infer permeability-surface area", BoolOption(default=False), key="infer-ps") self.model.add("Spatial regularization", BoolOption(default=False), key="spatial") self.model.option("model").sig_changed.connect(self._model_changed) self.model.option("aif").sig_changed.connect(self._aif_changed) vbox.addWidget(self.model) # Run button and progress vbox.addWidget(RunWidget(self, title="Run modelling")) vbox.addStretch(1) self._aif_changed() self._model_changed()
def init_ui(self): vbox = QtGui.QVBoxLayout() self.setLayout(vbox) try: self.FabberProcess = get_plugins("processes", "FabberProcess")[0] except: self.FabberProcess = None if self.FabberProcess is None: vbox.addWidget( QtGui.QLabel( "Fabber core library not found.\n\n You must install Fabber to use this widget" )) return title = TitleWidget( self, help="fabber-t1", subtitle="T1 mapping from VFA images using the Fabber process %s" % __version__) vbox.addWidget(title) cite = Citation(FAB_CITE_TITLE, FAB_CITE_AUTHOR, FAB_CITE_JOURNAL) vbox.addWidget(cite) grid = QtGui.QGridLayout() self.multivol_choice = ChoiceOption( "VFA data in", grid, ypos=0, choices=["Single data set", "Multiple data sets"]) self.multivol_choice.combo.currentIndexChanged.connect(self.update_ui) self.multivol_label = QtGui.QLabel("VFA data set") grid.addWidget(self.multivol_label, 1, 0) self.multivol_combo = OverlayCombo(self.ivm) grid.addWidget(self.multivol_combo, 1, 1) self.multivol_fas_label = QtGui.QLabel("FAs (\N{DEGREE SIGN})") grid.addWidget(self.multivol_fas_label, 2, 0) self.multivol_fas = NumberList(initial=[ 1, ]) grid.addWidget(self.multivol_fas, 2, 1, 1, 2) self.singlevol_label = QtGui.QLabel("VFA data sets") grid.addWidget(self.singlevol_label, 3, 0) grid.setAlignment(self.singlevol_label, QtCore.Qt.AlignTop) self.singlevol_table = QtGui.QTableWidget() self.singlevol_table.setColumnCount(2) self.singlevol_table.setHorizontalHeaderLabels( ["Data set", "Flip angle"]) self.singlevol_table.setEditTriggers( QtGui.QAbstractItemView.NoEditTriggers) grid.addWidget(self.singlevol_table, 3, 1) hbox = QtGui.QHBoxLayout() self.singlevol_add = QtGui.QPushButton("Add") self.singlevol_add.clicked.connect(self.add_vol) hbox.addWidget(self.singlevol_add) self.singlevol_clear = QtGui.QPushButton("Clear") self.singlevol_clear.clicked.connect(self.clear_vols) hbox.addWidget(self.singlevol_clear) grid.addLayout(hbox, 4, 1) self.tr = NumericOption("TR (ms)", grid, ypos=5, default=4.108, minval=0, step=0.1, decimals=3) grid.setColumnStretch(3, 1) vbox.addLayout(grid) self.run = RunBox(self.get_process, self.get_rundata) vbox.addWidget(self.run) vbox.addStretch(1) self.update_ui()