Changeset 3c6ecd9 in sasview for src/sas/qtgui/Utilities
- Timestamp:
- May 7, 2018 6:47:21 AM (7 years ago)
- 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. - Location:
- src/sas/qtgui/Utilities
- Files:
-
- 3 added
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
src/sas/qtgui/Utilities/GridPanel.py
r5a5e371 r3c6ecd9 1 1 import os 2 import sys 2 3 import time 3 4 import logging 4 5 import webbrowser 5 6 6 from PyQt5 import QtCore, QtWidgets 7 from PyQt5 import QtCore, QtWidgets, QtGui 7 8 8 9 import sas.qtgui.Utilities.GuiUtils as GuiUtils 9 10 from sas.qtgui.Plotting.PlotterData import Data1D 10 11 from sas.qtgui.Utilities.UI.GridPanelUI import Ui_GridPanelUI 11 12 … … 15 16 Class for stateless grid-like printout of model parameters for mutiple models 16 17 """ 18 ERROR_COLUMN_CAPTION = " (Err)" 19 IS_WIN = (sys.platform == 'win32') 17 20 def __init__(self, parent = None, output_data=None): 18 21 19 super(BatchOutputPanel, self).__init__( )22 super(BatchOutputPanel, self).__init__(parent._parent) 20 23 self.setupUi(self) 21 24 22 self.data = output_data23 25 self.parent = parent 24 26 if hasattr(self.parent, "communicate"): … … 30 32 self.grid_filename = "" 31 33 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 32 46 # context menu on the table 33 47 self.tblParams.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) 34 48 self.tblParams.customContextMenuRequested.connect(self.showContextMenu) 35 49 36 # Fill in the table from input data37 self.setupTable(output_data)38 39 50 # Command buttons 40 51 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() 41 68 42 69 def addToolbarActions(self): … … 64 91 65 92 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()] 66 100 67 101 def showContextMenu(self, position): … … 70 104 """ 71 105 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()] 73 107 num_rows = len(rows) 74 108 if num_rows <= 0: … … 84 118 85 119 # Define the callbacks 86 self.actionPlotResults.triggered.connect(self. plotFits)120 self.actionPlotResults.triggered.connect(self.onPlot) 87 121 try: 88 menu.exec_(self. tblParams.viewport().mapToGlobal(position))122 menu.exec_(self.currentTable().viewport().mapToGlobal(position)) 89 123 except AttributeError as ex: 90 124 logging.error("Error generating context menu: %s" % ex) 91 125 return 92 126 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 93 166 @classmethod 94 167 def onHelp(cls): … … 97 170 """ 98 171 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" 100 173 try: 101 174 webbrowser.open('file://' + os.path.realpath(location+url)) … … 103 176 logging.warning("Cannot display help. %s" % ex) 104 177 105 def plotFits(self):178 def onPlot(self): 106 179 """ 107 180 Plot selected fits by sending signal to the parent 108 181 """ 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()) 111 188 # data['Data'] -> ['filename1', 'filename2', ...] 112 189 # look for the 'Data' column and extract the filename … … 141 218 tmpfile = tempfile.NamedTemporaryFile(delete=False, mode="w+", suffix=".csv") 142 219 self.grid_filename = tmpfile.name 143 data = self.dataFromTable(self. tblParams)220 data = self.dataFromTable(self.currentTable()) 144 221 t = time.localtime(time.time()) 145 222 time_str = time.strftime("%b %d %H:%M of %Y", t) … … 181 258 if not filename: 182 259 return 183 data = self.dataFromTable(self. tblParams)260 data = self.dataFromTable(self.currentTable()) 184 261 details = "File generated by SasView\n" 185 262 with open(filename, 'w') as csv_file: … … 190 267 Create tablewidget items and show them, based on params 191 268 """ 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 194 277 # headers 195 278 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 196 286 for i, param in enumerate(param_list): 197 self.tblParams.setHorizontalHeaderItem(i, QtWidgets.QTableWidgetItem(param))287 current_page.setHorizontalHeaderItem(i, QtWidgets.QTableWidgetItem(param)) 198 288 199 289 # first - Chi2 and data filename 200 290 for i_row, row in enumerate(csv_data[2:]): 201 291 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): 207 297 """ 208 298 Create tablewidget items and show them, based on params 209 299 """ 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 211 305 model = data[0][0] 306 307 # TODO: add a conditional for magnetic models 212 308 param_list = [m for m in model.model.params.keys() if ":" not in m] 213 309 214 310 # 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') 215 314 216 315 rows = len(data) 217 316 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 221 322 param_list.insert(0, "Data") 222 323 param_list.insert(0, "Chi2") 223 324 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 = {} 226 330 # first - Chi2 and data filename 227 331 for i_row, row in enumerate(data): … … 231 335 if hasattr(row[0].data, "sas_data"): 232 336 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))) 235 339 # Now, all the parameters 236 340 for i_col, param in enumerate(param_list[2:]): … … 238 342 # parameter is on the to-optimize list - get the optimized value 239 343 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] 241 350 else: 242 351 # parameter was not varied 243 352 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( 245 355 GuiUtils.formatNumber(par_value, high=True))) 246 356 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() 248 378 249 379 @classmethod -
src/sas/qtgui/Utilities/GuiUtils.py
r3b3b40b rd4dac80 10 10 import webbrowser 11 11 import urllib.parse 12 13 import numpy as np 12 14 13 15 warnings.simplefilter("ignore") … … 243 245 customModelDirectoryChanged = QtCore.pyqtSignal() 244 246 247 # Notify the gui manager about new data to be added to the grid view 248 sendDataToGridSignal = QtCore.pyqtSignal(list) 249 250 245 251 def updateModelItemWithPlot(item, update_data, name=""): 246 252 """ … … 331 337 """ 332 338 assert isinstance(item, QtGui.QStandardItem) 333 #assert isinstance(update_data, list)334 339 335 340 # Add the actual Data1D/Data2D object … … 463 468 464 469 return info_item 470 471 def 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() 465 477 466 478 def openLink(url): … … 719 731 if data.id == 'fit': 720 732 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)' 721 739 722 740 # control axis labels from the panel itself … … 805 823 return (xLabel, yLabel, xscale, yscale) 806 824 807 def dataFromItem(item):808 """809 Retrieve Data1D/2D component from QStandardItem.810 The assumption - data stored in SasView standard, in child 0811 """812 return item.child(0).data()813 814 825 def formatNumber(value, high=False): 815 826 """ … … 920 931 input = input.replace(",", "") 921 932 933 def 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 922 960 923 961 def enum(*sequential, **named): -
src/sas/qtgui/Utilities/LocalConfig.py
r3b3b40b rd4dac80 134 134 135 135 # Default threading model 136 USING_TWISTED = False136 USING_TWISTED = True 137 137 138 138 # Logging levels to disable, if any -
src/sas/qtgui/Utilities/PluginDefinition.py
r8b480d27 r3b8cc00 58 58 59 59 # Validators 60 #rx = QtCore.QRegExp(r'^[\w,\s-]+$')61 #rx = QtCore.QRegExp("[a-z-A-Z_]+")62 60 rx = QtCore.QRegExp("^[A-Za-z0-9_]*$") 63 61 -
src/sas/qtgui/Utilities/PluginManager.py
r8b480d27 raed0532 19 19 """ 20 20 def __init__(self, parent=None): 21 super(PluginManager, self).__init__( )21 super(PluginManager, self).__init__(parent._parent) 22 22 self.setupUi(self) 23 23 … … 136 136 Show the help page in the default browser 137 137 """ 138 location = "/user/ sasgui/perspectives/fitting/fitting_help.html#new-plugin-model"138 location = "/user/qtgui/Perspectives/Fitting/fitting_help.html#new-plugin-model" 139 139 self.parent.showHelp(location) 140 140 -
src/sas/qtgui/Utilities/TabbedModelEditor.py
r8b480d27 raed0532 5 5 import numpy as np 6 6 import logging 7 import traceback 7 8 8 9 from PyQt5 import QtWidgets … … 10 11 from sas.sascalc.fit import models 11 12 13 import sas.qtgui.Utilities.GuiUtils as GuiUtils 12 14 from sas.qtgui.Utilities.UI.TabbedModelEditor import Ui_TabbedModelEditor 13 15 from sas.qtgui.Utilities.PluginDefinition import PluginDefinition … … 22 24 # Signals for intertab communication plugin -> editor 23 25 def __init__(self, parent=None, edit_only=False): 24 super(TabbedModelEditor, self).__init__( )26 super(TabbedModelEditor, self).__init__(parent._parent) 25 27 26 28 self.parent = parent … … 33 35 self.edit_only = edit_only 34 36 self.is_modified = False 37 self.label = None 35 38 36 39 self.addWidgets() … … 75 78 # signals from tabs 76 79 self.editor_widget.modelModified.connect(self.editorModelModified) 77 self.plugin_widget. modelModified.connect(self.pluginModelModified)80 self.plugin_widget.txtName.editingFinished.connect(self.pluginTitleSet) 78 81 79 82 def setPluginActive(self, is_active=True): … … 124 127 self.editor_widget.setEnabled(True) 125 128 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) 129 133 130 134 def onModifiedExit(self): … … 169 173 self.is_modified = True 170 174 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. 175 180 """ 176 181 # Ensure plugin name is non-empty … … 179 184 self.setWindowTitle(self.window_title + " - " + model['filename']) 180 185 self.setTabEdited(True) 181 # Enable editor182 self.editor_widget.setEnabled(True)183 186 self.buttonBox.button(QtWidgets.QDialogButtonBox.Apply).setEnabled(True) 184 187 self.is_modified = True 185 188 else: 189 # the model name is empty - disable Apply and clear the editor 186 190 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) 187 195 188 196 def setTabEdited(self, is_edited): … … 228 236 model_str = self.generateModel(model, full_path) 229 237 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) 238 258 239 259 # Update the editor here. … … 248 268 # Notify listeners 249 269 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) 250 275 251 276 def updateFromEditor(self): … … 261 286 # Update the tab title 262 287 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 264 293 def canWriteModel(self, model=None, full_path=""): 265 294 """ … … 300 329 documentation tree (after /doc/ ....". 301 330 """ 302 location = "/user/ sasgui/perspectives/fitting/plugin.html"331 location = "/user/qtgui/Perspectives/Fitting/plugin.html" 303 332 self.parent.showHelp(location) 304 333 … … 380 409 381 410 @classmethod 382 def checkModel(cls, path):383 """384 Check that the model save in file 'path' can run.385 """386 # try running the model387 from sasmodels.sasview_model import load_custom_model388 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 run396 from sasmodels.model_test import run_one397 result = run_one(path)398 399 return result400 401 @classmethod402 411 def getParamHelper(cls, param_str): 403 412 """ -
src/sas/qtgui/Utilities/UI/GridPanelUI.ui
r3b3b40b rd4dac80 8 8 <y>0</y> 9 9 <width>939</width> 10 <height>3 29</height>10 <height>330</height> 11 11 </rect> 12 12 </property> … … 21 21 </property> 22 22 <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> 24 54 <item row="1" column="0"> 25 55 <layout class="QHBoxLayout" name="horizontalLayout"> … … 36 66 </property> 37 67 </spacer> 68 </item> 69 <item> 70 <widget class="QPushButton" name="cmdPlot"> 71 <property name="text"> 72 <string>Plot</string> 73 </property> 74 </widget> 38 75 </item> 39 76 <item> … … 53 90 </layout> 54 91 </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>68 92 </layout> 69 93 </widget> … … 73 97 <x>0</x> 74 98 <y>0</y> 75 <width> 939</width>99 <width>510</width> 76 100 <height>26</height> 77 101 </rect> -
src/sas/qtgui/Utilities/UnitTesting/GridPanelTest.py
r3b3b40b r80468f6 16 16 17 17 from sas.sascalc.fit.AbstractFitEngine import FResult 18 from sas.sascalc.fit.AbstractFitEngine import FitData1D 18 19 from sasmodels.sasview_model import load_standard_models 19 20 from sas.qtgui.Plotting.PlotterData import Data1D … … 32 33 # dummy perspective 33 34 class dummy_manager(object): 35 _parent = QtWidgets.QWidget() 34 36 def communicator(self): 35 37 return GuiUtils.Communicate() … … 56 58 self.assertIsNotNone(m) 57 59 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) 58 61 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 60 64 output.theory = np.array([0.1,0.2]) 61 65 output.pvec = np.array([0.1, 0.02]) … … 63 67 output.fitness = 9000.0 64 68 output.fitter_id = 200 69 output.stderr = [0.001, 0.001] 65 70 output_data = [[output],[output]] 66 71 return output_data … … 70 75 self.assertIsInstance(self.widget, QtWidgets.QMainWindow) 71 76 # Default title 72 self.assertEqual(self.widget.windowTitle(), " Grid Panel")77 self.assertEqual(self.widget.windowTitle(), "Batch Fitting Results") 73 78 74 79 # non-modal window -
src/sas/qtgui/Utilities/UnitTesting/PluginDefinitionTest.py
- Property mode changed from 100755 to 100644
r3b3b40b r80468f6 16 16 from sas.qtgui.Utilities.PythonSyntax import PythonHighlighter 17 17 18 #if not QApplication.instance(): 19 # app = QApplication(sys.argv) 20 app = QApplication(sys.argv) 18 if not QApplication.instance(): 19 app = QApplication(sys.argv) 21 20 22 21 class PluginDefinitionTest(unittest.TestCase): -
src/sas/qtgui/Utilities/UnitTesting/TabbedModelEditorTest.py
- Property mode changed from 100755 to 100644
r3b3b40b r80468f6 16 16 17 17 # Local 18 import sas.qtgui.Utilities.GuiUtils as GuiUtils 18 19 from sas.qtgui.Utilities.TabbedModelEditor import TabbedModelEditor 19 20 from sas.qtgui.Utilities.PluginDefinition import PluginDefinition … … 21 22 22 23 23 #if not QApplication.instance(): 24 # app = QApplication(sys.argv) 25 app = QApplication(sys.argv) 24 if not QApplication.instance(): 25 app = QApplication(sys.argv) 26 26 27 27 class TabbedModelEditorTest(unittest.TestCase): … … 30 30 Prepare the editors 31 31 """ 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) 34 38 35 39 def tearDown(self): … … 139 143 140 144 141 def test PluginModelModified(self):145 def testpluginTitleSet(self): 142 146 """Test reaction to direct edit in plugin wizard""" 143 147 self.assertFalse(self.widget.is_modified) 144 148 145 149 # Call the tested method with no filename defined 146 self.widget.plugin ModelModified()150 self.widget.pluginTitleSet() 147 151 148 152 # Assure the apply button is disabled … … 157 161 self.assertIn("*", self.widget.windowTitle()) 158 162 self.assertIn(new_name, self.widget.windowTitle()) 159 self.assertTrue(self.widget.editor_widget.isEnabled())160 163 self.assertTrue(self.widget.buttonBox.button(QDialogButtonBox.Apply).isEnabled()) 161 164 self.assertTrue(self.widget.is_modified)
Note: See TracChangeset
for help on using the changeset viewer.