Changeset 481ff26 in sasview for src/sas/qtgui/DataExplorer.py


Ignore:
Timestamp:
Jul 4, 2016 5:32:49 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:
f0f309d
Parents:
f82ab8c
Message:

Modified Data Explorer slightly

File:
1 edited

Legend:

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

    rf82ab8c r481ff26  
    77from PyQt4 import QtGui 
    88from PyQt4 import QtWebKit 
     9from PyQt4.Qt import QMutex 
     10 
    911from twisted.internet import threads 
    1012 
     
    3840        self.loader = Loader() 
    3941        self.manager = DataManager() 
     42 
     43        # Be careful with twisted threads. 
     44        self.mutex = QMutex() 
    4045 
    4146        # Connect the buttons 
     
    4651        self.cmdSendTo.clicked.connect(self.sendData) 
    4752        self.cmdNew.clicked.connect(self.newPlot) 
     53        self.cmdHelp.clicked.connect(self.displayHelp) 
     54        self.cmdHelp_2.clicked.connect(self.displayHelp) 
     55 
     56        # Display HTML content 
     57        self._helpView = QtWebKit.QWebView() 
    4858 
    4959        # Connect the comboboxes 
     
    5666 
    5767        # Proxy model for showing a subset of Data1D/Data2D content 
    58         self.proxy = QtGui.QSortFilterProxyModel(self) 
    59         self.proxy.setSourceModel(self.model) 
     68        self.data_proxy = QtGui.QSortFilterProxyModel(self) 
     69        self.data_proxy.setSourceModel(self.model) 
     70 
     71        # Don't show "empty" rows with data objects 
     72        self.data_proxy.setFilterRegExp(r"[^()]") 
    6073 
    6174        # The Data viewer is QTreeView showing the proxy model 
    62         self.treeView.setModel(self.proxy) 
     75        self.treeView.setModel(self.data_proxy) 
     76 
     77        # Proxy model for showing a subset of Theory content 
     78        self.theory_proxy = QtGui.QSortFilterProxyModel(self) 
     79        self.theory_proxy.setSourceModel(self.theory_model) 
     80 
     81        # Don't show "empty" rows with data objects 
     82        self.theory_proxy.setFilterRegExp(r"[^()]") 
    6383 
    6484        # Theory model view 
    65         #self.freezeView.setModel(self.theory_model) 
     85        self.freezeView.setModel(self.theory_proxy) 
    6686 
    6787    def closeEvent(self, event): 
     
    7090        """ 
    7191        event.ignore() 
     92 
     93    def displayHelp(self): 
     94        """ 
     95        Show the "Loading data" section of help 
     96        """ 
     97        _TreeLocation = "html/user/sasgui/guiframe/data_explorer_help.html" 
     98        self._helpView.load(QtCore.QUrl(_TreeLocation)) 
     99        self._helpView.show() 
    72100 
    73101    def loadFromURL(self, url): 
     
    81109        """ 
    82110        Called when the "Load" button pressed. 
    83         Opens the Qt "Open File..." dialog  
     111        Opens the Qt "Open File..." dialog 
    84112        """ 
    85113        path_str = self.chooseFiles() 
     
    91119        """ 
    92120        Called when the "File/Load Folder" menu item chosen. 
    93         Opens the Qt "Open Folder..." dialog  
    94         """ 
    95         dir = QtGui.QFileDialog.getExistingDirectory(self, "Choose a directory", "", 
     121        Opens the Qt "Open Folder..." dialog 
     122        """ 
     123        folder = QtGui.QFileDialog.getExistingDirectory(self, "Choose a directory", "", 
    96124              QtGui.QFileDialog.ShowDirsOnly | QtGui.QFileDialog.DontUseNativeDialog) 
    97         if dir is None: 
    98             return 
    99  
    100         dir = str(dir) 
    101  
    102         if not os.path.isdir(dir): 
     125        if folder is None: 
     126            return 
     127 
     128        folder = str(folder) 
     129 
     130        if not os.path.isdir(folder): 
    103131            return 
    104132 
    105133        # get content of dir into a list 
    106         path_str = [os.path.join(os.path.abspath(dir), filename) for filename in os.listdir(dir)] 
     134        path_str = [os.path.join(os.path.abspath(folder), filename) 
     135                        for filename in os.listdir(folder)] 
    107136 
    108137        self.loadFromURL(path_str) 
     
    211240        and copying it to a separate top-level item. 
    212241        """ 
    213         import copy 
    214242        # Figure out which _inner_ rows are checked 
    215243        # Use 'while' so the row count is forced at every iteration 
    216244        outer_index = -1 
     245        theories_copied = 0 
    217246        while outer_index < self.model.rowCount(): 
    218247            outer_index += 1 
     
    220249            if not outer_item: 
    221250                continue 
    222             for inner_index in xrange(outer_item.rowCount()): 
     251            for inner_index in xrange(outer_item.rowCount()): # Should be just two rows: data and Info 
    223252                subitem = outer_item.child(inner_index) 
    224253                if subitem and subitem.isCheckable() and subitem.checkState() == QtCore.Qt.Checked: 
    225                     # Update the main model 
    226                     new_item = subitem.takeRow(inner_index) 
    227                     #new_item = QtGui.QStandardItem(subitem) 
    228                     #new_item = subitem.clone() 
    229                     #new_item = QtGui.QStandardItem() 
    230                     #new_item = copy.deepcopy(subitem) 
    231                     #super(new_item, self).__init__()    
    232                     self.model.insertRow(0, new_item) 
    233                     outer_index += 1 
    234  
    235         self.model.reset() 
     254                    theories_copied += 1 
     255                    new_item = self.recursivelyCloneItem(subitem) 
     256                    self.theory_model.appendRow(new_item) 
     257            self.theory_model.reset() 
     258 
     259        freeze_msg = "" 
     260        if theories_copied == 0: 
     261            return 
     262        elif theories_copied == 1: 
     263            freeze_msg = "1 theory sent to Theory tab" 
     264        elif theories_copied > 1: 
     265            freeze_msg = "%i theories sent to Theory tab" % theories_copied 
     266        else: 
     267            freeze_msg = "Unexpected number of theories copied: %i" % theories_copied 
     268            raise AttributeError, freeze_msg 
     269        self.communicator.statusBarUpdateSignal.emit(freeze_msg) 
     270        # Actively switch tabs 
     271        self.setCurrentIndex(1) 
     272 
     273    def recursivelyCloneItem(self, item): 
     274        """ 
     275        Clone QStandardItem() object 
     276        """ 
     277        new_item = item.clone() 
     278        # clone doesn't do deepcopy :( 
     279        for child_index in xrange(item.rowCount()): 
     280            child_item = self.recursivelyCloneItem(item.child(child_index)) 
     281            new_item.setChild(child_index, child_item) 
     282        return new_item 
    236283 
    237284    def newPlot(self): 
     
    266313            return 
    267314 
    268         if type(paths) == QtCore.QStringList: 
     315        #if type(paths) == QtCore.QStringList: 
     316        if isinstance(paths, QtCore.QStringList): 
    269317            paths = [str(f) for f in paths] 
    270318 
     
    276324    def readData(self, path): 
    277325        """ 
    278         verbatim copy/paste from 
    279             sasgui\guiframe\local_perspectives\data_loader\data_loader.py 
     326        verbatim copy-paste from 
     327           sasgui.guiframe.local_perspectives.data_loader.data_loader.py 
    280328        slightly modified for clarity 
    281329        """ 
     
    286334        data_error = False 
    287335        error_message = "" 
    288          
     336 
    289337        for p_file in path: 
    290             info = "info" 
    291338            basename = os.path.basename(p_file) 
    292339            _, extension = os.path.splitext(basename) 
     
    315362 
    316363                for item in output_objects: 
    317                     # cast sascalc.dataloader.data_info.Data1D into sasgui.guiframe.dataFitting.Data1D 
     364                    # cast sascalc.dataloader.data_info.Data1D into 
     365                    # sasgui.guiframe.dataFitting.Data1D 
    318366                    # TODO : Fix it 
    319367                    new_data = self.manager.create_gui_data(item, p_file) 
    320368                    output[new_data.id] = new_data 
     369 
     370                    # Model update should be protected 
     371                    self.mutex.lock() 
    321372                    self.updateModel(new_data, p_file) 
    322373                    self.model.reset() 
    323  
    324374                    QtGui.qApp.processEvents() 
     375                    self.mutex.unlock() 
    325376 
    326377                    if hasattr(item, 'errors'): 
     
    354405                    error_message += "%s\n" % str(p_file) 
    355406                info = "error" 
    356          
     407 
    357408        if any_error or error_message: 
    358             # self.loadUpdate(output=output, message=error_message, info=info) 
    359409            self.communicator.statusBarUpdateSignal.emit(error_message) 
    360410 
     
    362412            message = "Loading Data Complete! " 
    363413        message += log_msg 
     414 
    364415        return output, message 
    365416 
     
    470521        Post message to status bar and update the data manager 
    471522        """ 
    472         # Don't show "empty" rows with data objects 
    473         self.proxy.setFilterRegExp(r"[^()]") 
    474  
    475523        # Reset the model so the view gets updated. 
    476524        self.model.reset() 
    477         assert type(output)== tuple 
     525        assert type(output) == tuple 
    478526 
    479527        output_data = output[0] 
     
    486534    def updateModel(self, data, p_file): 
    487535        """ 
     536        Add data and Info fields to the model item 
    488537        """ 
    489538        # Structure of the model 
    490539        # checkbox + basename 
     540        #     |-------> Data.D object 
    491541        #     |-------> Info 
    492         #                 |----> Data.D object 
    493542        #                 |----> Title: 
    494543        #                 |----> Run: 
     
    519568        # New row in the model 
    520569        self.model.appendRow(checkbox_item) 
    521          
     570 
    522571    def updateModelFromPerspective(self, model_item): 
    523572        """ 
     
    537586        # Pass acting as a debugger anchor 
    538587        pass 
    539         
     588 
    540589 
    541590if __name__ == "__main__": 
Note: See TracChangeset for help on using the changeset viewer.