mirror of https://gitlab.com/pamhyr/pamhyr2
Debug: Add Timer window.
parent
476fa81bc2
commit
1306977954
|
|
@ -0,0 +1,74 @@
|
|||
# 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
|
||||
|
||||
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 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()
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
# 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
|
||||
# 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.PamhyrPythonEditor import PamhyrPythonEditor
|
||||
from View.Debug.Table import TableModel
|
||||
|
||||
from PyQt5.QtGui import (
|
||||
QKeySequence,
|
||||
|
|
@ -31,7 +32,7 @@ from PyQt5.QtGui import (
|
|||
from PyQt5.QtCore import (
|
||||
Qt, QVariant, QAbstractTableModel,
|
||||
QCoreApplication, QModelIndex, QRect, QThread,
|
||||
pyqtSlot, pyqtSignal,
|
||||
QTimer, pyqtSlot, pyqtSignal,
|
||||
)
|
||||
|
||||
from PyQt5.QtWidgets import (
|
||||
|
|
@ -101,3 +102,54 @@ class ReplWindow(PamhyrWindow):
|
|||
self.find(QTextEdit, "textEdit").append(msg)
|
||||
# Display results
|
||||
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):
|
||||
return
|
||||
|
||||
def export(self):
|
||||
return
|
||||
|
|
|
|||
|
|
@ -100,7 +100,7 @@ from View.CheckList.WindowAdisTS import CheckListWindowAdisTS
|
|||
from View.Results.WindowAdisTS import ResultsWindowAdisTS
|
||||
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.Pollutants.Window import PollutantsWindow
|
||||
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.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.setToolTip(self._trad["open_debug_sql"])
|
||||
self.debug_sqlite_action.triggered.connect(self.open_sqlite)
|
||||
|
||||
if self.conf.debug:
|
||||
menu.addAction(self.debug_action)
|
||||
menu.addAction(self.debug_timer_action)
|
||||
menu.addAction(self.debug_sqlite_action)
|
||||
self.set_debug_lvl(debug=True)
|
||||
else:
|
||||
if self.conf.debug:
|
||||
menu.addAction(self.debug_action)
|
||||
menu.addAction(self.debug_timer_action)
|
||||
menu.addAction(self.debug_sqlite_action)
|
||||
self.set_debug_lvl(debug=True)
|
||||
else:
|
||||
menu.removeAction(self.debug_action)
|
||||
menu.removeAction(self.debug_timer_action)
|
||||
menu.removeAction(self.debug_sqlite_action)
|
||||
self.set_debug_lvl(debug=False)
|
||||
|
||||
|
|
@ -2143,6 +2150,14 @@ class ApplicationWindow(QMainWindow, ListedSubWindow, WindowToolKit):
|
|||
)
|
||||
repl.show()
|
||||
|
||||
def open_debug_timer(self):
|
||||
repl = TimerWindow(
|
||||
study=self._study,
|
||||
config=self.conf,
|
||||
parent=self
|
||||
)
|
||||
repl.show()
|
||||
|
||||
def open_sqlite(self):
|
||||
if self._study is None:
|
||||
logger.debug("No study open for sql debuging...")
|
||||
|
|
|
|||
|
|
@ -0,0 +1,68 @@
|
|||
<?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_reset"/>
|
||||
<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