Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 22 additions & 6 deletions sailsim/gui/SailsimGUI.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
"""This class is the main GUI for the sailsim project."""

from typing import Any, Union
from PySide6.QtCore import QTimer
from PySide6.QtWidgets import QMainWindow

from sailsim.gui.boatInspector import BoatInspectorScene
from sailsim.gui.mapView import MapViewScene
from sailsim.simulation.Simulation import Simulation
from sailsim.gui.qtmain import Ui_MainWindow


class SailsimGUI(QMainWindow):
"""Main GUI for sailsim."""

def __init__(self, simulation):
frame = 0

def __init__(self, simulation: Simulation, varspace: Union[dict[str, Any], None] = None) -> None:
"""
Create SailsimGUI object.

Expand All @@ -21,7 +25,10 @@ def __init__(self, simulation):
super().__init__()

self.simulation = simulation
self.frame = 0

self.varspace = {"sailsim": self}
if varspace is not None:
self.varspace.update(varspace)

# Load UI from QT generated file
self.ui = Ui_MainWindow()
Expand All @@ -43,22 +50,22 @@ def __init__(self, simulation):
self.boatInspectorScene = BoatInspectorScene(simulation.boat)
self.ui.boatInspector.setScene(self.boatInspectorScene)

self.ui.valueInspector.setSimulation(simulation)

self.updateFrame(0)
self.updateViewStates()

def updateFrame(self, framenumber):
"""Update display when the frame changed."""
frames = self.simulation.boat.frameList.frames
if framenumber < len(frames):
if framenumber < len(self.simulation.boat.frameList.frames):
self.frame = framenumber
frame = frames[framenumber]

# Update widgets
maxFrame = str(len(self.simulation))
self.ui.frameNr.setText(str(framenumber).zfill(len(maxFrame)) + "/" + maxFrame)
self.mapViewScene.viewFrame(framenumber)
self.boatInspectorScene.viewFrame(framenumber)
self.ui.valueInspector.viewFrame(frame)
self.ui.valueInspector.viewFrame(framenumber)

def incFrame(self):
"""Move to the next frame if it is in the range of the slider."""
Expand Down Expand Up @@ -113,6 +120,15 @@ def updateViewStates(self):

# Slots

def runCode(self) -> None:
"""Run custom code in the window."""
try:
exec(self.ui.console.text(), self.varspace)
self.ui.console.setStyleSheet("")
except Exception:
self.ui.console.setStyleSheet("border: 1px solid red")
self.ui.console.setText("")

# Display for mapView
def actionViewShowBoatMap(self, state):
"""Show/hide the boat on the map view."""
Expand Down
80 changes: 67 additions & 13 deletions sailsim/gui/main.ui
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,22 @@
<property name="locale">
<locale language="English" country="Germany"/>
</property>
<layout class="QVBoxLayout" name="verticalLayout" stretch="1,0">
<layout class="QVBoxLayout" name="verticalLayout" stretch="1,0,0">
<property name="spacing">
<number>1</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QSplitter" name="main">
<property name="orientation">
Expand Down Expand Up @@ -532,6 +547,28 @@
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLineEdit" name="console">
<property name="font">
<font>
<family>Cascadia Mono</family>
</font>
</property>
<property name="toolTip">
<string>avaiable vars: sailsim, simulation, boat, wind</string>
</property>
<property name="text">
<string/>
</property>
<property name="frame">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<widget class="QMenuBar" name="menubar">
Expand Down Expand Up @@ -718,8 +755,8 @@
<slot>updateFrame(int)</slot>
<hints>
<hint type="sourcelabel">
<x>354</x>
<y>571</y>
<x>587</x>
<y>551</y>
</hint>
<hint type="destinationlabel">
<x>296</x>
Expand All @@ -734,8 +771,8 @@
<slot>incFrame()</slot>
<hints>
<hint type="sourcelabel">
<x>119</x>
<y>583</y>
<x>138</x>
<y>552</y>
</hint>
<hint type="destinationlabel">
<x>138</x>
Expand All @@ -750,8 +787,8 @@
<slot>decFrame()</slot>
<hints>
<hint type="sourcelabel">
<x>65</x>
<y>583</y>
<x>77</x>
<y>552</y>
</hint>
<hint type="destinationlabel">
<x>42</x>
Expand All @@ -766,8 +803,8 @@
<slot>pressedPlay(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>95</x>
<y>583</y>
<x>105</x>
<y>552</y>
</hint>
<hint type="destinationlabel">
<x>73</x>
Expand All @@ -782,8 +819,8 @@
<slot>startFrame()</slot>
<hints>
<hint type="sourcelabel">
<x>29</x>
<y>571</y>
<x>41</x>
<y>552</y>
</hint>
<hint type="destinationlabel">
<x>30</x>
Expand All @@ -798,8 +835,8 @@
<slot>endFrame()</slot>
<hints>
<hint type="sourcelabel">
<x>139</x>
<y>572</y>
<x>171</x>
<y>552</y>
</hint>
<hint type="destinationlabel">
<x>149</x>
Expand Down Expand Up @@ -919,6 +956,22 @@
</hint>
</hints>
</connection>
<connection>
<sender>console</sender>
<signal>returnPressed()</signal>
<receiver>MainWindow</receiver>
<slot>runCode()</slot>
<hints>
<hint type="sourcelabel">
<x>665</x>
<y>580</y>
</hint>
<hint type="destinationlabel">
<x>673</x>
<y>560</y>
</hint>
</hints>
</connection>
</connections>
<slots>
<slot>updateFrame(int)</slot>
Expand All @@ -934,5 +987,6 @@
<slot>actionViewShowWaypointsPathMap(bool)</slot>
<slot>actionViewShowBoatInspector(bool)</slot>
<slot>actionViewShowVectorsInspector(bool)</slot>
<slot>runCode()</slot>
</slots>
</ui>
27 changes: 24 additions & 3 deletions sailsim/gui/qtmain.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@
QPainter, QPalette, QPixmap, QRadialGradient,
QTransform)
from PySide6.QtWidgets import (QApplication, QAbstractItemView, QHBoxLayout, QHeaderView, QLabel,
QMainWindow, QMenu, QMenuBar, QSizePolicy,
QSlider, QSplitter, QToolButton, QTreeWidgetItem,
QVBoxLayout, QWidget)
QLineEdit, QMainWindow, QMenu, QMenuBar,
QSizePolicy, QSlider, QSplitter, QToolButton,
QTreeWidgetItem, QVBoxLayout, QWidget)

from sailsim.gui.boatInspector import BoatInspectorView
from sailsim.gui.mapView import MapViewView
Expand Down Expand Up @@ -68,7 +68,9 @@ def setupUi(self, MainWindow):
self.layout.setObjectName(u"layout")
self.layout.setLocale(QLocale(QLocale.English, QLocale.Germany))
self.verticalLayout = QVBoxLayout(self.layout)
self.verticalLayout.setSpacing(1)
self.verticalLayout.setObjectName(u"verticalLayout")
self.verticalLayout.setContentsMargins(0, 0, 0, 0)
self.main = QSplitter(self.layout)
self.main.setObjectName(u"main")
self.main.setOrientation(Qt.Horizontal)
Expand Down Expand Up @@ -186,6 +188,20 @@ def setupUi(self, MainWindow):

self.verticalLayout.addLayout(self.controlBar)

self.horizontalLayout = QHBoxLayout()
self.horizontalLayout.setObjectName(u"horizontalLayout")
self.console = QLineEdit(self.layout)
self.console.setObjectName(u"console")
font = QFont()
font.setFamilies([u"Cascadia Mono"])
self.console.setFont(font)
self.console.setFrame(False)

self.horizontalLayout.addWidget(self.console)


self.verticalLayout.addLayout(self.horizontalLayout)

self.verticalLayout.setStretch(0, 1)
MainWindow.setCentralWidget(self.layout)
self.menubar = QMenuBar(MainWindow)
Expand Down Expand Up @@ -241,6 +257,7 @@ def setupUi(self, MainWindow):
self.actionShowBoatMap.toggled.connect(MainWindow.actionViewShowBoatMap)
self.actionShowVectorsMap.toggled.connect(MainWindow.actionViewShowVectorsMap)
self.actionShowBoatPathMap.toggled.connect(MainWindow.actionViewShowBoatPathMap)
self.console.returnPressed.connect(MainWindow.runCode)

QMetaObject.connectSlotsByName(MainWindow)
# setupUi
Expand Down Expand Up @@ -377,6 +394,10 @@ def retranslateUi(self, MainWindow):
self.buttonIncFrame.setText(QCoreApplication.translate("MainWindow", u"\u23e9", None))
self.buttonEndFrame.setText(QCoreApplication.translate("MainWindow", u"\u23ed", None))
self.frameNr.setText(QCoreApplication.translate("MainWindow", u"0000/1000", None))
#if QT_CONFIG(tooltip)
self.console.setToolTip(QCoreApplication.translate("MainWindow", u"avaiable vars: sailsim, simulation, boat, wind", None))
#endif // QT_CONFIG(tooltip)
self.console.setText("")
self.menuFile.setTitle(QCoreApplication.translate("MainWindow", u"File", None))
self.menuEdit.setTitle(QCoreApplication.translate("MainWindow", u"Edit", None))
self.menuView.setTitle(QCoreApplication.translate("MainWindow", u"View", None))
Expand Down
16 changes: 14 additions & 2 deletions sailsim/gui/valueInspector.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,28 @@
"""This module contains the class declaration for the ValueInspectorWidget."""

from math import pi, sqrt
from typing import Optional, Union

from PySide6.QtWidgets import QTreeWidget
from PySide6.QtWidgets import QTreeWidget, QWidget

from sailsim.simulation.Simulation import Simulation

def toString(text):
return f'{text:.4f}'.rstrip('0').rstrip('.')

class ValueInspectorWidget(QTreeWidget):
"""List Widget that displays the boat's values."""

def viewFrame(self, frame):
simulation: Simulation

def __init__(self, parent: Optional[Union[QWidget, None]] = None) -> None:
super().__init__(parent)

def setSimulation(self, simulation: Simulation) -> None:
self.simulation = simulation

def viewFrame(self, framenumber):
frame = self.simulation.boat.frameList[framenumber]
self.updateValueInspectorRow(self.topLevelItem(0), frame.boatPosX, frame.boatPosY)

self.topLevelItem(1).setText(1, toString(frame.boatDirection * 180 / pi))
Expand Down
2 changes: 1 addition & 1 deletion sailsim/simulation/Simulation.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,4 +84,4 @@ def __repr__(self):

def __len__(self):
"""Return number of frames. Might be None."""
return self.lastFrame
return self.frame
16 changes: 8 additions & 8 deletions tests/basictest.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,25 +19,25 @@
sailor = Sailor(commandListExample)
#sailor = Sailor([Waypoint(-30, 30, 1), Waypoint(10, 47, 1), Waypoint(100, 60, 1), Waypoint(0, 100, 2)])

b = Boat(0, 0, 0)
b.sailor = sailor
boat = Boat(0, 0, 0)
boat.sailor = sailor

sailor.importBoat(b)
sailor.importBoat(boat)

# Create simulation
s = Simulation(b, wind, 0.01, 10000)
simulation = Simulation(boat, wind, 0.01, 10000)

# Run simulation
try:
s.run()
simulation.run()
except (OverflowError, ValueError):
s.lastFrame = s.frame - 1
print("Overflow after Frame", s.frame)
simulation.lastFrame = simulation.frame - 1
print("Overflow after Frame", simulation.frame)

#OUTPUT_PATH = "..\\..\\MATLAB\\sailsim\\out.csv"
#s.boat.frameList.saveCSV(OUTPUT_PATH)

app = QApplication(sys.argv)
window = SailsimGUI(s)
window = SailsimGUI(simulation, locals())
window.show()
sys.exit(app.exec())