Changeset 3c6ecd9 in sasview for src/sas/qtgui/Utilities


Ignore:
Timestamp:
May 7, 2018 6:47:21 AM (6 years ago)
Author:
Piotr Rozyczko <rozyczko@…>
Branches:
ESS_GUI, ESS_GUI_Docs, ESS_GUI_batch_fitting, ESS_GUI_bumps_abstraction, ESS_GUI_iss1116, ESS_GUI_iss879, ESS_GUI_iss959, ESS_GUI_opencl, ESS_GUI_ordering, ESS_GUI_sync_sascalc
Children:
42787fb
Parents:
b0ba43e (diff), 80468f6 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'ESS_GUI' into ESS_GUI_Pr

Location:
src/sas/qtgui/Utilities
Files:
3 added
10 edited

Legend:

Unmodified
Added
Removed
  • src/sas/qtgui/Utilities/GridPanel.py

    r5a5e371 r3c6ecd9  
    11import os 
     2import sys 
    23import time 
    34import logging 
    45import webbrowser 
    56 
    6 from PyQt5 import QtCore, QtWidgets 
     7from PyQt5 import QtCore, QtWidgets, QtGui 
    78 
    89import sas.qtgui.Utilities.GuiUtils as GuiUtils 
    9  
     10from sas.qtgui.Plotting.PlotterData import Data1D 
    1011from sas.qtgui.Utilities.UI.GridPanelUI import Ui_GridPanelUI 
    1112 
     
    1516    Class for stateless grid-like printout of model parameters for mutiple models 
    1617    """ 
     18    ERROR_COLUMN_CAPTION = " (Err)" 
     19    IS_WIN = (sys.platform == 'win32') 
    1720    def __init__(self, parent = None, output_data=None): 
    1821 
    19         super(BatchOutputPanel, self).__init__() 
     22        super(BatchOutputPanel, self).__init__(parent._parent) 
    2023        self.setupUi(self) 
    2124 
    22         self.data = output_data 
    2325        self.parent = parent 
    2426        if hasattr(self.parent, "communicate"): 
     
    3032        self.grid_filename = "" 
    3133 
     34        self.has_data = False if output_data is None else True 
     35        # Tab numbering 
     36        self.tab_number = 1 
     37 
     38        # System dependent menu items 
     39        if not self.IS_WIN: 
     40            self.actionOpen_with_Excel.setVisible(False) 
     41 
     42        # list of QTableWidgets, indexed by tab number 
     43        self.tables = [] 
     44        self.tables.append(self.tblParams) 
     45 
    3246        # context menu on the table 
    3347        self.tblParams.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) 
    3448        self.tblParams.customContextMenuRequested.connect(self.showContextMenu) 
    3549 
    36         # Fill in the table from input data 
    37         self.setupTable(output_data) 
    38  
    3950        # Command buttons 
    4051        self.cmdHelp.clicked.connect(self.onHelp) 
     52        self.cmdPlot.clicked.connect(self.onPlot) 
     53 
     54        # Fill in the table from input data 
     55        self.setupTable(widget=self.tblParams, data=output_data) 
     56        if output_data is not None: 
     57            # Set a table tooltip describing the model 
     58            model_name = output_data[0][0].model.id 
     59            self.tabWidget.setTabToolTip(0, model_name) 
     60 
     61    def closeEvent(self, event): 
     62        """ 
     63        Overwrite QDialog close method to allow for custom widget close 
     64        """ 
     65        # Maybe we should just minimize 
     66        self.setWindowState(QtCore.Qt.WindowMinimized) 
     67        event.ignore() 
    4168 
    4269    def addToolbarActions(self): 
     
    6491 
    6592        self.setupTableFromCSV(lines) 
     93        self.has_data = True 
     94 
     95    def currentTable(self): 
     96        """ 
     97        Returns the currently shown QTabWidget 
     98        """ 
     99        return self.tables[self.tabWidget.currentIndex()] 
    66100 
    67101    def showContextMenu(self, position): 
     
    70104        """ 
    71105        menu = QtWidgets.QMenu() 
    72         rows = [s.row() for s in self.tblParams.selectionModel().selectedRows()] 
     106        rows = [s.row() for s in self.currentTable().selectionModel().selectedRows()] 
    73107        num_rows = len(rows) 
    74108        if num_rows <= 0: 
     
    84118 
    85119        # Define the callbacks 
    86         self.actionPlotResults.triggered.connect(self.plotFits) 
     120        self.actionPlotResults.triggered.connect(self.onPlot) 
    87121        try: 
    88             menu.exec_(self.tblParams.viewport().mapToGlobal(position)) 
     122            menu.exec_(self.currentTable().viewport().mapToGlobal(position)) 
    89123        except AttributeError as ex: 
    90124            logging.error("Error generating context menu: %s" % ex) 
    91125        return 
    92126 
     127    def addTabPage(self): 
     128        """ 
     129        Add new tab page with QTableWidget 
     130        """ 
     131        layout = QtWidgets.QVBoxLayout() 
     132        tab_widget = QtWidgets.QTableWidget(parent=self) 
     133        # Same behaviour as the original tblParams 
     134        tab_widget.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) 
     135        tab_widget.setAlternatingRowColors(True) 
     136        tab_widget.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows) 
     137        tab_widget.setLayout(layout) 
     138        # Simple naming here. 
     139        # One would think naming the tab with current model name would be good. 
     140        # However, some models have LONG names, which doesn't look well on the tab bar. 
     141        self.tab_number += 1 
     142        tab_name = "Tab " + str(self.tab_number) 
     143        # each table needs separate slots. 
     144        tab_widget.customContextMenuRequested.connect(self.showContextMenu) 
     145        self.tables.append(tab_widget) 
     146        self.tabWidget.addTab(tab_widget, tab_name) 
     147        # Make the new tab active 
     148        self.tabWidget.setCurrentIndex(self.tab_number-1) 
     149 
     150    def addFitResults(self, results): 
     151        """ 
     152        Create a new tab with batch fitting results 
     153        """ 
     154        self.addTabPage() 
     155        # Update the new widget 
     156        # Fill in the table from input data in the last/newest page 
     157        assert(self.tables) 
     158        self.setupTable(widget=self.tables[-1], data=results) 
     159        self.has_data = True 
     160 
     161        # Set a table tooltip describing the model 
     162        model_name = results[0][0].model.id 
     163        self.tabWidget.setTabToolTip(self.tabWidget.count()-1, model_name) 
     164 
     165 
    93166    @classmethod 
    94167    def onHelp(cls): 
     
    97170        """ 
    98171        location = GuiUtils.HELP_DIRECTORY_LOCATION 
    99         url = "/user/sasgui/perspectives/fitting/fitting_help.html#batch-fit-mode" 
     172        url = "/user/qtgui/Perspectives/Fitting/fitting_help.html#batch-fit-mode" 
    100173        try: 
    101174            webbrowser.open('file://' + os.path.realpath(location+url)) 
     
    103176            logging.warning("Cannot display help. %s" % ex) 
    104177 
    105     def plotFits(self): 
     178    def onPlot(self): 
    106179        """ 
    107180        Plot selected fits by sending signal to the parent 
    108181        """ 
    109         rows = [s.row() for s in self.tblParams.selectionModel().selectedRows()] 
    110         data = self.dataFromTable(self.tblParams) 
     182        rows = [s.row() for s in self.currentTable().selectionModel().selectedRows()] 
     183        if not rows: 
     184            msg = "Nothing to plot!" 
     185            self.parent.communicate.statusBarUpdateSignal.emit(msg) 
     186            return 
     187        data = self.dataFromTable(self.currentTable()) 
    111188        # data['Data'] -> ['filename1', 'filename2', ...] 
    112189        # look for the 'Data' column and extract the filename 
     
    141218            tmpfile = tempfile.NamedTemporaryFile(delete=False, mode="w+", suffix=".csv") 
    142219            self.grid_filename = tmpfile.name 
    143             data = self.dataFromTable(self.tblParams) 
     220            data = self.dataFromTable(self.currentTable()) 
    144221            t = time.localtime(time.time()) 
    145222            time_str = time.strftime("%b %d %H:%M of %Y", t) 
     
    181258        if not filename: 
    182259            return 
    183         data = self.dataFromTable(self.tblParams) 
     260        data = self.dataFromTable(self.currentTable()) 
    184261        details = "File generated by SasView\n" 
    185262        with open(filename, 'w') as csv_file: 
     
    190267        Create tablewidget items and show them, based on params 
    191268        """ 
    192         # Clear existing display 
    193         self.tblParams.clear() 
     269        # Is this an empty grid? 
     270        if self.has_data: 
     271            # Add a new page 
     272            self.addTabPage() 
     273            # Access the newly created QTableWidget 
     274            current_page = self.tables[-1] 
     275        else: 
     276            current_page = self.tblParams 
    194277        # headers 
    195278        param_list = csv_data[1].rstrip().split(',') 
     279        # need to remove the 2 header rows to get the total data row number 
     280        rows = len(csv_data) -2 
     281        assert(rows > -1) 
     282        columns = len(param_list) 
     283        current_page.setColumnCount(columns) 
     284        current_page.setRowCount(rows) 
     285 
    196286        for i, param in enumerate(param_list): 
    197             self.tblParams.setHorizontalHeaderItem(i, QtWidgets.QTableWidgetItem(param)) 
     287            current_page.setHorizontalHeaderItem(i, QtWidgets.QTableWidgetItem(param)) 
    198288 
    199289        # first - Chi2 and data filename 
    200290        for i_row, row in enumerate(csv_data[2:]): 
    201291            for i_col, col in enumerate(row.rstrip().split(',')): 
    202                 self.tblParams.setItem(i_row, i_col, QtWidgets.QTableWidgetItem(col)) 
    203  
    204         self.tblParams.resizeColumnsToContents() 
    205  
    206     def setupTable(self, data): 
     292                current_page.setItem(i_row, i_col, QtWidgets.QTableWidgetItem(col)) 
     293 
     294        current_page.resizeColumnsToContents() 
     295 
     296    def setupTable(self, widget=None, data=None): 
    207297        """ 
    208298        Create tablewidget items and show them, based on params 
    209299        """ 
    210         # headers 
     300        # quietly leave is nothing to show 
     301        if data is None or widget is None: 
     302            return 
     303 
     304        # Figure out the headers 
    211305        model = data[0][0] 
     306 
     307        # TODO: add a conditional for magnetic models 
    212308        param_list = [m for m in model.model.params.keys() if ":" not in m] 
    213309 
    214310        # Check if 2D model. If not, remove theta/phi 
     311        if isinstance(model.data.sas_data, Data1D): 
     312            param_list.remove('theta') 
     313            param_list.remove('phi') 
    215314 
    216315        rows = len(data) 
    217316        columns = len(param_list) 
    218         self.tblParams.setColumnCount(columns+2) 
    219         self.tblParams.setRowCount(rows) 
    220  
     317 
     318        widget.setColumnCount(columns+2) # add 2 initial columns defined below 
     319        widget.setRowCount(rows) 
     320 
     321        # Insert two additional columns 
    221322        param_list.insert(0, "Data") 
    222323        param_list.insert(0, "Chi2") 
    223324        for i, param in enumerate(param_list): 
    224             self.tblParams.setHorizontalHeaderItem(i, QtWidgets.QTableWidgetItem(param)) 
    225  
     325            widget.setHorizontalHeaderItem(i, QtWidgets.QTableWidgetItem(param)) 
     326 
     327        # dictionary of parameter errors for post-processing 
     328        # [param_name] = [param_column_nr, error_for_row_1, error_for_row_2,...] 
     329        error_columns = {} 
    226330        # first - Chi2 and data filename 
    227331        for i_row, row in enumerate(data): 
     
    231335            if hasattr(row[0].data, "sas_data"): 
    232336                filename = row[0].data.sas_data.filename 
    233             self.tblParams.setItem(i_row, 0, QtWidgets.QTableWidgetItem(GuiUtils.formatNumber(chi2, high=True))) 
    234             self.tblParams.setItem(i_row, 1, QtWidgets.QTableWidgetItem(str(filename))) 
     337            widget.setItem(i_row, 0, QtWidgets.QTableWidgetItem(GuiUtils.formatNumber(chi2, high=True))) 
     338            widget.setItem(i_row, 1, QtWidgets.QTableWidgetItem(str(filename))) 
    235339            # Now, all the parameters 
    236340            for i_col, param in enumerate(param_list[2:]): 
     
    238342                    # parameter is on the to-optimize list - get the optimized value 
    239343                    par_value = row[0].pvec[row[0].param_list.index(param)] 
    240                     # should we parse out errors here and store them? 
     344                    # parse out errors and store them for later use 
     345                    err_value = row[0].stderr[row[0].param_list.index(param)] 
     346                    if param in error_columns: 
     347                        error_columns[param].append(err_value) 
     348                    else: 
     349                        error_columns[param] = [i_col, err_value] 
    241350                else: 
    242351                    # parameter was not varied 
    243352                    par_value = row[0].model.params[param] 
    244                 self.tblParams.setItem(i_row, i_col+2, QtWidgets.QTableWidgetItem( 
     353 
     354                widget.setItem(i_row, i_col+2, QtWidgets.QTableWidgetItem( 
    245355                    GuiUtils.formatNumber(par_value, high=True))) 
    246356 
    247         self.tblParams.resizeColumnsToContents() 
     357        # Add errors 
     358        error_list = list(error_columns.keys()) 
     359        for error_param in error_list[::-1]: # must be reverse to keep column indices 
     360            # the offset for the err column: +2 from the first two extra columns, +1 to append this column 
     361            error_column = error_columns[error_param][0]+3 
     362            error_values = error_columns[error_param][1:] 
     363            widget.insertColumn(error_column) 
     364 
     365            column_name = error_param + self.ERROR_COLUMN_CAPTION 
     366            widget.setHorizontalHeaderItem(error_column, QtWidgets.QTableWidgetItem(column_name)) 
     367 
     368            for i_row, error in enumerate(error_values): 
     369                item = QtWidgets.QTableWidgetItem(GuiUtils.formatNumber(error, high=True)) 
     370                # Fancy, italic font for errors 
     371                font = QtGui.QFont() 
     372                font.setItalic(True) 
     373                item.setFont(font) 
     374                widget.setItem(i_row, error_column, item) 
     375 
     376        # resize content 
     377        widget.resizeColumnsToContents() 
    248378 
    249379    @classmethod 
  • src/sas/qtgui/Utilities/GuiUtils.py

    r3b3b40b rd4dac80  
    1010import webbrowser 
    1111import urllib.parse 
     12 
     13import numpy as np 
    1214 
    1315warnings.simplefilter("ignore") 
     
    243245    customModelDirectoryChanged = QtCore.pyqtSignal() 
    244246 
     247    # Notify the gui manager about new data to be added to the grid view 
     248    sendDataToGridSignal = QtCore.pyqtSignal(list) 
     249 
     250 
    245251def updateModelItemWithPlot(item, update_data, name=""): 
    246252    """ 
     
    331337    """ 
    332338    assert isinstance(item, QtGui.QStandardItem) 
    333     #assert isinstance(update_data, list) 
    334339 
    335340    # Add the actual Data1D/Data2D object 
     
    463468 
    464469    return info_item 
     470 
     471def dataFromItem(item): 
     472    """ 
     473    Retrieve Data1D/2D component from QStandardItem. 
     474    The assumption - data stored in SasView standard, in child 0 
     475    """ 
     476    return item.child(0).data() 
    465477 
    466478def openLink(url): 
     
    719731    if data.id == 'fit': 
    720732        return 
     733 
     734    # make sure we have some function to operate on 
     735    if xLabel is None: 
     736        xLabel = 'log10(x)' 
     737    if yLabel is None: 
     738        yLabel = 'log10(y)' 
    721739 
    722740    # control axis labels from the panel itself 
     
    805823    return (xLabel, yLabel, xscale, yscale) 
    806824 
    807 def dataFromItem(item): 
    808     """ 
    809     Retrieve Data1D/2D component from QStandardItem. 
    810     The assumption - data stored in SasView standard, in child 0 
    811     """ 
    812     return item.child(0).data() 
    813  
    814825def formatNumber(value, high=False): 
    815826    """ 
     
    920931        input = input.replace(",", "") 
    921932 
     933def checkModel(path): 
     934    """ 
     935    Check that the model save in file 'path' can run. 
     936    """ 
     937    # The following return needs to be removed once 
     938    # the unittest related changes in Sasmodels are commited 
     939    return True 
     940    # try running the model 
     941    from sasmodels.sasview_model import load_custom_model 
     942    Model = load_custom_model(path) 
     943    model = Model() 
     944    q =  np.array([0.01, 0.1]) 
     945    _ = model.evalDistribution(q) 
     946    qx, qy =  np.array([0.01, 0.01]), np.array([0.1, 0.1]) 
     947    _ = model.evalDistribution([qx, qy]) 
     948 
     949    # check the model's unit tests run 
     950    from sasmodels.model_test import run_one 
     951    # TestSuite module in Qt5 now deletes tests in the suite after running, 
     952    # so suite[0] in run_one() in sasmodels/model_test.py will contain [None] and 
     953    # test.info.tests will raise. 
     954    # Not sure how to change the behaviour here, most likely sasmodels will have to 
     955    # be modified 
     956    result = run_one(path) 
     957 
     958    return result 
     959 
    922960 
    923961def enum(*sequential, **named): 
  • src/sas/qtgui/Utilities/LocalConfig.py

    r3b3b40b rd4dac80  
    134134 
    135135# Default threading model 
    136 USING_TWISTED = False 
     136USING_TWISTED = True 
    137137 
    138138# Logging levels to disable, if any 
  • src/sas/qtgui/Utilities/PluginDefinition.py

    r8b480d27 r3b8cc00  
    5858 
    5959        # Validators 
    60         #rx = QtCore.QRegExp(r'^[\w,\s-]+$') 
    61         #rx = QtCore.QRegExp("[a-z-A-Z_]+") 
    6260        rx = QtCore.QRegExp("^[A-Za-z0-9_]*$") 
    6361 
  • src/sas/qtgui/Utilities/PluginManager.py

    r8b480d27 raed0532  
    1919    """ 
    2020    def __init__(self, parent=None): 
    21         super(PluginManager, self).__init__() 
     21        super(PluginManager, self).__init__(parent._parent) 
    2222        self.setupUi(self) 
    2323 
     
    136136        Show the help page in the default browser 
    137137        """ 
    138         location = "/user/sasgui/perspectives/fitting/fitting_help.html#new-plugin-model" 
     138        location = "/user/qtgui/Perspectives/Fitting/fitting_help.html#new-plugin-model" 
    139139        self.parent.showHelp(location) 
    140140                 
  • src/sas/qtgui/Utilities/TabbedModelEditor.py

    r8b480d27 raed0532  
    55import numpy as np 
    66import logging 
     7import traceback 
    78 
    89from PyQt5 import QtWidgets 
     
    1011from sas.sascalc.fit import models 
    1112 
     13import sas.qtgui.Utilities.GuiUtils as GuiUtils 
    1214from sas.qtgui.Utilities.UI.TabbedModelEditor import Ui_TabbedModelEditor 
    1315from sas.qtgui.Utilities.PluginDefinition import PluginDefinition 
     
    2224    # Signals for intertab communication plugin -> editor 
    2325    def __init__(self, parent=None, edit_only=False): 
    24         super(TabbedModelEditor, self).__init__() 
     26        super(TabbedModelEditor, self).__init__(parent._parent) 
    2527 
    2628        self.parent = parent 
     
    3335        self.edit_only = edit_only 
    3436        self.is_modified = False 
     37        self.label = None 
    3538 
    3639        self.addWidgets() 
     
    7578        # signals from tabs 
    7679        self.editor_widget.modelModified.connect(self.editorModelModified) 
    77         self.plugin_widget.modelModified.connect(self.pluginModelModified) 
     80        self.plugin_widget.txtName.editingFinished.connect(self.pluginTitleSet) 
    7881 
    7982    def setPluginActive(self, is_active=True): 
     
    124127        self.editor_widget.setEnabled(True) 
    125128        self.editor_widget.blockSignals(False) 
    126         self.filename, _ = os.path.splitext(os.path.basename(filename)) 
    127  
    128         self.setWindowTitle(self.window_title + " - " + self.filename) 
     129        self.filename = filename 
     130        display_name, _ = os.path.splitext(os.path.basename(filename)) 
     131 
     132        self.setWindowTitle(self.window_title + " - " + display_name) 
    129133 
    130134    def onModifiedExit(self): 
     
    169173        self.is_modified = True 
    170174 
    171     def pluginModelModified(self): 
    172         """ 
    173         User modified the model in the Plugin Editor. 
    174         Show that the model is changed. 
     175    def pluginTitleSet(self): 
     176        """ 
     177        User modified the model name. 
     178        Display the model name in the window title 
     179        and allow for model save. 
    175180        """ 
    176181        # Ensure plugin name is non-empty 
     
    179184            self.setWindowTitle(self.window_title + " - " + model['filename']) 
    180185            self.setTabEdited(True) 
    181             # Enable editor 
    182             self.editor_widget.setEnabled(True) 
    183186            self.buttonBox.button(QtWidgets.QDialogButtonBox.Apply).setEnabled(True) 
    184187            self.is_modified = True 
    185188        else: 
     189            # the model name is empty - disable Apply and clear the editor 
    186190            self.buttonBox.button(QtWidgets.QDialogButtonBox.Apply).setEnabled(False) 
     191            self.editor_widget.blockSignals(True) 
     192            self.editor_widget.txtEditor.setPlainText('') 
     193            self.editor_widget.blockSignals(False) 
     194            self.editor_widget.setEnabled(False) 
    187195 
    188196    def setTabEdited(self, is_edited): 
     
    228236        model_str = self.generateModel(model, full_path) 
    229237        self.writeFile(full_path, model_str) 
    230         # TODO: 
    231         # Temporarily disable model check - 
    232         # unittest.suite() gives weird results in qt5. 
    233         # needs investigating 
    234         #try: 
    235         #    _, msg = self.checkModel(full_path), None 
    236         #except Exception as ex: 
    237         #    result, msg = None, "Error building model: "+ str(ex) 
     238 
     239        # test the model 
     240 
     241        # Run the model test in sasmodels 
     242        try: 
     243            model_results = self.checkModel(full_path) 
     244            logging.info(model_results) 
     245        except Exception as ex: 
     246            msg = "Error building model: "+ str(ex) 
     247            logging.error(msg) 
     248            #print three last lines of the stack trace 
     249            # this will point out the exact line failing 
     250            last_lines = traceback.format_exc().split('\n')[-4:] 
     251            traceback_to_show = '\n'.join(last_lines) 
     252            logging.error(traceback_to_show) 
     253 
     254            self.parent.communicate.statusBarUpdateSignal.emit("Model check failed") 
     255            return 
     256 
     257        self.editor_widget.setEnabled(True) 
    238258 
    239259        # Update the editor here. 
     
    248268        # Notify listeners 
    249269        self.parent.communicate.customModelDirectoryChanged.emit() 
     270 
     271        # Notify the user 
     272        msg = "Custom model "+filename + " successfully created." 
     273        self.parent.communicate.statusBarUpdateSignal.emit(msg) 
     274        logging.info(msg) 
    250275 
    251276    def updateFromEditor(self): 
     
    261286        # Update the tab title 
    262287        self.setTabEdited(False) 
    263          
     288        # notify the user 
     289        msg = self.filename + " successfully saved." 
     290        self.parent.communicate.statusBarUpdateSignal.emit(msg) 
     291        logging.info(msg) 
     292 
    264293    def canWriteModel(self, model=None, full_path=""): 
    265294        """ 
     
    300329        documentation tree (after /doc/ ....". 
    301330        """ 
    302         location = "/user/sasgui/perspectives/fitting/plugin.html" 
     331        location = "/user/qtgui/Perspectives/Fitting/plugin.html" 
    303332        self.parent.showHelp(location) 
    304333 
     
    380409 
    381410    @classmethod 
    382     def checkModel(cls, path): 
    383         """ 
    384         Check that the model save in file 'path' can run. 
    385         """ 
    386         # try running the model 
    387         from sasmodels.sasview_model import load_custom_model 
    388         Model = load_custom_model(path) 
    389         model = Model() 
    390         q =  np.array([0.01, 0.1]) 
    391         _ = model.evalDistribution(q) 
    392         qx, qy =  np.array([0.01, 0.01]), np.array([0.1, 0.1]) 
    393         _ = model.evalDistribution([qx, qy]) 
    394  
    395         # check the model's unit tests run 
    396         from sasmodels.model_test import run_one 
    397         result = run_one(path) 
    398  
    399         return result 
    400  
    401     @classmethod 
    402411    def getParamHelper(cls, param_str): 
    403412        """ 
  • src/sas/qtgui/Utilities/UI/GridPanelUI.ui

    r3b3b40b rd4dac80  
    88    <y>0</y> 
    99    <width>939</width> 
    10     <height>329</height> 
     10    <height>330</height> 
    1111   </rect> 
    1212  </property> 
     
    2121  </property> 
    2222  <widget class="QWidget" name="centralwidget"> 
    23    <layout class="QGridLayout" name="gridLayout"> 
     23   <layout class="QGridLayout" name="gridLayout_2"> 
     24    <item row="0" column="0"> 
     25     <widget class="QTabWidget" name="tabWidget"> 
     26      <property name="tabPosition"> 
     27       <enum>QTabWidget::South</enum> 
     28      </property> 
     29      <property name="currentIndex"> 
     30       <number>0</number> 
     31      </property> 
     32      <widget class="QWidget" name="tab"> 
     33       <attribute name="title"> 
     34        <string>Tab 1</string> 
     35       </attribute> 
     36       <layout class="QGridLayout" name="gridLayout"> 
     37        <item row="0" column="0"> 
     38         <widget class="QTableWidget" name="tblParams"> 
     39          <property name="contextMenuPolicy"> 
     40           <enum>Qt::CustomContextMenu</enum> 
     41          </property> 
     42          <property name="alternatingRowColors"> 
     43           <bool>true</bool> 
     44          </property> 
     45          <property name="selectionBehavior"> 
     46           <enum>QAbstractItemView::SelectRows</enum> 
     47          </property> 
     48         </widget> 
     49        </item> 
     50       </layout> 
     51      </widget> 
     52     </widget> 
     53    </item> 
    2454    <item row="1" column="0"> 
    2555     <layout class="QHBoxLayout" name="horizontalLayout"> 
     
    3666        </property> 
    3767       </spacer> 
     68      </item> 
     69      <item> 
     70       <widget class="QPushButton" name="cmdPlot"> 
     71        <property name="text"> 
     72         <string>Plot</string> 
     73        </property> 
     74       </widget> 
    3875      </item> 
    3976      <item> 
     
    5390     </layout> 
    5491    </item> 
    55     <item row="0" column="0"> 
    56      <widget class="QTableWidget" name="tblParams"> 
    57       <property name="contextMenuPolicy"> 
    58        <enum>Qt::CustomContextMenu</enum> 
    59       </property> 
    60       <property name="alternatingRowColors"> 
    61        <bool>true</bool> 
    62       </property> 
    63       <property name="selectionBehavior"> 
    64        <enum>QAbstractItemView::SelectRows</enum> 
    65       </property> 
    66      </widget> 
    67     </item> 
    6892   </layout> 
    6993  </widget> 
     
    7397     <x>0</x> 
    7498     <y>0</y> 
    75      <width>939</width> 
     99     <width>510</width> 
    76100     <height>26</height> 
    77101    </rect> 
  • src/sas/qtgui/Utilities/UnitTesting/GridPanelTest.py

    r3b3b40b r80468f6  
    1616 
    1717from sas.sascalc.fit.AbstractFitEngine import FResult 
     18from sas.sascalc.fit.AbstractFitEngine import FitData1D 
    1819from sasmodels.sasview_model import load_standard_models 
    1920from sas.qtgui.Plotting.PlotterData import Data1D 
     
    3233        # dummy perspective 
    3334        class dummy_manager(object): 
     35            _parent = QtWidgets.QWidget() 
    3436            def communicator(self): 
    3537                return GuiUtils.Communicate() 
     
    5658        self.assertIsNotNone(m) 
    5759        data = Data1D(x=[1,2], y=[3,4], dx=[0.1, 0.1], dy=[0.,0.]) 
     60        fit_data = FitData1D(x=[1,2], y=[3,4], data=data) 
    5861        param_list = ['sld_shell', 'sld_solvent'] 
    59         output = FResult(model=model, data=data, param_list=param_list) 
     62        output = FResult(model=model, data=fit_data, param_list=param_list) 
     63        output.sas_data = data 
    6064        output.theory = np.array([0.1,0.2]) 
    6165        output.pvec = np.array([0.1, 0.02]) 
     
    6367        output.fitness = 9000.0 
    6468        output.fitter_id = 200 
     69        output.stderr = [0.001, 0.001] 
    6570        output_data = [[output],[output]] 
    6671        return output_data 
     
    7075        self.assertIsInstance(self.widget, QtWidgets.QMainWindow) 
    7176        # Default title 
    72         self.assertEqual(self.widget.windowTitle(), "Grid Panel") 
     77        self.assertEqual(self.widget.windowTitle(), "Batch Fitting Results") 
    7378 
    7479        # non-modal window 
  • src/sas/qtgui/Utilities/UnitTesting/PluginDefinitionTest.py

    • Property mode changed from 100755 to 100644
    r3b3b40b r80468f6  
    1616from sas.qtgui.Utilities.PythonSyntax import PythonHighlighter 
    1717 
    18 #if not QApplication.instance(): 
    19 #    app = QApplication(sys.argv) 
    20 app = QApplication(sys.argv) 
     18if not QApplication.instance(): 
     19    app = QApplication(sys.argv) 
    2120 
    2221class PluginDefinitionTest(unittest.TestCase): 
  • src/sas/qtgui/Utilities/UnitTesting/TabbedModelEditorTest.py

    • Property mode changed from 100755 to 100644
    r3b3b40b r80468f6  
    1616 
    1717# Local 
     18import sas.qtgui.Utilities.GuiUtils as GuiUtils 
    1819from sas.qtgui.Utilities.TabbedModelEditor import TabbedModelEditor 
    1920from sas.qtgui.Utilities.PluginDefinition import PluginDefinition 
     
    2122 
    2223 
    23 #if not QApplication.instance(): 
    24 #    app = QApplication(sys.argv) 
    25 app = QApplication(sys.argv) 
     24if not QApplication.instance(): 
     25    app = QApplication(sys.argv) 
    2626 
    2727class TabbedModelEditorTest(unittest.TestCase): 
     
    3030        Prepare the editors 
    3131        """ 
    32         self.widget = TabbedModelEditor(None) 
    33         self.widget_edit = TabbedModelEditor(None, edit_only=True) 
     32        class dummy_manager(object): 
     33            _parent = QWidget() 
     34            communicate = GuiUtils.Communicate() 
     35 
     36        self.widget = TabbedModelEditor(parent=dummy_manager) 
     37        self.widget_edit = TabbedModelEditor(parent=dummy_manager, edit_only=True) 
    3438 
    3539    def tearDown(self): 
     
    139143 
    140144 
    141     def testPluginModelModified(self): 
     145    def testpluginTitleSet(self): 
    142146        """Test reaction to direct edit in plugin wizard""" 
    143147        self.assertFalse(self.widget.is_modified) 
    144148 
    145149        # Call the tested method with no filename defined 
    146         self.widget.pluginModelModified() 
     150        self.widget.pluginTitleSet() 
    147151 
    148152        # Assure the apply button is disabled 
     
    157161        self.assertIn("*", self.widget.windowTitle()) 
    158162        self.assertIn(new_name, self.widget.windowTitle()) 
    159         self.assertTrue(self.widget.editor_widget.isEnabled()) 
    160163        self.assertTrue(self.widget.buttonBox.button(QDialogButtonBox.Apply).isEnabled()) 
    161164        self.assertTrue(self.widget.is_modified) 
Note: See TracChangeset for help on using the changeset viewer.