Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MNT: make enums use python Enum class and updated Q_ENUM (no 's') #1146

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions pydm/tests/widgets/test_enum_button.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,11 @@ def test_widget_type(qtbot, widget_type):
qtbot.addWidget(widget)

assert widget.widgetType == WidgetType.PushButton
assert isinstance(widget._widgets[0], class_for_type[WidgetType.PushButton])
assert isinstance(widget._widgets[0], class_for_type[WidgetType.PushButton.value])

widget.widgetType = widget_type
assert widget.widgetType == widget_type
assert isinstance(widget._widgets[0], class_for_type[widget_type])
assert isinstance(widget._widgets[0], class_for_type[widget_type.value])


@pytest.mark.parametrize("orientation", [Qt.Horizontal, Qt.Vertical])
Expand Down Expand Up @@ -82,7 +82,7 @@ def test_widget_orientation(qtbot, orientation):
w = item.widget()
qtbot.addWidget(w)
assert w is not None
assert isinstance(w, class_for_type[widget.widgetType])
assert isinstance(w, class_for_type[widget.widgetType.value])


@pytest.mark.parametrize(
Expand Down
11 changes: 6 additions & 5 deletions pydm/widgets/datetime.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
import logging
from qtpy import QtWidgets, QtCore
from enum import Enum

from .base import PyDMWritableWidget, PyDMWidget

logger = logging.getLogger(__name__)


class TimeBase(object):
class TimeBase(Enum):
Milliseconds = 0
Seconds = 1


class PyDMDateTimeEdit(QtWidgets.QDateTimeEdit, PyDMWritableWidget, TimeBase):
QtCore.Q_ENUMS(TimeBase)
class PyDMDateTimeEdit(QtWidgets.QDateTimeEdit, PyDMWritableWidget):
QtCore.Q_ENUM(TimeBase)
nstelter-slac marked this conversation as resolved.
Show resolved Hide resolved
returnPressed = QtCore.Signal()
"""
A QDateTimeEdit with support for setting the text via a PyDM Channel, or
Expand Down Expand Up @@ -107,8 +108,8 @@ def value_changed(self, new_val):
self.setDateTime(val)


class PyDMDateTimeLabel(QtWidgets.QLabel, PyDMWidget, TimeBase):
QtCore.Q_ENUMS(TimeBase)
class PyDMDateTimeLabel(QtWidgets.QLabel, PyDMWidget):
QtCore.Q_ENUM(TimeBase)
nstelter-slac marked this conversation as resolved.
Show resolved Hide resolved
"""
A QLabel with support for setting the text via a PyDM Channel, or
through the PyDM Rules system.
Expand Down
3 changes: 2 additions & 1 deletion pydm/widgets/display_format.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@

import logging
import warnings
from enum import Enum

logger = logging.getLogger(__name__)


class DisplayFormat(object):
class DisplayFormat(Enum):
"""Display format for showing data in a PyDM widget."""

#: The default display format.
Expand Down
12 changes: 7 additions & 5 deletions pydm/widgets/enum_button.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
import logging
from enum import Enum

from qtpy.QtCore import Qt, QSize, Property, Slot, Q_ENUMS, QMargins
from qtpy.QtCore import Qt, QSize, Property, Slot, QMargins
from PyQt5.QtCore import Q_ENUM
from qtpy.QtGui import QPainter
from qtpy.QtWidgets import QWidget, QButtonGroup, QGridLayout, QPushButton, QRadioButton, QStyleOption, QStyle

from .base import PyDMWritableWidget
from .. import data_plugins


class WidgetType(object):
class WidgetType(Enum):
PushButton = 0
RadioButton = 1

Expand All @@ -18,7 +20,7 @@ class WidgetType(object):
logger = logging.getLogger(__name__)


class PyDMEnumButton(QWidget, PyDMWritableWidget, WidgetType):
class PyDMEnumButton(QWidget, PyDMWritableWidget):
"""
A QWidget that renders buttons for every option of Enum Items.
For now, two types of buttons can be rendered:
Expand All @@ -38,7 +40,7 @@ class PyDMEnumButton(QWidget, PyDMWritableWidget, WidgetType):
Emitted when the user changes the value.
"""

Q_ENUMS(WidgetType)
Q_ENUM(WidgetType)
WidgetType = WidgetType

def __init__(self, parent=None, init_channel=None):
Expand Down Expand Up @@ -399,7 +401,7 @@ def generate_widgets(items):
w.deleteLater()

for idx, entry in enumerate(items):
w = class_for_type[self._widget_type](parent=self)
w = class_for_type[self._widget_type.value](parent=self)
w.setCheckable(self.checkable)
w.setText(entry)
w.setVisible(False)
Expand Down
20 changes: 13 additions & 7 deletions pydm/widgets/image.py
Original file line number Diff line number Diff line change
@@ -1,25 +1,27 @@
from qtpy.QtWidgets import QActionGroup
from qtpy.QtCore import Signal, Slot, Property, QTimer, Q_ENUMS, QThread
from qtpy.QtCore import Signal, Slot, Property, QTimer, QThread
from PyQt5.QtCore import Q_ENUM
from pyqtgraph import ImageView, PlotItem
from pyqtgraph import ColorMap
from pyqtgraph.graphicsItems.ViewBox.ViewBoxMenu import ViewBoxMenu
import numpy as np
import logging
from enum import Enum
from .channel import PyDMChannel
from .colormaps import cmaps, cmap_names, PyDMColorMap
from .base import PyDMWidget

logger = logging.getLogger(__name__)


class ReadingOrder(object):
class ReadingOrder(Enum):
"""Class to build ReadingOrder ENUM property."""

Fortranlike = 0
Clike = 1


class DimensionOrder(object):
class DimensionOrder(Enum):
"""
Class to build DimensionOrder ENUM property.

Expand Down Expand Up @@ -98,7 +100,11 @@ def run(self):
self.image_view.needs_redraw = False


class PyDMImageView(ImageView, PyDMWidget, PyDMColorMap, ReadingOrder, DimensionOrder):
class PyDMImageView(
ImageView,
PyDMWidget,
PyDMColorMap,
):
"""
A PyQtGraph ImageView with support for Channels and more from PyDM.

Expand Down Expand Up @@ -126,9 +132,9 @@ class PyDMImageView(ImageView, PyDMWidget, PyDMColorMap, ReadingOrder, Dimension
ReadingOrder = ReadingOrder
DimensionOrder = DimensionOrder

Q_ENUMS(ReadingOrder)
Q_ENUMS(DimensionOrder)
Q_ENUMS(PyDMColorMap)
Q_ENUM(ReadingOrder)
Q_ENUM(DimensionOrder)
Q_ENUM(PyDMColorMap)

color_maps = cmaps

Expand Down
7 changes: 4 additions & 3 deletions pydm/widgets/label.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
from .base import PyDMWidget, TextFormatter, str_types
from qtpy.QtWidgets import QLabel, QApplication
from qtpy.QtCore import Qt, Property, Q_ENUMS
from qtpy.QtCore import Qt, Property
from .display_format import DisplayFormat, parse_value_for_display
from pydm.utilities import is_pydm_app, is_qt_designer
from pydm import config
from pydm.widgets.base import only_if_channel_set
from PyQt5.QtCore import Q_ENUM

_labelRuleProperties = {"Text": ["value_changed", str]}


class PyDMLabel(QLabel, TextFormatter, PyDMWidget, DisplayFormat, new_properties=_labelRuleProperties):
class PyDMLabel(QLabel, TextFormatter, PyDMWidget, new_properties=_labelRuleProperties):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removing DisplayFormat here (as well as in line_edit.py) will cause issues with saved ui files not being able to find the property in PyQt5, error I am seeing with the example label below.

This is where the idea to set up the enum this way came from
https://stackoverflow.com/questions/46917671/how-to-use-q-enums-in-pyqt

$ pydm examples/label/label.ui
<...>
AttributeError: type object 'PyDMLabel' has no attribute 'String'

"""
A QLabel with support for setting the text via a PyDM Channel, or
through the PyDM Rules system.
Expand All @@ -27,7 +28,7 @@ class PyDMLabel(QLabel, TextFormatter, PyDMWidget, DisplayFormat, new_properties
The channel to be used by the widget.
"""

Q_ENUMS(DisplayFormat)
Q_ENUM(DisplayFormat)
DisplayFormat = DisplayFormat

def __init__(self, parent=None, init_channel=None):
Expand Down
7 changes: 4 additions & 3 deletions pydm/widgets/line_edit.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
import logging
from functools import partial
from qtpy.QtWidgets import QLineEdit, QMenu, QApplication
from qtpy.QtCore import Property, Q_ENUMS, Qt
from qtpy.QtCore import Property, Qt
from PyQt5.QtCore import Q_ENUM
from qtpy.QtGui import QFocusEvent
from .. import utilities
from .base import PyDMWritableWidget, TextFormatter, str_types
Expand All @@ -14,7 +15,7 @@
logger = logging.getLogger(__name__)


class PyDMLineEdit(QLineEdit, TextFormatter, PyDMWritableWidget, DisplayFormat):
class PyDMLineEdit(QLineEdit, TextFormatter, PyDMWritableWidget):
"""
A QLineEdit (writable text field) with support for Channels and more
from PyDM.
Expand All @@ -29,7 +30,7 @@ class PyDMLineEdit(QLineEdit, TextFormatter, PyDMWritableWidget, DisplayFormat):
The channel to be used by the widget.
"""

Q_ENUMS(DisplayFormat)
Q_ENUM(DisplayFormat)
DisplayFormat = DisplayFormat

def __init__(self, parent=None, init_channel=None):
Expand Down
17 changes: 7 additions & 10 deletions pydm/widgets/logdisplay.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@
import functools

from collections import OrderedDict
from enum import Enum

from qtpy.QtCore import QObject, Slot, Signal, Property, Q_ENUMS, QSize
from qtpy.QtCore import QObject, Slot, Signal, Property, QSize
from PyQt5.QtCore import Q_ENUM
from qtpy.QtWidgets import (
QWidget,
QPlainTextEdit,
Expand Down Expand Up @@ -81,7 +83,7 @@ def emit(self, record):
logger.debug("Handler was destroyed at the C++ level.")


class LogLevels(object):
class LogLevels(Enum):
NOTSET = 0
DEBUG = 10
INFO = 20
Expand All @@ -99,16 +101,11 @@ def as_dict():
OrderedDict
"""
# First let's remove the internals
entries = [
(k, v)
for k, v in LogLevels.__dict__.items()
if not k.startswith("__") and not callable(v) and not isinstance(v, staticmethod)
]

entries = [(k, v.value) for k, v in LogLevels.__members__.items()]
return OrderedDict(sorted(entries, key=lambda x: x[1], reverse=False))


class PyDMLogDisplay(QWidget, LogLevels):
class PyDMLogDisplay(QWidget):
"""
Standard display for Log Output

Expand All @@ -129,7 +126,7 @@ class PyDMLogDisplay(QWidget, LogLevels):

"""

Q_ENUMS(LogLevels)
Q_ENUM(LogLevels)
LogLevels = LogLevels
terminator = "\n"
default_format = "%(asctime)s %(message)s"
Expand Down
12 changes: 7 additions & 5 deletions pydm/widgets/template_repeater.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@
import json
import copy
import logging
from enum import Enum
from qtpy.QtWidgets import QFrame, QApplication, QLabel, QVBoxLayout, QHBoxLayout, QWidget, QStyle, QSizePolicy, QLayout
from qtpy.QtCore import Qt, QSize, QRect, Property, QPoint, Q_ENUMS
from qtpy.QtCore import Qt, QSize, QRect, Property, QPoint
from PyQt5.QtCore import Q_ENUM
from .base import PyDMPrimitiveWidget
from pydm.utilities import is_qt_designer
import pydm.data_plugins
Expand Down Expand Up @@ -111,7 +113,7 @@ def smart_spacing(self, pm):
return parent.spacing()


class LayoutType(object):
class LayoutType(Enum):
Vertical = 0
Horizontal = 1
Flow = 2
Expand All @@ -120,7 +122,7 @@ class LayoutType(object):
layout_class_for_type = (QVBoxLayout, QHBoxLayout, FlowLayout)


class PyDMTemplateRepeater(QFrame, PyDMPrimitiveWidget, LayoutType):
class PyDMTemplateRepeater(QFrame, PyDMPrimitiveWidget):
"""
PyDMTemplateRepeater takes a .ui file with macro variables as a template, and a JSON
file (or a list of dictionaries) with a list of values to use to fill in
Expand All @@ -140,7 +142,7 @@ class PyDMTemplateRepeater(QFrame, PyDMPrimitiveWidget, LayoutType):
The parent of this widget.
"""

Q_ENUMS(LayoutType)
Q_ENUM(LayoutType)
LayoutType = LayoutType

def __init__(self, parent=None):
Expand Down Expand Up @@ -391,7 +393,7 @@ def rebuild(self):
return
self.setUpdatesEnabled(False)

layout_class = layout_class_for_type[self.layoutType]
layout_class = layout_class_for_type[self.layoutType.value]
if type(self.layout()) != layout_class:
if self.layout() is not None:
# Trick to remove the existing layout by re-parenting it in an empty widget.
Expand Down
12 changes: 7 additions & 5 deletions pydm/widgets/timeplot.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@
from pyqtgraph import BarGraphItem, ViewBox, AxisItem
import numpy as np
from qtpy.QtGui import QColor
from qtpy.QtCore import Signal, Slot, Property, QTimer, Q_ENUMS
from qtpy.QtCore import Signal, Slot, Property, QTimer
from PyQt5.QtCore import Q_ENUM
from .baseplot import BasePlot, BasePlotCurveItem
from .channel import PyDMChannel
from ..utilities import remove_protocol

import logging
from enum import Enum

logger = logging.getLogger(__name__)

Expand All @@ -24,7 +26,7 @@
DEFAULT_UPDATE_INTERVAL = 1000 # Plot update rate for fixed rate mode in milliseconds


class updateMode(object):
class updateMode(Enum):
"""updateMode as new type for plot update"""

OnValueChange = 1
Expand Down Expand Up @@ -376,7 +378,7 @@ def setUpdatesAsynchronously(self, value):
Check if value is from updatesAsynchronously(bool) or updateMode(int)
"""
if isinstance(value, int) and value == updateMode.AtFixedRate or isinstance(value, bool) and value is True:
self._update_mode = PyDMTimePlot.AtFixedRate
self._update_mode = PyDMTimePlot.AtFixedRated
else:
self._update_mode = PyDMTimePlot.OnValueChange
self.initialize_buffer()
Expand Down Expand Up @@ -412,7 +414,7 @@ def channels(self):
return [self.channel]


class PyDMTimePlot(BasePlot, updateMode):
class PyDMTimePlot(BasePlot):
"""
PyDMTimePlot is a widget to plot one or more channels vs. time.

Expand Down Expand Up @@ -440,7 +442,7 @@ class PyDMTimePlot(BasePlot, updateMode):
OnValueChange = 1
AtFixedRated = 2

Q_ENUMS(updateMode)
Q_ENUM(updateMode)
updateMode = updateMode

plot_redrawn_signal = Signal(TimePlotCurveItem)
Expand Down
Loading