Changeset 5032ea68 in sasview for src/sas/qtgui/DataExplorer.py


Ignore:
Timestamp:
Jun 14, 2016 2:51:18 AM (8 years ago)
Author:
Piotr Rozyczko <piotr.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:
a281ab8
Parents:
488c49d
Message:

threaded file load, data object related fixes, more unit tests.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/sas/qtgui/DataExplorer.py

    r488c49d r5032ea68  
    5252        self.treeView.setModel(self.proxy) 
    5353 
    54     def loadFile(self, event): 
     54 
     55    def loadFile(self, event=None): 
    5556        """ 
    5657        Called when the "Load" button pressed. 
     
    6465        self.communicate.fileReadSignal.emit(path_str) 
    6566 
    66         # Read in the data from chosen file(s) 
    67         self.readData(path_str) 
     67        # threaded file load 
     68        load_thread = threads.deferToThread(self.readData, path_str) 
     69        load_thread.addCallback(self.loadComplete) 
    6870 
    6971        return 
    7072 
     73    def loadFolder(self, event=None): 
     74        """ 
     75        Called when the "File/Load Folder" menu item chosen. 
     76        Opens the Qt "Open Folder..." dialog  
     77        """ 
     78        dir = QtGui.QFileDialog.getExistingDirectory(self, "Choose a directory", "", 
     79              QtGui.QFileDialog.ShowDirsOnly) 
     80        if dir is None: 
     81            return 
     82 
     83        dir = str(dir) 
     84 
     85        if not os.path.isdir(dir): 
     86            return 
     87 
     88        # get content of dir into a list 
     89        path_str = [os.path.join(os.path.abspath(dir), filename) for filename in os.listdir(dir)] 
     90 
     91        # threaded file load 
     92        load_thread = threads.deferToThread(self.readData, path_str) 
     93        load_thread.addCallback(self.loadComplete) 
     94         
     95        return 
     96 
    7197    def deleteFile(self, event): 
    7298        """ 
    73         """ 
     99        Delete selected rows from the model 
     100        """ 
     101        # Assure this is indeed wanted 
     102        delete_msg = "This operation will delete the checked data sets and all the dependents." +\ 
     103                     "\nDo you want to continue?" 
     104        reply = QtGui.QMessageBox.question(self, 'Warning', delete_msg, 
     105                QtGui.QMessageBox.Yes, QtGui.QMessageBox.No) 
     106 
     107        if reply == QtGui.QMessageBox.No: 
     108            return 
     109 
    74110        # Figure out which rows are checked 
    75  
    76         # Delete these rows from the model 
    77  
    78         # Call data_manager update with delete_data() 
    79  
     111        ind = -1 
     112        # Use 'while' so the row count is forced at every iteration 
     113        while ind < self.model.rowCount(): 
     114            ind += 1 
     115            item = self.model.item(ind) 
     116            if item and item.isCheckable() and item.checkState() == QtCore.Qt.Checked: 
     117                # Delete these rows from the model 
     118                self.model.removeRow(ind) 
     119                # Decrement index since we just deleted it 
     120                ind -= 1 
     121 
     122        # pass temporarily kept as a breakpoint anchor 
    80123        pass 
    81124 
    82125    def sendData(self, event): 
    83126        """ 
    84         """ 
     127        Send selected item data to the current perspective and set the relevant notifiers 
     128        """ 
     129        # should this reside on GuiManager or here? 
     130        self._perspective = self.parent.perspective() 
     131 
     132        # Set the signal handlers 
     133        self.communicator = self._perspective.communicator() 
     134        self.communicator.updateModelFromPerspectiveSignal.connect(self.updateModelFromPerspective) 
     135 
    85136        # Figure out which rows are checked 
    86  
     137        selected_items = [] 
     138        for index in range(self.model.rowCount()): 
     139            item = self.model.item(index) 
     140            if item.isCheckable() and item.checkState() == QtCore.Qt.Checked: 
     141                selected_items.append(item) 
     142 
     143        # Which perspective has been selected? 
     144        if len(selected_items) > 1 and not self._perspective.allowBatch(): 
     145            msg = self._perspective.title() + " does not allow multiple data." 
     146            msgbox = QtGui.QMessageBox() 
     147            msgbox.setIcon(QtGui.QMessageBox.Critical) 
     148            msgbox.setText(msg) 
     149            msgbox.setStandardButtons(QtGui.QMessageBox.Ok) 
     150            retval = msgbox.exec_() 
     151            return 
    87152        # Dig up data from model 
    88         # To get the original Data1D object back use: 
    89         # object_item.data().toPyObject() 
    90  
    91  
    92         # Which perspective has been selected? 
    93  
     153        data = [selected_items[0].child(0).data().toPyObject()] 
     154 
     155        # TODO 
    94156        # New plot or appended? 
    95157 
    96158        # Notify the GuiManager about the send request 
    97         # updatePerspectiveWithDataSignal() 
    98         pass 
     159        self._perspective.setData(data_list=data) 
     160 
    99161 
    100162    def chooseFiles(self): 
    101163        """ 
     164        Shows the Open file dialog and returns the chosen path(s) 
    102165        """ 
    103166        # List of known extensions 
     
    105168 
    106169        # Location is automatically saved - no need to keep track of the last dir 
    107         # TODO: is it really? 
    108         paths = QtGui.QFileDialog.getOpenFileName(self, "Choose a file", "", wlist) 
     170        # But only with Qt built-in dialog (non-platform native) 
     171        paths = QtGui.QFileDialog.getOpenFileName(self, "Choose a file", "", 
     172                wlist, None, QtGui.QFileDialog.DontUseNativeDialog) 
    109173        if paths is None: 
    110174            return 
     
    132196        data_error = False 
    133197        error_message = "" 
     198         
    134199        for p_file in path: 
    135200            info = "info" 
     
    147212 
    148213            try: 
    149                 message = "Loading Data... " + str(p_file) + "\n" 
     214                message = "Loading Data... " + str(basename) + "\n" 
    150215 
    151216                # change this to signal notification in GuiManager 
    152217                self.communicate.statusBarUpdateSignal.emit(message) 
    153  
    154                 # threaded file load 
    155                 # load_thread = threads.deferToThread(self.loadThread, p_file) 
    156                 # Add deferred callback for call return 
    157                 # load_thread.addCallback(self.plotResult) 
    158218 
    159219                output_objects = self.loader.load(p_file) 
     
    170230                    output[new_data.id] = new_data 
    171231                    self.updateModel(new_data, p_file) 
     232                    self.model.reset() 
     233 
     234                    QtGui.qApp.processEvents() 
    172235 
    173236                    if hasattr(item, 'errors'): 
     
    176239                            message += "\tError: {0}\n".format(error_data) 
    177240                    else: 
     241 
    178242                        logging.error("Loader returned an invalid object:\n %s" % str(item)) 
    179243                        data_error = True 
    180244 
    181             except: 
     245            except Exception as ex: 
    182246                logging.error(sys.exc_value) 
     247 
    183248                any_error = True 
    184249            if any_error or error_message != "": 
     
    207272            message = "Loading Data Complete! " 
    208273        message += log_msg 
    209         self.loadComplete(output=output, message=message) 
     274        return (output, message) 
    210275 
    211276    def getWlist(self): 
     
    314379        Post message to status bar and update the data manager 
    315380        """ 
     381        self.model.reset() 
    316382        # Notify the manager of the new data available 
    317383        self.communicate.statusBarUpdateSignal.emit(message) 
    318384        self.communicate.fileDataReceivedSignal.emit(output) 
    319  
    320385        self.manager.add_data(data_list=output) 
    321386 
     
    362427        self.proxy.setFilterRegExp(r"[^()]") 
    363428 
     429    def updateModelFromPerspective(self, model_item): 
     430        """ 
     431        """ 
     432        # Overwrite the index with what we got from the perspective 
     433        if type(model_item) != QtGui.QStandardItem: 
     434            msg = "Wrong data type returned from calculations." 
     435            raise AttributeError, msg 
     436        # self.model.insertRow(model_item) 
     437        # Reset the view 
     438        self.model.reset() 
     439        # Pass acting as a debugger anchor 
     440        pass 
    364441 
    365442    def addExtraRows(self, info_item, data): 
    366443        """ 
     444        Extract relevant data to include in the Info ModelItem 
    367445        """ 
    368446        title_item   = QtGui.QStandardItem("Title: "      + data.title) 
Note: See TracChangeset for help on using the changeset viewer.