BC: Edit: Edit time column with custom widget.

mesh
Pierre-Antoine Rouby 2023-05-11 11:23:47 +02:00
parent 4039182689
commit 1775bf2729
7 changed files with 219 additions and 7 deletions

View File

@ -17,7 +17,7 @@ from PyQt5.QtWidgets import (
QTimeEdit, QSpinBox, QTextEdit, QTimeEdit, QSpinBox, QTextEdit,
QRadioButton, QComboBox, QFileDialog, QRadioButton, QComboBox, QFileDialog,
QMessageBox, QTableView, QAction, QMessageBox, QTableView, QAction,
QDateTimeEdit, QDateTimeEdit, QWidget,
) )
from PyQt5.QtCore import ( from PyQt5.QtCore import (
QTime, QDateTime, QTime, QDateTime,
@ -409,7 +409,6 @@ class ASubMainWindow(QMainWindow, ASubWindowFeatures, WindowToolKit):
return self.ui.findChild(qtype, name) return self.ui.findChild(qtype, name)
class ASubWindow(QDialog, ASubWindowFeatures, WindowToolKit): class ASubWindow(QDialog, ASubWindowFeatures, WindowToolKit):
def __init__(self, name="", ui="dummy", parent=None): def __init__(self, name="", ui="dummy", parent=None):
super(ASubWindow, self).__init__(parent=parent) super(ASubWindow, self).__init__(parent=parent)
@ -439,3 +438,27 @@ class ASubWindow(QDialog, ASubWindowFeatures, WindowToolKit):
qtype = self._qtype_from_component_name(name) qtype = self._qtype_from_component_name(name)
return self.ui.findChild(qtype, name) return self.ui.findChild(qtype, name)
class AWidget(QWidget, ASubWindowFeatures):
def __init__(self, ui="", parent=None):
super(AWidget, self).__init__(parent=parent)
self.ui = loadUi(
os.path.join(os.path.dirname(__file__), "ui", "Widgets", f"{ui}.ui"),
self
)
self.parent = parent
def find(self, qtype, name):
"""Find an ui component
Args:
qtype: Type of QT component
name: Name for component
Returns:
return the component
"""
if qtype is None:
qtype = self._qtype_from_component_name(name)
return self.ui.findChild(qtype, name)

View File

@ -1,5 +1,7 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from datetime import datetime
from tools import timer, trace from tools import timer, trace
from View.Plot.APlot import APlot from View.Plot.APlot import APlot
@ -19,6 +21,35 @@ class Plot(APlot):
toolbar=toolbar toolbar=toolbar
) )
def custom_ticks(self):
t0 = datetime.fromtimestamp(0)
nb = len(self.data.data)
mod = int(nb / 5)
fx = list(
map(
lambda x: x[1],
filter(
lambda x: x[0] % mod == 0,
enumerate(self.data.data)
)
)
)
xx = list(map(lambda v: v[0], fx))
xt = list(
map(
lambda v: str(
datetime.fromtimestamp(v[0]) - t0
).split(",")[0]\
.replace("days", _translate("BoundaryCondition", "days"))\
.replace("day", _translate("BoundaryCondition", "day")),
fx
)
)
self.canvas.axes.set_xticks(ticks=xx, labels=xt, rotation=45)
@timer @timer
def draw(self): def draw(self):
self.canvas.axes.cla() self.canvas.axes.cla()
@ -38,6 +69,8 @@ class Plot(APlot):
picker=30, picker=30,
) )
self.custom_ticks()
# Plot label # Plot label
header = self.data.header header = self.data.header
self.canvas.axes.set_xlabel( self.canvas.axes.set_xlabel(
@ -65,6 +98,8 @@ class Plot(APlot):
self._line.set_data(x, y) self._line.set_data(x, y)
self.custom_ticks()
self.canvas.axes.relim() self.canvas.axes.relim()
self.canvas.axes.autoscale() self.canvas.axes.autoscale()
self.canvas.figure.tight_layout() self.canvas.figure.tight_layout()

View File

@ -1,18 +1,21 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from datetime import date, time, datetime, timedelta
from tools import trace, timer from tools import trace, timer
from View.ASubWindow import ASubMainWindow from View.ASubWindow import ASubMainWindow, AWidget
from View.ListedSubWindow import ListedSubWindow from View.ListedSubWindow import ListedSubWindow
from PyQt5.QtCore import ( from PyQt5.QtCore import (
Qt, QVariant, QAbstractTableModel, Qt, QVariant, QAbstractTableModel,
QCoreApplication, QModelIndex, pyqtSlot, QCoreApplication, QModelIndex, pyqtSlot,
QRect, QRect, QTime,
) )
from PyQt5.QtWidgets import ( from PyQt5.QtWidgets import (
QTableView, QAbstractItemView, QTableView, QAbstractItemView, QSpinBox,
QTimeEdit, QItemDelegate,
) )
from Model.BoundaryCondition.BoundaryConditionTypes import ( from Model.BoundaryCondition.BoundaryConditionTypes import (
@ -30,6 +33,79 @@ from View.BoundaryCondition.Edit.translate import *
_translate = QCoreApplication.translate _translate = QCoreApplication.translate
class ExtendedTimeEdit(AWidget):
def __init__(self, parent=None):
super(ExtendedTimeEdit, self).__init__(
ui="extendedTimeEdit",
parent=parent
)
self.parent = parent
self.spinBox_days = self.find(QSpinBox, "spinBox_days")
self.timeEdit = self.find(QTimeEdit, "timeEdit")
def set_time(self, time):
days = 0
stime = time
if "," in time:
s = time.strip().split(" ")
days = int(s[0])
stime = s[-1]
qtime = QTime.fromString(
stime,
"h:mm:ss"
)
self.spinBox_days.setValue(days)
self.timeEdit.setTime(qtime)
def get_time(self):
days = self.spinBox_days.value()
time = self.timeEdit.time().toPyTime()
secs = (
(time.hour * 3600) +
(time.minute * 60) +
time.second
)
return timedelta(days=days, seconds=secs)
class ExTimeDelegate(QItemDelegate):
def __init__(self, data=None, mode="time", parent=None):
super(ExTimeDelegate, self).__init__(parent)
self._data = data
self._mode = mode
def createEditor(self, parent, option, index):
self.editor = ExtendedTimeEdit(parent=parent)
value = index.data(Qt.DisplayRole)
self.editor.set_time(value)
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):
time = editor.get_time()
model.setData(index, int(time.total_seconds()))
editor.close()
editor.deleteLater()
def updateEditorGeometry(self, editor, option, index):
r = QRect(option.rect)
if self.editor.windowFlags() & Qt.Popup and 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(QAbstractTableModel): class TableModel(QAbstractTableModel):
def __init__(self, data=None, undo=None): def __init__(self, data=None, undo=None):
super(QAbstractTableModel, self).__init__() super(QAbstractTableModel, self).__init__()
@ -65,6 +141,11 @@ class TableModel(QAbstractTableModel):
v = self._data.get_i(row)[column] v = self._data.get_i(row)[column]
if self._data.get_type_column(column) == float: if self._data.get_type_column(column) == float:
value = f"{v:.4f}" value = f"{v:.4f}"
elif self._data.header[column] == "time":
t0 = datetime.fromtimestamp(0)
t = datetime.fromtimestamp(v)
value = str(t - t0)
#value = v
else: else:
# TODO: Time format # TODO: Time format
value = f"{v}" value = f"{v}"

View File

@ -21,7 +21,7 @@ from PyQt5.QtWidgets import (
from View.Plot.MplCanvas import MplCanvas from View.Plot.MplCanvas import MplCanvas
from View.BoundaryCondition.translate import long_types from View.BoundaryCondition.translate import long_types
from View.BoundaryCondition.Edit.Table import TableModel from View.BoundaryCondition.Edit.Table import TableModel, ExTimeDelegate
from View.BoundaryCondition.Edit.Plot import Plot from View.BoundaryCondition.Edit.Plot import Plot
_translate = QCoreApplication.translate _translate = QCoreApplication.translate
@ -68,6 +68,17 @@ class EditBoundaryConditionWindow(ASubMainWindow, ListedSubWindow):
data = self._data, data = self._data,
undo = self._undo_stack undo = self._undo_stack
) )
self._delegate_time = ExTimeDelegate(
data = self._data,
mode = "type",
parent=self
)
table.setItemDelegateForColumn(
0, self._delegate_time
)
table.setModel(self._table) table.setModel(self._table)
table.setSelectionBehavior(QAbstractItemView.SelectRows) table.setSelectionBehavior(QAbstractItemView.SelectRows)
table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch) table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)

View File

@ -50,7 +50,6 @@ class ComboBoxDelegate(QItemDelegate):
) )
) )
) )
print(lst)
self.editor.addItems( self.editor.addItems(
lst lst
) )

View File

@ -78,6 +78,9 @@
<property name="enabled"> <property name="enabled">
<bool>false</bool> <bool>false</bool>
</property> </property>
<property name="displayFormat">
<string>dd/MM/yyyy HH:mm:ss</string>
</property>
</widget> </widget>
</item> </item>
</layout> </layout>

View File

@ -0,0 +1,60 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Form</class>
<widget class="QWidget" name="Form">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>178</width>
<height>44</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QSpinBox" name="spinBox_days">
<property name="frame">
<bool>false</bool>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>days</string>
</property>
</widget>
</item>
<item>
<widget class="QTimeEdit" name="timeEdit">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="frame">
<bool>false</bool>
</property>
<property name="displayFormat">
<string>HH:mm:ss</string>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>