mirror of https://gitlab.com/pamhyr/pamhyr2
dirty work on BHS
commit
f302e18d71
|
|
@ -122,7 +122,7 @@ test-pep8:
|
|||
- pip3 install -r ./requirements.txt
|
||||
- pip3 install -U -r ./requirements.txt
|
||||
- pip3 install pycodestyle
|
||||
- pycodestyle ./src
|
||||
- pycodestyle --exclude="*_to_*.py" ./src
|
||||
allow_failure: true
|
||||
|
||||
#########
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ from Model.Tools.PamhyrDB import SQLSubModel
|
|||
|
||||
logger = logging.getLogger()
|
||||
|
||||
|
||||
class Friction(SQLSubModel):
|
||||
def __init__(self, name: str = "", status=None):
|
||||
super(Friction, self).__init__()
|
||||
|
|
|
|||
|
|
@ -437,42 +437,57 @@ class ProfileXYZ(Profile, SQLSubModel):
|
|||
return abs(rg.dist(rd))
|
||||
|
||||
def get_water_limits(self, z):
|
||||
#==============================================================================
|
||||
# détermination des points limites RG et RD pour un niveau d'eau donné
|
||||
#
|
||||
# irg et ird sont les premiers indices en partant des rives gauche et
|
||||
# droite qui correspondent à des points sous la surface de l'eau
|
||||
# ptX et ptY sont les points interpolés où le plan d'eau intersecte le profil
|
||||
# known_level est le niveau d'eau pour lequel on a obtenu irg, ird, ptX et ptY
|
||||
#==============================================================================
|
||||
# ====================================================================
|
||||
# détermination des points limites RG et RD pour un niveau
|
||||
# d'eau donné
|
||||
#
|
||||
# irg et ird sont les premiers indices en partant des rives
|
||||
# gauche et droite qui correspondent à des points sous la
|
||||
# surface de l'eau ptX et ptY sont les points interpolés où
|
||||
# le plan d'eau intersecte le profil known_level est le
|
||||
# niveau d'eau pour lequel on a obtenu irg, ird, ptX et ptY
|
||||
# ====================================================================
|
||||
|
||||
# initialisation
|
||||
irg = -1 ; ird = -1
|
||||
irg = -1
|
||||
ird = -1
|
||||
|
||||
for i in range(self.number_points):
|
||||
if self.point(i).z <= z:
|
||||
irg = i
|
||||
|
||||
for i in reversed(range(self.number_points)):
|
||||
if self.point(i).z <= z:
|
||||
ird = i
|
||||
|
||||
# interpolation des points ptX et ptY
|
||||
if (irg < self.number_points-1):
|
||||
x=np.interp(z,
|
||||
[self.point(irg).z,self.point(irg+1).z],
|
||||
[self.point(irg).x,self.point(irg+1).x])
|
||||
y=np.interp(z,
|
||||
[self.point(irg).z,self.point(irg+1).z],
|
||||
[self.point(irg).y,self.point(irg+1).y])
|
||||
ptX=PointXYZ(x,y,z)
|
||||
if (irg < self.number_points - 1):
|
||||
x = np.interp(
|
||||
z,
|
||||
[self.point(irg).z, self.point(irg + 1).z],
|
||||
[self.point(irg).x, self.point(irg + 1).x]
|
||||
)
|
||||
y = np.interp(
|
||||
z,
|
||||
[self.point(irg).z, self.point(irg + 1).z],
|
||||
[self.point(irg).y, self.point(irg + 1).y]
|
||||
)
|
||||
ptX = PointXYZ(x, y, z)
|
||||
else:
|
||||
ptX = self.point(0)
|
||||
if (ird > 0):
|
||||
x=np.interp(z,
|
||||
[self.point(ird-1).z,self.point(ird).z],
|
||||
[self.point(ird-1).x,self.point(ird).x])
|
||||
y=np.interp(z,
|
||||
[self.point(ird).z,self.point(ird-1).z],
|
||||
[self.point(ird).y,self.point(ird-1).y])
|
||||
ptY=PointXYZ(x,y,z)
|
||||
x = np.interp(
|
||||
z,
|
||||
[self.point(ird-1).z, self.point(ird).z],
|
||||
[self.point(ird-1).x, self.point(ird).x]
|
||||
)
|
||||
y = np.interp(
|
||||
z,
|
||||
[self.point(ird).z, self.point(ird - 1).z],
|
||||
[self.point(ird).y, self.point(ird - 1).y]
|
||||
)
|
||||
ptY = PointXYZ(x, y, z)
|
||||
else:
|
||||
ptY = self.point(self.number_points-1)
|
||||
ptY = self.point(self.number_points - 1)
|
||||
|
||||
return ptX,ptY
|
||||
return ptX, ptY
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ from Model.HydraulicStructures.Basic.Value import (
|
|||
|
||||
logger = logging.getLogger()
|
||||
|
||||
|
||||
class BasicHS(SQLSubModel):
|
||||
_sub_classes = [
|
||||
BHSValue,
|
||||
|
|
@ -142,7 +143,7 @@ class BasicHS(SQLSubModel):
|
|||
|
||||
data['bhs_id'] = self.id
|
||||
execute(
|
||||
"DELETE FROM hydraulic_structures_basic_value "+
|
||||
"DELETE FROM hydraulic_structures_basic_value " +
|
||||
f"WHERE bhs = {bhs_id}"
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -16,18 +16,22 @@
|
|||
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from Model.Except import NotImplementedMethodeError
|
||||
|
||||
from Model.HydraulicStructures.Basic.HydraulicStructures import (
|
||||
BasicHS
|
||||
)
|
||||
|
||||
from Model.HydraulicStructures.Basic.Value import (
|
||||
BHSValue
|
||||
)
|
||||
|
||||
|
||||
class NotDefined(BasicHS):
|
||||
def __init__(self, id: int = -1, name: str = "", status=None):
|
||||
super(NotDefined, self).__init__(id=id, name=name, status=status)
|
||||
def __init__(self, id: int = -1, name: str = "",
|
||||
status=None):
|
||||
super(NotDefined, self).__init__(
|
||||
id=id, name=name,
|
||||
status=status
|
||||
)
|
||||
|
||||
self._type = "ND"
|
||||
self._data = [
|
||||
|
|
|
|||
|
|
@ -18,11 +18,12 @@
|
|||
|
||||
from Model.Tools.PamhyrDB import SQLSubModel
|
||||
|
||||
|
||||
class BHSValue(SQLSubModel):
|
||||
_sub_classes = []
|
||||
_id_cnt = 0
|
||||
|
||||
def __init__(self, name: str = "", type = float, value = 0.0,
|
||||
def __init__(self, name: str = "", type=float, value=0.0,
|
||||
status=None):
|
||||
super(BHSValue, self).__init__()
|
||||
|
||||
|
|
@ -117,7 +118,7 @@ class BHSValue(SQLSubModel):
|
|||
"hydraulic_structures_basic_value(name, type, value, bhs) " +
|
||||
"VALUES (" +
|
||||
f"'{self._db_format(self._name)}', " +
|
||||
f"'{self._db_format(self._type_to_str(self._type))}', "+
|
||||
f"'{self._db_format(self._type_to_str(self._type))}', " +
|
||||
f"'{self._db_format(self._value)}', " +
|
||||
f"{bhs_id}" +
|
||||
")"
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ from Model.HydraulicStructures.Basic.Types import (
|
|||
|
||||
logger = logging.getLogger()
|
||||
|
||||
|
||||
class HydraulicStructure(SQLSubModel):
|
||||
_sub_classes = [
|
||||
BasicHS,
|
||||
|
|
@ -55,7 +56,10 @@ class HydraulicStructure(SQLSubModel):
|
|||
self._enabled = True
|
||||
self._data = []
|
||||
|
||||
HydraulicStructure._id_cnt = max(HydraulicStructure._id_cnt + 1, self.id)
|
||||
HydraulicStructure._id_cnt = max(
|
||||
HydraulicStructure._id_cnt + 1,
|
||||
self.id
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def _db_create(cls, execute):
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ from tools import trace, timer
|
|||
from Model.Tools.PamhyrList import PamhyrModelList
|
||||
from Model.HydraulicStructures.HydraulicStructures import HydraulicStructure
|
||||
|
||||
|
||||
class HydraulicStructureList(PamhyrModelList):
|
||||
_sub_classes = [
|
||||
HydraulicStructure,
|
||||
|
|
|
|||
|
|
@ -376,7 +376,7 @@ class InitialConditions(SQLSubModel):
|
|||
* (abs(incline) ** (0.5)))
|
||||
)
|
||||
|
||||
elevation= max(
|
||||
elevation = max(
|
||||
profile.z_min() + height,
|
||||
previous_elevation
|
||||
)
|
||||
|
|
@ -422,7 +422,7 @@ class InitialConditions(SQLSubModel):
|
|||
((width * 0.8) * strickler * (abs(incline) ** (0.5)))
|
||||
) ** (0.6)
|
||||
|
||||
elevation= max(
|
||||
elevation = max(
|
||||
profile.z_min() + height,
|
||||
previous_elevation
|
||||
)
|
||||
|
|
|
|||
|
|
@ -213,7 +213,7 @@ class Graph(object):
|
|||
def is_enable_edge(self, edge):
|
||||
return edge._enable
|
||||
|
||||
#def get_edge_id(self, reach):
|
||||
# def get_edge_id(self, reach):
|
||||
# for i, e in enumerate(self.enable_edges):
|
||||
# if e.id == reach.id:
|
||||
# return i
|
||||
|
|
|
|||
|
|
@ -94,7 +94,11 @@ class Reservoir(SQLSubModel):
|
|||
|
||||
new_reservoir._node = None
|
||||
if node_id != -1:
|
||||
new_reservoir._node = next(filter(lambda n: n.id == node_id, data["nodes"]))
|
||||
new_reservoir._node = next(
|
||||
filter(
|
||||
lambda n: n.id == node_id, data["nodes"]
|
||||
)
|
||||
)
|
||||
|
||||
new_data = []
|
||||
table = execute(
|
||||
|
|
|
|||
|
|
@ -242,7 +242,9 @@ class River(Graph, SQLSubModel):
|
|||
self._parameters = {}
|
||||
self._sediment_layers = SedimentLayerList(status=self._status)
|
||||
self._reservoir = ReservoirList(status=self._status)
|
||||
self._hydraulic_structures = HydraulicStructureList(status=self._status)
|
||||
self._hydraulic_structures = HydraulicStructureList(
|
||||
status=self._status
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def _db_create(cls, execute):
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ class PamhyrModelDict(SQLSubModel):
|
|||
if key in self._dict:
|
||||
v = self._dict[key]
|
||||
|
||||
if type(v) == types.GeneratorType:
|
||||
if type(v) is types.GeneratorType:
|
||||
return list(v)
|
||||
|
||||
return v
|
||||
|
|
|
|||
|
|
@ -453,9 +453,20 @@ class Mage(CommandLineSolver):
|
|||
for hs in hydraulic_structures:
|
||||
if hs.reach.is_enable:
|
||||
reach_id = study.river.get_edge_id(hs.reach)
|
||||
params = [p.value for p in hs.basic_hydraulic_structure.param]
|
||||
param_str = ' '.join([f'{p.value:>10.3f}' for p in hs.basic_hydraulic_structure.param])
|
||||
f.write(f"{hs.basic_hydraulic_structure.type} {reach_id} {hs.kp:>12.3f} {params} {hs.name}\n")
|
||||
params = [
|
||||
p.value for p in hs.basic_hydraulic_structure.param
|
||||
]
|
||||
param_str = ' '.join(
|
||||
[
|
||||
f'{p.value:>10.3f}'
|
||||
for p in hs.basic_hydraulic_structure.param
|
||||
]
|
||||
)
|
||||
f.write(
|
||||
f"{hs.basic_hydraulic_structure.type} " +
|
||||
f"{reach_id} {hs.kp:>12.3f} {params} " +
|
||||
"{hs.name}\n"
|
||||
)
|
||||
|
||||
return files
|
||||
|
||||
|
|
@ -465,7 +476,11 @@ class Mage(CommandLineSolver):
|
|||
qlog.put("Export REP file")
|
||||
|
||||
# Write header
|
||||
with mage_file_open(os.path.join(repertory, f"{name}.REP"), "w+") as f:
|
||||
with mage_file_open(
|
||||
os.path.join(
|
||||
repertory, f"{name}.REP"
|
||||
), "w+"
|
||||
) as f:
|
||||
f.write("confirmation=non\n")
|
||||
|
||||
for file in files:
|
||||
|
|
@ -832,12 +847,13 @@ class Mage8(Mage):
|
|||
# Set data for profile RI
|
||||
reach.set(ri, timestamp, key, d)
|
||||
if key == "Z":
|
||||
profile = study.river.current_reach().reach.profile(ri)
|
||||
ptX,ptY = profile.get_water_limits(d)
|
||||
profile = study.river\
|
||||
.current_reach()\
|
||||
.reach.profile(ri)
|
||||
ptX, ptY = profile.get_water_limits(d)
|
||||
reach.set(ri, timestamp, "ptX", ptX)
|
||||
reach.set(ri, timestamp, "ptY", ptY)
|
||||
|
||||
|
||||
endline()
|
||||
end = newline().size <= 0
|
||||
|
||||
|
|
|
|||
|
|
@ -160,7 +160,7 @@ class EditBoundaryConditionWindow(PamhyrWindow):
|
|||
table_headers=headers,
|
||||
editable_headers=self._data.header,
|
||||
delegates={
|
||||
#"time": self._delegate_time,
|
||||
# "time": self._delegate_time,
|
||||
},
|
||||
data=self._data,
|
||||
undo=self._undo_stack,
|
||||
|
|
|
|||
|
|
@ -115,13 +115,13 @@ class ComboBoxDelegate(QItemDelegate):
|
|||
|
||||
|
||||
class TableModel(PamhyrTableModel):
|
||||
def __init__(self, trad = None, **kwargs):
|
||||
def __init__(self, trad=None, **kwargs):
|
||||
self._trad = trad
|
||||
self._long_types = {}
|
||||
if self._trad is not None:
|
||||
self._long_types = self._trad.get_dict("long_types")
|
||||
|
||||
super(TableModel, self).__init__(trad = trad, **kwargs)
|
||||
super(TableModel, self).__init__(trad=trad, **kwargs)
|
||||
|
||||
def _setup_lst(self):
|
||||
self._lst = self._data.boundary_condition
|
||||
|
|
|
|||
|
|
@ -18,3 +18,160 @@
|
|||
|
||||
import logging
|
||||
import traceback
|
||||
|
||||
from tools import trace, timer
|
||||
|
||||
from PyQt5.QtCore import (
|
||||
Qt, QVariant, QAbstractTableModel,
|
||||
QCoreApplication, QModelIndex, pyqtSlot,
|
||||
QRect,
|
||||
)
|
||||
|
||||
from PyQt5.QtWidgets import (
|
||||
QDialogButtonBox, QPushButton, QLineEdit,
|
||||
QFileDialog, QTableView, QAbstractItemView,
|
||||
QUndoStack, QShortcut, QAction, QItemDelegate,
|
||||
QComboBox,
|
||||
)
|
||||
|
||||
from View.Tools.PamhyrTable import PamhyrTableModel
|
||||
|
||||
from View.HydraulicStructures.BasicHydraulicStructures.UndoCommand import (
|
||||
SetNameCommand, SetTypeCommand,
|
||||
AddCommand, DelCommand,
|
||||
)
|
||||
from Model.HydraulicStructures.Basic.Types import BHS_types
|
||||
|
||||
logger = logging.getLogger()
|
||||
|
||||
_translate = QCoreApplication.translate
|
||||
|
||||
|
||||
class ComboBoxDelegate(QItemDelegate):
|
||||
def __init__(self, data=None, trad=None, parent=None):
|
||||
super(ComboBoxDelegate, self).__init__(parent)
|
||||
|
||||
self._data = data
|
||||
self._trad = trad
|
||||
|
||||
self._long_types = {}
|
||||
if self._trad is not None:
|
||||
self._long_types = self._trad.get_dict("long_types")
|
||||
|
||||
def createEditor(self, parent, option, index):
|
||||
self.editor = QComboBox(parent)
|
||||
|
||||
|
||||
lst = list(
|
||||
map(
|
||||
lambda k: self._long_types[k], BHS_types.keys()
|
||||
)
|
||||
)
|
||||
self.editor.addItems(
|
||||
lst
|
||||
)
|
||||
|
||||
self.editor.setCurrentText(index.data(Qt.DisplayRole))
|
||||
return self.editor
|
||||
|
||||
def setEditorData(self, editor, index):
|
||||
value = index.data(Qt.DisplayRole)
|
||||
self.editor.currentTextChanged.connect(self.currentItemChanged)
|
||||
|
||||
def setModelData(self, editor, model, index):
|
||||
text = str(editor.currentText())
|
||||
model.setData(index, text)
|
||||
editor.close()
|
||||
editor.deleteLater()
|
||||
|
||||
def updateEditorGeometry(self, editor, option, index):
|
||||
r = QRect(option.rect)
|
||||
if self.editor.windowFlags() & Qt.Popup:
|
||||
if editor.parent() is not None:
|
||||
r.setTopLeft(self.editor.parent().mapToGlobal(r.topLeft()))
|
||||
editor.setGeometry(r)
|
||||
|
||||
@pyqtSlot()
|
||||
def currentItemChanged(self):
|
||||
self.commitData.emit(self.sender())
|
||||
|
||||
|
||||
class TableModel(PamhyrTableModel):
|
||||
def _setup_lst(self):
|
||||
self._lst = self._data.basic_structures
|
||||
|
||||
def rowCount(self, parent):
|
||||
return len(self._lst)
|
||||
|
||||
def data(self, index, role):
|
||||
if role != Qt.ItemDataRole.DisplayRole:
|
||||
return QVariant()
|
||||
|
||||
row = index.row()
|
||||
column = index.column()
|
||||
|
||||
if self._headers[column] == "name":
|
||||
return self._lst[row].name
|
||||
elif self._headers[column] == "type":
|
||||
n = self._lst[row].type
|
||||
|
||||
return QVariant()
|
||||
|
||||
def setData(self, index, value, role=Qt.EditRole):
|
||||
if not index.isValid() or role != Qt.EditRole:
|
||||
return False
|
||||
|
||||
row = index.row()
|
||||
column = index.column()
|
||||
|
||||
try:
|
||||
if self._headers[column] == "name":
|
||||
self._undo.push(
|
||||
SetNameCommand(
|
||||
self._data, row, value
|
||||
)
|
||||
)
|
||||
elif self._headers[column] == "type":
|
||||
self._undo.push(
|
||||
SetTypeCommand(
|
||||
self._data, row, type
|
||||
)
|
||||
)
|
||||
except Exception as e:
|
||||
logger.info(e)
|
||||
logger.debug(traceback.format_exc())
|
||||
|
||||
self.dataChanged.emit(index, index)
|
||||
return True
|
||||
|
||||
def add(self, row, parent=QModelIndex()):
|
||||
self.beginInsertRows(parent, row, row - 1)
|
||||
|
||||
self._undo.push(
|
||||
AddCommand(
|
||||
self._data, row
|
||||
)
|
||||
)
|
||||
|
||||
self.endInsertRows()
|
||||
self.layoutChanged.emit()
|
||||
|
||||
def delete(self, rows, parent=QModelIndex()):
|
||||
self.beginRemoveRows(parent, rows[0], rows[-1])
|
||||
|
||||
self._undo.push(
|
||||
DelCommand(
|
||||
self._data, rows
|
||||
)
|
||||
)
|
||||
|
||||
self.endRemoveRows()
|
||||
self.layoutChanged.emit()
|
||||
|
||||
def undo(self):
|
||||
self._undo.undo()
|
||||
self.layoutChanged.emit()
|
||||
|
||||
def redo(self):
|
||||
self._undo.redo()
|
||||
self.layoutChanged.emit()
|
||||
|
|
|
|||
|
|
@ -21,3 +21,17 @@ from PyQt5.QtCore import QCoreApplication
|
|||
from View.Tools.PamhyrTranslate import PamhyrTranslate
|
||||
|
||||
_translate = QCoreApplication.translate
|
||||
|
||||
|
||||
class BasicHydraulicStructuresTranslate(PamhyrTranslate):
|
||||
def __init__(self):
|
||||
super(BasicHydraulicStructuresTranslate, self).__init__()
|
||||
|
||||
self._sub_dict["long_types"] = {
|
||||
"ND": _translate("BasicHydraulicStructures", "Not defined"),
|
||||
}
|
||||
|
||||
self._sub_dict["table_headers"] = {
|
||||
"name": _translate("BasicHydraulicStructures", "Name"),
|
||||
"type": _translate("BasicHydraulicStructures", "Type"),
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,3 +15,104 @@
|
|||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from copy import deepcopy
|
||||
from tools import trace, timer
|
||||
|
||||
from PyQt5.QtWidgets import (
|
||||
QMessageBox, QUndoCommand, QUndoStack,
|
||||
)
|
||||
|
||||
|
||||
class SetNameCommand(QUndoCommand):
|
||||
def __init__(self, hs, index, new_value):
|
||||
QUndoCommand.__init__(self)
|
||||
|
||||
self._hs = hs
|
||||
self._index = index
|
||||
self._old = self._hs.basic_structure(self._index).name
|
||||
self._new = str(new_value)
|
||||
|
||||
def undo(self):
|
||||
self._hs.basic_structure(self._index).name = self._old
|
||||
|
||||
def redo(self):
|
||||
self._hs.basic_structure(self._index).name = self._new
|
||||
|
||||
|
||||
class SetTypeCommand(QUndoCommand):
|
||||
def __init__(self, hs, index, reach):
|
||||
QUndoCommand.__init__(self)
|
||||
|
||||
self._hs = hs
|
||||
self._index = index
|
||||
self._type = _type
|
||||
self._old = self._hs.basic_structure(self._index)
|
||||
self._new = self._hs.basic_structure(self._index)\
|
||||
.convert(self._type)
|
||||
|
||||
def undo(self):
|
||||
self._hs.basic_structure(self._index).convert(self._old)
|
||||
|
||||
def redo(self):
|
||||
self._hs.basic_structure(self._index).convert(self._new)
|
||||
|
||||
|
||||
class AddCommand(QUndoCommand):
|
||||
def __init__(self, hs, index):
|
||||
QUndoCommand.__init__(self)
|
||||
|
||||
self._hs = hs
|
||||
|
||||
self._index = index
|
||||
self._new = None
|
||||
|
||||
def undo(self):
|
||||
self._hs.delete_i([self._index])
|
||||
|
||||
def redo(self):
|
||||
if self._new is None:
|
||||
self._new = self._hs.add(self._index)
|
||||
else:
|
||||
self._hs.insert(self._index, self._new)
|
||||
|
||||
|
||||
class DelCommand(QUndoCommand):
|
||||
def __init__(self, hs, rows):
|
||||
QUndoCommand.__init__(self)
|
||||
|
||||
self._hs = hs
|
||||
|
||||
self._rows = rows
|
||||
|
||||
self._bhs = []
|
||||
for row in rows:
|
||||
self._bhs.append((row, self._hs.basic_structure(row)))
|
||||
|
||||
def undo(self):
|
||||
for row, el in self._bhs:
|
||||
self._hs.insert(row, el)
|
||||
|
||||
def redo(self):
|
||||
self._hs.delete_i(self._rows)
|
||||
|
||||
|
||||
class PasteCommand(QUndoCommand):
|
||||
def __init__(self, hs, row, h_s):
|
||||
QUndoCommand.__init__(self)
|
||||
|
||||
self._hs = hs
|
||||
|
||||
self._row = row
|
||||
self._bhs = deepcopy(h_s)
|
||||
self._bhs.reverse()
|
||||
|
||||
def undo(self):
|
||||
self._hs.delete_i(
|
||||
self._tab,
|
||||
range(self._row, self._row + len(self._bhs))
|
||||
)
|
||||
|
||||
def redo(self):
|
||||
for r in self._bhs:
|
||||
self._hs.insert(self._row, r)
|
||||
|
|
|
|||
|
|
@ -15,3 +15,207 @@
|
|||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import logging
|
||||
|
||||
from tools import timer, trace
|
||||
|
||||
from View.Tools.PamhyrWindow import PamhyrWindow
|
||||
|
||||
from PyQt5 import QtCore
|
||||
from PyQt5.QtCore import (
|
||||
Qt, QVariant, QAbstractTableModel, QCoreApplication,
|
||||
pyqtSlot, pyqtSignal, QItemSelectionModel,
|
||||
)
|
||||
|
||||
from PyQt5.QtWidgets import (
|
||||
QDialogButtonBox, QPushButton, QLineEdit,
|
||||
QFileDialog, QTableView, QAbstractItemView,
|
||||
QUndoStack, QShortcut, QAction, QItemDelegate,
|
||||
QHeaderView, QDoubleSpinBox, QVBoxLayout, QCheckBox
|
||||
)
|
||||
|
||||
from View.Tools.Plot.PamhyrCanvas import MplCanvas
|
||||
from View.Tools.Plot.PamhyrToolbar import PamhyrPlotToolbar
|
||||
|
||||
from View.HydraulicStructures.PlotAC import PlotAC
|
||||
|
||||
from View.HydraulicStructures.BasicHydraulicStructures.Table import (
|
||||
TableModel, ComboBoxDelegate
|
||||
)
|
||||
|
||||
from View.Network.GraphWidget import GraphWidget
|
||||
from View.HydraulicStructures.BasicHydraulicStructures.Translate import BasicHydraulicStructuresTranslate
|
||||
|
||||
_translate = QCoreApplication.translate
|
||||
|
||||
logger = logging.getLogger()
|
||||
|
||||
|
||||
class BasicHydraulicStructuresWindow(PamhyrWindow):
|
||||
_pamhyr_ui = "BasicHydraulicStructures"
|
||||
_pamhyr_name = "Basic Hydraulic Structures"
|
||||
|
||||
def __init__(self, data=None, study=None, config=None, parent=None):
|
||||
name = self._pamhyr_name + " - " + study.name
|
||||
|
||||
super(BasicHydraulicStructuresWindow, self).__init__(
|
||||
title=name,
|
||||
study=study,
|
||||
config=config,
|
||||
trad=BasicHydraulicStructuresTranslate(),
|
||||
parent=parent
|
||||
)
|
||||
|
||||
self._hash_data.append(data)
|
||||
|
||||
self._hs = data
|
||||
|
||||
self.setup_table()
|
||||
self.setup_checkbox()
|
||||
self.setup_plot()
|
||||
self.setup_connections()
|
||||
|
||||
def setup_table(self):
|
||||
self._table = None
|
||||
|
||||
self._delegate_type = ComboBoxDelegate(
|
||||
trad=self._trad,
|
||||
parent=self
|
||||
)
|
||||
|
||||
table = self.find(QTableView, f"tableView")
|
||||
self._table = TableModel(
|
||||
table_view=table,
|
||||
table_headers=self._trad.get_dict("table_headers"),
|
||||
editable_headers=["name", "type"],
|
||||
delegates={
|
||||
"type": self._delegate_type,
|
||||
},
|
||||
trad=self._trad,
|
||||
data=self._hs,
|
||||
undo=self._undo_stack,
|
||||
)
|
||||
|
||||
selectionModel = table.selectionModel()
|
||||
index = table.model().index(0, 0)
|
||||
|
||||
selectionModel.select(
|
||||
index,
|
||||
QItemSelectionModel.Rows |
|
||||
QItemSelectionModel.ClearAndSelect |
|
||||
QItemSelectionModel.Select
|
||||
)
|
||||
table.scrollTo(index)
|
||||
|
||||
def setup_checkbox(self):
|
||||
self._checkbox = self.find(QCheckBox, f"checkBox")
|
||||
self._set_checkbox_state()
|
||||
|
||||
def setup_plot(self):
|
||||
self.canvas = MplCanvas(width=5, height=4, dpi=100)
|
||||
self.canvas.setObjectName("canvas")
|
||||
self.toolbar = PamhyrPlotToolbar(
|
||||
self.canvas, self
|
||||
)
|
||||
self.plot_layout = self.find(QVBoxLayout, "verticalLayout")
|
||||
self.plot_layout.addWidget(self.toolbar)
|
||||
self.plot_layout.addWidget(self.canvas)
|
||||
|
||||
self.plot_ac = PlotAC(
|
||||
canvas=self.canvas,
|
||||
river=self._study.river,
|
||||
reach=None,
|
||||
profile=None,
|
||||
toolbar=self.toolbar
|
||||
)
|
||||
self.plot_ac.draw()
|
||||
|
||||
def setup_connections(self):
|
||||
self.find(QAction, "action_add").triggered.connect(self.add)
|
||||
self.find(QAction, "action_delete").triggered.connect(self.delete)
|
||||
self._checkbox.stateChanged.connect(self._set_basic_structure_state)
|
||||
|
||||
table = self.find(QTableView, "tableView")
|
||||
table.selectionModel()\
|
||||
.selectionChanged\
|
||||
.connect(self.update)
|
||||
|
||||
def index_selected(self):
|
||||
table = self.find(QTableView, "tableView")
|
||||
r = table.selectionModel()\
|
||||
.selectedRows()
|
||||
if len(r)>0:
|
||||
return r[0]
|
||||
else:
|
||||
return None
|
||||
|
||||
def index_selected_row(self):
|
||||
table = self.find(QTableView, "tableView")
|
||||
r = table.selectionModel()\
|
||||
.selectedRows()
|
||||
if len(r)>0:
|
||||
return r[0].row()
|
||||
else:
|
||||
return None
|
||||
|
||||
def index_selected_rows(self):
|
||||
table = self.find(QTableView, "tableView")
|
||||
return list(
|
||||
# Delete duplicate
|
||||
set(
|
||||
map(
|
||||
lambda i: i.row(),
|
||||
table.selectedIndexes()
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
def add(self):
|
||||
rows = self.index_selected_rows()
|
||||
if len(self._hs) == 0 or len(rows) == 0:
|
||||
self._table.add(0)
|
||||
else:
|
||||
self._table.add(rows[0])
|
||||
|
||||
def delete(self):
|
||||
rows = self.index_selected_rows()
|
||||
if len(rows) == 0:
|
||||
return
|
||||
|
||||
self._table.delete(rows)
|
||||
|
||||
def _copy(self):
|
||||
logger.info("TODO: copy")
|
||||
|
||||
def _paste(self):
|
||||
logger.info("TODO: paste")
|
||||
|
||||
def _undo(self):
|
||||
self._table.undo()
|
||||
|
||||
def _redo(self):
|
||||
self._table.redo()
|
||||
|
||||
def _set_checkbox_state(self):
|
||||
row = self.index_selected_row()
|
||||
if row is None:
|
||||
self._checkbox.setEnabled(False)
|
||||
self._checkbox.setChecked(True)
|
||||
else:
|
||||
self._checkbox.setEnabled(True)
|
||||
self._checkbox.setChecked(self._hs.basic_structure(row).enabled)
|
||||
|
||||
def _set_basic_structure_state(self):
|
||||
row = self.index_selected_row()
|
||||
if row is None:
|
||||
self._checkbox.setEnabled(False)
|
||||
else:
|
||||
self._hs.basic_structure(row).enabled = self._checkbox.isChecked()
|
||||
|
||||
def update(self):
|
||||
self._set_checkbox_state()
|
||||
self._update_clear_plot()
|
||||
|
||||
def _update_clear_plot(self):
|
||||
rows = self.index_selected_rows()
|
||||
|
|
|
|||
|
|
@ -126,5 +126,5 @@ class PlotAC(PamhyrPlot):
|
|||
|
||||
def clear(self):
|
||||
if self.line_kp is not None:
|
||||
self.line_kp.set_data([],[])
|
||||
self.line_kp.set_data([], [])
|
||||
self.canvas.figure.canvas.draw_idle()
|
||||
|
|
|
|||
|
|
@ -110,7 +110,6 @@ class PlotKPC(PamhyrPlot):
|
|||
color='red', lw=1.
|
||||
)
|
||||
|
||||
|
||||
self.canvas.figure.tight_layout()
|
||||
self.canvas.figure.canvas.draw_idle()
|
||||
if self.toolbar is not None:
|
||||
|
|
@ -144,16 +143,15 @@ class PlotKPC(PamhyrPlot):
|
|||
|
||||
def clear(self):
|
||||
if self.profile is not None:
|
||||
self.profile.set_data([],[])
|
||||
self.profile.set_data([], [])
|
||||
if self.line_kp_zmin_zmax is not None:
|
||||
self.line_kp_zmin_zmax.remove()
|
||||
self.line_kp_zmin_zmax = None
|
||||
if self.line_kp_zmin is not None:
|
||||
self.line_kp_zmin.set_data([],[])
|
||||
self.line_kp_zmin.set_data([], [])
|
||||
self.canvas.figure.canvas.draw_idle()
|
||||
|
||||
def clear_profile(self):
|
||||
if self.profile is not None:
|
||||
self.profile.set_data([],[])
|
||||
self.profile.set_data([], [])
|
||||
self.canvas.figure.canvas.draw_idle()
|
||||
|
||||
|
|
|
|||
|
|
@ -59,7 +59,9 @@ class ComboBoxDelegate(QItemDelegate):
|
|||
|
||||
val = []
|
||||
if self._mode == "kp":
|
||||
reach = self._data.hydraulic_structures.get(index.row()).input_reach
|
||||
reach = self._data.hydraulic_structures\
|
||||
.get(index.row())\
|
||||
.input_reach
|
||||
if reach is not None:
|
||||
val = list(
|
||||
map(
|
||||
|
|
@ -138,6 +140,7 @@ class TableModel(PamhyrTableModel):
|
|||
|
||||
row = index.row()
|
||||
column = index.column()
|
||||
na = _translate("Hydraulic structure", "Not associated")
|
||||
|
||||
try:
|
||||
if self._headers[column] == "name":
|
||||
|
|
@ -147,12 +150,18 @@ class TableModel(PamhyrTableModel):
|
|||
)
|
||||
)
|
||||
elif self._headers[column] == "reach":
|
||||
if value == na:
|
||||
value = None
|
||||
|
||||
self._undo.push(
|
||||
SetReachCommand(
|
||||
self._lst, row, self._data.edge(value)
|
||||
)
|
||||
)
|
||||
elif self._headers[column] == "kp":
|
||||
if value == na:
|
||||
value = None
|
||||
|
||||
self._undo.push(
|
||||
SetKpCommand(
|
||||
self._lst, row, value
|
||||
|
|
|
|||
|
|
@ -99,6 +99,7 @@ class SetEnabledCommand(QUndoCommand):
|
|||
logger.info(f"Undo {self._old} -> {self._new}")
|
||||
self._h_s_lst.get(self._index).enabled = self._new
|
||||
|
||||
|
||||
class AddCommand(QUndoCommand):
|
||||
def __init__(self, h_s_lst, index):
|
||||
QUndoCommand.__init__(self)
|
||||
|
|
|
|||
|
|
@ -84,13 +84,13 @@ class HydraulicStructuresWindow(PamhyrWindow):
|
|||
trad=self._trad,
|
||||
data=self._study.river,
|
||||
parent=self,
|
||||
mode = "reaches"
|
||||
mode="reaches"
|
||||
)
|
||||
self._delegate_kp = ComboBoxDelegate(
|
||||
trad=self._trad,
|
||||
data=self._study.river,
|
||||
parent=self,
|
||||
mode = "kp"
|
||||
mode="kp"
|
||||
)
|
||||
|
||||
table = self.find(QTableView, f"tableView")
|
||||
|
|
@ -177,7 +177,7 @@ class HydraulicStructuresWindow(PamhyrWindow):
|
|||
table = self.find(QTableView, "tableView")
|
||||
r = table.selectionModel().selectedRows()
|
||||
|
||||
if len(r)>0:
|
||||
if len(r) > 0:
|
||||
return r[0]
|
||||
else:
|
||||
return None
|
||||
|
|
@ -186,7 +186,7 @@ class HydraulicStructuresWindow(PamhyrWindow):
|
|||
table = self.find(QTableView, "tableView")
|
||||
r = table.selectionModel().selectedRows()
|
||||
|
||||
if len(r)>0:
|
||||
if len(r) > 0:
|
||||
return r[0].row()
|
||||
else:
|
||||
return None
|
||||
|
|
@ -233,7 +233,8 @@ class HydraulicStructuresWindow(PamhyrWindow):
|
|||
rows = self.index_selected_rows()
|
||||
for row in rows:
|
||||
data = self._hs_lst.get(row)
|
||||
|
||||
print(row)
|
||||
print(data)
|
||||
if self.sub_window_exists(
|
||||
BasicHydraulicStructuresWindow,
|
||||
data=[self._study, None, data]
|
||||
|
|
@ -266,37 +267,43 @@ class HydraulicStructuresWindow(PamhyrWindow):
|
|||
|
||||
def update(self):
|
||||
self._set_checkbox_state()
|
||||
self._update_clear_plot()
|
||||
|
||||
def _update_clear_plot(self):
|
||||
rows = self.index_selected_rows()
|
||||
|
||||
if len(rows) > 0 and len(self._hs_lst) > 0:
|
||||
reach = self._hs_lst.get(rows[0]).input_reach
|
||||
else:
|
||||
reach=None
|
||||
self.plot_kpc.clear()
|
||||
self.plot_ac.clear()
|
||||
if len(rows) == 0 or len(self._hs_lst) == 0:
|
||||
self._update_clear_all()
|
||||
return
|
||||
|
||||
profile_kp = self._hs_lst.get(rows[0]).input_kp
|
||||
if profile_kp is None or profile_kp == "Not associated":
|
||||
profile = None
|
||||
self.plot_ac.clear()
|
||||
self.plot_kpc.clear_profile()
|
||||
else:
|
||||
profile = reach.reach.get_profiles_from_kp(float(profile_kp))
|
||||
|
||||
if reach is not None and reach != "Not associated":
|
||||
reach = self._hs_lst.get(rows[0]).input_reach
|
||||
if reach is not None:
|
||||
self.plot_kpc.set_reach(reach)
|
||||
self.plot_ac.set_reach(reach)
|
||||
else:
|
||||
self.plot_kpc.clear()
|
||||
self.plot_ac.clear()
|
||||
return
|
||||
|
||||
profile_kp = self._hs_lst.get(rows[0]).input_kp
|
||||
if profile_kp is not None:
|
||||
profiles = reach.reach\
|
||||
.get_profiles_from_kp(
|
||||
float(profile_kp)
|
||||
)
|
||||
|
||||
if profile is not None:
|
||||
self.plot_kpc.set_profile(profile[0])
|
||||
self.plot_ac.set_profile(profile[0])
|
||||
if profiles is not None:
|
||||
profile = profiles[0]
|
||||
|
||||
self.plot_kpc.set_profile(profile)
|
||||
self.plot_ac.set_profile(profile)
|
||||
else:
|
||||
self._update_clear_profile()
|
||||
else:
|
||||
self._update_clear_profile()
|
||||
else:
|
||||
self.plot_ac.clear()
|
||||
self.plot_kpc.clear_profile()
|
||||
self._update_clear_all()
|
||||
|
||||
def _update_clear_all(self):
|
||||
self.plot_kpc.clear()
|
||||
self.plot_ac.clear()
|
||||
|
||||
def _update_clear_profile(self):
|
||||
self.plot_ac.clear()
|
||||
self.plot_kpc.clear_profile()
|
||||
|
|
|
|||
|
|
@ -101,7 +101,7 @@ class EditLateralContributionWindow(PamhyrWindow):
|
|||
table_headers=headers,
|
||||
editable_headers=self._data.header,
|
||||
delegates={
|
||||
#"time": self._delegate_time,
|
||||
# "time": self._delegate_time,
|
||||
},
|
||||
data=self._data,
|
||||
undo=self._undo_stack,
|
||||
|
|
|
|||
|
|
@ -195,7 +195,8 @@ class ApplicationWindow(QMainWindow, ListedSubWindow, WindowToolKit):
|
|||
"action_menu_edit_geometry": self.open_geometry,
|
||||
"action_menu_boundary_conditions": self.open_boundary_cond,
|
||||
"action_menu_edit_reservoirs": self.open_reservoir,
|
||||
"action_menu_edit_hydraulic_structures": self.open_hydraulic_structures,
|
||||
"action_menu_edit_hydraulic_structures":
|
||||
self.open_hydraulic_structures,
|
||||
"action_menu_initial_conditions": self.open_initial_conditions,
|
||||
"action_menu_edit_friction": self.open_frictions,
|
||||
"action_menu_edit_lateral_contribution": self.open_lateral_contrib,
|
||||
|
|
@ -282,8 +283,7 @@ class ApplicationWindow(QMainWindow, ListedSubWindow, WindowToolKit):
|
|||
Nothing
|
||||
"""
|
||||
self.update_enable_action()
|
||||
# Maximise window
|
||||
#self.showMaximized()
|
||||
# self.showMaximized()
|
||||
|
||||
def set_debug_lvl(self, debug=True):
|
||||
if debug:
|
||||
|
|
@ -638,7 +638,10 @@ class ApplicationWindow(QMainWindow, ListedSubWindow, WindowToolKit):
|
|||
):
|
||||
return
|
||||
|
||||
hydraulic_structures = HydraulicStructuresWindow(study=self._study, parent=self)
|
||||
hydraulic_structures = HydraulicStructuresWindow(
|
||||
study=self._study,
|
||||
parent=self
|
||||
)
|
||||
hydraulic_structures.show()
|
||||
|
||||
def open_lateral_contrib(self):
|
||||
|
|
@ -648,7 +651,10 @@ class ApplicationWindow(QMainWindow, ListedSubWindow, WindowToolKit):
|
|||
):
|
||||
return
|
||||
|
||||
lateral = LateralContributionWindow(study=self._study, parent=self)
|
||||
lateral = LateralContributionWindow(
|
||||
study=self._study,
|
||||
parent=self
|
||||
)
|
||||
lateral.show()
|
||||
|
||||
def open_stricklers(self):
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ class Plot(PamhyrPlot):
|
|||
)
|
||||
|
||||
# Plot label
|
||||
#header = self.data.header
|
||||
# header = self.data.header
|
||||
self.canvas.axes.set_xlabel(
|
||||
self._table_headers["z"], color='black', fontsize=10
|
||||
)
|
||||
|
|
|
|||
|
|
@ -88,18 +88,13 @@ class EditReservoirWindow(PamhyrWindow):
|
|||
def setup_table(self):
|
||||
headers = {}
|
||||
table_headers = self._trad.get_dict("table_headers")
|
||||
#for h in self._data.header:
|
||||
#headers[h] = table_headers[h]
|
||||
|
||||
table = self.find(QTableView, "tableView")
|
||||
self._table = TableModel(
|
||||
table_view=table,
|
||||
table_headers=table_headers,
|
||||
editable_headers=table_headers,
|
||||
#editable_headers=self._data.header,
|
||||
delegates={
|
||||
#"time": self._delegate_time,
|
||||
},
|
||||
delegates={},
|
||||
data=self._data,
|
||||
undo=self._undo_stack,
|
||||
opt_data=self._study.time_system
|
||||
|
|
@ -181,7 +176,7 @@ class EditReservoirWindow(PamhyrWindow):
|
|||
rows = self.index_selected_rows()
|
||||
|
||||
table = []
|
||||
#table.append(self._data.header)
|
||||
# table.append(self._data.header)
|
||||
table.append(self._trad.get_dict("table_headers"))
|
||||
|
||||
data = self._data.data
|
||||
|
|
|
|||
|
|
@ -175,12 +175,12 @@ class PlotH(PamhyrPlot):
|
|||
|
||||
def set_timestamp(self, timestamp):
|
||||
self._current_timestamp = timestamp
|
||||
#self.update()
|
||||
# self.update()
|
||||
|
||||
def update(self):
|
||||
reach = self.results.river.reach(self._current_reach_id)
|
||||
profile = reach.profile(self._current_profile_id)
|
||||
x = self.ts
|
||||
y = profile.get_key("Q")
|
||||
self._line.set_data(x,y)
|
||||
self._line.set_data(x, y)
|
||||
self.canvas.figure.canvas.draw_idle()
|
||||
|
|
|
|||
|
|
@ -105,8 +105,14 @@ class PlotKPC(PamhyrPlot):
|
|||
)
|
||||
|
||||
self.profile, = self.canvas.axes.plot(
|
||||
[kp[self._current_profile_id], kp[self._current_profile_id]],
|
||||
[z_max[self._current_profile_id],z_min[self._current_profile_id]],
|
||||
[
|
||||
kp[self._current_profile_id],
|
||||
kp[self._current_profile_id]
|
||||
],
|
||||
[
|
||||
z_max[self._current_profile_id],
|
||||
z_min[self._current_profile_id]
|
||||
],
|
||||
color='red', lw=1.
|
||||
)
|
||||
|
||||
|
|
@ -137,7 +143,13 @@ class PlotKPC(PamhyrPlot):
|
|||
z_min = reach.geometry.get_z_min()
|
||||
z_max = reach.geometry.get_z_max()
|
||||
self.profile.set_data(
|
||||
[kp[self._current_profile_id], kp[self._current_profile_id]],
|
||||
[z_max[self._current_profile_id],z_min[self._current_profile_id]]
|
||||
[
|
||||
kp[self._current_profile_id],
|
||||
kp[self._current_profile_id]
|
||||
],
|
||||
[
|
||||
z_max[self._current_profile_id],
|
||||
z_min[self._current_profile_id]
|
||||
]
|
||||
)
|
||||
self.canvas.figure.canvas.draw_idle()
|
||||
|
|
|
|||
|
|
@ -136,10 +136,14 @@ class PlotXY(PamhyrPlot):
|
|||
poly_x = [0]
|
||||
poly_y = [0]
|
||||
|
||||
self.fill = self.canvas.axes.fill(poly_x, poly_y, color='skyblue', alpha=0.7)
|
||||
self.fill = self.canvas.axes.fill(
|
||||
poly_x, poly_y,
|
||||
color='skyblue',
|
||||
alpha=0.7
|
||||
)
|
||||
|
||||
#self.canvas.axes.autoscale_view(True, True, True)
|
||||
#self.canvas.axes.autoscale()
|
||||
# self.canvas.axes.autoscale_view(True, True, True)
|
||||
# self.canvas.axes.autoscale()
|
||||
self.canvas.figure.tight_layout()
|
||||
self.canvas.figure.canvas.draw_idle()
|
||||
if self.toolbar is not None:
|
||||
|
|
@ -166,7 +170,7 @@ class PlotXY(PamhyrPlot):
|
|||
# Current profile
|
||||
profile = reach.profile(self._current_profile_id).geometry
|
||||
|
||||
self.plot_selected.set_data(profile.x(),profile.y())
|
||||
self.plot_selected.set_data(profile.x(), profile.y())
|
||||
self.plot_selected.set_visible(True)
|
||||
self.canvas.draw_idle()
|
||||
|
||||
|
|
@ -196,12 +200,12 @@ class PlotXY(PamhyrPlot):
|
|||
poly_r_x.append(ptY.x)
|
||||
poly_r_y.append(ptY.y)
|
||||
|
||||
#self.canvas.axes.plot(
|
||||
#x, y, lw=1.,
|
||||
#color='b',
|
||||
#markersize=1,
|
||||
#marker='o'
|
||||
#)
|
||||
# self.canvas.axes.plot(
|
||||
# x, y, lw=1.,
|
||||
# color='b',
|
||||
# markersize=1,
|
||||
# marker='o'
|
||||
# )
|
||||
|
||||
poly_x = poly_l_x + list(reversed(poly_r_x))
|
||||
poly_y = poly_l_y + list(reversed(poly_r_y))
|
||||
|
|
|
|||
|
|
@ -125,9 +125,13 @@ class ResultsWindow(PamhyrWindow):
|
|||
self._slider_time.setValue(len(self._timestamps) - 1)
|
||||
|
||||
self._icon_start = QIcon()
|
||||
self._icon_start.addPixmap(QPixmap('./src/View/ui/ressources/media-playback-start.png'))
|
||||
self._icon_start.addPixmap(
|
||||
QPixmap('./src/View/ui/ressources/media-playback-start.png')
|
||||
)
|
||||
self._icon_pause = QIcon()
|
||||
self._icon_pause.addPixmap(QPixmap('./src/View/ui/ressources/media-playback-pause.png'))
|
||||
self._icon_pause.addPixmap(
|
||||
QPixmap('./src/View/ui/ressources/media-playback-pause.png')
|
||||
)
|
||||
self._button_play = self.find(QPushButton, f"playButton")
|
||||
self._button_play.setIcon(self._icon_start)
|
||||
self._button_back = self.find(QPushButton, f"backButton")
|
||||
|
|
|
|||
|
|
@ -67,6 +67,7 @@ def logger_color_reset():
|
|||
return f"{Style.RESET_ALL}"
|
||||
return ""
|
||||
|
||||
|
||||
def logger_exception(exception):
|
||||
logger.error(
|
||||
f"[{Fore.RED}ERROR{Style.RESET_ALL}] " +
|
||||
|
|
|
|||
Loading…
Reference in New Issue