mirror of https://gitlab.com/pamhyr/pamhyr2
Compare commits
2 Commits
476fa81bc2
...
ee95f0e89e
| Author | SHA1 | Date |
|---|---|---|
|
|
ee95f0e89e | |
|
|
1306977954 |
|
|
@ -0,0 +1,82 @@
|
||||||
|
# Table.py -- Pamhyr
|
||||||
|
# Copyright (C) 2026 INRAE
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
import logging
|
||||||
|
|
||||||
|
from functools import reduce
|
||||||
|
from tools import trace, timer, _timers, _calls, reset_timers
|
||||||
|
|
||||||
|
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 Modules import Modules
|
||||||
|
from View.Tools.PamhyrTable import PamhyrTableModel
|
||||||
|
|
||||||
|
logger = logging.getLogger()
|
||||||
|
|
||||||
|
|
||||||
|
class TableModel(PamhyrTableModel):
|
||||||
|
def _setup_lst(self):
|
||||||
|
self._lst = sorted(
|
||||||
|
map(
|
||||||
|
lambda f: (
|
||||||
|
f"{f.__module__}.{f.__qualname__}",
|
||||||
|
_timers[f],
|
||||||
|
_calls[f]
|
||||||
|
),
|
||||||
|
_timers
|
||||||
|
),
|
||||||
|
key=lambda f: f[1],
|
||||||
|
reverse=True
|
||||||
|
)
|
||||||
|
|
||||||
|
def update_lst(self):
|
||||||
|
self._setup_lst()
|
||||||
|
self.layoutChanged.emit()
|
||||||
|
|
||||||
|
def reset_timers(self):
|
||||||
|
reset_timers()
|
||||||
|
self.update_lst()
|
||||||
|
|
||||||
|
def data(self, index, role):
|
||||||
|
row = index.row()
|
||||||
|
column = index.column()
|
||||||
|
|
||||||
|
if role == Qt.DisplayRole:
|
||||||
|
if self._headers[column] == "name":
|
||||||
|
return self._lst[row][0]
|
||||||
|
elif self._headers[column] == "time":
|
||||||
|
return self._lst[row][1]
|
||||||
|
elif self._headers[column] == "calls":
|
||||||
|
return self._lst[row][2]
|
||||||
|
|
||||||
|
return QVariant()
|
||||||
|
|
||||||
|
def to_csv(self):
|
||||||
|
data = "\n".join(map(lambda x: f"{x[0]},{x[1]},{x[2]}", self._lst))
|
||||||
|
return f"""name,time,calls\n{data}\n"""
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
# Window.py -- Pamhyr
|
# Window.py -- Pamhyr
|
||||||
# Copyright (C) 2023-2025 INRAE
|
# Copyright (C) 2023-2026 INRAE
|
||||||
#
|
#
|
||||||
# This program is free software: you can redistribute it and/or modify
|
# This program is free software: you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU General Public License as published by
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
|
@ -23,6 +23,7 @@ from tools import trace, timer
|
||||||
|
|
||||||
from View.Tools.PamhyrWindow import PamhyrWindow
|
from View.Tools.PamhyrWindow import PamhyrWindow
|
||||||
from View.Tools.PamhyrPythonEditor import PamhyrPythonEditor
|
from View.Tools.PamhyrPythonEditor import PamhyrPythonEditor
|
||||||
|
from View.Debug.Table import TableModel
|
||||||
|
|
||||||
from PyQt5.QtGui import (
|
from PyQt5.QtGui import (
|
||||||
QKeySequence,
|
QKeySequence,
|
||||||
|
|
@ -31,7 +32,7 @@ from PyQt5.QtGui import (
|
||||||
from PyQt5.QtCore import (
|
from PyQt5.QtCore import (
|
||||||
Qt, QVariant, QAbstractTableModel,
|
Qt, QVariant, QAbstractTableModel,
|
||||||
QCoreApplication, QModelIndex, QRect, QThread,
|
QCoreApplication, QModelIndex, QRect, QThread,
|
||||||
pyqtSlot, pyqtSignal,
|
QTimer, pyqtSlot, pyqtSignal,
|
||||||
)
|
)
|
||||||
|
|
||||||
from PyQt5.QtWidgets import (
|
from PyQt5.QtWidgets import (
|
||||||
|
|
@ -101,3 +102,65 @@ class ReplWindow(PamhyrWindow):
|
||||||
self.find(QTextEdit, "textEdit").append(msg)
|
self.find(QTextEdit, "textEdit").append(msg)
|
||||||
# Display results
|
# Display results
|
||||||
self.find(QTextEdit, "textEdit").append(str(value))
|
self.find(QTextEdit, "textEdit").append(str(value))
|
||||||
|
|
||||||
|
class TimerWindow(PamhyrWindow):
|
||||||
|
_pamhyr_ui = "DebugTimer"
|
||||||
|
_pamhyr_name = "Debug Timer"
|
||||||
|
|
||||||
|
def __init__(self, study=None, config=None,
|
||||||
|
solver=None, parent=None):
|
||||||
|
title = _translate("Debug", "Debug Timer")
|
||||||
|
|
||||||
|
super(TimerWindow, self).__init__(
|
||||||
|
title=title,
|
||||||
|
study=study,
|
||||||
|
config=config,
|
||||||
|
options=[],
|
||||||
|
parent=parent
|
||||||
|
)
|
||||||
|
|
||||||
|
self.setup_table()
|
||||||
|
self.setup_alarm()
|
||||||
|
self.setup_connections()
|
||||||
|
|
||||||
|
def setup_table(self):
|
||||||
|
table = self.find(QTableView, f"tableView")
|
||||||
|
self._table = TableModel(
|
||||||
|
table_view=table,
|
||||||
|
table_headers={
|
||||||
|
"name": "Function name",
|
||||||
|
"time": "Time (sec)",
|
||||||
|
"calls": "Number of calls"
|
||||||
|
},
|
||||||
|
data=None,
|
||||||
|
)
|
||||||
|
|
||||||
|
def setup_alarm(self):
|
||||||
|
self._alarm = QTimer()
|
||||||
|
self._alarm.start(2000)
|
||||||
|
|
||||||
|
def setup_connections(self):
|
||||||
|
# self.find(QAction, "action_reset").triggered.connect(self.reset)
|
||||||
|
self.find(QAction, "action_export").triggered.connect(self.export)
|
||||||
|
|
||||||
|
self._alarm.timeout.connect(self.update)
|
||||||
|
|
||||||
|
def update(self):
|
||||||
|
self._table.update_lst()
|
||||||
|
|
||||||
|
# def reset(self):
|
||||||
|
# self._table.reset_timers()
|
||||||
|
|
||||||
|
def export(self):
|
||||||
|
self.file_dialog(
|
||||||
|
select_file="AnyFile",
|
||||||
|
callback=lambda f: self.export_to(f[0]),
|
||||||
|
default_suffix=".csv",
|
||||||
|
file_filter=["CSV file (*.csv)"],
|
||||||
|
)
|
||||||
|
|
||||||
|
def export_to(self, filename):
|
||||||
|
csv = self._table.to_csv()
|
||||||
|
|
||||||
|
with open(filename, 'w', newline='') as csvfile:
|
||||||
|
csvfile.write(csv)
|
||||||
|
|
|
||||||
|
|
@ -100,7 +100,7 @@ from View.CheckList.WindowAdisTS import CheckListWindowAdisTS
|
||||||
from View.Results.WindowAdisTS import ResultsWindowAdisTS
|
from View.Results.WindowAdisTS import ResultsWindowAdisTS
|
||||||
from View.Results.ReadingResultsDialog import ReadingResultsDialog
|
from View.Results.ReadingResultsDialog import ReadingResultsDialog
|
||||||
|
|
||||||
from View.Debug.Window import ReplWindow
|
from View.Debug.Window import ReplWindow, TimerWindow
|
||||||
from View.OutputRKAdisTS.Window import OutputRKAdisTSWindow
|
from View.OutputRKAdisTS.Window import OutputRKAdisTSWindow
|
||||||
from View.Pollutants.Window import PollutantsWindow
|
from View.Pollutants.Window import PollutantsWindow
|
||||||
from View.D90AdisTS.Window import D90AdisTSWindow
|
from View.D90AdisTS.Window import D90AdisTSWindow
|
||||||
|
|
@ -409,21 +409,28 @@ class ApplicationWindow(QMainWindow, ListedSubWindow, WindowToolKit):
|
||||||
self.debug_action.setToolTip(self._trad["open_debug"])
|
self.debug_action.setToolTip(self._trad["open_debug"])
|
||||||
self.debug_action.triggered.connect(self.open_debug)
|
self.debug_action.triggered.connect(self.open_debug)
|
||||||
|
|
||||||
|
self.debug_timer_action = QAction("Debug timer", self)
|
||||||
|
self.debug_timer_action.setToolTip(self._trad["open_debug_timer"])
|
||||||
|
self.debug_timer_action.triggered.connect(self.open_debug_timer)
|
||||||
|
|
||||||
self.debug_sqlite_action = QAction("Debug SQLite", self)
|
self.debug_sqlite_action = QAction("Debug SQLite", self)
|
||||||
self.debug_sqlite_action.setToolTip(self._trad["open_debug_sql"])
|
self.debug_sqlite_action.setToolTip(self._trad["open_debug_sql"])
|
||||||
self.debug_sqlite_action.triggered.connect(self.open_sqlite)
|
self.debug_sqlite_action.triggered.connect(self.open_sqlite)
|
||||||
|
|
||||||
if self.conf.debug:
|
if self.conf.debug:
|
||||||
menu.addAction(self.debug_action)
|
menu.addAction(self.debug_action)
|
||||||
|
menu.addAction(self.debug_timer_action)
|
||||||
menu.addAction(self.debug_sqlite_action)
|
menu.addAction(self.debug_sqlite_action)
|
||||||
self.set_debug_lvl(debug=True)
|
self.set_debug_lvl(debug=True)
|
||||||
else:
|
else:
|
||||||
if self.conf.debug:
|
if self.conf.debug:
|
||||||
menu.addAction(self.debug_action)
|
menu.addAction(self.debug_action)
|
||||||
|
menu.addAction(self.debug_timer_action)
|
||||||
menu.addAction(self.debug_sqlite_action)
|
menu.addAction(self.debug_sqlite_action)
|
||||||
self.set_debug_lvl(debug=True)
|
self.set_debug_lvl(debug=True)
|
||||||
else:
|
else:
|
||||||
menu.removeAction(self.debug_action)
|
menu.removeAction(self.debug_action)
|
||||||
|
menu.removeAction(self.debug_timer_action)
|
||||||
menu.removeAction(self.debug_sqlite_action)
|
menu.removeAction(self.debug_sqlite_action)
|
||||||
self.set_debug_lvl(debug=False)
|
self.set_debug_lvl(debug=False)
|
||||||
|
|
||||||
|
|
@ -2143,6 +2150,14 @@ class ApplicationWindow(QMainWindow, ListedSubWindow, WindowToolKit):
|
||||||
)
|
)
|
||||||
repl.show()
|
repl.show()
|
||||||
|
|
||||||
|
def open_debug_timer(self):
|
||||||
|
repl = TimerWindow(
|
||||||
|
study=self._study,
|
||||||
|
config=self.conf,
|
||||||
|
parent=self
|
||||||
|
)
|
||||||
|
repl.show()
|
||||||
|
|
||||||
def open_sqlite(self):
|
def open_sqlite(self):
|
||||||
if self._study is None:
|
if self._study is None:
|
||||||
logger.debug("No study open for sql debuging...")
|
logger.debug("No study open for sql debuging...")
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,67 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>MainWindow</class>
|
||||||
|
<widget class="QMainWindow" name="MainWindow">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>800</width>
|
||||||
|
<height>600</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>MainWindow</string>
|
||||||
|
</property>
|
||||||
|
<widget class="QWidget" name="centralwidget">
|
||||||
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QTableView" name="tableView"/>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<widget class="QMenuBar" name="menubar">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>800</width>
|
||||||
|
<height>24</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<widget class="QStatusBar" name="statusbar"/>
|
||||||
|
<widget class="QToolBar" name="toolBar">
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>toolBar</string>
|
||||||
|
</property>
|
||||||
|
<attribute name="toolBarArea">
|
||||||
|
<enum>TopToolBarArea</enum>
|
||||||
|
</attribute>
|
||||||
|
<attribute name="toolBarBreak">
|
||||||
|
<bool>false</bool>
|
||||||
|
</attribute>
|
||||||
|
<addaction name="action_export"/>
|
||||||
|
</widget>
|
||||||
|
<action name="action_export">
|
||||||
|
<property name="icon">
|
||||||
|
<iconset>
|
||||||
|
<normaloff>ressources/export.png</normaloff>ressources/export.png</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Export</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="action_reset">
|
||||||
|
<property name="icon">
|
||||||
|
<iconset>
|
||||||
|
<normaloff>ressources/reload.png</normaloff>ressources/reload.png</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Reset</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
||||||
Loading…
Reference in New Issue