Skip to content

Commit

Permalink
Use PySide6
Browse files Browse the repository at this point in the history
Upgrade from qtpy with pyqt5 to PySide6.
Using PySide6 directly should give us better typing.
  • Loading branch information
JHolba committed Dec 18, 2024
1 parent 72babc5 commit 2ffd7d0
Show file tree
Hide file tree
Showing 125 changed files with 834 additions and 685 deletions.
7 changes: 3 additions & 4 deletions .github/actions/install_dependencies/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@ name: install_dependencies
description: Installs dependencies for the pip build

inputs:
os:
required: true

os:
required: true

runs:
using: "composite"
Expand All @@ -13,5 +12,5 @@ runs:
if: inputs.os == 'ubuntu-latest'
run: |
sudo apt-get update
sudo apt-get install libxcb-image0 libxcb-icccm4 libxcb-keysyms1 libxcb-randr0 libxcb-render0 libxcb-render-util0 libxcb-shape0 libxcb-shm0 libxcb-xfixes0 libxcb-xinerama0 libfontconfig1 libxcb-xkb1 libxkbcommon-x11-0 libdbus-1-3 x11-xserver-utils
sudo apt-get install libegl1 libxcb-image0 libxcb-icccm4 libxcb-keysyms1 libxcb-randr0 libxcb-render0 libxcb-render-util0 libxcb-shape0 libxcb-shm0 libxcb-xfixes0 libxcb-xinerama0 libfontconfig1 libxcb-xkb1 libxkbcommon-x11-0 libdbus-1-3 x11-xserver-utils
shell: bash
7 changes: 4 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ dependencies = [
"python-dateutil",
"python-multipart", # extra dependency for fastapi
"pyyaml",
"qtpy",
"PySide6",
"requests",
"resfo",
"scipy >= 1.10.1",
Expand Down Expand Up @@ -126,6 +126,7 @@ style = [
]
types = [
"mypy",
"pyside6-stubs",
"types-lxml",
"types-requests",
"types-PyYAML",
Expand Down Expand Up @@ -246,7 +247,7 @@ typeCheckingMode = "standard"
pythonVersion = "3.11"

[tool.pyright.defineConstant]
PYSIDE6 = false
PYQT5 = true
PYSIDE6 = true
PYQT5 = false
PYSIDE2 = false
PYQT6 = false
5 changes: 4 additions & 1 deletion src/ert/config/ert_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
import polars
from pydantic import ValidationError as PydanticValidationError
from pydantic import field_validator
from pydantic.dataclasses import dataclass
from pydantic.dataclasses import dataclass, rebuild_dataclass

from ert.plugins import ErtPluginManager
from ert.substitutions import Substitutions
Expand Down Expand Up @@ -1193,3 +1193,6 @@ def _forward_model_step_from_config_file(
)
except OSError as err:
raise ConfigValidationError.with_context(str(err), config_file) from err


rebuild_dataclass(ErtConfig)
2 changes: 1 addition & 1 deletion src/ert/ensemble_evaluator/snapshot.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from datetime import datetime
from typing import Any, TypeVar, cast, get_args

from qtpy.QtGui import QColor
from PySide6.QtGui import QColor
from typing_extensions import TypedDict

from _ert.events import (
Expand Down
15 changes: 5 additions & 10 deletions src/ert/gui/about_dialog.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from qtpy.QtCore import QSize, Qt
from qtpy.QtGui import QFont
from qtpy.QtWidgets import (
from PySide6.QtCore import QSize, Qt
from PySide6.QtGui import QFont
from PySide6.QtWidgets import (
QDialog,
QHBoxLayout,
QLabel,
Expand All @@ -19,13 +19,8 @@ def __init__(self, parent: QWidget | None) -> None:
self.setWindowTitle("About")
self.setModal(True)
self.setFixedSize(QSize(600, 480))
self.setWindowFlags(
self.windowFlags()
& ~Qt.WindowFlags(Qt.WindowType.WindowContextHelpButtonHint)
)
self.setWindowFlags(
self.windowFlags() & ~Qt.WindowFlags(Qt.WindowType.WindowCloseButtonHint)
)
self.setWindowFlag(Qt.WindowType.WindowContextHelpButtonHint, False)
self.setWindowFlag(Qt.WindowType.WindowCloseButtonHint, False)

main_layout = QVBoxLayout()

Expand Down
2 changes: 1 addition & 1 deletion src/ert/gui/ertnotifier.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from qtpy.QtCore import QObject, Signal, Slot
from PySide6.QtCore import QObject, Signal, Slot

from ert.storage import Ensemble, Storage

Expand Down
6 changes: 3 additions & 3 deletions src/ert/gui/ertwidgets/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# isort: skip_file
from qtpy.QtCore import Qt
from qtpy.QtGui import QCursor
from qtpy.QtWidgets import QApplication
from PySide6.QtCore import Qt
from PySide6.QtGui import QCursor
from PySide6.QtWidgets import QApplication
from typing import Any
from collections.abc import Callable

Expand Down
6 changes: 3 additions & 3 deletions src/ert/gui/ertwidgets/analysismoduleedit.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

from typing import TYPE_CHECKING

from qtpy.QtCore import QMargins, Qt
from qtpy.QtGui import QIcon
from qtpy.QtWidgets import QHBoxLayout, QToolButton, QWidget
from PySide6.QtCore import QMargins, Qt
from PySide6.QtGui import QIcon
from PySide6.QtWidgets import QHBoxLayout, QToolButton, QWidget

from ert.gui.ertwidgets import ClosableDialog
from ert.gui.ertwidgets.analysismodulevariablespanel import AnalysisModuleVariablesPanel
Expand Down
14 changes: 7 additions & 7 deletions src/ert/gui/ertwidgets/analysismodulevariablespanel.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,15 @@
from typing import cast, get_args

from annotated_types import Ge, Gt, Le
from qtpy.QtCore import Qt
from qtpy.QtWidgets import (
from PySide6.QtCore import Qt
from PySide6.QtWidgets import (
QCheckBox,
QComboBox,
QDoubleSpinBox,
QFormLayout,
QFrame,
QHBoxLayout,
QLabel,
QLayout,
QWidget,
)

Expand Down Expand Up @@ -52,7 +51,7 @@ def __init__(self, analysis_module: AnalysisModule, ensemble_size: int):
):
metadata = analysis_module.model_fields[variable_name]
layout.addRow(
metadata.title,
metadata.title if metadata.title else "",
self.createDoubleSpinBox(
variable_name,
analysis_module.__getattribute__(variable_name),
Expand Down Expand Up @@ -105,7 +104,8 @@ def __init__(self, analysis_module: AnalysisModule, ensemble_size: int):

localization_frame = QFrame()
localization_frame.setLayout(QHBoxLayout())
lf_layout = cast(QLayout, localization_frame.layout())
lf_layout = localization_frame.layout()
assert lf_layout is not None
lf_layout.setContentsMargins(0, 0, 0, 0)

metadata = analysis_module.model_fields[
Expand Down Expand Up @@ -154,8 +154,8 @@ def update_inversion_algorithm(
@staticmethod
def create_horizontal_line() -> QFrame:
hline = QFrame()
hline.setFrameShape(QFrame.HLine)
hline.setFrameShadow(QFrame.Sunken)
hline.setFrameShape(QFrame.Shape.HLine)
hline.setFrameShadow(QFrame.Shadow.Sunken)
hline.setFixedHeight(20)
return hline

Expand Down
10 changes: 5 additions & 5 deletions src/ert/gui/ertwidgets/checklist.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

from typing import TYPE_CHECKING

from qtpy.QtCore import QPoint, QSize, Qt
from qtpy.QtGui import QIcon
from qtpy.QtWidgets import (
from PySide6.QtCore import QPoint, QSize, Qt
from PySide6.QtGui import QIcon
from PySide6.QtWidgets import (
QAbstractItemView,
QHBoxLayout,
QLabel,
Expand Down Expand Up @@ -44,7 +44,7 @@ def __init__(

self._list = QListWidget()
self._list.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu)
self._list.setSelectionMode(QAbstractItemView.ExtendedSelection)
self._list.setSelectionMode(QAbstractItemView.SelectionMode.ExtendedSelection)

self._search_box = SearchBox()

Expand Down Expand Up @@ -162,7 +162,7 @@ def uncheckSelected(self) -> None:

def showContextMenu(self, point: QPoint) -> None:
p = self._list.mapToGlobal(point)
menu = QMenu()
menu = QMenu(self)
check_selected = menu.addAction("Check selected")
uncheck_selected = menu.addAction("Uncheck selected")
menu.addSeparator()
Expand Down
35 changes: 16 additions & 19 deletions src/ert/gui/ertwidgets/closabledialog.py
Original file line number Diff line number Diff line change
@@ -1,30 +1,25 @@
from __future__ import annotations

from typing import TYPE_CHECKING
from collections.abc import Callable
from typing import TYPE_CHECKING, cast

from qtpy.QtCore import Qt
from qtpy.QtWidgets import QDialog, QHBoxLayout, QPushButton, QVBoxLayout, QWidget
from PySide6.QtCore import Qt
from PySide6.QtWidgets import QDialog, QHBoxLayout, QPushButton, QVBoxLayout, QWidget

if TYPE_CHECKING:
from qtpy.QtGui import QKeyEvent
from qtpy.QtWidgets import QT_SLOT
from PySide6.QtGui import QKeyEvent


class ClosableDialog(QDialog):
def __init__(
self, title: str | None, widget: QWidget, parent: QWidget | None = None
) -> None:
QDialog.__init__(self, parent)
self.setWindowTitle(title)
self.setWindowTitle(title if title else "")
self.setModal(True)
self.setWindowFlags(self.windowFlags() | Qt.WindowType.CustomizeWindowHint)
self.setWindowFlags(
self.windowFlags()
& ~Qt.WindowFlags(Qt.WindowType.WindowContextHelpButtonHint)
)
self.setWindowFlags(
self.windowFlags() & ~Qt.WindowFlags(Qt.WindowType.WindowCloseButtonHint)
)
self.setWindowFlag(Qt.WindowType.CustomizeWindowHint, True)
self.setWindowFlag(Qt.WindowType.WindowContextHelpButtonHint, False)
self.setWindowFlag(Qt.WindowType.WindowCloseButtonHint, False)

layout = QVBoxLayout()
layout.addWidget(widget, stretch=1)
Expand All @@ -47,18 +42,20 @@ def disableCloseButton(self) -> None:
def enableCloseButton(self) -> None:
self.close_button.setEnabled(True)

def keyPressEvent(self, a0: QKeyEvent | None) -> None:
if self.close_button.isEnabled() or a0 is None or a0.key() != Qt.Key.Key_Escape:
QDialog.keyPressEvent(self, a0)
def keyPressEvent(self, arg__1: QKeyEvent) -> None:
if self.close_button.isEnabled() or arg__1.key() != Qt.Key.Key_Escape:
QDialog.keyPressEvent(self, arg__1)

def addButton(self, caption: str, listener: QT_SLOT) -> QPushButton:
def addButton(self, caption: str, listener: Callable) -> QPushButton:

Check failure on line 49 in src/ert/gui/ertwidgets/closabledialog.py

View workflow job for this annotation

GitHub Actions / type-checking (3.12)

Missing type parameters for generic type "Callable"
button = QPushButton(caption)
button.setObjectName(str(caption).capitalize())
self.__button_layout.insertWidget(1, button)
button.clicked.connect(listener)
return button

def toggleButton(self, caption: str, enabled: bool) -> None:
button = self.findChild(QPushButton, str(caption).capitalize())
button = cast(
QPushButton, self.findChild(QPushButton, str(caption).capitalize())
)
if button is not None:
button.setEnabled(enabled)
10 changes: 5 additions & 5 deletions src/ert/gui/ertwidgets/copy_button.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
from abc import abstractmethod

from qtpy.QtCore import QTimer
from qtpy.QtGui import QIcon
from qtpy.QtWidgets import QApplication, QMessageBox, QPushButton, QSizePolicy
from PySide6.QtCore import QTimer
from PySide6.QtGui import QIcon
from PySide6.QtWidgets import QApplication, QMessageBox, QPushButton, QSizePolicy


class CopyButton(QPushButton):
def __init__(self) -> None:
super().__init__()
self.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed)
self.setSizePolicy(QSizePolicy.Policy.Preferred, QSizePolicy.Policy.Fixed)
self.setIcon(QIcon("img:copy.svg"))
self.restore_timer = QTimer(self)

Expand All @@ -32,7 +32,7 @@ def copy_text(self, text: str) -> None:
None,
"Error",
"Cannot copy text to clipboard because your system does not have a clipboard",
QMessageBox.Ok,
QMessageBox.StandardButton.Ok,
)
self.setIcon(QIcon("img:check.svg"))
self.restore_timer.start(1000)
4 changes: 2 additions & 2 deletions src/ert/gui/ertwidgets/copyablelabel.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from os import path

from qtpy.QtCore import Qt
from qtpy.QtWidgets import QHBoxLayout, QLabel
from PySide6.QtCore import Qt
from PySide6.QtWidgets import QHBoxLayout, QLabel

from .copy_button import CopyButton

Expand Down
8 changes: 4 additions & 4 deletions src/ert/gui/ertwidgets/create_experiment_dialog.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
from qtpy.QtCore import (
from PySide6.QtCore import (
Qt,
Signal,
)
from qtpy.QtWidgets import (
from PySide6.QtWidgets import (
QDialog,
QDialogButtonBox,
QGridLayout,
Expand Down Expand Up @@ -59,13 +59,13 @@ def __init__(
self._iterations_field.setValidator(IntegerArgument(from_value=0))
self._iterations_field.setObjectName("iterations_field_ced")
buttons = QDialogButtonBox(
QDialogButtonBox.Ok | QDialogButtonBox.Cancel,
QDialogButtonBox.StandardButton.Ok | QDialogButtonBox.StandardButton.Cancel,
Qt.Orientation.Horizontal,
self,
)
buttons.accepted.connect(self.accept)
buttons.rejected.connect(self.reject)
ok_button = buttons.button(QDialogButtonBox.Ok)
ok_button = buttons.button(QDialogButtonBox.StandardButton.Ok)
assert ok_button
self._ok_button = ok_button

Expand Down
12 changes: 6 additions & 6 deletions src/ert/gui/ertwidgets/customdialog.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
from typing import Any

from qtpy.QtCore import QSize, Qt
from qtpy.QtGui import QColor
from qtpy.QtWidgets import (
from PySide6.QtCore import QSize, Qt
from PySide6.QtGui import QColor
from PySide6.QtWidgets import (
QDialog,
QDialogButtonBox,
QFormLayout,
Expand Down Expand Up @@ -93,18 +93,18 @@ def addLabeledOption(self, label: Any, option_widget: QWidget) -> None:

self._layout.addRow(f"{label}:", option_widget)

def addWidget(self, widget: QWidget | QLayout | None, label: str = "") -> None:
def addWidget(self, widget: QWidget | QLayout, label: str = "") -> None:
if not label.endswith(":"):
label = f"{label}:"
self._layout.addRow(label, widget)

def addButtons(self) -> None:
buttons = QDialogButtonBox(
QDialogButtonBox.Ok | QDialogButtonBox.Cancel,
QDialogButtonBox.StandardButton.Ok | QDialogButtonBox.StandardButton.Cancel,
Qt.Orientation.Horizontal,
self,
)
self.ok_button = buttons.button(QDialogButtonBox.Ok)
self.ok_button = buttons.button(QDialogButtonBox.StandardButton.Ok)
if self.ok_button:
self.ok_button.setEnabled(False)

Expand Down
8 changes: 4 additions & 4 deletions src/ert/gui/ertwidgets/ensembleselector.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
from collections.abc import Iterable
from typing import TYPE_CHECKING

from qtpy.QtCore import Qt, Signal
from qtpy.QtWidgets import QComboBox
from PySide6.QtCore import Qt, Signal
from PySide6.QtWidgets import QComboBox

from ert.gui.ertnotifier import ErtNotifier
from ert.storage.realization_storage_state import RealizationStorageState
Expand Down Expand Up @@ -36,13 +36,13 @@ def __init__(
# if the ensemble has not been used in an update, as that would
# invalidate the result
self._show_only_no_children = show_only_no_children
self.setSizeAdjustPolicy(QComboBox.AdjustToContents)
self.setSizeAdjustPolicy(QComboBox.SizeAdjustPolicy.AdjustToContents)

self.setEnabled(False)

if update_ert:
# Update ERT when this combo box is changed
self.currentIndexChanged[int].connect(self._on_current_index_changed)
self.currentIndexChanged.connect(self._on_current_index_changed)

# Update this combo box when ERT is changed
notifier.current_ensemble_changed.connect(
Expand Down
Loading

0 comments on commit 2ffd7d0

Please sign in to comment.