Index: src/sas/qtgui/Perspectives/Inversion/DMaxExplorerWidget.py
===================================================================
--- src/sas/qtgui/Perspectives/Inversion/DMaxExplorerWidget.py	(revision f4480f0b7b106ef818f94ad2879e54baa53e4a6a)
+++ src/sas/qtgui/Perspectives/Inversion/DMaxExplorerWidget.py	(revision ae34d30993ebe39bd8bb7ec8e8117212afe7e15e)
@@ -42,4 +42,5 @@
         super(DmaxWindow, self).__init__()
         self.setupUi(self)
+        self.parent = parent
 
         self.setWindowTitle("Dââ Explorer")
@@ -188,2 +189,7 @@
         data._yunit = y_unit
         self.plot.plot(data=data, marker="-")
+
+    def closeEvent(self, event):
+        """Override close event"""
+        self.parent.dmaxWindow = None
+        event.accept()
Index: src/sas/qtgui/Perspectives/Inversion/InversionPerspective.py
===================================================================
--- src/sas/qtgui/Perspectives/Inversion/InversionPerspective.py	(revision 98485fe969002d557f5e1664222aefe844f7a074)
+++ src/sas/qtgui/Perspectives/Inversion/InversionPerspective.py	(revision ae34d30993ebe39bd8bb7ec8e8117212afe7e15e)
@@ -1,5 +1,3 @@
-import sys
 import logging
-import pylab
 import numpy as np
 
@@ -16,5 +14,4 @@
 # pr inversion calculation elements
 from sas.sascalc.pr.invertor import Invertor
-
 # Batch calculation display
 from sas.qtgui.Utilities.GridPanel import BatchInversionOutputPanel
@@ -60,7 +57,7 @@
 
         # The window should not close
-        self._allow_close = False
-
-        # Visible data set items
+        self._allowClose = False
+
+        # Visible data items
         # current QStandardItem showing on the panel
         self._data = None
@@ -72,18 +69,17 @@
         self._calculator.est_bck = True
         # plots of self._data
-        self.pr_plot = None
-        self.data_plot = None
+        self.prPlot = None
+        self.dataPlot = None
         # suggested nTerms
         self.nTermsSuggested = NUMBER_OF_TERMS
 
         # Calculation threads used by all data items
-        self.isBatch = False
-        self.calc_thread = None
-        self.estimation_thread = None
-        self.estimation_thread_nt = None
+        self.calcThread = None
+        self.estimationThread = None
+        self.estimationThreadNT = None
 
         # Mapping for all data items
-        # list mapping data to all parameters
-        self._data_list = {}
+        # Dictionary mapping data to all parameters
+        self._dataList = {}
         if not isinstance(data, list):
             data_list = [data]
@@ -97,6 +93,7 @@
         self.mapper = QtWidgets.QDataWidgetMapper(self)
 
-        # Batch fitting results
-        self.grid_window = None
+        # Batch fitting parameters
+        self.isBatch = False
+        self.batchResultsWindow = None
         self.batchResults = {}
         self.batchComplete = []
@@ -127,5 +124,5 @@
         """
         assert isinstance(value, bool)
-        self._allow_close = value
+        self._allowClose = value
 
     def closeEvent(self, event):
@@ -133,5 +130,8 @@
         Overwrite QDialog close method to allow for custom widget close
         """
-        if self._allow_close:
+        # Close report widgets before closing/minimizing main widget
+        self.closeDMax()
+        self.closeBatchResults()
+        if self._allowClose:
             # reset the closability flag
             self.setClosable(value=False)
@@ -143,4 +143,12 @@
             # Maybe we should just minimize
             self.setWindowState(QtCore.Qt.WindowMinimized)
+
+    def closeDMax(self):
+        if self.dmaxWindow is not None:
+            self.dmaxWindow.close()
+
+    def closeBatchResults(self):
+        if self.batchResultsWindow is not None:
+            self.batchResultsWindow.close()
 
     ######################################################################
@@ -230,36 +238,25 @@
         Update boxes with initial values
         """
-        item = QtGui.QStandardItem(str(BACKGROUND_INPUT))
-        self.model.setItem(WIDGETS.W_BACKGROUND_INPUT, item)
-        item = QtGui.QStandardItem("")
-        self.model.setItem(WIDGETS.W_QMIN, item)
-        item = QtGui.QStandardItem("")
-        self.model.setItem(WIDGETS.W_QMAX, item)
-        item = QtGui.QStandardItem("")
-        self.model.setItem(WIDGETS.W_SLIT_WIDTH, item)
-        item = QtGui.QStandardItem("")
-        self.model.setItem(WIDGETS.W_SLIT_HEIGHT, item)
-        item = QtGui.QStandardItem(str(NUMBER_OF_TERMS))
-        self.model.setItem(WIDGETS.W_NO_TERMS, item)
-        item = QtGui.QStandardItem(str(REGULARIZATION))
-        self.model.setItem(WIDGETS.W_REGULARIZATION, item)
-        item = QtGui.QStandardItem(str(MAX_DIST))
-        self.model.setItem(WIDGETS.W_MAX_DIST, item)
-        item = QtGui.QStandardItem("")
-        self.model.setItem(WIDGETS.W_RG, item)
-        item = QtGui.QStandardItem("")
-        self.model.setItem(WIDGETS.W_I_ZERO, item)
-        item = QtGui.QStandardItem("")
-        self.model.setItem(WIDGETS.W_BACKGROUND_OUTPUT, item)
-        item = QtGui.QStandardItem("")
-        self.model.setItem(WIDGETS.W_COMP_TIME, item)
-        item = QtGui.QStandardItem("")
-        self.model.setItem(WIDGETS.W_CHI_SQUARED, item)
-        item = QtGui.QStandardItem("")
-        self.model.setItem(WIDGETS.W_OSCILLATION, item)
-        item = QtGui.QStandardItem("")
-        self.model.setItem(WIDGETS.W_POS_FRACTION, item)
-        item = QtGui.QStandardItem("")
-        self.model.setItem(WIDGETS.W_SIGMA_POS_FRACTION, item)
+        blank_item = QtGui.QStandardItem("")
+        no_terms_item = QtGui.QStandardItem(str(NUMBER_OF_TERMS))
+        bgd_item = QtGui.QStandardItem(str(BACKGROUND_INPUT))
+        reg_item = QtGui.QStandardItem(str(REGULARIZATION))
+        max_dist_item = QtGui.QStandardItem(str(MAX_DIST))
+        self.model.setItem(WIDGETS.W_BACKGROUND_INPUT, bgd_item)
+        self.model.setItem(WIDGETS.W_QMIN, blank_item)
+        self.model.setItem(WIDGETS.W_QMAX, blank_item)
+        self.model.setItem(WIDGETS.W_SLIT_WIDTH, blank_item)
+        self.model.setItem(WIDGETS.W_SLIT_HEIGHT, blank_item)
+        self.model.setItem(WIDGETS.W_NO_TERMS, no_terms_item)
+        self.model.setItem(WIDGETS.W_REGULARIZATION, reg_item)
+        self.model.setItem(WIDGETS.W_MAX_DIST, max_dist_item)
+        self.model.setItem(WIDGETS.W_RG, blank_item)
+        self.model.setItem(WIDGETS.W_I_ZERO, blank_item)
+        self.model.setItem(WIDGETS.W_BACKGROUND_OUTPUT, bgd_item)
+        self.model.setItem(WIDGETS.W_COMP_TIME, blank_item)
+        self.model.setItem(WIDGETS.W_CHI_SQUARED, blank_item)
+        self.model.setItem(WIDGETS.W_OSCILLATION, blank_item)
+        self.model.setItem(WIDGETS.W_POS_FRACTION, blank_item)
+        self.model.setItem(WIDGETS.W_SIGMA_POS_FRACTION, blank_item)
 
     def setupWindow(self):
@@ -285,6 +282,8 @@
         Enable buttons when data is present, else disable them
         """
-        self.calculateAllButton.setEnabled(len(self._data_list) > 1)
-        self.calculateThisButton.setEnabled(self.logic.data_is_loaded)
+        self.calculateAllButton.setEnabled(len(self._dataList) > 1
+                                           and not self.isBatch)
+        self.calculateThisButton.setEnabled(self.logic.data_is_loaded
+                                            and not self.isBatch)
         self.removeButton.setEnabled(self.logic.data_is_loaded)
         self.explorerButton.setEnabled(self.logic.data_is_loaded)
@@ -320,5 +319,5 @@
     # GUI Interaction Events
 
-    def update_calculator(self):
+    def updateCalculator(self):
         """Update all p(r) params"""
         self._calculator.set_x(self.logic.data.x)
@@ -338,5 +337,5 @@
             self.setClosable(True)
             self.close()
-            InversionWindow.__init__(self.parent(), list(self._data_list.keys()))
+            InversionWindow.__init__(self.parent(), list(self._dataList.keys()))
             exit(0)
         if self.dmaxWindow is not None:
@@ -384,10 +383,10 @@
         :param output_data: Dictionary mapping filename -> P(r) instance
         """
-        if self.grid_window is None:
-            self.grid_window = BatchInversionOutputPanel(
+        if self.batchResultsWindow is None:
+            self.batchResultsWindow = BatchInversionOutputPanel(
                 parent=self, output_data=self.batchResults)
         else:
-            self.grid_window.setupTable(self.batchResults)
-        self.grid_window.show()
+            self.batchResultsWindow.setupTable(self.batchResults)
+        self.batchResultsWindow.show()
 
     ######################################################################
@@ -407,5 +406,5 @@
 
         for data in data_item:
-            if data in self._data_list.keys():
+            if data in self._dataList.keys():
                 # Don't add data if it's already in
                 continue
@@ -425,12 +424,12 @@
         if dataRef is None:
             return
-        self._data_list[dataRef] = {
+        self._dataList[dataRef] = {
             DICT_KEYS[0]: self._calculator,
-            DICT_KEYS[1]: self.pr_plot,
-            DICT_KEYS[2]: self.data_plot
+            DICT_KEYS[1]: self.prPlot,
+            DICT_KEYS[2]: self.dataPlot
         }
         # Update batch results window when finished
         self.batchResults[self.logic.data.filename] = self._calculator
-        if self.grid_window is not None:
+        if self.batchResultsWindow is not None:
             self.showBatchOutput()
 
@@ -456,7 +455,7 @@
         self._data = data_ref
         self.logic.data = GuiUtils.dataFromItem(data_ref)
-        self._calculator = self._data_list[data_ref].get(DICT_KEYS[0])
-        self.pr_plot = self._data_list[data_ref].get(DICT_KEYS[1])
-        self.data_plot = self._data_list[data_ref].get(DICT_KEYS[2])
+        self._calculator = self._dataList[data_ref].get(DICT_KEYS[0])
+        self.prPlot = self._dataList[data_ref].get(DICT_KEYS[1])
+        self.dataPlot = self._dataList[data_ref].get(DICT_KEYS[2])
         self.performEstimate()
 
@@ -477,9 +476,9 @@
         self.model.setItem(WIDGETS.W_COMP_TIME,
                            QtGui.QStandardItem("{:.4g}".format(elapsed)))
+        self.model.setItem(WIDGETS.W_MAX_DIST,
+                           QtGui.QStandardItem("{:.4g}".format(pr.get_dmax())))
         self.regConstantSuggestionButton.setText("{:-3.2g}".format(alpha))
         self.noOfTermsSuggestionButton.setText(
             "{:n}".format(self.nTermsSuggested))
-        self.model.setItem(WIDGETS.W_COMP_TIME,
-                           QtGui.QStandardItem("{:.2g}".format(elapsed)))
 
         if isinstance(pr.chi2, np.ndarray):
@@ -501,26 +500,24 @@
                                        "{:.3g}".format(
                                            pr.get_pos_err(out, cov))))
-        if self.pr_plot is not None:
-            title = self.pr_plot.name
-            GuiUtils.updateModelItemWithPlot(self._data, self.pr_plot, title)
-            self.communicate.plotRequestedSignal.emit([self.pr_plot])
-        if self.data_plot is not None:
-            title = self.data_plot.name
-            GuiUtils.updateModelItemWithPlot(self._data, self.data_plot, title)
+        if self.prPlot is not None:
+            title = self.prPlot.name
+            GuiUtils.updateModelItemWithPlot(self._data, self.prPlot, title)
+            self.communicate.plotRequestedSignal.emit([self.prPlot])
+        if self.dataPlot is not None:
+            title = self.dataPlot.name
+            GuiUtils.updateModelItemWithPlot(self._data, self.dataPlot, title)
             self.communicate.plotRequestedSignal.emit(
-                [self.data_plot, self.logic.data])
+                [self.dataPlot, self.logic.data])
         self.enableButtons()
 
     def removeData(self, data_list=None):
         """Remove the existing data reference from the P(r) Persepective"""
-        if self.dmaxWindow is not None:
-            self.dmaxWindow.close()
-            self.dmaxWindow = None
-        if self.grid_window is not None:
-            self.grid_window.close()
         if not data_list:
             data_list = [self._data]
+        self.closeDMax()
         for data in data_list:
-            self._data_list.pop(data)
+            self._dataList.pop(data)
+            data_file = GuiUtils.dataFromItem(data)
+            self.batchResults.pop(data_file.filename)
         self._data = None
         for index in range(0, len(self.dataList)):
@@ -528,10 +525,10 @@
                 self.dataList.removeItem(index)
         # Last file removed
-        if len(self._data_list) == 0:
-            self._data = None
-            self.pr_plot = None
-            self.data_plot = None
+        if len(self._dataList) == 0:
+            self.prPlot = None
+            self.dataPlot = None
+            self.logic.data = None
             self._calculator = Invertor()
-            self.logic.data = None
+            self.closeBatchResults()
             self.nTermsSuggested = NUMBER_OF_TERMS
             self.noOfTermsSuggestionButton.setText("{:n}".format(
@@ -549,4 +546,5 @@
 
     def startThreadAll(self):
+        self.calculateAllButton.setText("Calculating...")
         self.batchComplete = []
         self.isBatch = True
@@ -556,12 +554,15 @@
     def startNextBatchItem(self):
         self.isBatch = False
-        for index in range(len(self._data_list)):
+        for index in range(len(self._dataList)):
             if index not in self.batchComplete:
                 self.dataList.setCurrentIndex(index)
                 self.isBatch = True
                 break
-        # If none left, end
         if self.isBatch:
             self.performEstimate()
+        else:
+            # If no data sets left, end batch calculation
+            self.calculateAllButton.setText("Calculate All")
+            self.enableButtons()
 
     def startThread(self):
@@ -572,17 +573,17 @@
 
         # Set data before running the calculations
-        self.update_calculator()
+        self.updateCalculator()
 
         # If a thread is already started, stop it
-        if self.calc_thread is not None and self.calc_thread.isrunning():
-            self.calc_thread.stop()
+        if self.calcThread is not None and self.calcThread.isrunning():
+            self.calcThread.stop()
         pr = self._calculator.clone()
         nfunc = self.getNFunc()
-        self.calc_thread = CalcPr(pr, nfunc,
-                                  error_func=self._threadError,
-                                  completefn=self._calculateCompleted,
-                                  updatefn=None)
-        self.calc_thread.queue()
-        self.calc_thread.ready(2.5)
+        self.calcThread = CalcPr(pr, nfunc,
+                                 error_func=self._threadError,
+                                 completefn=self._calculateCompleted,
+                                 updatefn=None)
+        self.calcThread.queue()
+        self.calcThread.ready(2.5)
 
     def performEstimateNT(self):
@@ -592,10 +593,10 @@
         from .Thread import EstimateNT
 
-        self.update_calculator()
+        self.updateCalculator()
 
         # If a thread is already started, stop it
-        if (self.estimation_thread_nt is not None and
-                self.estimation_thread_nt.isrunning()):
-            self.estimation_thread_nt.stop()
+        if (self.estimationThreadNT is not None and
+                self.estimationThreadNT.isrunning()):
+            self.estimationThreadNT.stop()
         pr = self._calculator.clone()
         # Skip the slit settings for the estimation
@@ -605,10 +606,10 @@
         nfunc = self.getNFunc()
 
-        self.estimation_thread_nt = EstimateNT(pr, nfunc,
-                                            error_func=self._threadError,
-                                            completefn=self._estimateNTCompleted,
-                                            updatefn=None)
-        self.estimation_thread_nt.queue()
-        self.estimation_thread_nt.ready(2.5)
+        self.estimationThreadNT = EstimateNT(pr, nfunc,
+                                             error_func=self._threadError,
+                                             completefn=self._estimateNTCompleted,
+                                             updatefn=None)
+        self.estimationThreadNT.queue()
+        self.estimationThreadNT.ready(2.5)
 
     def performEstimate(self):
@@ -619,14 +620,14 @@
 
         # If a thread is already started, stop it
-        if (self.estimation_thread is not None and
-                self.estimation_thread.isrunning()):
-            self.estimation_thread.stop()
-        self.estimation_thread = EstimatePr(self._calculator.clone(),
-                                            self.getNFunc(),
-                                            error_func=self._threadError,
-                                            completefn=self._estimateCompleted,
-                                            updatefn=None)
-        self.estimation_thread.queue()
-        self.estimation_thread.ready(2.5)
+        if (self.estimationThread is not None and
+                self.estimationThread.isrunning()):
+            self.estimationThread.stop()
+        self.estimationThread = EstimatePr(self._calculator.clone(),
+                                           self.getNFunc(),
+                                           error_func=self._threadError,
+                                           completefn=self._estimateCompleted,
+                                           updatefn=None)
+        self.estimationThread.queue()
+        self.estimationThread.ready(2.5)
 
     ######################################################################
@@ -700,8 +701,8 @@
 
         # Update P(r) and fit plots
-        self.pr_plot = self.logic.newPRPlot(out, self._calculator, cov)
-        self.pr_plot.filename = self.logic.data.filename
-        self.data_plot = self.logic.new1DPlot(out, self._calculator)
-        self.data_plot.filename = self.logic.data.filename
+        self.prPlot = self.logic.newPRPlot(out, self._calculator, cov)
+        self.prPlot.filename = self.logic.data.filename
+        self.dataPlot = self.logic.new1DPlot(out, self._calculator)
+        self.dataPlot.filename = self.logic.data.filename
 
         # Udpate internals and GUI
Index: src/sas/qtgui/Utilities/GridPanel.py
===================================================================
--- src/sas/qtgui/Utilities/GridPanel.py	(revision 98485fe969002d557f5e1664222aefe844f7a074)
+++ src/sas/qtgui/Utilities/GridPanel.py	(revision ae34d30993ebe39bd8bb7ec8e8117212afe7e15e)
@@ -352,4 +352,4 @@
     def closeEvent(self, event):
         """Tell the parent window the window closed"""
-        self.parent.grid_window = None
+        self.parent.batchResultsWindow = None
         event.accept()
