From f4f6f1350bda8891030df666d7a82b751d86666f Mon Sep 17 00:00:00 2001 From: Giulio Romualdi Date: Sun, 5 Oct 2025 13:22:35 +0200 Subject: [PATCH 1/5] Refactor codebase to migrate from PyQt5 to PyQt6 - Updated imports from PyQt5 to PyQt6 across multiple files including meshcat_provider.py, signal_provider.py, and various autogenerated UI files. - Adjusted signal and slot connections to align with PyQt6 conventions. - Modified widget creation to include parent arguments where necessary. - Changed usage of enums and constants to match the updated PyQt6 API. - Updated setup.cfg to reflect the new dependencies for PyQt6 and PyQt6-WebEngine. --- .github/workflows/ci.yml | 2 +- generate-ui.sh | 27 +++- robot_log_visualizer/__main__.py | 4 +- .../plotter/pyqtgraph_viewer_canvas.py | 2 +- .../robot_visualizer/meshcat_provider.py | 2 +- .../signal_provider/signal_provider.py | 2 +- .../ui/autogenerated/about.py | 12 +- .../ui/autogenerated/plot_tab.py | 8 +- .../ui/autogenerated/set_robot_model.py | 64 +++++---- .../ui/autogenerated/video_tab.py | 12 +- .../ui/autogenerated/visualizer.py | 130 +++++++++--------- robot_log_visualizer/ui/gui.py | 69 ++++++---- robot_log_visualizer/ui/misc/video_tab.ui | 2 +- robot_log_visualizer/ui/plot_item.py | 2 +- robot_log_visualizer/ui/text_logging.py | 13 +- robot_log_visualizer/ui/video_item.py | 14 +- setup.cfg | 4 +- 17 files changed, 192 insertions(+), 177 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d656c0a..33c9ee2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -35,7 +35,7 @@ jobs: - name: Dependencies [Ubuntu] run: | sudo apt update - sudo apt install -y pyqt5-dev-tools + sudo apt install -y pyqt6-dev-tools - name: Generate python files run: | bash ./generate-ui.sh diff --git a/generate-ui.sh b/generate-ui.sh index a85013c..3554667 100755 --- a/generate-ui.sh +++ b/generate-ui.sh @@ -1,13 +1,30 @@ #! /bin/bash +SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) + +if command -v pyuic6 >/dev/null 2>&1; then + PYUIC_CMD=(pyuic6) +elif [ -x "${SCRIPT_DIR}/.venv/bin/pyuic6" ]; then + PYUIC_CMD=("${SCRIPT_DIR}/.venv/bin/pyuic6") +elif [ -x "${SCRIPT_DIR}/.venv/bin/python" ]; then + PYUIC_CMD=("${SCRIPT_DIR}/.venv/bin/python" -m PyQt6.uic.pyuic) +elif command -v python >/dev/null 2>&1; then + PYUIC_CMD=(python -m PyQt6.uic.pyuic) +elif command -v python3 >/dev/null 2>&1; then + PYUIC_CMD=(python3 -m PyQt6.uic.pyuic) +else + echo "Error: pyuic6 not found. Please install PyQt6 tools." >&2 + exit 1 +fi + echo "Generate the main window" -pyuic5 -o robot_log_visualizer/ui/autogenerated/visualizer.py robot_log_visualizer/ui/misc/visualizer.ui +"${PYUIC_CMD[@]}" -o robot_log_visualizer/ui/autogenerated/visualizer.py robot_log_visualizer/ui/misc/visualizer.ui echo "Generate Additional windows" -pyuic5 -o robot_log_visualizer/ui/autogenerated/about.py robot_log_visualizer/ui/misc/about.ui -pyuic5 -o robot_log_visualizer/ui/autogenerated/set_robot_model.py robot_log_visualizer/ui/misc/set_robot_model.ui +"${PYUIC_CMD[@]}" -o robot_log_visualizer/ui/autogenerated/about.py robot_log_visualizer/ui/misc/about.ui +"${PYUIC_CMD[@]}" -o robot_log_visualizer/ui/autogenerated/set_robot_model.py robot_log_visualizer/ui/misc/set_robot_model.ui echo "Generate tab" -pyuic5 -o robot_log_visualizer/ui/autogenerated/plot_tab.py robot_log_visualizer/ui/misc/plot_tab.ui -pyuic5 -o robot_log_visualizer/ui/autogenerated/video_tab.py robot_log_visualizer/ui/misc/video_tab.ui +"${PYUIC_CMD[@]}" -o robot_log_visualizer/ui/autogenerated/plot_tab.py robot_log_visualizer/ui/misc/plot_tab.ui +"${PYUIC_CMD[@]}" -o robot_log_visualizer/ui/autogenerated/video_tab.py robot_log_visualizer/ui/misc/video_tab.ui echo "The ui is generated" diff --git a/robot_log_visualizer/__main__.py b/robot_log_visualizer/__main__.py index 7027c7a..b9940eb 100755 --- a/robot_log_visualizer/__main__.py +++ b/robot_log_visualizer/__main__.py @@ -7,8 +7,8 @@ import sys # GUI +from PyQt6.QtWidgets import QApplication from robot_log_visualizer.ui.gui import RobotViewerMainWindow -from PyQt5.QtWidgets import QApplication # Meshcat from robot_log_visualizer.robot_visualizer.meshcat_provider import MeshcatProvider @@ -36,7 +36,7 @@ def main(): # show the main window gui.show() - return app.exec_() + return app.exec() if __name__ == "__main__": diff --git a/robot_log_visualizer/plotter/pyqtgraph_viewer_canvas.py b/robot_log_visualizer/plotter/pyqtgraph_viewer_canvas.py index 4d7a6ea..0b02e00 100644 --- a/robot_log_visualizer/plotter/pyqtgraph_viewer_canvas.py +++ b/robot_log_visualizer/plotter/pyqtgraph_viewer_canvas.py @@ -8,7 +8,7 @@ import numpy as np import pyqtgraph as pg # type: ignore -from PyQt5 import QtCore, QtWidgets # type: ignore +from PyQt6 import QtCore, QtWidgets # type: ignore from robot_log_visualizer.plotter.color_palette import ColorPalette from robot_log_visualizer.signal_provider.signal_provider import ProviderType diff --git a/robot_log_visualizer/robot_visualizer/meshcat_provider.py b/robot_log_visualizer/robot_visualizer/meshcat_provider.py index 5efb0be..b4d9e15 100644 --- a/robot_log_visualizer/robot_visualizer/meshcat_provider.py +++ b/robot_log_visualizer/robot_visualizer/meshcat_provider.py @@ -10,7 +10,7 @@ import idyntree.swig as idyn import numpy as np from idyntree.visualize import MeshcatVisualizer -from PyQt5.QtCore import QMutex, QMutexLocker, QThread +from PyQt6.QtCore import QMutex, QMutexLocker, QThread from robot_log_visualizer.utils.utils import PeriodicThreadState diff --git a/robot_log_visualizer/signal_provider/signal_provider.py b/robot_log_visualizer/signal_provider/signal_provider.py index e18efc1..8135ab1 100644 --- a/robot_log_visualizer/signal_provider/signal_provider.py +++ b/robot_log_visualizer/signal_provider/signal_provider.py @@ -9,7 +9,7 @@ import h5py import idyntree.swig as idyn import numpy as np -from PyQt5.QtCore import QMutex, QMutexLocker, QThread, pyqtSignal +from PyQt6.QtCore import QMutex, QMutexLocker, QThread, pyqtSignal from robot_log_visualizer.utils.utils import PeriodicThreadState, RobotStatePath diff --git a/robot_log_visualizer/ui/autogenerated/about.py b/robot_log_visualizer/ui/autogenerated/about.py index d9a94e7..4aaf47d 100644 --- a/robot_log_visualizer/ui/autogenerated/about.py +++ b/robot_log_visualizer/ui/autogenerated/about.py @@ -1,14 +1,12 @@ -# -*- coding: utf-8 -*- - # Form implementation generated from reading ui file 'robot_log_visualizer/ui/misc/about.ui' # -# Created by: PyQt5 UI code generator 5.15.6 +# Created by: PyQt6 UI code generator 6.9.1 # -# WARNING: Any manual changes made to this file will be lost when pyuic5 is +# WARNING: Any manual changes made to this file will be lost when pyuic6 is # run again. Do not edit this file unless you know what you are doing. -from PyQt5 import QtCore, QtGui, QtWidgets +from PyQt6 import QtCore, QtGui, QtWidgets class Ui_aboutWindow(object): @@ -16,11 +14,11 @@ def setupUi(self, aboutWindow): aboutWindow.setObjectName("aboutWindow") aboutWindow.resize(541, 102) aboutWindow.setMaximumSize(QtCore.QSize(541, 102)) - self.centralwidget = QtWidgets.QWidget(aboutWindow) + self.centralwidget = QtWidgets.QWidget(parent=aboutWindow) self.centralwidget.setObjectName("centralwidget") self.horizontalLayout = QtWidgets.QHBoxLayout(self.centralwidget) self.horizontalLayout.setObjectName("horizontalLayout") - self.label_2 = QtWidgets.QLabel(self.centralwidget) + self.label_2 = QtWidgets.QLabel(parent=self.centralwidget) self.label_2.setEnabled(True) self.label_2.setOpenExternalLinks(True) self.label_2.setObjectName("label_2") diff --git a/robot_log_visualizer/ui/autogenerated/plot_tab.py b/robot_log_visualizer/ui/autogenerated/plot_tab.py index 871104a..9b53710 100644 --- a/robot_log_visualizer/ui/autogenerated/plot_tab.py +++ b/robot_log_visualizer/ui/autogenerated/plot_tab.py @@ -1,14 +1,12 @@ -# -*- coding: utf-8 -*- - # Form implementation generated from reading ui file 'robot_log_visualizer/ui/misc/plot_tab.ui' # -# Created by: PyQt5 UI code generator 5.15.6 +# Created by: PyQt6 UI code generator 6.9.1 # -# WARNING: Any manual changes made to this file will be lost when pyuic5 is +# WARNING: Any manual changes made to this file will be lost when pyuic6 is # run again. Do not edit this file unless you know what you are doing. -from PyQt5 import QtCore, QtGui, QtWidgets +from PyQt6 import QtCore, QtGui, QtWidgets class Ui_PlotTab(object): diff --git a/robot_log_visualizer/ui/autogenerated/set_robot_model.py b/robot_log_visualizer/ui/autogenerated/set_robot_model.py index 2c45f50..810fe00 100644 --- a/robot_log_visualizer/ui/autogenerated/set_robot_model.py +++ b/robot_log_visualizer/ui/autogenerated/set_robot_model.py @@ -1,14 +1,12 @@ -# -*- coding: utf-8 -*- - # Form implementation generated from reading ui file 'robot_log_visualizer/ui/misc/set_robot_model.ui' # -# Created by: PyQt5 UI code generator 5.15.6 +# Created by: PyQt6 UI code generator 6.9.1 # -# WARNING: Any manual changes made to this file will be lost when pyuic5 is +# WARNING: Any manual changes made to this file will be lost when pyuic6 is # run again. Do not edit this file unless you know what you are doing. -from PyQt5 import QtCore, QtGui, QtWidgets +from PyQt6 import QtCore, QtGui, QtWidgets class Ui_setRobotModelDialog(object): @@ -17,95 +15,95 @@ def setupUi(self, setRobotModelDialog): setRobotModelDialog.resize(711, 363) self.gridLayout = QtWidgets.QGridLayout(setRobotModelDialog) self.gridLayout.setObjectName("gridLayout") - spacerItem = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) + spacerItem = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Expanding) self.gridLayout.addItem(spacerItem, 1, 0, 1, 1) - self.buttonBox = QtWidgets.QDialogButtonBox(setRobotModelDialog) - self.buttonBox.setOrientation(QtCore.Qt.Horizontal) - self.buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.Close|QtWidgets.QDialogButtonBox.Save|QtWidgets.QDialogButtonBox.SaveAll) + self.buttonBox = QtWidgets.QDialogButtonBox(parent=setRobotModelDialog) + self.buttonBox.setOrientation(QtCore.Qt.Orientation.Horizontal) + self.buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.StandardButton.Close|QtWidgets.QDialogButtonBox.StandardButton.Save|QtWidgets.QDialogButtonBox.StandardButton.SaveAll) self.buttonBox.setObjectName("buttonBox") self.gridLayout.addWidget(self.buttonBox, 2, 0, 1, 1) - self.tabWidget = QtWidgets.QTabWidget(setRobotModelDialog) + self.tabWidget = QtWidgets.QTabWidget(parent=setRobotModelDialog) self.tabWidget.setObjectName("tabWidget") self.robot_tab = QtWidgets.QWidget() self.robot_tab.setObjectName("robot_tab") self.verticalLayout = QtWidgets.QVBoxLayout(self.robot_tab) self.verticalLayout.setObjectName("verticalLayout") - self.frame = QtWidgets.QFrame(self.robot_tab) - self.frame.setFrameShape(QtWidgets.QFrame.StyledPanel) + self.frame = QtWidgets.QFrame(parent=self.robot_tab) + self.frame.setFrameShape(QtWidgets.QFrame.Shape.StyledPanel) self.frame.setObjectName("frame") self.gridLayout_2 = QtWidgets.QGridLayout(self.frame) self.gridLayout_2.setObjectName("gridLayout_2") - self.robotModelToolButton = QtWidgets.QToolButton(self.frame) + self.robotModelToolButton = QtWidgets.QToolButton(parent=self.frame) self.robotModelToolButton.setObjectName("robotModelToolButton") self.gridLayout_2.addWidget(self.robotModelToolButton, 1, 1, 1, 1) - self.label = QtWidgets.QLabel(self.frame) + self.label = QtWidgets.QLabel(parent=self.frame) self.label.setObjectName("label") self.gridLayout_2.addWidget(self.label, 0, 0, 1, 1) - self.robotModelLineEdit = QtWidgets.QLineEdit(self.frame) + self.robotModelLineEdit = QtWidgets.QLineEdit(parent=self.frame) font = QtGui.QFont() font.setFamily("Ubuntu Mono") self.robotModelLineEdit.setFont(font) self.robotModelLineEdit.setObjectName("robotModelLineEdit") self.gridLayout_2.addWidget(self.robotModelLineEdit, 1, 0, 1, 1) self.verticalLayout.addWidget(self.frame) - self.frame_2 = QtWidgets.QFrame(self.robot_tab) - self.frame_2.setFrameShape(QtWidgets.QFrame.StyledPanel) + self.frame_2 = QtWidgets.QFrame(parent=self.robot_tab) + self.frame_2.setFrameShape(QtWidgets.QFrame.Shape.StyledPanel) self.frame_2.setObjectName("frame_2") self.gridLayout_3 = QtWidgets.QGridLayout(self.frame_2) self.gridLayout_3.setObjectName("gridLayout_3") - self.packageDirToolButton = QtWidgets.QToolButton(self.frame_2) + self.packageDirToolButton = QtWidgets.QToolButton(parent=self.frame_2) self.packageDirToolButton.setObjectName("packageDirToolButton") self.gridLayout_3.addWidget(self.packageDirToolButton, 1, 1, 1, 1) - self.label_3 = QtWidgets.QLabel(self.frame_2) + self.label_3 = QtWidgets.QLabel(parent=self.frame_2) self.label_3.setObjectName("label_3") self.gridLayout_3.addWidget(self.label_3, 0, 0, 1, 1) - self.packageDirLineEdit = QtWidgets.QLineEdit(self.frame_2) + self.packageDirLineEdit = QtWidgets.QLineEdit(parent=self.frame_2) font = QtGui.QFont() font.setFamily("Ubuntu Mono") self.packageDirLineEdit.setFont(font) self.packageDirLineEdit.setObjectName("packageDirLineEdit") self.gridLayout_3.addWidget(self.packageDirLineEdit, 1, 0, 1, 1) self.verticalLayout.addWidget(self.frame_2) - self.frame_3 = QtWidgets.QFrame(self.robot_tab) - self.frame_3.setFrameShape(QtWidgets.QFrame.StyledPanel) + self.frame_3 = QtWidgets.QFrame(parent=self.robot_tab) + self.frame_3.setFrameShape(QtWidgets.QFrame.Shape.StyledPanel) self.frame_3.setObjectName("frame_3") self.formLayout_2 = QtWidgets.QFormLayout(self.frame_3) self.formLayout_2.setObjectName("formLayout_2") - self.label_5 = QtWidgets.QLabel(self.frame_3) + self.label_5 = QtWidgets.QLabel(parent=self.frame_3) self.label_5.setObjectName("label_5") - self.formLayout_2.setWidget(0, QtWidgets.QFormLayout.LabelRole, self.label_5) - self.frameNameComboBox = QtWidgets.QComboBox(self.frame_3) + self.formLayout_2.setWidget(0, QtWidgets.QFormLayout.ItemRole.LabelRole, self.label_5) + self.frameNameComboBox = QtWidgets.QComboBox(parent=self.frame_3) self.frameNameComboBox.setMaxVisibleItems(5) self.frameNameComboBox.setObjectName("frameNameComboBox") - self.formLayout_2.setWidget(1, QtWidgets.QFormLayout.SpanningRole, self.frameNameComboBox) + self.formLayout_2.setWidget(1, QtWidgets.QFormLayout.ItemRole.SpanningRole, self.frameNameComboBox) self.verticalLayout.addWidget(self.frame_3) self.tabWidget.addTab(self.robot_tab, "") self.mischellanea_tab = QtWidgets.QWidget() self.mischellanea_tab.setObjectName("mischellanea_tab") self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.mischellanea_tab) self.verticalLayout_2.setObjectName("verticalLayout_2") - self.frame_4 = QtWidgets.QFrame(self.mischellanea_tab) - self.frame_4.setFrameShape(QtWidgets.QFrame.StyledPanel) - self.frame_4.setFrameShadow(QtWidgets.QFrame.Raised) + self.frame_4 = QtWidgets.QFrame(parent=self.mischellanea_tab) + self.frame_4.setFrameShape(QtWidgets.QFrame.Shape.StyledPanel) + self.frame_4.setFrameShadow(QtWidgets.QFrame.Shadow.Raised) self.frame_4.setObjectName("frame_4") self.gridLayout_4 = QtWidgets.QGridLayout(self.frame_4) self.gridLayout_4.setObjectName("gridLayout_4") - self.label_2 = QtWidgets.QLabel(self.frame_4) + self.label_2 = QtWidgets.QLabel(parent=self.frame_4) self.label_2.setObjectName("label_2") self.gridLayout_4.addWidget(self.label_2, 0, 0, 1, 1) - self.arrowScaling_lineEdit = QtWidgets.QLineEdit(self.frame_4) + self.arrowScaling_lineEdit = QtWidgets.QLineEdit(parent=self.frame_4) self.arrowScaling_lineEdit.setEnabled(False) self.arrowScaling_lineEdit.setReadOnly(False) self.arrowScaling_lineEdit.setClearButtonEnabled(False) self.arrowScaling_lineEdit.setObjectName("arrowScaling_lineEdit") self.gridLayout_4.addWidget(self.arrowScaling_lineEdit, 0, 1, 1, 1) - self.arrowScaling_checkBox = QtWidgets.QCheckBox(self.frame_4) + self.arrowScaling_checkBox = QtWidgets.QCheckBox(parent=self.frame_4) self.arrowScaling_checkBox.setChecked(True) self.arrowScaling_checkBox.setTristate(False) self.arrowScaling_checkBox.setObjectName("arrowScaling_checkBox") self.gridLayout_4.addWidget(self.arrowScaling_checkBox, 0, 2, 1, 1) self.verticalLayout_2.addWidget(self.frame_4) - spacerItem1 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) + spacerItem1 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Expanding) self.verticalLayout_2.addItem(spacerItem1) self.tabWidget.addTab(self.mischellanea_tab, "") self.gridLayout.addWidget(self.tabWidget, 0, 0, 1, 1) diff --git a/robot_log_visualizer/ui/autogenerated/video_tab.py b/robot_log_visualizer/ui/autogenerated/video_tab.py index b43318e..02531e2 100644 --- a/robot_log_visualizer/ui/autogenerated/video_tab.py +++ b/robot_log_visualizer/ui/autogenerated/video_tab.py @@ -1,14 +1,12 @@ -# -*- coding: utf-8 -*- - # Form implementation generated from reading ui file 'robot_log_visualizer/ui/misc/video_tab.ui' # -# Created by: PyQt5 UI code generator 5.15.6 +# Created by: PyQt6 UI code generator 6.9.1 # -# WARNING: Any manual changes made to this file will be lost when pyuic5 is +# WARNING: Any manual changes made to this file will be lost when pyuic6 is # run again. Do not edit this file unless you know what you are doing. -from PyQt5 import QtCore, QtGui, QtWidgets +from PyQt6 import QtCore, QtGui, QtWidgets class Ui_VideoTab(object): @@ -17,7 +15,7 @@ def setupUi(self, VideoTab): VideoTab.resize(400, 300) self.horizontalLayout = QtWidgets.QHBoxLayout(VideoTab) self.horizontalLayout.setObjectName("horizontalLayout") - self.webcamView = QVideoWidget(VideoTab) + self.webcamView = QVideoWidget(parent=VideoTab) self.webcamView.setObjectName("webcamView") self.horizontalLayout.addWidget(self.webcamView) @@ -27,4 +25,4 @@ def setupUi(self, VideoTab): def retranslateUi(self, VideoTab): _translate = QtCore.QCoreApplication.translate VideoTab.setWindowTitle(_translate("VideoTab", "Form")) -from PyQt5.QtMultimediaWidgets import QVideoWidget +from PyQt6.QtMultimediaWidgets import QVideoWidget diff --git a/robot_log_visualizer/ui/autogenerated/visualizer.py b/robot_log_visualizer/ui/autogenerated/visualizer.py index 3ba96b8..d221721 100644 --- a/robot_log_visualizer/ui/autogenerated/visualizer.py +++ b/robot_log_visualizer/ui/autogenerated/visualizer.py @@ -1,14 +1,12 @@ -# -*- coding: utf-8 -*- - # Form implementation generated from reading ui file 'robot_log_visualizer/ui/misc/visualizer.ui' # -# Created by: PyQt5 UI code generator 5.15.6 +# Created by: PyQt6 UI code generator 6.9.1 # -# WARNING: Any manual changes made to this file will be lost when pyuic5 is +# WARNING: Any manual changes made to this file will be lost when pyuic6 is # run again. Do not edit this file unless you know what you are doing. -from PyQt5 import QtCore, QtGui, QtWidgets +from PyQt6 import QtCore, QtGui, QtWidgets class Ui_MainWindow(object): @@ -16,8 +14,8 @@ def setupUi(self, MainWindow): MainWindow.setObjectName("MainWindow") MainWindow.resize(929, 908) MainWindow.setAcceptDrops(True) - self.centralwidget = QtWidgets.QWidget(MainWindow) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding) + self.centralwidget = QtWidgets.QWidget(parent=MainWindow) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Expanding) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.centralwidget.sizePolicy().hasHeightForWidth()) @@ -25,23 +23,23 @@ def setupUi(self, MainWindow): self.centralwidget.setObjectName("centralwidget") self.verticalLayout = QtWidgets.QVBoxLayout(self.centralwidget) self.verticalLayout.setObjectName("verticalLayout") - self.splitter_2 = QtWidgets.QSplitter(self.centralwidget) - self.splitter_2.setOrientation(QtCore.Qt.Vertical) + self.splitter_2 = QtWidgets.QSplitter(parent=self.centralwidget) + self.splitter_2.setOrientation(QtCore.Qt.Orientation.Vertical) self.splitter_2.setChildrenCollapsible(False) self.splitter_2.setObjectName("splitter_2") - self.dataVisualizationFrame = QtWidgets.QFrame(self.splitter_2) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding) + self.dataVisualizationFrame = QtWidgets.QFrame(parent=self.splitter_2) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Expanding) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(2) sizePolicy.setHeightForWidth(self.dataVisualizationFrame.sizePolicy().hasHeightForWidth()) self.dataVisualizationFrame.setSizePolicy(sizePolicy) self.dataVisualizationFrame.setMaximumSize(QtCore.QSize(16777215, 16777215)) - self.dataVisualizationFrame.setFrameShape(QtWidgets.QFrame.NoFrame) + self.dataVisualizationFrame.setFrameShape(QtWidgets.QFrame.Shape.NoFrame) self.dataVisualizationFrame.setObjectName("dataVisualizationFrame") self.gridLayout_3 = QtWidgets.QGridLayout(self.dataVisualizationFrame) self.gridLayout_3.setContentsMargins(-1, 9, -1, -1) self.gridLayout_3.setObjectName("gridLayout_3") - self.pauseButton = QtWidgets.QPushButton(self.dataVisualizationFrame) + self.pauseButton = QtWidgets.QPushButton(parent=self.dataVisualizationFrame) self.pauseButton.setEnabled(False) self.pauseButton.setMaximumSize(QtCore.QSize(40, 16777215)) self.pauseButton.setText("") @@ -52,29 +50,29 @@ def setupUi(self, MainWindow): self.pauseButton.setFlat(False) self.pauseButton.setObjectName("pauseButton") self.gridLayout_3.addWidget(self.pauseButton, 1, 4, 1, 1) - self.timeSlider = QtWidgets.QSlider(self.dataVisualizationFrame) + self.timeSlider = QtWidgets.QSlider(parent=self.dataVisualizationFrame) self.timeSlider.setEnabled(False) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.timeSlider.sizePolicy().hasHeightForWidth()) self.timeSlider.setSizePolicy(sizePolicy) self.timeSlider.setPageStep(1) self.timeSlider.setTracking(True) - self.timeSlider.setOrientation(QtCore.Qt.Horizontal) + self.timeSlider.setOrientation(QtCore.Qt.Orientation.Horizontal) self.timeSlider.setObjectName("timeSlider") self.gridLayout_3.addWidget(self.timeSlider, 1, 1, 1, 2) - self.startButton = QtWidgets.QPushButton(self.dataVisualizationFrame) + self.startButton = QtWidgets.QPushButton(parent=self.dataVisualizationFrame) self.startButton.setEnabled(False) self.startButton.setMaximumSize(QtCore.QSize(40, 16777215)) - self.startButton.setCursor(QtGui.QCursor(QtCore.Qt.ArrowCursor)) + self.startButton.setCursor(QtGui.QCursor(QtCore.Qt.CursorShape.ArrowCursor)) self.startButton.setText("") icon = QtGui.QIcon.fromTheme("media-playback-start") self.startButton.setIcon(icon) self.startButton.setObjectName("startButton") self.gridLayout_3.addWidget(self.startButton, 1, 3, 1, 1) - self.timeLabel = QtWidgets.QLabel(self.dataVisualizationFrame) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Ignored) + self.timeLabel = QtWidgets.QLabel(parent=self.dataVisualizationFrame) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Fixed, QtWidgets.QSizePolicy.Policy.Ignored) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.timeLabel.sizePolicy().hasHeightForWidth()) @@ -82,12 +80,12 @@ def setupUi(self, MainWindow): self.timeLabel.setMinimumSize(QtCore.QSize(60, 0)) self.timeLabel.setObjectName("timeLabel") self.gridLayout_3.addWidget(self.timeLabel, 1, 0, 1, 1) - self.splitter = QtWidgets.QSplitter(self.dataVisualizationFrame) - self.splitter.setOrientation(QtCore.Qt.Horizontal) + self.splitter = QtWidgets.QSplitter(parent=self.dataVisualizationFrame) + self.splitter.setOrientation(QtCore.Qt.Orientation.Horizontal) self.splitter.setChildrenCollapsible(True) self.splitter.setObjectName("splitter") - self.variableTreeWidget = QtWidgets.QTreeWidget(self.splitter) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.MinimumExpanding) + self.variableTreeWidget = QtWidgets.QTreeWidget(parent=self.splitter) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.MinimumExpanding, QtWidgets.QSizePolicy.Policy.MinimumExpanding) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.variableTreeWidget.sizePolicy().hasHeightForWidth()) @@ -95,15 +93,15 @@ def setupUi(self, MainWindow): self.variableTreeWidget.setMaximumSize(QtCore.QSize(16777215, 16777215)) self.variableTreeWidget.setSizeIncrement(QtCore.QSize(0, 0)) self.variableTreeWidget.setBaseSize(QtCore.QSize(0, 0)) - self.variableTreeWidget.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) - self.variableTreeWidget.setFrameShape(QtWidgets.QFrame.Box) - self.variableTreeWidget.setSelectionMode(QtWidgets.QAbstractItemView.MultiSelection) + self.variableTreeWidget.setContextMenuPolicy(QtCore.Qt.ContextMenuPolicy.CustomContextMenu) + self.variableTreeWidget.setFrameShape(QtWidgets.QFrame.Shape.Box) + self.variableTreeWidget.setSelectionMode(QtWidgets.QAbstractItemView.SelectionMode.MultiSelection) self.variableTreeWidget.setAnimated(True) self.variableTreeWidget.setObjectName("variableTreeWidget") self.variableTreeWidget.header().setVisible(False) self.variableTreeWidget.header().setDefaultSectionSize(100) - self.tabPlotWidget = QtWidgets.QTabWidget(self.splitter) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding) + self.tabPlotWidget = QtWidgets.QTabWidget(parent=self.splitter) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Expanding) sizePolicy.setHorizontalStretch(1) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.tabPlotWidget.sizePolicy().hasHeightForWidth()) @@ -112,21 +110,21 @@ def setupUi(self, MainWindow): self.tabPlotWidget.setMovable(False) self.tabPlotWidget.setTabBarAutoHide(False) self.tabPlotWidget.setObjectName("tabPlotWidget") - self.meshcatAndVideoTab = QtWidgets.QTabWidget(self.splitter) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding) + self.meshcatAndVideoTab = QtWidgets.QTabWidget(parent=self.splitter) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Expanding) sizePolicy.setHorizontalStretch(2) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.meshcatAndVideoTab.sizePolicy().hasHeightForWidth()) self.meshcatAndVideoTab.setSizePolicy(sizePolicy) - self.meshcatAndVideoTab.setTabPosition(QtWidgets.QTabWidget.East) + self.meshcatAndVideoTab.setTabPosition(QtWidgets.QTabWidget.TabPosition.East) self.meshcatAndVideoTab.setDocumentMode(False) self.meshcatAndVideoTab.setObjectName("meshcatAndVideoTab") self.meshcatTab = QtWidgets.QWidget() self.meshcatTab.setObjectName("meshcatTab") self.horizontalLayout = QtWidgets.QHBoxLayout(self.meshcatTab) self.horizontalLayout.setObjectName("horizontalLayout") - self.meshcatView = QtWebEngineWidgets.QWebEngineView(self.meshcatTab) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.MinimumExpanding) + self.meshcatView = QtWebEngineWidgets.QWebEngineView(parent=self.meshcatTab) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.MinimumExpanding, QtWidgets.QSizePolicy.Policy.MinimumExpanding) sizePolicy.setHorizontalStretch(1) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.meshcatView.sizePolicy().hasHeightForWidth()) @@ -136,10 +134,10 @@ def setupUi(self, MainWindow): icon = QtGui.QIcon.fromTheme("input-gaming") self.meshcatAndVideoTab.addTab(self.meshcatTab, icon, "") self.gridLayout_3.addWidget(self.splitter, 0, 0, 1, 5) - self.tabWidget = QtWidgets.QTabWidget(self.splitter_2) + self.tabWidget = QtWidgets.QTabWidget(parent=self.splitter_2) self.tabWidget.setMinimumSize(QtCore.QSize(0, 0)) self.tabWidget.setAutoFillBackground(False) - self.tabWidget.setTabPosition(QtWidgets.QTabWidget.West) + self.tabWidget.setTabPosition(QtWidgets.QTabWidget.TabPosition.West) self.tabWidget.setUsesScrollButtons(False) self.tabWidget.setDocumentMode(False) self.tabWidget.setTabsClosable(False) @@ -149,11 +147,11 @@ def setupUi(self, MainWindow): self.yarpTextLogWidget.setObjectName("yarpTextLogWidget") self.verticalLayout_3 = QtWidgets.QVBoxLayout(self.yarpTextLogWidget) self.verticalLayout_3.setObjectName("verticalLayout_3") - self.splitter_3 = QtWidgets.QSplitter(self.yarpTextLogWidget) - self.splitter_3.setOrientation(QtCore.Qt.Horizontal) + self.splitter_3 = QtWidgets.QSplitter(parent=self.yarpTextLogWidget) + self.splitter_3.setOrientation(QtCore.Qt.Orientation.Horizontal) self.splitter_3.setObjectName("splitter_3") - self.yarpTextLogTreeWidget = QtWidgets.QTreeWidget(self.splitter_3) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding) + self.yarpTextLogTreeWidget = QtWidgets.QTreeWidget(parent=self.splitter_3) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Expanding) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.yarpTextLogTreeWidget.sizePolicy().hasHeightForWidth()) @@ -161,26 +159,26 @@ def setupUi(self, MainWindow): self.yarpTextLogTreeWidget.setMaximumSize(QtCore.QSize(16777215, 16777215)) self.yarpTextLogTreeWidget.setSizeIncrement(QtCore.QSize(0, 0)) self.yarpTextLogTreeWidget.setBaseSize(QtCore.QSize(0, 0)) - self.yarpTextLogTreeWidget.setFrameShape(QtWidgets.QFrame.Box) - self.yarpTextLogTreeWidget.setSelectionMode(QtWidgets.QAbstractItemView.SingleSelection) + self.yarpTextLogTreeWidget.setFrameShape(QtWidgets.QFrame.Shape.Box) + self.yarpTextLogTreeWidget.setSelectionMode(QtWidgets.QAbstractItemView.SelectionMode.SingleSelection) self.yarpTextLogTreeWidget.setAnimated(True) self.yarpTextLogTreeWidget.setObjectName("yarpTextLogTreeWidget") self.yarpTextLogTreeWidget.header().setVisible(False) self.yarpTextLogTreeWidget.header().setDefaultSectionSize(100) - self.yarpTextLogTableWidget = QtWidgets.QTableWidget(self.splitter_3) + self.yarpTextLogTableWidget = QtWidgets.QTableWidget(parent=self.splitter_3) self.yarpTextLogTableWidget.setEnabled(True) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Expanding) sizePolicy.setHorizontalStretch(10) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.yarpTextLogTableWidget.sizePolicy().hasHeightForWidth()) self.yarpTextLogTableWidget.setSizePolicy(sizePolicy) - self.yarpTextLogTableWidget.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded) - self.yarpTextLogTableWidget.setSizeAdjustPolicy(QtWidgets.QAbstractScrollArea.AdjustIgnored) - self.yarpTextLogTableWidget.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers) - self.yarpTextLogTableWidget.setSelectionMode(QtWidgets.QAbstractItemView.NoSelection) - self.yarpTextLogTableWidget.setHorizontalScrollMode(QtWidgets.QAbstractItemView.ScrollPerPixel) + self.yarpTextLogTableWidget.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarPolicy.ScrollBarAsNeeded) + self.yarpTextLogTableWidget.setSizeAdjustPolicy(QtWidgets.QAbstractScrollArea.SizeAdjustPolicy.AdjustIgnored) + self.yarpTextLogTableWidget.setEditTriggers(QtWidgets.QAbstractItemView.EditTrigger.NoEditTriggers) + self.yarpTextLogTableWidget.setSelectionMode(QtWidgets.QAbstractItemView.SelectionMode.NoSelection) + self.yarpTextLogTableWidget.setHorizontalScrollMode(QtWidgets.QAbstractItemView.ScrollMode.ScrollPerPixel) self.yarpTextLogTableWidget.setShowGrid(False) - self.yarpTextLogTableWidget.setGridStyle(QtCore.Qt.NoPen) + self.yarpTextLogTableWidget.setGridStyle(QtCore.Qt.PenStyle.NoPen) self.yarpTextLogTableWidget.setObjectName("yarpTextLogTableWidget") self.yarpTextLogTableWidget.setColumnCount(0) self.yarpTextLogTableWidget.setRowCount(0) @@ -200,12 +198,12 @@ def setupUi(self, MainWindow): self.tab_5.setObjectName("tab_5") self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.tab_5) self.verticalLayout_2.setObjectName("verticalLayout_2") - self.logScrollArea = QtWidgets.QScrollArea(self.tab_5) + self.logScrollArea = QtWidgets.QScrollArea(parent=self.tab_5) self.logScrollArea.setMinimumSize(QtCore.QSize(0, 120)) self.logScrollArea.setAutoFillBackground(False) self.logScrollArea.setStyleSheet("background: white") - self.logScrollArea.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded) - self.logScrollArea.setSizeAdjustPolicy(QtWidgets.QAbstractScrollArea.AdjustToContents) + self.logScrollArea.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarPolicy.ScrollBarAsNeeded) + self.logScrollArea.setSizeAdjustPolicy(QtWidgets.QAbstractScrollArea.SizeAdjustPolicy.AdjustToContents) self.logScrollArea.setWidgetResizable(True) self.logScrollArea.setObjectName("logScrollArea") self.logScrollAreaWidgetContents = QtWidgets.QWidget() @@ -213,10 +211,10 @@ def setupUi(self, MainWindow): self.logScrollAreaWidgetContents.setObjectName("logScrollAreaWidgetContents") self.gridLayout = QtWidgets.QGridLayout(self.logScrollAreaWidgetContents) self.gridLayout.setObjectName("gridLayout") - spacerItem = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) + spacerItem = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Expanding) self.gridLayout.addItem(spacerItem, 2, 0, 1, 1) - self.logLabel = QtWidgets.QLabel(self.logScrollAreaWidgetContents) - self.logLabel.setCursor(QtGui.QCursor(QtCore.Qt.ArrowCursor)) + self.logLabel = QtWidgets.QLabel(parent=self.logScrollAreaWidgetContents) + self.logLabel.setCursor(QtGui.QCursor(QtCore.Qt.CursorShape.ArrowCursor)) self.logLabel.setText("") self.logLabel.setObjectName("logLabel") self.gridLayout.addWidget(self.logLabel, 1, 0, 1, 1) @@ -226,29 +224,29 @@ def setupUi(self, MainWindow): self.tabWidget.addTab(self.tab_5, icon, "") self.verticalLayout.addWidget(self.splitter_2) MainWindow.setCentralWidget(self.centralwidget) - self.menubar = QtWidgets.QMenuBar(MainWindow) + self.menubar = QtWidgets.QMenuBar(parent=MainWindow) self.menubar.setGeometry(QtCore.QRect(0, 0, 929, 22)) self.menubar.setObjectName("menubar") - self.menuFile = QtWidgets.QMenu(self.menubar) + self.menuFile = QtWidgets.QMenu(parent=self.menubar) self.menuFile.setObjectName("menuFile") - self.menuHelp = QtWidgets.QMenu(self.menubar) + self.menuHelp = QtWidgets.QMenu(parent=self.menubar) self.menuHelp.setObjectName("menuHelp") - self.menuEdit = QtWidgets.QMenu(self.menubar) + self.menuEdit = QtWidgets.QMenu(parent=self.menubar) self.menuEdit.setObjectName("menuEdit") MainWindow.setMenuBar(self.menubar) - self.actionQuit = QtWidgets.QAction(MainWindow) + self.actionQuit = QtGui.QAction(parent=MainWindow) icon = QtGui.QIcon.fromTheme("exit") self.actionQuit.setIcon(icon) self.actionQuit.setObjectName("actionQuit") - self.actionOpen = QtWidgets.QAction(MainWindow) + self.actionOpen = QtGui.QAction(parent=MainWindow) icon = QtGui.QIcon.fromTheme("document-open") self.actionOpen.setIcon(icon) self.actionOpen.setObjectName("actionOpen") - self.actionAbout = QtWidgets.QAction(MainWindow) + self.actionAbout = QtGui.QAction(parent=MainWindow) self.actionAbout.setObjectName("actionAbout") - self.actionSet_Robot_Model = QtWidgets.QAction(MainWindow) + self.actionSet_Robot_Model = QtGui.QAction(parent=MainWindow) self.actionSet_Robot_Model.setObjectName("actionSet_Robot_Model") - self.actionRealtime_Connect = QtWidgets.QAction(MainWindow) + self.actionRealtime_Connect = QtGui.QAction(parent=MainWindow) self.actionRealtime_Connect.setObjectName("actionRealtime_Connect") self.menuFile.addAction(self.actionOpen) self.menuFile.addAction(self.actionRealtime_Connect) @@ -284,4 +282,4 @@ def retranslateUi(self, MainWindow): self.actionSet_Robot_Model.setText(_translate("MainWindow", "Options")) self.actionRealtime_Connect.setText(_translate("MainWindow", "Realtime Connect")) self.actionRealtime_Connect.setShortcut(_translate("MainWindow", "Ctrl+R")) -from PyQt5 import QtWebEngineWidgets +from PyQt6 import QtWebEngineWidgets diff --git a/robot_log_visualizer/ui/gui.py b/robot_log_visualizer/ui/gui.py index dc9edfd..26027bb 100644 --- a/robot_log_visualizer/ui/gui.py +++ b/robot_log_visualizer/ui/gui.py @@ -2,18 +2,17 @@ # This software may be modified and distributed under the terms of the # Released under the terms of the BSD 3-Clause License -# PyQt5 -from PyQt5 import QtWidgets, QtGui -from PyQt5.QtCore import QUrl -from PyQt5.QtCore import pyqtSlot, Qt, QMutex, QMutexLocker -from PyQt5.QtWidgets import ( +# PyQt6 +from PyQt6 import QtWidgets, QtGui, QtCore +from PyQt6.QtCore import QMutex, QMutexLocker, QUrl, Qt, pyqtSlot +from PyQt6.QtWidgets import ( + QDialog, + QDialogButtonBox, QFileDialog, - QTreeWidgetItem, + QLineEdit, QToolButton, - QDialog, + QTreeWidgetItem, QVBoxLayout, - QLineEdit, - QDialogButtonBox, ) from robot_log_visualizer.robot_visualizer.meshcat_provider import MeshcatProvider from robot_log_visualizer.signal_provider.realtime_signal_provider import ( @@ -24,7 +23,10 @@ MatfileSignalProvider, ) -from robot_log_visualizer.signal_provider.signal_provider import SignalProvider +from robot_log_visualizer.signal_provider.signal_provider import ( + ProviderType, + SignalProvider, +) from robot_log_visualizer.ui.plot_item import PlotItem from robot_log_visualizer.ui.video_item import VideoItem from robot_log_visualizer.ui.text_logging import TextLoggingItem @@ -153,7 +155,9 @@ def build_plot_title_box_dialog(): la = QVBoxLayout(dlg) line_edit = QLineEdit() la.addWidget(line_edit) - bb = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) + bb = QDialogButtonBox( + QDialogButtonBox.StandardButton.Ok | QDialogButtonBox.StandardButton.Cancel + ) bb.clicked.connect(dlg.accept) bb.rejected.connect(dlg.reject) la.addWidget(bb) @@ -165,8 +169,8 @@ def get_icon(icon_name): icon = QtGui.QIcon() icon.addPixmap( QtGui.QPixmap(str(pathlib.Path(__file__).parent / "misc" / icon_name)), - QtGui.QIcon.Normal, - QtGui.QIcon.Off, + QtGui.QIcon.Mode.Normal, + QtGui.QIcon.State.Off, ) return icon @@ -277,7 +281,9 @@ def __init__(self, signal_provider_period, meshcat_provider, animation_period): self.ui.tabPlotWidget.currentChanged.connect(self.plotTabBar_currentChanged) # add a custom context menu to the variable tree widget - self.ui.variableTreeWidget.setContextMenuPolicy(Qt.CustomContextMenu) + self.ui.variableTreeWidget.setContextMenuPolicy( + Qt.ContextMenuPolicy.CustomContextMenu + ) self.ui.variableTreeWidget.customContextMenuRequested.connect( self.variableTreeWidget_on_right_click ) @@ -323,8 +329,8 @@ def keyPressEvent(self, event): if not self.dataset_loaded: return - if event.modifiers() & Qt.ControlModifier: - if event.key() == Qt.Key_B: + if event.modifiers() & Qt.KeyboardModifier.ControlModifier: + if event.key() == Qt.Key.Key_B: self.slider_pressed = True new_index = int(self.ui.timeSlider.value()) - 1 dataset_percentage = float(new_index) / float( @@ -346,7 +352,7 @@ def keyPressEvent(self, event): # update the time slider self.ui.timeSlider.setValue(new_index) self.slider_pressed = False - elif event.key() == Qt.Key_F: + elif event.key() == Qt.Key.Key_F: self.slider_pressed = True new_index = int(self.ui.timeSlider.value()) + 1 dataset_percentage = float(new_index) / float( @@ -369,7 +375,7 @@ def keyPressEvent(self, event): self.slider_pressed = False else: # If the user presses the space bar, the play/pause state is toggled. - if event.key() == Qt.Key_Space: + if event.key() == Qt.Key.Key_Space: # toggle the play/pause button if self.ui.startButton.isEnabled(): self.ui.startButton.click() @@ -452,7 +458,7 @@ def plotTabCloseButton_on_click(self, index): def plotTabBar_on_doubleClick(self, index): dlg, plot_title = build_plot_title_box_dialog() - if dlg.exec() == QDialog.Accepted: + if dlg.exec() == QDialog.DialogCode.Accepted: self.ui.tabPlotWidget.setTabText(index, plot_title.text()) def variableTreeWidget_on_click(self): @@ -639,7 +645,7 @@ def __populate_variable_tree_widget(self, obj, parent) -> QTreeWidgetItem: for key, value in obj.items(): item = QTreeWidgetItem([key]) item = self.__populate_variable_tree_widget(value, item) - item.setFlags(item.flags() & ~Qt.ItemIsSelectable) + item.setFlags(item.flags() & ~Qt.ItemFlag.ItemIsSelectable) parent.addChild(item) return parent @@ -654,7 +660,7 @@ def __populate_text_logging_tree_widget(self, obj, parent) -> QTreeWidgetItem: item = QTreeWidgetItem([key]) item = self.__populate_text_logging_tree_widget(value, item) if "data" not in value.keys(): - item.setFlags(item.flags() & ~Qt.ItemIsSelectable) + item.setFlags(item.flags() & ~Qt.ItemFlag.ItemIsSelectable) parent.addChild(item) return parent @@ -690,7 +696,7 @@ def __load_mat_file(self, file_name): # populate tree root = list(self.signal_provider.data.keys())[0] root_item = QTreeWidgetItem([root]) - root_item.setFlags(root_item.flags() & ~Qt.ItemIsSelectable) + root_item.setFlags(root_item.flags() & ~Qt.ItemFlag.ItemIsSelectable) items = self.__populate_variable_tree_widget( self.signal_provider.data[root], root_item ) @@ -700,7 +706,7 @@ def __load_mat_file(self, file_name): if self.signal_provider.text_logging_data: root = list(self.signal_provider.text_logging_data.keys())[0] root_item = QTreeWidgetItem([root]) - root_item.setFlags(root_item.flags() & ~Qt.ItemIsSelectable) + root_item.setFlags(root_item.flags() & ~Qt.ItemFlag.ItemIsSelectable) items = self.__populate_text_logging_tree_widget( self.signal_provider.text_logging_data[root], root_item ) @@ -773,7 +779,7 @@ def connect_realtime_logger(self): # only display one root in the gui root = list(self.signal_provider.data.keys())[0] root_item = QTreeWidgetItem([root]) - root_item.setFlags(root_item.flags() & ~Qt.ItemIsSelectable) + root_item.setFlags(root_item.flags() & ~Qt.ItemFlag.ItemIsSelectable) items = self.__populate_variable_tree_widget( self.signal_provider.data[root], root_item ) @@ -814,14 +820,17 @@ def open_set_robot_model(self): self.dataset_loaded, ) outcome = dlg.exec() - if outcome == QDialog.Accepted: + if outcome == QDialog.DialogCode.Accepted: # check which button was clicked button_role = dlg.get_clicked_button_role() button_text = dlg.get_clicked_button_text() std_button = dlg.get_clicked_standard_button() - if std_button == QtWidgets.QDialogButtonBox.SaveAll: + if ( + std_button + == QtWidgets.QDialogButtonBox.StandardButton.SaveAll + ): if not self.dataset_loaded: self.meshcat_provider.model_path = dlg.get_urdf_path() self.meshcat_provider.custom_package_dir = ( @@ -836,7 +845,7 @@ def open_set_robot_model(self): self.signal_provider.set_custom_max_arrow( not dlg.ui.arrowScaling_checkBox.isChecked(), arrow_scaling_value ) - if std_button == QtWidgets.QDialogButtonBox.Save: + if std_button == QtWidgets.QDialogButtonBox.StandardButton.Save: # we need to check which tab is selected in the dlg if dlg.ui.tabWidget.currentIndex() == 0: if not self.dataset_loaded: @@ -886,7 +895,7 @@ def variableTreeWidget_on_right_click(self, item_position): if self.ui.variableTreeWidget.topLevelItemCount() == 0: menu = QtWidgets.QMenu() menu.addAction("Open a mat file") - action = menu.exec_(self.ui.variableTreeWidget.mapToGlobal(item_position)) + action = menu.exec(self.ui.variableTreeWidget.mapToGlobal(item_position)) if action is None: return if action.text() == "Open a mat file": @@ -977,7 +986,7 @@ def variableTreeWidget_on_right_click(self, item_position): menu.addAction(add_3d_arrow_str) # show the menu - action = menu.exec_(self.ui.variableTreeWidget.mapToGlobal(item_position)) + action = menu.exec(self.ui.variableTreeWidget.mapToGlobal(item_position)) if action is None: return @@ -1178,4 +1187,4 @@ def scroll_down(self): # show the main window gui.show() - sys.exit(app.exec_()) + sys.exit(app.exec()) diff --git a/robot_log_visualizer/ui/misc/video_tab.ui b/robot_log_visualizer/ui/misc/video_tab.ui index 35d09b0..be72504 100644 --- a/robot_log_visualizer/ui/misc/video_tab.ui +++ b/robot_log_visualizer/ui/misc/video_tab.ui @@ -23,7 +23,7 @@ QVideoWidget QWidget -
PyQt5.QtMultimediaWidgets
+
PyQt6.QtMultimediaWidgets
1
diff --git a/robot_log_visualizer/ui/plot_item.py b/robot_log_visualizer/ui/plot_item.py index b4ba329..2e73e4c 100644 --- a/robot_log_visualizer/ui/plot_item.py +++ b/robot_log_visualizer/ui/plot_item.py @@ -2,7 +2,7 @@ # This software may be modified and distributed under the terms of the # Released under the terms of the BSD 3-Clause License -from PyQt5.QtWidgets import QFrame +from PyQt6.QtWidgets import QFrame from robot_log_visualizer.plotter.pyqtgraph_viewer_canvas import PyQtGraphViewerCanvas from robot_log_visualizer.ui.autogenerated.plot_tab import Ui_PlotTab diff --git a/robot_log_visualizer/ui/text_logging.py b/robot_log_visualizer/ui/text_logging.py index 477b4b8..14b00dc 100644 --- a/robot_log_visualizer/ui/text_logging.py +++ b/robot_log_visualizer/ui/text_logging.py @@ -1,9 +1,6 @@ -from PyQt5 import QtWidgets -from PyQt5.QtWidgets import ( - QTableWidgetItem, -) - -from PyQt5.QtGui import QColor, QBrush +from PyQt6 import QtWidgets +from PyQt6.QtGui import QColor, QBrush +from PyQt6.QtWidgets import QTableWidgetItem class TextLoggingItem: @@ -35,7 +32,9 @@ def clean(self): self.table_widget.resizeColumnToContents(1) self.table_widget.clear() header = self.table_widget.horizontalHeader() - header.setSectionResizeMode(QtWidgets.QHeaderView.ResizeToContents) + header.setSectionResizeMode( + QtWidgets.QHeaderView.ResizeMode.ResizeToContents + ) self.index_coloured_cell = None def highlight_cell(self, index): diff --git a/robot_log_visualizer/ui/video_item.py b/robot_log_visualizer/ui/video_item.py index 8db0ad8..6fc021e 100644 --- a/robot_log_visualizer/ui/video_item.py +++ b/robot_log_visualizer/ui/video_item.py @@ -2,9 +2,9 @@ # This software may be modified and distributed under the terms of the # Released under the terms of the BSD 3-Clause License -from PyQt5.QtCore import QUrl -from PyQt5.QtWidgets import QFrame -from PyQt5.QtMultimedia import QMediaContent, QMediaPlayer +from PyQt6.QtCore import QUrl +from PyQt6.QtMultimedia import QAudioOutput, QMediaPlayer +from PyQt6.QtWidgets import QFrame from robot_log_visualizer.ui.autogenerated.video_tab import Ui_VideoTab import os @@ -16,13 +16,13 @@ def __init__(self, video_filename: str): self.ui = Ui_VideoTab() self.ui.setupUi(self) - self.media_player = QMediaPlayer(None, QMediaPlayer.VideoSurface) + self.media_player = QMediaPlayer(self) + self.audio_output = QAudioOutput(self) + self.media_player.setAudioOutput(self.audio_output) self.media_player.setVideoOutput(self.ui.webcamView) self.media_loaded = False if os.path.isfile(video_filename): - self.media_player.setMedia( - QMediaContent(QUrl.fromLocalFile(video_filename)) - ) + self.media_player.setSource(QUrl.fromLocalFile(video_filename)) self.media_loaded = True diff --git a/setup.cfg b/setup.cfg index b2ccf29..7bac303 100644 --- a/setup.cfg +++ b/setup.cfg @@ -43,8 +43,8 @@ install_requires = idyntree >= 10.2.0 meshcat numpy - PyQt5 - PyQtWebEngine + PyQt6 + PyQt6-WebEngine pyqtconsole matplotlib h5py From bf4028915d544bf8ba0efc3aeec61946a2cbf1bd Mon Sep 17 00:00:00 2001 From: Giulio Romualdi Date: Sun, 5 Oct 2025 13:32:54 +0200 Subject: [PATCH 2/5] Upgrade CI workflow to use Ubuntu 24.04 --- .github/workflows/ci.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 33c9ee2..e29c191 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -9,7 +9,7 @@ on: jobs: check-style: name: Find Trailing Whitespace - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v4 - name: Find Trailing Whitespace @@ -26,7 +26,7 @@ jobs: build: name: Generate python files from ui - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v4 - name: Remove broken apt repos [Ubuntu] @@ -47,7 +47,7 @@ jobs: path: robot_log_visualizer/ui/autogenerated deploy: - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 needs: [build] if: github.ref == 'refs/heads/main' steps: From c6a8ba2c222daa1f61f2f5ae2f341d0be02d7ec3 Mon Sep 17 00:00:00 2001 From: Giulio Romualdi Date: Sun, 5 Oct 2025 14:49:35 +0200 Subject: [PATCH 3/5] Refactor to use PySide6 and QtPy for UI components - Updated CI workflow to install pyside6-tools instead of pyqt6-dev-tools. - Modified generate-ui.sh to support both PySide6 and QtPy for UI file generation. - Changed imports in various Python files from PyQt6 to qtpy for better compatibility. - Updated autogenerated UI files to reflect the new QtPy imports and modified generated comments. - Adjusted setup.cfg to replace PyQt6 with PySide6 and added qtpy as a dependency. --- .github/workflows/ci.yml | 2 +- generate-ui.sh | 77 +++++++++++++++++-- robot_log_visualizer/__init__.py | 4 + robot_log_visualizer/__main__.py | 8 +- .../plotter/pyqtgraph_viewer_canvas.py | 2 +- .../robot_visualizer/meshcat_provider.py | 2 +- .../signal_provider/signal_provider.py | 4 +- .../ui/autogenerated/about.py | 4 +- .../ui/autogenerated/plot_tab.py | 4 +- .../ui/autogenerated/set_robot_model.py | 22 +++--- .../ui/autogenerated/video_tab.py | 6 +- .../ui/autogenerated/visualizer.py | 72 ++++++++--------- robot_log_visualizer/ui/gui.py | 63 ++++++++------- robot_log_visualizer/ui/misc/video_tab.ui | 6 +- robot_log_visualizer/ui/plot_item.py | 2 +- robot_log_visualizer/ui/text_logging.py | 10 +-- robot_log_visualizer/ui/video_item.py | 6 +- setup.cfg | 18 ++--- 18 files changed, 190 insertions(+), 122 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e29c191..ad91922 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -35,7 +35,7 @@ jobs: - name: Dependencies [Ubuntu] run: | sudo apt update - sudo apt install -y pyqt6-dev-tools + sudo apt install -y pyside6-tools - name: Generate python files run: | bash ./generate-ui.sh diff --git a/generate-ui.sh b/generate-ui.sh index 3554667..2486d76 100755 --- a/generate-ui.sh +++ b/generate-ui.sh @@ -1,18 +1,25 @@ #! /bin/bash SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) +cd "${SCRIPT_DIR}" || exit 1 -if command -v pyuic6 >/dev/null 2>&1; then - PYUIC_CMD=(pyuic6) -elif [ -x "${SCRIPT_DIR}/.venv/bin/pyuic6" ]; then - PYUIC_CMD=("${SCRIPT_DIR}/.venv/bin/pyuic6") +if [ -x "${SCRIPT_DIR}/.venv/bin/python" ] && "${SCRIPT_DIR}/.venv/bin/python" -c "import importlib.util as _il; mod=_il.find_spec('qtpy.uic.pyuic'); import sys; sys.exit(0 if mod else 1)" >/dev/null 2>&1; then + PYUIC_CMD=("${SCRIPT_DIR}/.venv/bin/python" "-m" "qtpy.uic.pyuic") +elif command -v python >/dev/null 2>&1 && python -c "import importlib.util as _il; mod=_il.find_spec('qtpy.uic.pyuic'); import sys; sys.exit(0 if mod else 1)" >/dev/null 2>&1; then + PYUIC_CMD=(python "-m" "qtpy.uic.pyuic") +elif command -v python3 >/dev/null 2>&1 && python3 -c "import importlib.util as _il; mod=_il.find_spec('qtpy.uic.pyuic'); import sys; sys.exit(0 if mod else 1)" >/dev/null 2>&1; then + PYUIC_CMD=(python3 "-m" "qtpy.uic.pyuic") +elif command -v pyside6-uic >/dev/null 2>&1; then + PYUIC_CMD=(pyside6-uic) +elif [ -x "${SCRIPT_DIR}/.venv/bin/pyside6-uic" ]; then + PYUIC_CMD=("${SCRIPT_DIR}/.venv/bin/pyside6-uic") elif [ -x "${SCRIPT_DIR}/.venv/bin/python" ]; then - PYUIC_CMD=("${SCRIPT_DIR}/.venv/bin/python" -m PyQt6.uic.pyuic) + PYUIC_CMD=("${SCRIPT_DIR}/.venv/bin/python" "-m" "PySide6.scripts.uic") elif command -v python >/dev/null 2>&1; then - PYUIC_CMD=(python -m PyQt6.uic.pyuic) + PYUIC_CMD=(python "-m" "PySide6.scripts.uic") elif command -v python3 >/dev/null 2>&1; then - PYUIC_CMD=(python3 -m PyQt6.uic.pyuic) + PYUIC_CMD=(python3 "-m" "PySide6.scripts.uic") else - echo "Error: pyuic6 not found. Please install PyQt6 tools." >&2 + echo "Error: pyside6-uic or qtpy.uic.pyuic not found. Please install the Qt tools." >&2 exit 1 fi @@ -27,4 +34,58 @@ echo "Generate tab" "${PYUIC_CMD[@]}" -o robot_log_visualizer/ui/autogenerated/plot_tab.py robot_log_visualizer/ui/misc/plot_tab.ui "${PYUIC_CMD[@]}" -o robot_log_visualizer/ui/autogenerated/video_tab.py robot_log_visualizer/ui/misc/video_tab.ui +if [ -x "${SCRIPT_DIR}/.venv/bin/python" ]; then + POST_PYTHON="${SCRIPT_DIR}/.venv/bin/python" +elif command -v python >/dev/null 2>&1; then + POST_PYTHON=$(command -v python) +elif command -v python3 >/dev/null 2>&1; then + POST_PYTHON=$(command -v python3) +else + echo "Error: Python interpreter not found for post-processing." >&2 + exit 1 +fi + +"${POST_PYTHON}" <<'PYCODE' +from pathlib import Path + +AUTOGEN_DIR = Path("robot_log_visualizer/ui/autogenerated") + +REPLACEMENTS = { + "from PyQt6 import QtCore, QtGui, QtWidgets": "from qtpy import QtCore, QtGui, QtWidgets", + "from PyQt6 import QtWebEngineWidgets": "from qtpy import QtWebEngineWidgets", + "from PyQt6.QtMultimediaWidgets import QVideoWidget": "from qtpy.QtMultimediaWidgets import QVideoWidget", + "from PySide6 import QtCore, QtGui, QtWidgets": "from qtpy import QtCore, QtGui, QtWidgets", + "from PySide6 import QtWebEngineWidgets": "from qtpy import QtWebEngineWidgets", + "from PySide6.QtMultimediaWidgets import QVideoWidget": "from qtpy.QtMultimediaWidgets import QVideoWidget", + "QtWidgets.QSizePolicy.Policy.": "QtWidgets.QSizePolicy.", + "QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.": "QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.", + "QtCore.Qt.Orientation.": "QtCore.Qt.", + "QtWidgets.QFrame.Shape.": "QtWidgets.QFrame.", + "QtWidgets.QFrame.Shadow.": "QtWidgets.QFrame.", + "QtWidgets.QAbstractItemView.SelectionMode.": "QtWidgets.QAbstractItemView.", + "QtWidgets.QAbstractItemView.EditTrigger.": "QtWidgets.QAbstractItemView.", + "QtWidgets.QAbstractScrollArea.SizeAdjustPolicy.": "QtWidgets.QAbstractScrollArea.", + "QtWidgets.QAbstractItemView.ScrollMode.": "QtWidgets.QAbstractItemView.", + "QtCore.Qt.ScrollBarPolicy.": "QtCore.Qt.", + "QtCore.Qt.PenStyle.": "QtCore.Qt.", + "QtWidgets.QTabWidget.TabPosition.": "QtWidgets.QTabWidget.", + "QtWidgets.QHeaderView.ResizeMode.": "QtWidgets.QHeaderView.", + "QtGui.QIcon.Mode.": "QtGui.QIcon.", + "QtGui.QIcon.State.": "QtGui.QIcon.", + "QtGui.QCursor(QtCore.Qt.CursorShape.": "QtGui.QCursor(QtCore.Qt.", + "QtCore.Qt.ContextMenuPolicy.": "QtCore.Qt.", + "QtWidgets.QDialogButtonBox.StandardButton.": "QtWidgets.QDialogButtonBox.", +} + +for path in AUTOGEN_DIR.glob("*.py"): + text = path.read_text() + original = text + for old, new in REPLACEMENTS.items(): + text = text.replace(old, new) + text = text.replace("PyQt6 UI code generator", "Qt-based UI code generator") + text = text.replace("PySide6 UI code generator", "Qt-based UI code generator") + if text != original: + path.write_text(text) +PYCODE + echo "The ui is generated" diff --git a/robot_log_visualizer/__init__.py b/robot_log_visualizer/__init__.py index e69de29..44f7859 100644 --- a/robot_log_visualizer/__init__.py +++ b/robot_log_visualizer/__init__.py @@ -0,0 +1,4 @@ +import os + +# Prefer the PySide6 backend when QtPy resolves the Qt binding. +os.environ.setdefault("QT_API", "pyside6") diff --git a/robot_log_visualizer/__main__.py b/robot_log_visualizer/__main__.py index b9940eb..6e7196f 100755 --- a/robot_log_visualizer/__main__.py +++ b/robot_log_visualizer/__main__.py @@ -7,7 +7,7 @@ import sys # GUI -from PyQt6.QtWidgets import QApplication +from qtpy.QtWidgets import QApplication from robot_log_visualizer.ui.gui import RobotViewerMainWindow # Meshcat @@ -36,7 +36,11 @@ def main(): # show the main window gui.show() - return app.exec() + exec_method = getattr(app, "exec", None) + if exec_method is None: + exec_method = app.exec_ + + return exec_method() if __name__ == "__main__": diff --git a/robot_log_visualizer/plotter/pyqtgraph_viewer_canvas.py b/robot_log_visualizer/plotter/pyqtgraph_viewer_canvas.py index 0b02e00..7704f31 100644 --- a/robot_log_visualizer/plotter/pyqtgraph_viewer_canvas.py +++ b/robot_log_visualizer/plotter/pyqtgraph_viewer_canvas.py @@ -8,7 +8,7 @@ import numpy as np import pyqtgraph as pg # type: ignore -from PyQt6 import QtCore, QtWidgets # type: ignore +from qtpy import QtCore, QtWidgets # type: ignore from robot_log_visualizer.plotter.color_palette import ColorPalette from robot_log_visualizer.signal_provider.signal_provider import ProviderType diff --git a/robot_log_visualizer/robot_visualizer/meshcat_provider.py b/robot_log_visualizer/robot_visualizer/meshcat_provider.py index b4d9e15..dad2a36 100644 --- a/robot_log_visualizer/robot_visualizer/meshcat_provider.py +++ b/robot_log_visualizer/robot_visualizer/meshcat_provider.py @@ -10,7 +10,7 @@ import idyntree.swig as idyn import numpy as np from idyntree.visualize import MeshcatVisualizer -from PyQt6.QtCore import QMutex, QMutexLocker, QThread +from qtpy.QtCore import QMutex, QMutexLocker, QThread from robot_log_visualizer.utils.utils import PeriodicThreadState diff --git a/robot_log_visualizer/signal_provider/signal_provider.py b/robot_log_visualizer/signal_provider/signal_provider.py index 8135ab1..285fb49 100644 --- a/robot_log_visualizer/signal_provider/signal_provider.py +++ b/robot_log_visualizer/signal_provider/signal_provider.py @@ -9,7 +9,9 @@ import h5py import idyntree.swig as idyn import numpy as np -from PyQt6.QtCore import QMutex, QMutexLocker, QThread, pyqtSignal +from qtpy.QtCore import QMutex, QMutexLocker, QThread, Signal + +pyqtSignal = Signal from robot_log_visualizer.utils.utils import PeriodicThreadState, RobotStatePath diff --git a/robot_log_visualizer/ui/autogenerated/about.py b/robot_log_visualizer/ui/autogenerated/about.py index 4aaf47d..9e00f6f 100644 --- a/robot_log_visualizer/ui/autogenerated/about.py +++ b/robot_log_visualizer/ui/autogenerated/about.py @@ -1,12 +1,12 @@ # Form implementation generated from reading ui file 'robot_log_visualizer/ui/misc/about.ui' # -# Created by: PyQt6 UI code generator 6.9.1 +# Created by: Qt-based UI code generator # # WARNING: Any manual changes made to this file will be lost when pyuic6 is # run again. Do not edit this file unless you know what you are doing. -from PyQt6 import QtCore, QtGui, QtWidgets +from qtpy import QtCore, QtGui, QtWidgets class Ui_aboutWindow(object): diff --git a/robot_log_visualizer/ui/autogenerated/plot_tab.py b/robot_log_visualizer/ui/autogenerated/plot_tab.py index 9b53710..e1af271 100644 --- a/robot_log_visualizer/ui/autogenerated/plot_tab.py +++ b/robot_log_visualizer/ui/autogenerated/plot_tab.py @@ -1,12 +1,12 @@ # Form implementation generated from reading ui file 'robot_log_visualizer/ui/misc/plot_tab.ui' # -# Created by: PyQt6 UI code generator 6.9.1 +# Created by: Qt-based UI code generator # # WARNING: Any manual changes made to this file will be lost when pyuic6 is # run again. Do not edit this file unless you know what you are doing. -from PyQt6 import QtCore, QtGui, QtWidgets +from qtpy import QtCore, QtGui, QtWidgets class Ui_PlotTab(object): diff --git a/robot_log_visualizer/ui/autogenerated/set_robot_model.py b/robot_log_visualizer/ui/autogenerated/set_robot_model.py index 810fe00..c522aeb 100644 --- a/robot_log_visualizer/ui/autogenerated/set_robot_model.py +++ b/robot_log_visualizer/ui/autogenerated/set_robot_model.py @@ -1,12 +1,12 @@ # Form implementation generated from reading ui file 'robot_log_visualizer/ui/misc/set_robot_model.ui' # -# Created by: PyQt6 UI code generator 6.9.1 +# Created by: Qt-based UI code generator # # WARNING: Any manual changes made to this file will be lost when pyuic6 is # run again. Do not edit this file unless you know what you are doing. -from PyQt6 import QtCore, QtGui, QtWidgets +from qtpy import QtCore, QtGui, QtWidgets class Ui_setRobotModelDialog(object): @@ -15,11 +15,11 @@ def setupUi(self, setRobotModelDialog): setRobotModelDialog.resize(711, 363) self.gridLayout = QtWidgets.QGridLayout(setRobotModelDialog) self.gridLayout.setObjectName("gridLayout") - spacerItem = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Expanding) + spacerItem = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) self.gridLayout.addItem(spacerItem, 1, 0, 1, 1) self.buttonBox = QtWidgets.QDialogButtonBox(parent=setRobotModelDialog) - self.buttonBox.setOrientation(QtCore.Qt.Orientation.Horizontal) - self.buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.StandardButton.Close|QtWidgets.QDialogButtonBox.StandardButton.Save|QtWidgets.QDialogButtonBox.StandardButton.SaveAll) + self.buttonBox.setOrientation(QtCore.Qt.Horizontal) + self.buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.Close|QtWidgets.QDialogButtonBox.Save|QtWidgets.QDialogButtonBox.SaveAll) self.buttonBox.setObjectName("buttonBox") self.gridLayout.addWidget(self.buttonBox, 2, 0, 1, 1) self.tabWidget = QtWidgets.QTabWidget(parent=setRobotModelDialog) @@ -29,7 +29,7 @@ def setupUi(self, setRobotModelDialog): self.verticalLayout = QtWidgets.QVBoxLayout(self.robot_tab) self.verticalLayout.setObjectName("verticalLayout") self.frame = QtWidgets.QFrame(parent=self.robot_tab) - self.frame.setFrameShape(QtWidgets.QFrame.Shape.StyledPanel) + self.frame.setFrameShape(QtWidgets.QFrame.StyledPanel) self.frame.setObjectName("frame") self.gridLayout_2 = QtWidgets.QGridLayout(self.frame) self.gridLayout_2.setObjectName("gridLayout_2") @@ -47,7 +47,7 @@ def setupUi(self, setRobotModelDialog): self.gridLayout_2.addWidget(self.robotModelLineEdit, 1, 0, 1, 1) self.verticalLayout.addWidget(self.frame) self.frame_2 = QtWidgets.QFrame(parent=self.robot_tab) - self.frame_2.setFrameShape(QtWidgets.QFrame.Shape.StyledPanel) + self.frame_2.setFrameShape(QtWidgets.QFrame.StyledPanel) self.frame_2.setObjectName("frame_2") self.gridLayout_3 = QtWidgets.QGridLayout(self.frame_2) self.gridLayout_3.setObjectName("gridLayout_3") @@ -65,7 +65,7 @@ def setupUi(self, setRobotModelDialog): self.gridLayout_3.addWidget(self.packageDirLineEdit, 1, 0, 1, 1) self.verticalLayout.addWidget(self.frame_2) self.frame_3 = QtWidgets.QFrame(parent=self.robot_tab) - self.frame_3.setFrameShape(QtWidgets.QFrame.Shape.StyledPanel) + self.frame_3.setFrameShape(QtWidgets.QFrame.StyledPanel) self.frame_3.setObjectName("frame_3") self.formLayout_2 = QtWidgets.QFormLayout(self.frame_3) self.formLayout_2.setObjectName("formLayout_2") @@ -83,8 +83,8 @@ def setupUi(self, setRobotModelDialog): self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.mischellanea_tab) self.verticalLayout_2.setObjectName("verticalLayout_2") self.frame_4 = QtWidgets.QFrame(parent=self.mischellanea_tab) - self.frame_4.setFrameShape(QtWidgets.QFrame.Shape.StyledPanel) - self.frame_4.setFrameShadow(QtWidgets.QFrame.Shadow.Raised) + self.frame_4.setFrameShape(QtWidgets.QFrame.StyledPanel) + self.frame_4.setFrameShadow(QtWidgets.QFrame.Raised) self.frame_4.setObjectName("frame_4") self.gridLayout_4 = QtWidgets.QGridLayout(self.frame_4) self.gridLayout_4.setObjectName("gridLayout_4") @@ -103,7 +103,7 @@ def setupUi(self, setRobotModelDialog): self.arrowScaling_checkBox.setObjectName("arrowScaling_checkBox") self.gridLayout_4.addWidget(self.arrowScaling_checkBox, 0, 2, 1, 1) self.verticalLayout_2.addWidget(self.frame_4) - spacerItem1 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Expanding) + spacerItem1 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) self.verticalLayout_2.addItem(spacerItem1) self.tabWidget.addTab(self.mischellanea_tab, "") self.gridLayout.addWidget(self.tabWidget, 0, 0, 1, 1) diff --git a/robot_log_visualizer/ui/autogenerated/video_tab.py b/robot_log_visualizer/ui/autogenerated/video_tab.py index 02531e2..2ccdb22 100644 --- a/robot_log_visualizer/ui/autogenerated/video_tab.py +++ b/robot_log_visualizer/ui/autogenerated/video_tab.py @@ -1,12 +1,12 @@ # Form implementation generated from reading ui file 'robot_log_visualizer/ui/misc/video_tab.ui' # -# Created by: PyQt6 UI code generator 6.9.1 +# Created by: Qt-based UI code generator # # WARNING: Any manual changes made to this file will be lost when pyuic6 is # run again. Do not edit this file unless you know what you are doing. -from PyQt6 import QtCore, QtGui, QtWidgets +from qtpy import QtCore, QtGui, QtWidgets class Ui_VideoTab(object): @@ -25,4 +25,4 @@ def setupUi(self, VideoTab): def retranslateUi(self, VideoTab): _translate = QtCore.QCoreApplication.translate VideoTab.setWindowTitle(_translate("VideoTab", "Form")) -from PyQt6.QtMultimediaWidgets import QVideoWidget +from qtpy.QtMultimediaWidgets import QVideoWidget diff --git a/robot_log_visualizer/ui/autogenerated/visualizer.py b/robot_log_visualizer/ui/autogenerated/visualizer.py index d221721..23ea21a 100644 --- a/robot_log_visualizer/ui/autogenerated/visualizer.py +++ b/robot_log_visualizer/ui/autogenerated/visualizer.py @@ -1,12 +1,12 @@ # Form implementation generated from reading ui file 'robot_log_visualizer/ui/misc/visualizer.ui' # -# Created by: PyQt6 UI code generator 6.9.1 +# Created by: Qt-based UI code generator # # WARNING: Any manual changes made to this file will be lost when pyuic6 is # run again. Do not edit this file unless you know what you are doing. -from PyQt6 import QtCore, QtGui, QtWidgets +from qtpy import QtCore, QtGui, QtWidgets class Ui_MainWindow(object): @@ -15,7 +15,7 @@ def setupUi(self, MainWindow): MainWindow.resize(929, 908) MainWindow.setAcceptDrops(True) self.centralwidget = QtWidgets.QWidget(parent=MainWindow) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Expanding) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.centralwidget.sizePolicy().hasHeightForWidth()) @@ -24,17 +24,17 @@ def setupUi(self, MainWindow): self.verticalLayout = QtWidgets.QVBoxLayout(self.centralwidget) self.verticalLayout.setObjectName("verticalLayout") self.splitter_2 = QtWidgets.QSplitter(parent=self.centralwidget) - self.splitter_2.setOrientation(QtCore.Qt.Orientation.Vertical) + self.splitter_2.setOrientation(QtCore.Qt.Vertical) self.splitter_2.setChildrenCollapsible(False) self.splitter_2.setObjectName("splitter_2") self.dataVisualizationFrame = QtWidgets.QFrame(parent=self.splitter_2) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Expanding) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(2) sizePolicy.setHeightForWidth(self.dataVisualizationFrame.sizePolicy().hasHeightForWidth()) self.dataVisualizationFrame.setSizePolicy(sizePolicy) self.dataVisualizationFrame.setMaximumSize(QtCore.QSize(16777215, 16777215)) - self.dataVisualizationFrame.setFrameShape(QtWidgets.QFrame.Shape.NoFrame) + self.dataVisualizationFrame.setFrameShape(QtWidgets.QFrame.NoFrame) self.dataVisualizationFrame.setObjectName("dataVisualizationFrame") self.gridLayout_3 = QtWidgets.QGridLayout(self.dataVisualizationFrame) self.gridLayout_3.setContentsMargins(-1, 9, -1, -1) @@ -52,27 +52,27 @@ def setupUi(self, MainWindow): self.gridLayout_3.addWidget(self.pauseButton, 1, 4, 1, 1) self.timeSlider = QtWidgets.QSlider(parent=self.dataVisualizationFrame) self.timeSlider.setEnabled(False) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Fixed) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.timeSlider.sizePolicy().hasHeightForWidth()) self.timeSlider.setSizePolicy(sizePolicy) self.timeSlider.setPageStep(1) self.timeSlider.setTracking(True) - self.timeSlider.setOrientation(QtCore.Qt.Orientation.Horizontal) + self.timeSlider.setOrientation(QtCore.Qt.Horizontal) self.timeSlider.setObjectName("timeSlider") self.gridLayout_3.addWidget(self.timeSlider, 1, 1, 1, 2) self.startButton = QtWidgets.QPushButton(parent=self.dataVisualizationFrame) self.startButton.setEnabled(False) self.startButton.setMaximumSize(QtCore.QSize(40, 16777215)) - self.startButton.setCursor(QtGui.QCursor(QtCore.Qt.CursorShape.ArrowCursor)) + self.startButton.setCursor(QtGui.QCursor(QtCore.Qt.ArrowCursor)) self.startButton.setText("") icon = QtGui.QIcon.fromTheme("media-playback-start") self.startButton.setIcon(icon) self.startButton.setObjectName("startButton") self.gridLayout_3.addWidget(self.startButton, 1, 3, 1, 1) self.timeLabel = QtWidgets.QLabel(parent=self.dataVisualizationFrame) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Fixed, QtWidgets.QSizePolicy.Policy.Ignored) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Ignored) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.timeLabel.sizePolicy().hasHeightForWidth()) @@ -81,11 +81,11 @@ def setupUi(self, MainWindow): self.timeLabel.setObjectName("timeLabel") self.gridLayout_3.addWidget(self.timeLabel, 1, 0, 1, 1) self.splitter = QtWidgets.QSplitter(parent=self.dataVisualizationFrame) - self.splitter.setOrientation(QtCore.Qt.Orientation.Horizontal) + self.splitter.setOrientation(QtCore.Qt.Horizontal) self.splitter.setChildrenCollapsible(True) self.splitter.setObjectName("splitter") self.variableTreeWidget = QtWidgets.QTreeWidget(parent=self.splitter) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.MinimumExpanding, QtWidgets.QSizePolicy.Policy.MinimumExpanding) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.MinimumExpanding) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.variableTreeWidget.sizePolicy().hasHeightForWidth()) @@ -93,15 +93,15 @@ def setupUi(self, MainWindow): self.variableTreeWidget.setMaximumSize(QtCore.QSize(16777215, 16777215)) self.variableTreeWidget.setSizeIncrement(QtCore.QSize(0, 0)) self.variableTreeWidget.setBaseSize(QtCore.QSize(0, 0)) - self.variableTreeWidget.setContextMenuPolicy(QtCore.Qt.ContextMenuPolicy.CustomContextMenu) - self.variableTreeWidget.setFrameShape(QtWidgets.QFrame.Shape.Box) - self.variableTreeWidget.setSelectionMode(QtWidgets.QAbstractItemView.SelectionMode.MultiSelection) + self.variableTreeWidget.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) + self.variableTreeWidget.setFrameShape(QtWidgets.QFrame.Box) + self.variableTreeWidget.setSelectionMode(QtWidgets.QAbstractItemView.MultiSelection) self.variableTreeWidget.setAnimated(True) self.variableTreeWidget.setObjectName("variableTreeWidget") self.variableTreeWidget.header().setVisible(False) self.variableTreeWidget.header().setDefaultSectionSize(100) self.tabPlotWidget = QtWidgets.QTabWidget(parent=self.splitter) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Expanding) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding) sizePolicy.setHorizontalStretch(1) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.tabPlotWidget.sizePolicy().hasHeightForWidth()) @@ -111,12 +111,12 @@ def setupUi(self, MainWindow): self.tabPlotWidget.setTabBarAutoHide(False) self.tabPlotWidget.setObjectName("tabPlotWidget") self.meshcatAndVideoTab = QtWidgets.QTabWidget(parent=self.splitter) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Expanding) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding) sizePolicy.setHorizontalStretch(2) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.meshcatAndVideoTab.sizePolicy().hasHeightForWidth()) self.meshcatAndVideoTab.setSizePolicy(sizePolicy) - self.meshcatAndVideoTab.setTabPosition(QtWidgets.QTabWidget.TabPosition.East) + self.meshcatAndVideoTab.setTabPosition(QtWidgets.QTabWidget.East) self.meshcatAndVideoTab.setDocumentMode(False) self.meshcatAndVideoTab.setObjectName("meshcatAndVideoTab") self.meshcatTab = QtWidgets.QWidget() @@ -124,7 +124,7 @@ def setupUi(self, MainWindow): self.horizontalLayout = QtWidgets.QHBoxLayout(self.meshcatTab) self.horizontalLayout.setObjectName("horizontalLayout") self.meshcatView = QtWebEngineWidgets.QWebEngineView(parent=self.meshcatTab) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.MinimumExpanding, QtWidgets.QSizePolicy.Policy.MinimumExpanding) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.MinimumExpanding) sizePolicy.setHorizontalStretch(1) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.meshcatView.sizePolicy().hasHeightForWidth()) @@ -137,7 +137,7 @@ def setupUi(self, MainWindow): self.tabWidget = QtWidgets.QTabWidget(parent=self.splitter_2) self.tabWidget.setMinimumSize(QtCore.QSize(0, 0)) self.tabWidget.setAutoFillBackground(False) - self.tabWidget.setTabPosition(QtWidgets.QTabWidget.TabPosition.West) + self.tabWidget.setTabPosition(QtWidgets.QTabWidget.West) self.tabWidget.setUsesScrollButtons(False) self.tabWidget.setDocumentMode(False) self.tabWidget.setTabsClosable(False) @@ -148,10 +148,10 @@ def setupUi(self, MainWindow): self.verticalLayout_3 = QtWidgets.QVBoxLayout(self.yarpTextLogWidget) self.verticalLayout_3.setObjectName("verticalLayout_3") self.splitter_3 = QtWidgets.QSplitter(parent=self.yarpTextLogWidget) - self.splitter_3.setOrientation(QtCore.Qt.Orientation.Horizontal) + self.splitter_3.setOrientation(QtCore.Qt.Horizontal) self.splitter_3.setObjectName("splitter_3") self.yarpTextLogTreeWidget = QtWidgets.QTreeWidget(parent=self.splitter_3) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Expanding) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.yarpTextLogTreeWidget.sizePolicy().hasHeightForWidth()) @@ -159,26 +159,26 @@ def setupUi(self, MainWindow): self.yarpTextLogTreeWidget.setMaximumSize(QtCore.QSize(16777215, 16777215)) self.yarpTextLogTreeWidget.setSizeIncrement(QtCore.QSize(0, 0)) self.yarpTextLogTreeWidget.setBaseSize(QtCore.QSize(0, 0)) - self.yarpTextLogTreeWidget.setFrameShape(QtWidgets.QFrame.Shape.Box) - self.yarpTextLogTreeWidget.setSelectionMode(QtWidgets.QAbstractItemView.SelectionMode.SingleSelection) + self.yarpTextLogTreeWidget.setFrameShape(QtWidgets.QFrame.Box) + self.yarpTextLogTreeWidget.setSelectionMode(QtWidgets.QAbstractItemView.SingleSelection) self.yarpTextLogTreeWidget.setAnimated(True) self.yarpTextLogTreeWidget.setObjectName("yarpTextLogTreeWidget") self.yarpTextLogTreeWidget.header().setVisible(False) self.yarpTextLogTreeWidget.header().setDefaultSectionSize(100) self.yarpTextLogTableWidget = QtWidgets.QTableWidget(parent=self.splitter_3) self.yarpTextLogTableWidget.setEnabled(True) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Expanding) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding) sizePolicy.setHorizontalStretch(10) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.yarpTextLogTableWidget.sizePolicy().hasHeightForWidth()) self.yarpTextLogTableWidget.setSizePolicy(sizePolicy) - self.yarpTextLogTableWidget.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarPolicy.ScrollBarAsNeeded) - self.yarpTextLogTableWidget.setSizeAdjustPolicy(QtWidgets.QAbstractScrollArea.SizeAdjustPolicy.AdjustIgnored) - self.yarpTextLogTableWidget.setEditTriggers(QtWidgets.QAbstractItemView.EditTrigger.NoEditTriggers) - self.yarpTextLogTableWidget.setSelectionMode(QtWidgets.QAbstractItemView.SelectionMode.NoSelection) - self.yarpTextLogTableWidget.setHorizontalScrollMode(QtWidgets.QAbstractItemView.ScrollMode.ScrollPerPixel) + self.yarpTextLogTableWidget.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded) + self.yarpTextLogTableWidget.setSizeAdjustPolicy(QtWidgets.QAbstractScrollArea.AdjustIgnored) + self.yarpTextLogTableWidget.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers) + self.yarpTextLogTableWidget.setSelectionMode(QtWidgets.QAbstractItemView.NoSelection) + self.yarpTextLogTableWidget.setHorizontalScrollMode(QtWidgets.QAbstractItemView.ScrollPerPixel) self.yarpTextLogTableWidget.setShowGrid(False) - self.yarpTextLogTableWidget.setGridStyle(QtCore.Qt.PenStyle.NoPen) + self.yarpTextLogTableWidget.setGridStyle(QtCore.Qt.NoPen) self.yarpTextLogTableWidget.setObjectName("yarpTextLogTableWidget") self.yarpTextLogTableWidget.setColumnCount(0) self.yarpTextLogTableWidget.setRowCount(0) @@ -202,8 +202,8 @@ def setupUi(self, MainWindow): self.logScrollArea.setMinimumSize(QtCore.QSize(0, 120)) self.logScrollArea.setAutoFillBackground(False) self.logScrollArea.setStyleSheet("background: white") - self.logScrollArea.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarPolicy.ScrollBarAsNeeded) - self.logScrollArea.setSizeAdjustPolicy(QtWidgets.QAbstractScrollArea.SizeAdjustPolicy.AdjustToContents) + self.logScrollArea.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded) + self.logScrollArea.setSizeAdjustPolicy(QtWidgets.QAbstractScrollArea.AdjustToContents) self.logScrollArea.setWidgetResizable(True) self.logScrollArea.setObjectName("logScrollArea") self.logScrollAreaWidgetContents = QtWidgets.QWidget() @@ -211,10 +211,10 @@ def setupUi(self, MainWindow): self.logScrollAreaWidgetContents.setObjectName("logScrollAreaWidgetContents") self.gridLayout = QtWidgets.QGridLayout(self.logScrollAreaWidgetContents) self.gridLayout.setObjectName("gridLayout") - spacerItem = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Expanding) + spacerItem = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) self.gridLayout.addItem(spacerItem, 2, 0, 1, 1) self.logLabel = QtWidgets.QLabel(parent=self.logScrollAreaWidgetContents) - self.logLabel.setCursor(QtGui.QCursor(QtCore.Qt.CursorShape.ArrowCursor)) + self.logLabel.setCursor(QtGui.QCursor(QtCore.Qt.ArrowCursor)) self.logLabel.setText("") self.logLabel.setObjectName("logLabel") self.gridLayout.addWidget(self.logLabel, 1, 0, 1, 1) @@ -282,4 +282,4 @@ def retranslateUi(self, MainWindow): self.actionSet_Robot_Model.setText(_translate("MainWindow", "Options")) self.actionRealtime_Connect.setText(_translate("MainWindow", "Realtime Connect")) self.actionRealtime_Connect.setShortcut(_translate("MainWindow", "Ctrl+R")) -from PyQt6 import QtWebEngineWidgets +from qtpy import QtWebEngineWidgets diff --git a/robot_log_visualizer/ui/gui.py b/robot_log_visualizer/ui/gui.py index 26027bb..d6af97c 100644 --- a/robot_log_visualizer/ui/gui.py +++ b/robot_log_visualizer/ui/gui.py @@ -2,10 +2,10 @@ # This software may be modified and distributed under the terms of the # Released under the terms of the BSD 3-Clause License -# PyQt6 -from PyQt6 import QtWidgets, QtGui, QtCore -from PyQt6.QtCore import QMutex, QMutexLocker, QUrl, Qt, pyqtSlot -from PyQt6.QtWidgets import ( +# QtPy abstraction +from qtpy import QtWidgets, QtGui, QtCore +from qtpy.QtCore import QMutex, QMutexLocker, QUrl, Qt, Slot +from qtpy.QtWidgets import ( QDialog, QDialogButtonBox, QFileDialog, @@ -14,6 +14,8 @@ QTreeWidgetItem, QVBoxLayout, ) + +pyqtSlot = Slot from robot_log_visualizer.robot_visualizer.meshcat_provider import MeshcatProvider from robot_log_visualizer.signal_provider.realtime_signal_provider import ( RealtimeSignalProvider, @@ -155,9 +157,7 @@ def build_plot_title_box_dialog(): la = QVBoxLayout(dlg) line_edit = QLineEdit() la.addWidget(line_edit) - bb = QDialogButtonBox( - QDialogButtonBox.StandardButton.Ok | QDialogButtonBox.StandardButton.Cancel - ) + bb = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) bb.clicked.connect(dlg.accept) bb.rejected.connect(dlg.reject) la.addWidget(bb) @@ -169,8 +169,8 @@ def get_icon(icon_name): icon = QtGui.QIcon() icon.addPixmap( QtGui.QPixmap(str(pathlib.Path(__file__).parent / "misc" / icon_name)), - QtGui.QIcon.Mode.Normal, - QtGui.QIcon.State.Off, + QtGui.QIcon.Normal, + QtGui.QIcon.Off, ) return icon @@ -281,9 +281,7 @@ def __init__(self, signal_provider_period, meshcat_provider, animation_period): self.ui.tabPlotWidget.currentChanged.connect(self.plotTabBar_currentChanged) # add a custom context menu to the variable tree widget - self.ui.variableTreeWidget.setContextMenuPolicy( - Qt.ContextMenuPolicy.CustomContextMenu - ) + self.ui.variableTreeWidget.setContextMenuPolicy(Qt.CustomContextMenu) self.ui.variableTreeWidget.customContextMenuRequested.connect( self.variableTreeWidget_on_right_click ) @@ -329,8 +327,8 @@ def keyPressEvent(self, event): if not self.dataset_loaded: return - if event.modifiers() & Qt.KeyboardModifier.ControlModifier: - if event.key() == Qt.Key.Key_B: + if event.modifiers() & Qt.ControlModifier: + if event.key() == Qt.Key_B: self.slider_pressed = True new_index = int(self.ui.timeSlider.value()) - 1 dataset_percentage = float(new_index) / float( @@ -352,7 +350,7 @@ def keyPressEvent(self, event): # update the time slider self.ui.timeSlider.setValue(new_index) self.slider_pressed = False - elif event.key() == Qt.Key.Key_F: + elif event.key() == Qt.Key_F: self.slider_pressed = True new_index = int(self.ui.timeSlider.value()) + 1 dataset_percentage = float(new_index) / float( @@ -375,7 +373,7 @@ def keyPressEvent(self, event): self.slider_pressed = False else: # If the user presses the space bar, the play/pause state is toggled. - if event.key() == Qt.Key.Key_Space: + if event.key() == Qt.Key_Space: # toggle the play/pause button if self.ui.startButton.isEnabled(): self.ui.startButton.click() @@ -458,7 +456,7 @@ def plotTabCloseButton_on_click(self, index): def plotTabBar_on_doubleClick(self, index): dlg, plot_title = build_plot_title_box_dialog() - if dlg.exec() == QDialog.DialogCode.Accepted: + if dlg.exec_() == QDialog.Accepted: self.ui.tabPlotWidget.setTabText(index, plot_title.text()) def variableTreeWidget_on_click(self): @@ -645,7 +643,7 @@ def __populate_variable_tree_widget(self, obj, parent) -> QTreeWidgetItem: for key, value in obj.items(): item = QTreeWidgetItem([key]) item = self.__populate_variable_tree_widget(value, item) - item.setFlags(item.flags() & ~Qt.ItemFlag.ItemIsSelectable) + item.setFlags(item.flags() & ~Qt.ItemIsSelectable) parent.addChild(item) return parent @@ -660,7 +658,7 @@ def __populate_text_logging_tree_widget(self, obj, parent) -> QTreeWidgetItem: item = QTreeWidgetItem([key]) item = self.__populate_text_logging_tree_widget(value, item) if "data" not in value.keys(): - item.setFlags(item.flags() & ~Qt.ItemFlag.ItemIsSelectable) + item.setFlags(item.flags() & ~Qt.ItemIsSelectable) parent.addChild(item) return parent @@ -696,7 +694,7 @@ def __load_mat_file(self, file_name): # populate tree root = list(self.signal_provider.data.keys())[0] root_item = QTreeWidgetItem([root]) - root_item.setFlags(root_item.flags() & ~Qt.ItemFlag.ItemIsSelectable) + root_item.setFlags(root_item.flags() & ~Qt.ItemIsSelectable) items = self.__populate_variable_tree_widget( self.signal_provider.data[root], root_item ) @@ -706,7 +704,7 @@ def __load_mat_file(self, file_name): if self.signal_provider.text_logging_data: root = list(self.signal_provider.text_logging_data.keys())[0] root_item = QTreeWidgetItem([root]) - root_item.setFlags(root_item.flags() & ~Qt.ItemFlag.ItemIsSelectable) + root_item.setFlags(root_item.flags() & ~Qt.ItemIsSelectable) items = self.__populate_text_logging_tree_widget( self.signal_provider.text_logging_data[root], root_item ) @@ -779,7 +777,7 @@ def connect_realtime_logger(self): # only display one root in the gui root = list(self.signal_provider.data.keys())[0] root_item = QTreeWidgetItem([root]) - root_item.setFlags(root_item.flags() & ~Qt.ItemFlag.ItemIsSelectable) + root_item.setFlags(root_item.flags() & ~Qt.ItemIsSelectable) items = self.__populate_variable_tree_widget( self.signal_provider.data[root], root_item ) @@ -819,18 +817,15 @@ def open_set_robot_model(self): self, self.dataset_loaded, ) - outcome = dlg.exec() - if outcome == QDialog.DialogCode.Accepted: + outcome = dlg.exec_() + if outcome == QDialog.Accepted: # check which button was clicked button_role = dlg.get_clicked_button_role() button_text = dlg.get_clicked_button_text() std_button = dlg.get_clicked_standard_button() - if ( - std_button - == QtWidgets.QDialogButtonBox.StandardButton.SaveAll - ): + if std_button == QtWidgets.QDialogButtonBox.SaveAll: if not self.dataset_loaded: self.meshcat_provider.model_path = dlg.get_urdf_path() self.meshcat_provider.custom_package_dir = ( @@ -845,7 +840,7 @@ def open_set_robot_model(self): self.signal_provider.set_custom_max_arrow( not dlg.ui.arrowScaling_checkBox.isChecked(), arrow_scaling_value ) - if std_button == QtWidgets.QDialogButtonBox.StandardButton.Save: + if std_button == QtWidgets.QDialogButtonBox.Save: # we need to check which tab is selected in the dlg if dlg.ui.tabWidget.currentIndex() == 0: if not self.dataset_loaded: @@ -895,7 +890,7 @@ def variableTreeWidget_on_right_click(self, item_position): if self.ui.variableTreeWidget.topLevelItemCount() == 0: menu = QtWidgets.QMenu() menu.addAction("Open a mat file") - action = menu.exec(self.ui.variableTreeWidget.mapToGlobal(item_position)) + action = menu.exec_(self.ui.variableTreeWidget.mapToGlobal(item_position)) if action is None: return if action.text() == "Open a mat file": @@ -986,7 +981,7 @@ def variableTreeWidget_on_right_click(self, item_position): menu.addAction(add_3d_arrow_str) # show the menu - action = menu.exec(self.ui.variableTreeWidget.mapToGlobal(item_position)) + action = menu.exec_(self.ui.variableTreeWidget.mapToGlobal(item_position)) if action is None: return @@ -1187,4 +1182,8 @@ def scroll_down(self): # show the main window gui.show() - sys.exit(app.exec()) + exec_method = getattr(app, "exec", None) + if exec_method is None: + exec_method = app.exec_ + + sys.exit(exec_method()) diff --git a/robot_log_visualizer/ui/misc/video_tab.ui b/robot_log_visualizer/ui/misc/video_tab.ui index be72504..82d80aa 100644 --- a/robot_log_visualizer/ui/misc/video_tab.ui +++ b/robot_log_visualizer/ui/misc/video_tab.ui @@ -21,9 +21,9 @@ - QVideoWidget - QWidget -
PyQt6.QtMultimediaWidgets
+ QVideoWidget + QWidget +
qtpy.QtMultimediaWidgets
1
diff --git a/robot_log_visualizer/ui/plot_item.py b/robot_log_visualizer/ui/plot_item.py index 2e73e4c..68c06b5 100644 --- a/robot_log_visualizer/ui/plot_item.py +++ b/robot_log_visualizer/ui/plot_item.py @@ -2,7 +2,7 @@ # This software may be modified and distributed under the terms of the # Released under the terms of the BSD 3-Clause License -from PyQt6.QtWidgets import QFrame +from qtpy.QtWidgets import QFrame from robot_log_visualizer.plotter.pyqtgraph_viewer_canvas import PyQtGraphViewerCanvas from robot_log_visualizer.ui.autogenerated.plot_tab import Ui_PlotTab diff --git a/robot_log_visualizer/ui/text_logging.py b/robot_log_visualizer/ui/text_logging.py index 14b00dc..dcb2403 100644 --- a/robot_log_visualizer/ui/text_logging.py +++ b/robot_log_visualizer/ui/text_logging.py @@ -1,6 +1,6 @@ -from PyQt6 import QtWidgets -from PyQt6.QtGui import QColor, QBrush -from PyQt6.QtWidgets import QTableWidgetItem +from qtpy import QtWidgets +from qtpy.QtGui import QColor, QBrush +from qtpy.QtWidgets import QTableWidgetItem class TextLoggingItem: @@ -32,9 +32,7 @@ def clean(self): self.table_widget.resizeColumnToContents(1) self.table_widget.clear() header = self.table_widget.horizontalHeader() - header.setSectionResizeMode( - QtWidgets.QHeaderView.ResizeMode.ResizeToContents - ) + header.setSectionResizeMode(QtWidgets.QHeaderView.ResizeToContents) self.index_coloured_cell = None def highlight_cell(self, index): diff --git a/robot_log_visualizer/ui/video_item.py b/robot_log_visualizer/ui/video_item.py index 6fc021e..e8efa5b 100644 --- a/robot_log_visualizer/ui/video_item.py +++ b/robot_log_visualizer/ui/video_item.py @@ -2,9 +2,9 @@ # This software may be modified and distributed under the terms of the # Released under the terms of the BSD 3-Clause License -from PyQt6.QtCore import QUrl -from PyQt6.QtMultimedia import QAudioOutput, QMediaPlayer -from PyQt6.QtWidgets import QFrame +from qtpy.QtCore import QUrl +from qtpy.QtMultimedia import QAudioOutput, QMediaPlayer +from qtpy.QtWidgets import QFrame from robot_log_visualizer.ui.autogenerated.video_tab import Ui_VideoTab import os diff --git a/setup.cfg b/setup.cfg index 7bac303..698c659 100644 --- a/setup.cfg +++ b/setup.cfg @@ -40,15 +40,15 @@ classifiers = packages = find: python_requires = >=3.8 install_requires = - idyntree >= 10.2.0 - meshcat - numpy - PyQt6 - PyQt6-WebEngine - pyqtconsole - matplotlib - h5py - pyqtgraph + idyntree >= 10.2.0 + meshcat + numpy + PySide6 + qtpy + pyqtconsole + matplotlib + h5py + pyqtgraph include_package_data = True [options.entry_points] From 9988670a2ad2e3af0dc1fa7904760049539afed3 Mon Sep 17 00:00:00 2001 From: Giulio Romualdi Date: Sun, 5 Oct 2025 16:33:59 +0200 Subject: [PATCH 4/5] Refactor UI loading mechanism and remove autogenerated files --- .github/workflows/ci.yml | 39 --- generate-ui.sh | 91 ------ .../ui/autogenerated/__init__.py | 0 .../ui/autogenerated/about.py | 34 --- .../ui/autogenerated/plot_tab.py | 27 -- .../ui/autogenerated/set_robot_model.py | 128 -------- .../ui/autogenerated/video_tab.py | 28 -- .../ui/autogenerated/visualizer.py | 285 ------------------ robot_log_visualizer/ui/gui.py | 14 +- robot_log_visualizer/ui/misc/visualizer.ui | 2 +- robot_log_visualizer/ui/plot_item.py | 5 +- robot_log_visualizer/ui/ui_loader.py | 55 ++++ robot_log_visualizer/ui/video_item.py | 5 +- setup.cfg | 2 +- 14 files changed, 66 insertions(+), 649 deletions(-) delete mode 100755 generate-ui.sh delete mode 100644 robot_log_visualizer/ui/autogenerated/__init__.py delete mode 100644 robot_log_visualizer/ui/autogenerated/about.py delete mode 100644 robot_log_visualizer/ui/autogenerated/plot_tab.py delete mode 100644 robot_log_visualizer/ui/autogenerated/set_robot_model.py delete mode 100644 robot_log_visualizer/ui/autogenerated/video_tab.py delete mode 100644 robot_log_visualizer/ui/autogenerated/visualizer.py create mode 100644 robot_log_visualizer/ui/ui_loader.py diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ad91922..4d06c23 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -23,42 +23,3 @@ jobs: exit 1 fi exit 0 - - build: - name: Generate python files from ui - runs-on: ubuntu-24.04 - steps: - - uses: actions/checkout@v4 - - name: Remove broken apt repos [Ubuntu] - run: | - for apt_file in `grep -lr microsoft /etc/apt/sources.list.d/`; do sudo rm $apt_file; done - - name: Dependencies [Ubuntu] - run: | - sudo apt update - sudo apt install -y pyside6-tools - - name: Generate python files - run: | - bash ./generate-ui.sh - - - name: Archive artifacts - uses: actions/upload-artifact@v4 - with: - name: autogenerated_files - path: robot_log_visualizer/ui/autogenerated - - deploy: - runs-on: ubuntu-24.04 - needs: [build] - if: github.ref == 'refs/heads/main' - steps: - - uses: actions/checkout@v4 - - - name: Download artifacts - uses: actions/download-artifact@v4 - with: - name: autogenerated_files - path: robot_log_visualizer/ui/autogenerated - - name: Deploy - uses: stefanzweifel/git-auto-commit-action@v5 - with: - commit_message: ⚙️ Automatic update of the python UI classes diff --git a/generate-ui.sh b/generate-ui.sh deleted file mode 100755 index 2486d76..0000000 --- a/generate-ui.sh +++ /dev/null @@ -1,91 +0,0 @@ -#! /bin/bash -SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) -cd "${SCRIPT_DIR}" || exit 1 - -if [ -x "${SCRIPT_DIR}/.venv/bin/python" ] && "${SCRIPT_DIR}/.venv/bin/python" -c "import importlib.util as _il; mod=_il.find_spec('qtpy.uic.pyuic'); import sys; sys.exit(0 if mod else 1)" >/dev/null 2>&1; then - PYUIC_CMD=("${SCRIPT_DIR}/.venv/bin/python" "-m" "qtpy.uic.pyuic") -elif command -v python >/dev/null 2>&1 && python -c "import importlib.util as _il; mod=_il.find_spec('qtpy.uic.pyuic'); import sys; sys.exit(0 if mod else 1)" >/dev/null 2>&1; then - PYUIC_CMD=(python "-m" "qtpy.uic.pyuic") -elif command -v python3 >/dev/null 2>&1 && python3 -c "import importlib.util as _il; mod=_il.find_spec('qtpy.uic.pyuic'); import sys; sys.exit(0 if mod else 1)" >/dev/null 2>&1; then - PYUIC_CMD=(python3 "-m" "qtpy.uic.pyuic") -elif command -v pyside6-uic >/dev/null 2>&1; then - PYUIC_CMD=(pyside6-uic) -elif [ -x "${SCRIPT_DIR}/.venv/bin/pyside6-uic" ]; then - PYUIC_CMD=("${SCRIPT_DIR}/.venv/bin/pyside6-uic") -elif [ -x "${SCRIPT_DIR}/.venv/bin/python" ]; then - PYUIC_CMD=("${SCRIPT_DIR}/.venv/bin/python" "-m" "PySide6.scripts.uic") -elif command -v python >/dev/null 2>&1; then - PYUIC_CMD=(python "-m" "PySide6.scripts.uic") -elif command -v python3 >/dev/null 2>&1; then - PYUIC_CMD=(python3 "-m" "PySide6.scripts.uic") -else - echo "Error: pyside6-uic or qtpy.uic.pyuic not found. Please install the Qt tools." >&2 - exit 1 -fi - -echo "Generate the main window" -"${PYUIC_CMD[@]}" -o robot_log_visualizer/ui/autogenerated/visualizer.py robot_log_visualizer/ui/misc/visualizer.ui - -echo "Generate Additional windows" -"${PYUIC_CMD[@]}" -o robot_log_visualizer/ui/autogenerated/about.py robot_log_visualizer/ui/misc/about.ui -"${PYUIC_CMD[@]}" -o robot_log_visualizer/ui/autogenerated/set_robot_model.py robot_log_visualizer/ui/misc/set_robot_model.ui - -echo "Generate tab" -"${PYUIC_CMD[@]}" -o robot_log_visualizer/ui/autogenerated/plot_tab.py robot_log_visualizer/ui/misc/plot_tab.ui -"${PYUIC_CMD[@]}" -o robot_log_visualizer/ui/autogenerated/video_tab.py robot_log_visualizer/ui/misc/video_tab.ui - -if [ -x "${SCRIPT_DIR}/.venv/bin/python" ]; then - POST_PYTHON="${SCRIPT_DIR}/.venv/bin/python" -elif command -v python >/dev/null 2>&1; then - POST_PYTHON=$(command -v python) -elif command -v python3 >/dev/null 2>&1; then - POST_PYTHON=$(command -v python3) -else - echo "Error: Python interpreter not found for post-processing." >&2 - exit 1 -fi - -"${POST_PYTHON}" <<'PYCODE' -from pathlib import Path - -AUTOGEN_DIR = Path("robot_log_visualizer/ui/autogenerated") - -REPLACEMENTS = { - "from PyQt6 import QtCore, QtGui, QtWidgets": "from qtpy import QtCore, QtGui, QtWidgets", - "from PyQt6 import QtWebEngineWidgets": "from qtpy import QtWebEngineWidgets", - "from PyQt6.QtMultimediaWidgets import QVideoWidget": "from qtpy.QtMultimediaWidgets import QVideoWidget", - "from PySide6 import QtCore, QtGui, QtWidgets": "from qtpy import QtCore, QtGui, QtWidgets", - "from PySide6 import QtWebEngineWidgets": "from qtpy import QtWebEngineWidgets", - "from PySide6.QtMultimediaWidgets import QVideoWidget": "from qtpy.QtMultimediaWidgets import QVideoWidget", - "QtWidgets.QSizePolicy.Policy.": "QtWidgets.QSizePolicy.", - "QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.": "QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.", - "QtCore.Qt.Orientation.": "QtCore.Qt.", - "QtWidgets.QFrame.Shape.": "QtWidgets.QFrame.", - "QtWidgets.QFrame.Shadow.": "QtWidgets.QFrame.", - "QtWidgets.QAbstractItemView.SelectionMode.": "QtWidgets.QAbstractItemView.", - "QtWidgets.QAbstractItemView.EditTrigger.": "QtWidgets.QAbstractItemView.", - "QtWidgets.QAbstractScrollArea.SizeAdjustPolicy.": "QtWidgets.QAbstractScrollArea.", - "QtWidgets.QAbstractItemView.ScrollMode.": "QtWidgets.QAbstractItemView.", - "QtCore.Qt.ScrollBarPolicy.": "QtCore.Qt.", - "QtCore.Qt.PenStyle.": "QtCore.Qt.", - "QtWidgets.QTabWidget.TabPosition.": "QtWidgets.QTabWidget.", - "QtWidgets.QHeaderView.ResizeMode.": "QtWidgets.QHeaderView.", - "QtGui.QIcon.Mode.": "QtGui.QIcon.", - "QtGui.QIcon.State.": "QtGui.QIcon.", - "QtGui.QCursor(QtCore.Qt.CursorShape.": "QtGui.QCursor(QtCore.Qt.", - "QtCore.Qt.ContextMenuPolicy.": "QtCore.Qt.", - "QtWidgets.QDialogButtonBox.StandardButton.": "QtWidgets.QDialogButtonBox.", -} - -for path in AUTOGEN_DIR.glob("*.py"): - text = path.read_text() - original = text - for old, new in REPLACEMENTS.items(): - text = text.replace(old, new) - text = text.replace("PyQt6 UI code generator", "Qt-based UI code generator") - text = text.replace("PySide6 UI code generator", "Qt-based UI code generator") - if text != original: - path.write_text(text) -PYCODE - -echo "The ui is generated" diff --git a/robot_log_visualizer/ui/autogenerated/__init__.py b/robot_log_visualizer/ui/autogenerated/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/robot_log_visualizer/ui/autogenerated/about.py b/robot_log_visualizer/ui/autogenerated/about.py deleted file mode 100644 index 9e00f6f..0000000 --- a/robot_log_visualizer/ui/autogenerated/about.py +++ /dev/null @@ -1,34 +0,0 @@ -# Form implementation generated from reading ui file 'robot_log_visualizer/ui/misc/about.ui' -# -# Created by: Qt-based UI code generator -# -# WARNING: Any manual changes made to this file will be lost when pyuic6 is -# run again. Do not edit this file unless you know what you are doing. - - -from qtpy import QtCore, QtGui, QtWidgets - - -class Ui_aboutWindow(object): - def setupUi(self, aboutWindow): - aboutWindow.setObjectName("aboutWindow") - aboutWindow.resize(541, 102) - aboutWindow.setMaximumSize(QtCore.QSize(541, 102)) - self.centralwidget = QtWidgets.QWidget(parent=aboutWindow) - self.centralwidget.setObjectName("centralwidget") - self.horizontalLayout = QtWidgets.QHBoxLayout(self.centralwidget) - self.horizontalLayout.setObjectName("horizontalLayout") - self.label_2 = QtWidgets.QLabel(parent=self.centralwidget) - self.label_2.setEnabled(True) - self.label_2.setOpenExternalLinks(True) - self.label_2.setObjectName("label_2") - self.horizontalLayout.addWidget(self.label_2) - aboutWindow.setCentralWidget(self.centralwidget) - - self.retranslateUi(aboutWindow) - QtCore.QMetaObject.connectSlotsByName(aboutWindow) - - def retranslateUi(self, aboutWindow): - _translate = QtCore.QCoreApplication.translate - aboutWindow.setWindowTitle(_translate("aboutWindow", "Robot Log Visualizer - About")) - self.label_2.setText(_translate("aboutWindow", "

About Robot Log Visualizer

This program is Licensed under the 3-Clause BSD License

The project is mantained by the Artificial and Mechanical Intelligence lab

")) diff --git a/robot_log_visualizer/ui/autogenerated/plot_tab.py b/robot_log_visualizer/ui/autogenerated/plot_tab.py deleted file mode 100644 index e1af271..0000000 --- a/robot_log_visualizer/ui/autogenerated/plot_tab.py +++ /dev/null @@ -1,27 +0,0 @@ -# Form implementation generated from reading ui file 'robot_log_visualizer/ui/misc/plot_tab.ui' -# -# Created by: Qt-based UI code generator -# -# WARNING: Any manual changes made to this file will be lost when pyuic6 is -# run again. Do not edit this file unless you know what you are doing. - - -from qtpy import QtCore, QtGui, QtWidgets - - -class Ui_PlotTab(object): - def setupUi(self, PlotTab): - PlotTab.setObjectName("PlotTab") - PlotTab.resize(331, 149) - self.horizontalLayout = QtWidgets.QHBoxLayout(PlotTab) - self.horizontalLayout.setObjectName("horizontalLayout") - self.plotLayout = QtWidgets.QVBoxLayout() - self.plotLayout.setObjectName("plotLayout") - self.horizontalLayout.addLayout(self.plotLayout) - - self.retranslateUi(PlotTab) - QtCore.QMetaObject.connectSlotsByName(PlotTab) - - def retranslateUi(self, PlotTab): - _translate = QtCore.QCoreApplication.translate - PlotTab.setWindowTitle(_translate("PlotTab", "Form")) diff --git a/robot_log_visualizer/ui/autogenerated/set_robot_model.py b/robot_log_visualizer/ui/autogenerated/set_robot_model.py deleted file mode 100644 index c522aeb..0000000 --- a/robot_log_visualizer/ui/autogenerated/set_robot_model.py +++ /dev/null @@ -1,128 +0,0 @@ -# Form implementation generated from reading ui file 'robot_log_visualizer/ui/misc/set_robot_model.ui' -# -# Created by: Qt-based UI code generator -# -# WARNING: Any manual changes made to this file will be lost when pyuic6 is -# run again. Do not edit this file unless you know what you are doing. - - -from qtpy import QtCore, QtGui, QtWidgets - - -class Ui_setRobotModelDialog(object): - def setupUi(self, setRobotModelDialog): - setRobotModelDialog.setObjectName("setRobotModelDialog") - setRobotModelDialog.resize(711, 363) - self.gridLayout = QtWidgets.QGridLayout(setRobotModelDialog) - self.gridLayout.setObjectName("gridLayout") - spacerItem = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) - self.gridLayout.addItem(spacerItem, 1, 0, 1, 1) - self.buttonBox = QtWidgets.QDialogButtonBox(parent=setRobotModelDialog) - self.buttonBox.setOrientation(QtCore.Qt.Horizontal) - self.buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.Close|QtWidgets.QDialogButtonBox.Save|QtWidgets.QDialogButtonBox.SaveAll) - self.buttonBox.setObjectName("buttonBox") - self.gridLayout.addWidget(self.buttonBox, 2, 0, 1, 1) - self.tabWidget = QtWidgets.QTabWidget(parent=setRobotModelDialog) - self.tabWidget.setObjectName("tabWidget") - self.robot_tab = QtWidgets.QWidget() - self.robot_tab.setObjectName("robot_tab") - self.verticalLayout = QtWidgets.QVBoxLayout(self.robot_tab) - self.verticalLayout.setObjectName("verticalLayout") - self.frame = QtWidgets.QFrame(parent=self.robot_tab) - self.frame.setFrameShape(QtWidgets.QFrame.StyledPanel) - self.frame.setObjectName("frame") - self.gridLayout_2 = QtWidgets.QGridLayout(self.frame) - self.gridLayout_2.setObjectName("gridLayout_2") - self.robotModelToolButton = QtWidgets.QToolButton(parent=self.frame) - self.robotModelToolButton.setObjectName("robotModelToolButton") - self.gridLayout_2.addWidget(self.robotModelToolButton, 1, 1, 1, 1) - self.label = QtWidgets.QLabel(parent=self.frame) - self.label.setObjectName("label") - self.gridLayout_2.addWidget(self.label, 0, 0, 1, 1) - self.robotModelLineEdit = QtWidgets.QLineEdit(parent=self.frame) - font = QtGui.QFont() - font.setFamily("Ubuntu Mono") - self.robotModelLineEdit.setFont(font) - self.robotModelLineEdit.setObjectName("robotModelLineEdit") - self.gridLayout_2.addWidget(self.robotModelLineEdit, 1, 0, 1, 1) - self.verticalLayout.addWidget(self.frame) - self.frame_2 = QtWidgets.QFrame(parent=self.robot_tab) - self.frame_2.setFrameShape(QtWidgets.QFrame.StyledPanel) - self.frame_2.setObjectName("frame_2") - self.gridLayout_3 = QtWidgets.QGridLayout(self.frame_2) - self.gridLayout_3.setObjectName("gridLayout_3") - self.packageDirToolButton = QtWidgets.QToolButton(parent=self.frame_2) - self.packageDirToolButton.setObjectName("packageDirToolButton") - self.gridLayout_3.addWidget(self.packageDirToolButton, 1, 1, 1, 1) - self.label_3 = QtWidgets.QLabel(parent=self.frame_2) - self.label_3.setObjectName("label_3") - self.gridLayout_3.addWidget(self.label_3, 0, 0, 1, 1) - self.packageDirLineEdit = QtWidgets.QLineEdit(parent=self.frame_2) - font = QtGui.QFont() - font.setFamily("Ubuntu Mono") - self.packageDirLineEdit.setFont(font) - self.packageDirLineEdit.setObjectName("packageDirLineEdit") - self.gridLayout_3.addWidget(self.packageDirLineEdit, 1, 0, 1, 1) - self.verticalLayout.addWidget(self.frame_2) - self.frame_3 = QtWidgets.QFrame(parent=self.robot_tab) - self.frame_3.setFrameShape(QtWidgets.QFrame.StyledPanel) - self.frame_3.setObjectName("frame_3") - self.formLayout_2 = QtWidgets.QFormLayout(self.frame_3) - self.formLayout_2.setObjectName("formLayout_2") - self.label_5 = QtWidgets.QLabel(parent=self.frame_3) - self.label_5.setObjectName("label_5") - self.formLayout_2.setWidget(0, QtWidgets.QFormLayout.ItemRole.LabelRole, self.label_5) - self.frameNameComboBox = QtWidgets.QComboBox(parent=self.frame_3) - self.frameNameComboBox.setMaxVisibleItems(5) - self.frameNameComboBox.setObjectName("frameNameComboBox") - self.formLayout_2.setWidget(1, QtWidgets.QFormLayout.ItemRole.SpanningRole, self.frameNameComboBox) - self.verticalLayout.addWidget(self.frame_3) - self.tabWidget.addTab(self.robot_tab, "") - self.mischellanea_tab = QtWidgets.QWidget() - self.mischellanea_tab.setObjectName("mischellanea_tab") - self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.mischellanea_tab) - self.verticalLayout_2.setObjectName("verticalLayout_2") - self.frame_4 = QtWidgets.QFrame(parent=self.mischellanea_tab) - self.frame_4.setFrameShape(QtWidgets.QFrame.StyledPanel) - self.frame_4.setFrameShadow(QtWidgets.QFrame.Raised) - self.frame_4.setObjectName("frame_4") - self.gridLayout_4 = QtWidgets.QGridLayout(self.frame_4) - self.gridLayout_4.setObjectName("gridLayout_4") - self.label_2 = QtWidgets.QLabel(parent=self.frame_4) - self.label_2.setObjectName("label_2") - self.gridLayout_4.addWidget(self.label_2, 0, 0, 1, 1) - self.arrowScaling_lineEdit = QtWidgets.QLineEdit(parent=self.frame_4) - self.arrowScaling_lineEdit.setEnabled(False) - self.arrowScaling_lineEdit.setReadOnly(False) - self.arrowScaling_lineEdit.setClearButtonEnabled(False) - self.arrowScaling_lineEdit.setObjectName("arrowScaling_lineEdit") - self.gridLayout_4.addWidget(self.arrowScaling_lineEdit, 0, 1, 1, 1) - self.arrowScaling_checkBox = QtWidgets.QCheckBox(parent=self.frame_4) - self.arrowScaling_checkBox.setChecked(True) - self.arrowScaling_checkBox.setTristate(False) - self.arrowScaling_checkBox.setObjectName("arrowScaling_checkBox") - self.gridLayout_4.addWidget(self.arrowScaling_checkBox, 0, 2, 1, 1) - self.verticalLayout_2.addWidget(self.frame_4) - spacerItem1 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) - self.verticalLayout_2.addItem(spacerItem1) - self.tabWidget.addTab(self.mischellanea_tab, "") - self.gridLayout.addWidget(self.tabWidget, 0, 0, 1, 1) - - self.retranslateUi(setRobotModelDialog) - self.tabWidget.setCurrentIndex(0) - self.buttonBox.accepted.connect(setRobotModelDialog.accept) # type: ignore - self.buttonBox.rejected.connect(setRobotModelDialog.reject) # type: ignore - QtCore.QMetaObject.connectSlotsByName(setRobotModelDialog) - - def retranslateUi(self, setRobotModelDialog): - _translate = QtCore.QCoreApplication.translate - setRobotModelDialog.setWindowTitle(_translate("setRobotModelDialog", "Dialog")) - self.robotModelToolButton.setText(_translate("setRobotModelDialog", "...")) - self.label.setText(_translate("setRobotModelDialog", "Robot Model")) - self.packageDirToolButton.setText(_translate("setRobotModelDialog", "...")) - self.label_3.setText(_translate("setRobotModelDialog", "Package Directory")) - self.label_5.setText(_translate("setRobotModelDialog", "Base Frame")) - self.tabWidget.setTabText(self.tabWidget.indexOf(self.robot_tab), _translate("setRobotModelDialog", "Robot")) - self.label_2.setText(_translate("setRobotModelDialog", "Arrow scaling")) - self.arrowScaling_checkBox.setText(_translate("setRobotModelDialog", "Automatic")) - self.tabWidget.setTabText(self.tabWidget.indexOf(self.mischellanea_tab), _translate("setRobotModelDialog", "Miscellanea")) diff --git a/robot_log_visualizer/ui/autogenerated/video_tab.py b/robot_log_visualizer/ui/autogenerated/video_tab.py deleted file mode 100644 index 2ccdb22..0000000 --- a/robot_log_visualizer/ui/autogenerated/video_tab.py +++ /dev/null @@ -1,28 +0,0 @@ -# Form implementation generated from reading ui file 'robot_log_visualizer/ui/misc/video_tab.ui' -# -# Created by: Qt-based UI code generator -# -# WARNING: Any manual changes made to this file will be lost when pyuic6 is -# run again. Do not edit this file unless you know what you are doing. - - -from qtpy import QtCore, QtGui, QtWidgets - - -class Ui_VideoTab(object): - def setupUi(self, VideoTab): - VideoTab.setObjectName("VideoTab") - VideoTab.resize(400, 300) - self.horizontalLayout = QtWidgets.QHBoxLayout(VideoTab) - self.horizontalLayout.setObjectName("horizontalLayout") - self.webcamView = QVideoWidget(parent=VideoTab) - self.webcamView.setObjectName("webcamView") - self.horizontalLayout.addWidget(self.webcamView) - - self.retranslateUi(VideoTab) - QtCore.QMetaObject.connectSlotsByName(VideoTab) - - def retranslateUi(self, VideoTab): - _translate = QtCore.QCoreApplication.translate - VideoTab.setWindowTitle(_translate("VideoTab", "Form")) -from qtpy.QtMultimediaWidgets import QVideoWidget diff --git a/robot_log_visualizer/ui/autogenerated/visualizer.py b/robot_log_visualizer/ui/autogenerated/visualizer.py deleted file mode 100644 index 23ea21a..0000000 --- a/robot_log_visualizer/ui/autogenerated/visualizer.py +++ /dev/null @@ -1,285 +0,0 @@ -# Form implementation generated from reading ui file 'robot_log_visualizer/ui/misc/visualizer.ui' -# -# Created by: Qt-based UI code generator -# -# WARNING: Any manual changes made to this file will be lost when pyuic6 is -# run again. Do not edit this file unless you know what you are doing. - - -from qtpy import QtCore, QtGui, QtWidgets - - -class Ui_MainWindow(object): - def setupUi(self, MainWindow): - MainWindow.setObjectName("MainWindow") - MainWindow.resize(929, 908) - MainWindow.setAcceptDrops(True) - self.centralwidget = QtWidgets.QWidget(parent=MainWindow) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.centralwidget.sizePolicy().hasHeightForWidth()) - self.centralwidget.setSizePolicy(sizePolicy) - self.centralwidget.setObjectName("centralwidget") - self.verticalLayout = QtWidgets.QVBoxLayout(self.centralwidget) - self.verticalLayout.setObjectName("verticalLayout") - self.splitter_2 = QtWidgets.QSplitter(parent=self.centralwidget) - self.splitter_2.setOrientation(QtCore.Qt.Vertical) - self.splitter_2.setChildrenCollapsible(False) - self.splitter_2.setObjectName("splitter_2") - self.dataVisualizationFrame = QtWidgets.QFrame(parent=self.splitter_2) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(2) - sizePolicy.setHeightForWidth(self.dataVisualizationFrame.sizePolicy().hasHeightForWidth()) - self.dataVisualizationFrame.setSizePolicy(sizePolicy) - self.dataVisualizationFrame.setMaximumSize(QtCore.QSize(16777215, 16777215)) - self.dataVisualizationFrame.setFrameShape(QtWidgets.QFrame.NoFrame) - self.dataVisualizationFrame.setObjectName("dataVisualizationFrame") - self.gridLayout_3 = QtWidgets.QGridLayout(self.dataVisualizationFrame) - self.gridLayout_3.setContentsMargins(-1, 9, -1, -1) - self.gridLayout_3.setObjectName("gridLayout_3") - self.pauseButton = QtWidgets.QPushButton(parent=self.dataVisualizationFrame) - self.pauseButton.setEnabled(False) - self.pauseButton.setMaximumSize(QtCore.QSize(40, 16777215)) - self.pauseButton.setText("") - icon = QtGui.QIcon.fromTheme("media-playback-pause") - self.pauseButton.setIcon(icon) - self.pauseButton.setCheckable(False) - self.pauseButton.setDefault(False) - self.pauseButton.setFlat(False) - self.pauseButton.setObjectName("pauseButton") - self.gridLayout_3.addWidget(self.pauseButton, 1, 4, 1, 1) - self.timeSlider = QtWidgets.QSlider(parent=self.dataVisualizationFrame) - self.timeSlider.setEnabled(False) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.timeSlider.sizePolicy().hasHeightForWidth()) - self.timeSlider.setSizePolicy(sizePolicy) - self.timeSlider.setPageStep(1) - self.timeSlider.setTracking(True) - self.timeSlider.setOrientation(QtCore.Qt.Horizontal) - self.timeSlider.setObjectName("timeSlider") - self.gridLayout_3.addWidget(self.timeSlider, 1, 1, 1, 2) - self.startButton = QtWidgets.QPushButton(parent=self.dataVisualizationFrame) - self.startButton.setEnabled(False) - self.startButton.setMaximumSize(QtCore.QSize(40, 16777215)) - self.startButton.setCursor(QtGui.QCursor(QtCore.Qt.ArrowCursor)) - self.startButton.setText("") - icon = QtGui.QIcon.fromTheme("media-playback-start") - self.startButton.setIcon(icon) - self.startButton.setObjectName("startButton") - self.gridLayout_3.addWidget(self.startButton, 1, 3, 1, 1) - self.timeLabel = QtWidgets.QLabel(parent=self.dataVisualizationFrame) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Ignored) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.timeLabel.sizePolicy().hasHeightForWidth()) - self.timeLabel.setSizePolicy(sizePolicy) - self.timeLabel.setMinimumSize(QtCore.QSize(60, 0)) - self.timeLabel.setObjectName("timeLabel") - self.gridLayout_3.addWidget(self.timeLabel, 1, 0, 1, 1) - self.splitter = QtWidgets.QSplitter(parent=self.dataVisualizationFrame) - self.splitter.setOrientation(QtCore.Qt.Horizontal) - self.splitter.setChildrenCollapsible(True) - self.splitter.setObjectName("splitter") - self.variableTreeWidget = QtWidgets.QTreeWidget(parent=self.splitter) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.MinimumExpanding) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.variableTreeWidget.sizePolicy().hasHeightForWidth()) - self.variableTreeWidget.setSizePolicy(sizePolicy) - self.variableTreeWidget.setMaximumSize(QtCore.QSize(16777215, 16777215)) - self.variableTreeWidget.setSizeIncrement(QtCore.QSize(0, 0)) - self.variableTreeWidget.setBaseSize(QtCore.QSize(0, 0)) - self.variableTreeWidget.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) - self.variableTreeWidget.setFrameShape(QtWidgets.QFrame.Box) - self.variableTreeWidget.setSelectionMode(QtWidgets.QAbstractItemView.MultiSelection) - self.variableTreeWidget.setAnimated(True) - self.variableTreeWidget.setObjectName("variableTreeWidget") - self.variableTreeWidget.header().setVisible(False) - self.variableTreeWidget.header().setDefaultSectionSize(100) - self.tabPlotWidget = QtWidgets.QTabWidget(parent=self.splitter) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding) - sizePolicy.setHorizontalStretch(1) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.tabPlotWidget.sizePolicy().hasHeightForWidth()) - self.tabPlotWidget.setSizePolicy(sizePolicy) - self.tabPlotWidget.setTabsClosable(True) - self.tabPlotWidget.setMovable(False) - self.tabPlotWidget.setTabBarAutoHide(False) - self.tabPlotWidget.setObjectName("tabPlotWidget") - self.meshcatAndVideoTab = QtWidgets.QTabWidget(parent=self.splitter) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding) - sizePolicy.setHorizontalStretch(2) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.meshcatAndVideoTab.sizePolicy().hasHeightForWidth()) - self.meshcatAndVideoTab.setSizePolicy(sizePolicy) - self.meshcatAndVideoTab.setTabPosition(QtWidgets.QTabWidget.East) - self.meshcatAndVideoTab.setDocumentMode(False) - self.meshcatAndVideoTab.setObjectName("meshcatAndVideoTab") - self.meshcatTab = QtWidgets.QWidget() - self.meshcatTab.setObjectName("meshcatTab") - self.horizontalLayout = QtWidgets.QHBoxLayout(self.meshcatTab) - self.horizontalLayout.setObjectName("horizontalLayout") - self.meshcatView = QtWebEngineWidgets.QWebEngineView(parent=self.meshcatTab) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.MinimumExpanding) - sizePolicy.setHorizontalStretch(1) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.meshcatView.sizePolicy().hasHeightForWidth()) - self.meshcatView.setSizePolicy(sizePolicy) - self.meshcatView.setObjectName("meshcatView") - self.horizontalLayout.addWidget(self.meshcatView) - icon = QtGui.QIcon.fromTheme("input-gaming") - self.meshcatAndVideoTab.addTab(self.meshcatTab, icon, "") - self.gridLayout_3.addWidget(self.splitter, 0, 0, 1, 5) - self.tabWidget = QtWidgets.QTabWidget(parent=self.splitter_2) - self.tabWidget.setMinimumSize(QtCore.QSize(0, 0)) - self.tabWidget.setAutoFillBackground(False) - self.tabWidget.setTabPosition(QtWidgets.QTabWidget.West) - self.tabWidget.setUsesScrollButtons(False) - self.tabWidget.setDocumentMode(False) - self.tabWidget.setTabsClosable(False) - self.tabWidget.setMovable(True) - self.tabWidget.setObjectName("tabWidget") - self.yarpTextLogWidget = QtWidgets.QWidget() - self.yarpTextLogWidget.setObjectName("yarpTextLogWidget") - self.verticalLayout_3 = QtWidgets.QVBoxLayout(self.yarpTextLogWidget) - self.verticalLayout_3.setObjectName("verticalLayout_3") - self.splitter_3 = QtWidgets.QSplitter(parent=self.yarpTextLogWidget) - self.splitter_3.setOrientation(QtCore.Qt.Horizontal) - self.splitter_3.setObjectName("splitter_3") - self.yarpTextLogTreeWidget = QtWidgets.QTreeWidget(parent=self.splitter_3) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.yarpTextLogTreeWidget.sizePolicy().hasHeightForWidth()) - self.yarpTextLogTreeWidget.setSizePolicy(sizePolicy) - self.yarpTextLogTreeWidget.setMaximumSize(QtCore.QSize(16777215, 16777215)) - self.yarpTextLogTreeWidget.setSizeIncrement(QtCore.QSize(0, 0)) - self.yarpTextLogTreeWidget.setBaseSize(QtCore.QSize(0, 0)) - self.yarpTextLogTreeWidget.setFrameShape(QtWidgets.QFrame.Box) - self.yarpTextLogTreeWidget.setSelectionMode(QtWidgets.QAbstractItemView.SingleSelection) - self.yarpTextLogTreeWidget.setAnimated(True) - self.yarpTextLogTreeWidget.setObjectName("yarpTextLogTreeWidget") - self.yarpTextLogTreeWidget.header().setVisible(False) - self.yarpTextLogTreeWidget.header().setDefaultSectionSize(100) - self.yarpTextLogTableWidget = QtWidgets.QTableWidget(parent=self.splitter_3) - self.yarpTextLogTableWidget.setEnabled(True) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding) - sizePolicy.setHorizontalStretch(10) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.yarpTextLogTableWidget.sizePolicy().hasHeightForWidth()) - self.yarpTextLogTableWidget.setSizePolicy(sizePolicy) - self.yarpTextLogTableWidget.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded) - self.yarpTextLogTableWidget.setSizeAdjustPolicy(QtWidgets.QAbstractScrollArea.AdjustIgnored) - self.yarpTextLogTableWidget.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers) - self.yarpTextLogTableWidget.setSelectionMode(QtWidgets.QAbstractItemView.NoSelection) - self.yarpTextLogTableWidget.setHorizontalScrollMode(QtWidgets.QAbstractItemView.ScrollPerPixel) - self.yarpTextLogTableWidget.setShowGrid(False) - self.yarpTextLogTableWidget.setGridStyle(QtCore.Qt.NoPen) - self.yarpTextLogTableWidget.setObjectName("yarpTextLogTableWidget") - self.yarpTextLogTableWidget.setColumnCount(0) - self.yarpTextLogTableWidget.setRowCount(0) - self.yarpTextLogTableWidget.horizontalHeader().setVisible(False) - self.yarpTextLogTableWidget.verticalHeader().setVisible(False) - self.verticalLayout_3.addWidget(self.splitter_3) - icon = QtGui.QIcon.fromTheme("zoom-in") - self.tabWidget.addTab(self.yarpTextLogWidget, icon, "") - self.pythonWidget = QtWidgets.QWidget() - self.pythonWidget.setAutoFillBackground(False) - self.pythonWidget.setObjectName("pythonWidget") - self.pythonWidgetLayout = QtWidgets.QVBoxLayout(self.pythonWidget) - self.pythonWidgetLayout.setObjectName("pythonWidgetLayout") - icon = QtGui.QIcon.fromTheme("terminal") - self.tabWidget.addTab(self.pythonWidget, icon, "") - self.tab_5 = QtWidgets.QWidget() - self.tab_5.setObjectName("tab_5") - self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.tab_5) - self.verticalLayout_2.setObjectName("verticalLayout_2") - self.logScrollArea = QtWidgets.QScrollArea(parent=self.tab_5) - self.logScrollArea.setMinimumSize(QtCore.QSize(0, 120)) - self.logScrollArea.setAutoFillBackground(False) - self.logScrollArea.setStyleSheet("background: white") - self.logScrollArea.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded) - self.logScrollArea.setSizeAdjustPolicy(QtWidgets.QAbstractScrollArea.AdjustToContents) - self.logScrollArea.setWidgetResizable(True) - self.logScrollArea.setObjectName("logScrollArea") - self.logScrollAreaWidgetContents = QtWidgets.QWidget() - self.logScrollAreaWidgetContents.setGeometry(QtCore.QRect(0, 0, 860, 190)) - self.logScrollAreaWidgetContents.setObjectName("logScrollAreaWidgetContents") - self.gridLayout = QtWidgets.QGridLayout(self.logScrollAreaWidgetContents) - self.gridLayout.setObjectName("gridLayout") - spacerItem = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) - self.gridLayout.addItem(spacerItem, 2, 0, 1, 1) - self.logLabel = QtWidgets.QLabel(parent=self.logScrollAreaWidgetContents) - self.logLabel.setCursor(QtGui.QCursor(QtCore.Qt.ArrowCursor)) - self.logLabel.setText("") - self.logLabel.setObjectName("logLabel") - self.gridLayout.addWidget(self.logLabel, 1, 0, 1, 1) - self.logScrollArea.setWidget(self.logScrollAreaWidgetContents) - self.verticalLayout_2.addWidget(self.logScrollArea) - icon = QtGui.QIcon.fromTheme("document") - self.tabWidget.addTab(self.tab_5, icon, "") - self.verticalLayout.addWidget(self.splitter_2) - MainWindow.setCentralWidget(self.centralwidget) - self.menubar = QtWidgets.QMenuBar(parent=MainWindow) - self.menubar.setGeometry(QtCore.QRect(0, 0, 929, 22)) - self.menubar.setObjectName("menubar") - self.menuFile = QtWidgets.QMenu(parent=self.menubar) - self.menuFile.setObjectName("menuFile") - self.menuHelp = QtWidgets.QMenu(parent=self.menubar) - self.menuHelp.setObjectName("menuHelp") - self.menuEdit = QtWidgets.QMenu(parent=self.menubar) - self.menuEdit.setObjectName("menuEdit") - MainWindow.setMenuBar(self.menubar) - self.actionQuit = QtGui.QAction(parent=MainWindow) - icon = QtGui.QIcon.fromTheme("exit") - self.actionQuit.setIcon(icon) - self.actionQuit.setObjectName("actionQuit") - self.actionOpen = QtGui.QAction(parent=MainWindow) - icon = QtGui.QIcon.fromTheme("document-open") - self.actionOpen.setIcon(icon) - self.actionOpen.setObjectName("actionOpen") - self.actionAbout = QtGui.QAction(parent=MainWindow) - self.actionAbout.setObjectName("actionAbout") - self.actionSet_Robot_Model = QtGui.QAction(parent=MainWindow) - self.actionSet_Robot_Model.setObjectName("actionSet_Robot_Model") - self.actionRealtime_Connect = QtGui.QAction(parent=MainWindow) - self.actionRealtime_Connect.setObjectName("actionRealtime_Connect") - self.menuFile.addAction(self.actionOpen) - self.menuFile.addAction(self.actionRealtime_Connect) - self.menuFile.addSeparator() - self.menuFile.addAction(self.actionQuit) - self.menuHelp.addAction(self.actionAbout) - self.menuEdit.addAction(self.actionSet_Robot_Model) - self.menubar.addAction(self.menuFile.menuAction()) - self.menubar.addAction(self.menuEdit.menuAction()) - self.menubar.addAction(self.menuHelp.menuAction()) - - self.retranslateUi(MainWindow) - self.tabPlotWidget.setCurrentIndex(-1) - self.meshcatAndVideoTab.setCurrentIndex(0) - self.tabWidget.setCurrentIndex(0) - QtCore.QMetaObject.connectSlotsByName(MainWindow) - - def retranslateUi(self, MainWindow): - _translate = QtCore.QCoreApplication.translate - MainWindow.setWindowTitle(_translate("MainWindow", "Robot Log Visualizer")) - self.timeLabel.setText(_translate("MainWindow", "0.0")) - self.variableTreeWidget.headerItem().setText(0, _translate("MainWindow", "Variables")) - self.yarpTextLogTreeWidget.headerItem().setText(0, _translate("MainWindow", "Variables")) - self.yarpTextLogTableWidget.setSortingEnabled(False) - self.menuFile.setTitle(_translate("MainWindow", "&File")) - self.menuHelp.setTitle(_translate("MainWindow", "Help")) - self.menuEdit.setTitle(_translate("MainWindow", "&Edit")) - self.actionQuit.setText(_translate("MainWindow", "&Quit")) - self.actionQuit.setShortcut(_translate("MainWindow", "Ctrl+Q")) - self.actionOpen.setText(_translate("MainWindow", "&Open")) - self.actionOpen.setShortcut(_translate("MainWindow", "Ctrl+O")) - self.actionAbout.setText(_translate("MainWindow", "About")) - self.actionSet_Robot_Model.setText(_translate("MainWindow", "Options")) - self.actionRealtime_Connect.setText(_translate("MainWindow", "Realtime Connect")) - self.actionRealtime_Connect.setShortcut(_translate("MainWindow", "Ctrl+R")) -from qtpy import QtWebEngineWidgets diff --git a/robot_log_visualizer/ui/gui.py b/robot_log_visualizer/ui/gui.py index d6af97c..0e66a27 100644 --- a/robot_log_visualizer/ui/gui.py +++ b/robot_log_visualizer/ui/gui.py @@ -4,6 +4,7 @@ # QtPy abstraction from qtpy import QtWidgets, QtGui, QtCore +from qtpy import QtWebEngineWidgets # noqa: F401 # Ensure WebEngine is initialised from qtpy.QtCore import QMutex, QMutexLocker, QUrl, Qt, Slot from qtpy.QtWidgets import ( QDialog, @@ -47,9 +48,7 @@ import numpy as np # QtDesigner generated classes -from robot_log_visualizer.ui.autogenerated.visualizer import Ui_MainWindow -from robot_log_visualizer.ui.autogenerated.about import Ui_aboutWindow -from robot_log_visualizer.ui.autogenerated.set_robot_model import Ui_setRobotModelDialog +from robot_log_visualizer.ui.ui_loader import load_ui # for logging from time import localtime, strftime @@ -64,8 +63,7 @@ class SetRobotModelDialog(QtWidgets.QDialog): def __init__(self, meshcat_provider, parent=None, dataset_loaded=False): # call QMainWindow constructor super().__init__(parent) - self.ui = Ui_setRobotModelDialog() - self.ui.setupUi(self) + self.ui = load_ui("set_robot_model.ui", self) model_path = meshcat_provider.model_path package_dir = meshcat_provider.custom_package_dir @@ -147,8 +145,7 @@ class About(QtWidgets.QMainWindow): def __init__(self): # call QMainWindow constructor super().__init__() - self.ui = Ui_aboutWindow() - self.ui.setupUi(self) + self.ui = load_ui("about.ui", self) def build_plot_title_box_dialog(): @@ -191,8 +188,7 @@ def __init__(self, signal_provider_period, meshcat_provider, animation_period): self.animation_period = animation_period # set up the user interface - self.ui = Ui_MainWindow() - self.ui.setupUi(self) + self.ui = load_ui("visualizer.ui", self) # Set all the icons self.ui.startButton.setIcon(get_icon("play-outline.svg")) diff --git a/robot_log_visualizer/ui/misc/visualizer.ui b/robot_log_visualizer/ui/misc/visualizer.ui index 85ff73b..32e531f 100644 --- a/robot_log_visualizer/ui/misc/visualizer.ui +++ b/robot_log_visualizer/ui/misc/visualizer.ui @@ -570,7 +570,7 @@ QWebEngineView QWidget -
QtWebEngineWidgets/QWebEngineView
+
qtpy.QtWebEngineWidgets
1
diff --git a/robot_log_visualizer/ui/plot_item.py b/robot_log_visualizer/ui/plot_item.py index 68c06b5..c0889c0 100644 --- a/robot_log_visualizer/ui/plot_item.py +++ b/robot_log_visualizer/ui/plot_item.py @@ -5,14 +5,13 @@ from qtpy.QtWidgets import QFrame from robot_log_visualizer.plotter.pyqtgraph_viewer_canvas import PyQtGraphViewerCanvas -from robot_log_visualizer.ui.autogenerated.plot_tab import Ui_PlotTab +from robot_log_visualizer.ui.ui_loader import load_ui class PlotItem(QFrame): def __init__(self, period): super().__init__(None) - self.ui = Ui_PlotTab() - self.ui.setupUi(self) + self.ui = load_ui("plot_tab.ui", self) self.canvas = PyQtGraphViewerCanvas(parent=self, period=period) self.ui.plotLayout.addWidget(self.canvas) diff --git a/robot_log_visualizer/ui/ui_loader.py b/robot_log_visualizer/ui/ui_loader.py new file mode 100644 index 0000000..3524916 --- /dev/null +++ b/robot_log_visualizer/ui/ui_loader.py @@ -0,0 +1,55 @@ +# Copyright (C) 2022 Istituto Italiano di Tecnologia (IIT). All rights reserved. +# This software may be modified and distributed under the terms of the +# Released under the terms of the BSD 3-Clause License + +"""Utilities to load Qt Designer `.ui` files at runtime.""" + +from __future__ import annotations + +from importlib import resources +from typing import Any + +from qtpy import uic + + +class UiProxy: + """Proxy object exposing UI attributes through the ``ui`` namespace. + + Historically the project relied on the Qt Designer generated ``Ui_*`` + classes that exposed widgets under a ``ui`` attribute. We keep the same + interface by wrapping the current instance in this proxy so existing code + can continue to access widgets as ``self.ui.someWidget``. + """ + + def __init__(self, target: Any) -> None: + super().__setattr__("_target", target) + + def __getattr__(self, name: str) -> Any: + return getattr(self._target, name) + + def __setattr__(self, name: str, value: Any) -> None: + setattr(self._target, name, value) + + +def load_ui(ui_filename: str, baseinstance: Any) -> UiProxy: + """Load a Qt Designer ``.ui`` file into an existing widget instance. + + Parameters + ---------- + ui_filename + Name of the ``.ui`` file stored inside ``robot_log_visualizer.ui.misc``. + baseinstance + The Qt widget instance where the UI should be loaded. + + Returns + ------- + UiProxy + A proxy object that exposes the loaded widgets under the ``ui`` + namespace, preserving the previous ``self.ui`` calling convention. + """ + + package = "robot_log_visualizer.ui.misc" + with resources.path(package, ui_filename) as ui_path: + uic.loadUi(str(ui_path), baseinstance) + + return UiProxy(baseinstance) diff --git a/robot_log_visualizer/ui/video_item.py b/robot_log_visualizer/ui/video_item.py index e8efa5b..723573e 100644 --- a/robot_log_visualizer/ui/video_item.py +++ b/robot_log_visualizer/ui/video_item.py @@ -6,15 +6,14 @@ from qtpy.QtMultimedia import QAudioOutput, QMediaPlayer from qtpy.QtWidgets import QFrame -from robot_log_visualizer.ui.autogenerated.video_tab import Ui_VideoTab +from robot_log_visualizer.ui.ui_loader import load_ui import os class VideoItem(QFrame): def __init__(self, video_filename: str): super().__init__(None) - self.ui = Ui_VideoTab() - self.ui.setupUi(self) + self.ui = load_ui("video_tab.ui", self) self.media_player = QMediaPlayer(self) self.audio_output = QAudioOutput(self) diff --git a/setup.cfg b/setup.cfg index 698c659..8122e5a 100644 --- a/setup.cfg +++ b/setup.cfg @@ -56,4 +56,4 @@ console_scripts = robot-log-visualizer = robot_log_visualizer.__main__:main [options.package_data] -* = *.png, *.svg +* = *.png, *.svg, *.ui From 7f0c55fb4eab604e76a02864b705f3c99d7ee561 Mon Sep 17 00:00:00 2001 From: Giulio Romualdi Date: Sun, 5 Oct 2025 19:47:58 +0200 Subject: [PATCH 5/5] Switch from PySide6 to PySide2 in configuration and signal provider --- robot_log_visualizer/__init__.py | 2 +- .../signal_provider/realtime_signal_provider.py | 3 ++- setup.cfg | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/robot_log_visualizer/__init__.py b/robot_log_visualizer/__init__.py index 44f7859..88cb257 100644 --- a/robot_log_visualizer/__init__.py +++ b/robot_log_visualizer/__init__.py @@ -1,4 +1,4 @@ import os # Prefer the PySide6 backend when QtPy resolves the Qt binding. -os.environ.setdefault("QT_API", "pyside6") +os.environ.setdefault("QT_API", "pyside2") diff --git a/robot_log_visualizer/signal_provider/realtime_signal_provider.py b/robot_log_visualizer/signal_provider/realtime_signal_provider.py index a6479c7..d41c6c0 100644 --- a/robot_log_visualizer/signal_provider/realtime_signal_provider.py +++ b/robot_log_visualizer/signal_provider/realtime_signal_provider.py @@ -5,6 +5,7 @@ import time import traceback from collections import deque +from typing import Iterable, Union import numpy as np @@ -117,7 +118,7 @@ def __init__(self, period: float, signal_root_name: str): self.buffered_signals.add("robot_realtime::joints_state::positions") # TODO: implement a logic to remove signals that are not needed anymore - def add_signals_to_buffer(self, signals: list | set | str): + def add_signals_to_buffer(self, signals: Union[str, Iterable[str]]): """Add signals to the buffer set.""" if isinstance(signals, str): signals = {signals} diff --git a/setup.cfg b/setup.cfg index 8122e5a..0d9cb5c 100644 --- a/setup.cfg +++ b/setup.cfg @@ -43,7 +43,7 @@ install_requires = idyntree >= 10.2.0 meshcat numpy - PySide6 + PySide2 qtpy pyqtconsole matplotlib