Source code for spyder.api.widgets.dialogs
# -----------------------------------------------------------------------------
# Copyright (c) 2024- Spyder Project Contributors
#
# Released under the terms of the MIT License
# (see LICENSE.txt in the project root directory for details)
# -----------------------------------------------------------------------------
"""
Spyder dialog widgets.
"""
from __future__ import annotations
# Standard library imports
from typing import TYPE_CHECKING
# Third-party imports
from qtpy import QT6
from qtpy.QtCore import Qt
from qtpy.QtGui import QIcon
from qtpy.QtWidgets import QDialogButtonBox, QProxyStyle, QStyle
# Local imports
from spyder.utils.stylesheet import AppStyle
if TYPE_CHECKING:
from qtpy.QtWidgets import QWidget
class _SpyderButtonsProxyStyle(QProxyStyle):
"""Style adjustments for :class:`SpyderDialogButtonBox`."""
def styleHint(self, hint, option=None, widget=None, return_data=None):
if hint == QStyle.SH_DialogButtonLayout:
# Use the Windows buttons layout to have a uniform layout in all
# platforms. We selected that layout because Windows is our most
# popular platform.
# Solution found in https://stackoverflow.com/a/35907926/438386
if QT6: # PySide6/PyQt6
return QDialogButtonBox.ButtonLayout.WinLayout.value
else: # PySide2/PyQt5
return int(QDialogButtonBox.ButtonLayout.WinLayout)
return super().styleHint(hint, option, widget, return_data)
[docs]
class SpyderDialogButtonBox(QDialogButtonBox):
"""Action button section (OK, Cancel, etc) widget for dialog boxes."""
[docs]
def __init__(
self,
buttons: QDialogButtonBox.StandardButton | None = None,
orientation: Qt.Orientation = Qt.Horizontal,
parent: QWidget | None = None,
):
"""
Create a new group of dialog box buttons.
Parameters
----------
buttons : QDialogButtonBox.StandardButton | None, optional
The standard buttons to include in the dialog box button group,
such as "OK", "Cancel" or "Apply", passed as a single argument
composed of Qt enum members bitwise or-ed (``|``) together.
For example, ``QDialogButtonBox.Ok | QDialogButtonBox.Cancel``.
If ``None``, the default, is an empty button box with no buttons.
orientation : Qt.Orientation, optional
Whether the button box is laid out horizontally, with buttons
side by side, or vertically, with buttons on top of one another.
By default, horizontal (``Qt.Horizontal``).
parent : QWidget | None, optional
The parent widget of this button box, ``None`` by default.
Returns
-------
None
"""
if buttons:
super().__init__(buttons, orientation, parent)
elif orientation:
super().__init__(orientation=orientation, parent=parent)
else:
super().__init__(parent=parent)
# Don't display icons on standard buttons. This is a problem on Linux
button_constants = [
QDialogButtonBox.Ok,
QDialogButtonBox.Open,
QDialogButtonBox.Save,
QDialogButtonBox.Cancel,
QDialogButtonBox.Close,
QDialogButtonBox.Discard,
QDialogButtonBox.Apply,
QDialogButtonBox.Reset,
QDialogButtonBox.RestoreDefaults,
QDialogButtonBox.Help,
QDialogButtonBox.SaveAll,
QDialogButtonBox.Yes,
QDialogButtonBox.YesToAll,
QDialogButtonBox.No,
QDialogButtonBox.NoToAll,
QDialogButtonBox.Abort,
QDialogButtonBox.Retry,
QDialogButtonBox.Ignore,
]
for constant in button_constants:
button = self.button(constant)
if button is not None:
button.setIcon(QIcon())
# Set a reasonable spacing between buttons. This is a problem on Mac
self.layout().setSpacing(2 * AppStyle.MarginSize)
# Set style
style = _SpyderButtonsProxyStyle(None)
style.setParent(self)
self.setStyle(style)