mirror of https://gitlab.com/pamhyr/pamhyr2
Results: Add tables and open window.
parent
b31be5ac36
commit
d499636cb6
|
|
@ -34,6 +34,11 @@ class Results(object):
|
|||
"creation_date": datetime.now(),
|
||||
}
|
||||
|
||||
@property
|
||||
def date(self):
|
||||
date = self._meta_data["creation_date"]
|
||||
return f"{date.isoformat(sep=' ')}"
|
||||
|
||||
@property
|
||||
def river(self):
|
||||
return self._river
|
||||
|
|
|
|||
|
|
@ -26,6 +26,14 @@ class Profile(object):
|
|||
self._profile = profile # Source profile in the study
|
||||
self._data = {} # Dict of dict {<ts>: {<key>: <value>, ...}, ...}
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
return self._profile.name
|
||||
|
||||
@property
|
||||
def kp(self):
|
||||
return self._profile.kp
|
||||
|
||||
def set(self, timestamp, key, data):
|
||||
if timestamp not in self._data:
|
||||
self._data[timestamp] = {}
|
||||
|
|
@ -54,10 +62,17 @@ class Reach(object):
|
|||
)
|
||||
)
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
return self._reach.name
|
||||
|
||||
@property
|
||||
def profiles(self):
|
||||
return self._profiles.copy()
|
||||
|
||||
def profile(self, id):
|
||||
return self._profiles[id]
|
||||
|
||||
def set(self, profile_id, timestamp, key, data):
|
||||
self._profiles[profile_id].set(timestamp, key, data)
|
||||
|
||||
|
|
@ -70,7 +85,10 @@ class River(object):
|
|||
|
||||
@property
|
||||
def reachs(self):
|
||||
return self.reachs.copy()
|
||||
return self._reachs.copy()
|
||||
|
||||
def reach(self, id):
|
||||
return self._reachs[id]
|
||||
|
||||
def add(self, reach_id):
|
||||
reachs = self._study.river.enable_edges()
|
||||
|
|
|
|||
|
|
@ -52,6 +52,7 @@ from View.Frictions.Window import FrictionsWindow
|
|||
from View.SolverParameters.Window import SolverParametersWindow
|
||||
from View.RunSolver.Window import SelectSolverWindow, SolverLogWindow
|
||||
from View.CheckList.Window import CheckListWindow
|
||||
from View.Results.Window import ResultsWindow
|
||||
from View.Debug.Window import ReplWindow
|
||||
|
||||
from Model.Study import Study
|
||||
|
|
@ -105,6 +106,9 @@ class ApplicationWindow(QMainWindow, ListedSubWindow, WindowToolKit):
|
|||
# Model
|
||||
self.model = None
|
||||
|
||||
# Results
|
||||
self._last_results = None
|
||||
|
||||
# UI
|
||||
self.ui = loadUi(
|
||||
os.path.join(os.path.dirname(__file__), "ui", "MainWindow.ui"),
|
||||
|
|
@ -304,6 +308,9 @@ class ApplicationWindow(QMainWindow, ListedSubWindow, WindowToolKit):
|
|||
for action in model_action:
|
||||
self.enable_actions(action, not no_model)
|
||||
|
||||
def set_results(self, results):
|
||||
self._last_results = results
|
||||
|
||||
############
|
||||
# FEATURES #
|
||||
############
|
||||
|
|
@ -638,6 +645,32 @@ class ApplicationWindow(QMainWindow, ListedSubWindow, WindowToolKit):
|
|||
)
|
||||
sol.show()
|
||||
|
||||
def open_solver_results(self, solver, results = None):
|
||||
# If no specific results, get last results
|
||||
if results is None:
|
||||
results = self._last_results
|
||||
|
||||
# No results available
|
||||
if results is None:
|
||||
return
|
||||
|
||||
# Windows already opened
|
||||
res = self.sub_win_filter_first(
|
||||
"Results",
|
||||
contain = [solver.name, results.date]
|
||||
)
|
||||
|
||||
if res is None:
|
||||
res = ResultsWindow(
|
||||
study = self.model,
|
||||
solver = solver,
|
||||
results = results,
|
||||
parent = self
|
||||
)
|
||||
res.show()
|
||||
else:
|
||||
res.activateWindow()
|
||||
|
||||
#########
|
||||
# DEBUG #
|
||||
#########
|
||||
|
|
|
|||
|
|
@ -15,3 +15,93 @@
|
|||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import logging
|
||||
import traceback
|
||||
|
||||
from tools import timer, trace
|
||||
|
||||
from PyQt5.QtGui import (
|
||||
QKeySequence, QColor
|
||||
)
|
||||
from PyQt5.QtCore import (
|
||||
Qt, QAbstractTableModel, QModelIndex,
|
||||
QVariant, pyqtSlot, QCoreApplication,
|
||||
)
|
||||
from PyQt5.QtWidgets import (
|
||||
QMessageBox, QUndoCommand, QUndoStack,
|
||||
QStyledItemDelegate, QLineEdit, QAbstractItemView,
|
||||
QComboBox,
|
||||
)
|
||||
|
||||
from View.Results.translate import *
|
||||
|
||||
logger = logging.getLogger()
|
||||
|
||||
_translate = QCoreApplication.translate
|
||||
|
||||
|
||||
class TableModel(QAbstractTableModel):
|
||||
def __init__(self, results = None, study = None, mode = None, undo=None):
|
||||
super(QAbstractTableModel, self).__init__()
|
||||
|
||||
self._results = results
|
||||
self._study = study
|
||||
self._mode = mode
|
||||
self._undo_stack = undo
|
||||
|
||||
self._table_headers = table_headers_reach
|
||||
if mode != "reach":
|
||||
self._table_headers = table_headers_profile
|
||||
|
||||
self._headers = list(self._table_headers.keys())
|
||||
|
||||
self._selected = 0
|
||||
self._timestamp = 0
|
||||
|
||||
def rowCount(self, parent=QModelIndex()):
|
||||
if self._mode == "reach":
|
||||
return len(self._results.river.reachs)
|
||||
|
||||
current_reach = self._results.river.reach(self._selected)
|
||||
return len(current_reach.profiles)
|
||||
|
||||
def columnCount(self, parent=QModelIndex()):
|
||||
return len(self._headers)
|
||||
|
||||
def data(self, index, role=Qt.DisplayRole):
|
||||
if role != Qt.ItemDataRole.DisplayRole:
|
||||
return QVariant()
|
||||
|
||||
row = index.row()
|
||||
column = index.column()
|
||||
|
||||
if self._mode == "reach":
|
||||
if self._headers[column] == "name":
|
||||
v = self._results.river.reach(row).name
|
||||
return str(v)
|
||||
else:
|
||||
current_reach = self._results.river.reach(self._selected)
|
||||
if self._headers[column] == "name":
|
||||
v = current_reach.profile(row).name
|
||||
return str(v)
|
||||
elif self._headers[column] == "kp":
|
||||
v = current_reach.profile(row).kp
|
||||
return f"{v:.4f}"
|
||||
|
||||
return QVariant()
|
||||
|
||||
def headerData(self, section, orientation, role=Qt.DisplayRole):
|
||||
if role == Qt.ItemDataRole.DisplayRole and orientation == Qt.Orientation.Horizontal:
|
||||
return self._table_headers[self._headers[section]]
|
||||
|
||||
return QVariant()
|
||||
|
||||
def index(self, row, column, parent=QModelIndex()):
|
||||
if not self.hasIndex(row, column, parent):
|
||||
return QModelIndex()
|
||||
|
||||
return self.createIndex(row, column, QModelIndex())
|
||||
|
||||
def flags(self, index):
|
||||
return Qt.ItemIsEnabled | Qt.ItemIsSelectable
|
||||
|
|
|
|||
|
|
@ -75,7 +75,8 @@ class ResultsWindow(ASubMainWindow, ListedSubWindow):
|
|||
self._title = (
|
||||
title + " - "
|
||||
+ self._study.name + " - "
|
||||
+ self._solver.name
|
||||
+ self._solver.name + " - "
|
||||
+ self._results.date
|
||||
)
|
||||
|
||||
def setup_sc(self):
|
||||
|
|
@ -153,7 +154,7 @@ class ResultsWindow(ASubMainWindow, ListedSubWindow):
|
|||
.selectionChanged\
|
||||
.connect(fun[t])
|
||||
|
||||
self._table.dataChanged.connect(fun[t])
|
||||
self._table[t].dataChanged.connect(fun[t])
|
||||
|
||||
def _set_current_reach(self):
|
||||
return
|
||||
|
|
|
|||
|
|
@ -15,3 +15,16 @@
|
|||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from PyQt5.QtCore import QCoreApplication
|
||||
|
||||
_translate = QCoreApplication.translate
|
||||
|
||||
table_headers_reach = {
|
||||
"name": _translate("Results", "Reach name"),
|
||||
}
|
||||
|
||||
table_headers_profile = {
|
||||
"name": _translate("Results", "Name"),
|
||||
"kp": _translate("Results", "KP (m)"),
|
||||
}
|
||||
|
|
|
|||
|
|
@ -219,6 +219,7 @@ class SolverLogWindow(ASubMainWindow, ListedSubWindow):
|
|||
self._process = self.new_process(self._parent)
|
||||
|
||||
self._log(" *** Start", color="blue")
|
||||
self._results = None
|
||||
self._solver.start(self._process)
|
||||
|
||||
self.find(QAction, "action_start").setEnabled(False)
|
||||
|
|
@ -251,7 +252,9 @@ class SolverLogWindow(ASubMainWindow, ListedSubWindow):
|
|||
self.find(QAction, "action_log_file").setEnabled(True)
|
||||
|
||||
def results(self):
|
||||
if self._results is None:
|
||||
self._results = self._solver.results(self._study, self._workdir, qlog = self._output)
|
||||
self._parent.open_solver_results(self._solver, self._results)
|
||||
|
||||
def log_file(self):
|
||||
file_name = os.path.join(self._workdir, self._solver.log_file())
|
||||
|
|
|
|||
Loading…
Reference in New Issue