We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
`pen` parameter fires `sigValueChanged` without setting value
This line should be `setValue` rather than emitting `sigValueChanged`:
https://github.com/pyqtgraph/pyqtgraph/blob/8be2d6a88edc1e26b1f6f85c47a72c400db9a28b/pyqtgraph/parametertree/parameterTypes/pen.py#L52

In all other parameters, the signal doesn't fire until after the value is set.
`pen` parameter fires `sigValueChanged` without setting value
This line should be `setValue` rather than emitting `sigValueChanged`:
https://github.com/pyqtgraph/pyqtgraph/blob/8be2d6a88edc1e26b1f6f85c47a72c400db9a28b/pyqtgraph/parametertree/parameterTypes/pen.py#L52

In all other parameters, the signal doesn't fire until after the value is set.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `pyqtgraph/parametertree/parameterTypes/pen.py`
Content:
```
1 import re
2 from contextlib import ExitStack
3 
4 from . import GroupParameterItem
5 from .basetypes import GroupParameter, Parameter, ParameterItem
6 from .qtenum import QtEnumParameter
7 from ... import functions as fn
8 from ...Qt import QtCore
9 from ...SignalProxy import SignalProxy
10 from ...widgets.PenPreviewLabel import PenPreviewLabel
11 
12 class PenParameterItem(GroupParameterItem):
13     def __init__(self, param, depth):
14         super().__init__(param, depth)
15         self.penLabel = PenPreviewLabel(param)
16 
17     def treeWidgetChanged(self):
18         ParameterItem.treeWidgetChanged(self)
19         tw = self.treeWidget()
20         if tw is None:
21             return
22         tw.setItemWidget(self, 1, self.penLabel
23                          )
24 
25 class PenParameter(GroupParameter):
26     """
27     Controls the appearance of a QPen value.
28 
29     When `saveState` is called, the value is encoded as (color, width, style, capStyle, joinStyle, cosmetic)
30 
31     ============== ========================================================
32     **Options:**
33     color          pen color, can be any argument accepted by :func:`~pyqtgraph.mkColor` (defaults to black)
34     width          integer width >= 0 (defaults to 1)
35     style          String version of QPenStyle enum, i.e. 'SolidLine' (default), 'DashLine', etc.
36     capStyle       String version of QPenCapStyle enum, i.e. 'SquareCap' (default), 'RoundCap', etc.
37     joinStyle      String version of QPenJoinStyle enum, i.e. 'BevelJoin' (default), 'RoundJoin', etc.
38     cosmetic       Boolean, whether or not the pen is cosmetic (defaults to True)
39     ============== ========================================================
40     """
41     itemClass = PenParameterItem
42 
43     def __init__(self, **opts):
44         self.pen = fn.mkPen(**opts)
45         children = self._makeChildren(self.pen)
46         if 'children' in opts:
47             raise KeyError('Cannot set "children" argument in Pen Parameter opts')
48         super().__init__(**opts, children=list(children))
49         self.valChangingProxy = SignalProxy(self.sigValueChanging, delay=1.0, slot=self._childrenFinishedChanging)
50 
51     def _childrenFinishedChanging(self, paramAndValue):
52         self.sigValueChanged.emit(*paramAndValue)
53 
54     def saveState(self, filter=None):
55         state = super().saveState(filter)
56         opts = state.pop('children')
57         state['value'] = tuple(o['value'] for o in opts.values())
58         return state
59 
60     def restoreState(self, state, recursive=True, addChildren=True, removeChildren=True, blockSignals=True):
61         return super().restoreState(state, recursive=False, addChildren=False, removeChildren=False, blockSignals=blockSignals)
62 
63     def _interpretValue(self, v):
64         return self.mkPen(v)
65 
66     def setValue(self, value, blockSignal=None):
67         if not fn.eq(value, self.pen):
68             value = self.mkPen(value)
69             self.updateFromPen(self, value)
70         return super().setValue(self.pen, blockSignal)
71 
72     def applyOptsToPen(self, **opts):
73         # Transform opts into a value for the current pen
74         paramNames = set(opts).intersection(self.names)
75         # Value should be overridden by opts
76         with self.treeChangeBlocker():
77             if 'value' in opts:
78                 pen = self.mkPen(opts.pop('value'))
79                 if not fn.eq(pen, self.pen):
80                     self.updateFromPen(self, pen)
81             penOpts = {}
82             for kk in paramNames:
83                 penOpts[kk] = opts[kk]
84                 self[kk] = opts[kk]
85         return penOpts
86 
87     def setOpts(self, **opts):
88         # Transform opts into a value
89         penOpts = self.applyOptsToPen(**opts)
90         if penOpts:
91             self.setValue(self.pen)
92         return super().setOpts(**opts)
93 
94     def mkPen(self, *args, **kwargs):
95         """Thin wrapper around fn.mkPen which accepts the serialized state from saveState"""
96         if len(args) == 1 and isinstance(args[0], tuple) and len(args[0]) == len(self.childs):
97             opts = dict(zip(self.names, args[0]))
98             self.applyOptsToPen(**opts)
99             args = (self.pen,)
100             kwargs = {}
101         return fn.mkPen(*args, **kwargs)
102 
103     def _makeChildren(self, boundPen=None):
104         cs = QtCore.Qt.PenCapStyle
105         js = QtCore.Qt.PenJoinStyle
106         ps = QtCore.Qt.PenStyle
107         param = Parameter.create(
108             name='Params', type='group', children=[
109                 dict(name='color', type='color', value='k'),
110                 dict(name='width', value=1, type='int', limits=[0, None]),
111                 QtEnumParameter(ps, name='style', value='SolidLine'),
112                 QtEnumParameter(cs, name='capStyle'),
113                 QtEnumParameter(js, name='joinStyle'),
114                 dict(name='cosmetic', type='bool', value=True)
115             ]
116             )
117 
118         optsPen = boundPen or fn.mkPen()
119         for p in param:
120             name = p.name()
121             # Qt naming scheme uses isXXX for booleans
122             if isinstance(p.value(), bool):
123                 attrName = f'is{name.title()}'
124             else:
125                 attrName = name
126             default = getattr(optsPen, attrName)()
127             replace = r'\1 \2'
128             name = re.sub(r'(\w)([A-Z])', replace, name)
129             name = name.title().strip()
130             p.setOpts(title=name, default=default)
131 
132         def penPropertyWrapper(propertySetter):
133             def tiePenPropToParam(_, value):
134                 propertySetter(value)
135                 self.sigValueChanging.emit(self, self.pen)
136 
137             return tiePenPropToParam
138 
139         if boundPen is not None:
140             self.updateFromPen(param, boundPen)
141             for p in param:
142                 setter, setName = self._setterForParam(p.name(), boundPen, returnName=True)
143                 # Instead, set the parameter which will signal the old setter
144                 setattr(boundPen, setName, p.setValue)
145                 newSetter = penPropertyWrapper(setter)
146                 # Edge case: color picker uses a dialog with user interaction, so wait until full change there
147                 if p.type() != 'color':
148                     p.sigValueChanging.connect(newSetter)
149                 # Force children to emulate self's value instead of being part of a tree like normal
150                 p.sigValueChanged.disconnect(p._emitValueChanged)
151                 # Some widgets (e.g. checkbox, combobox) don't emit 'changing' signals, so tie to 'changed' as well
152                 p.sigValueChanged.connect(newSetter)
153 
154         return param
155 
156     @staticmethod
157     def _setterForParam(paramName, obj, returnName=False):
158         formatted = paramName[0].upper() + paramName[1:]
159         setter = getattr(obj, f'set{formatted}')
160         if returnName:
161             return setter, formatted
162         return setter
163 
164     @staticmethod
165     def updateFromPen(param, pen):
166         """
167         Applies settings from a pen to either a Parameter or dict. The Parameter or dict must already
168         be populated with the relevant keys that can be found in `PenSelectorDialog.mkParam`.
169         """
170         stack = ExitStack()
171         if isinstance(param, Parameter):
172             names = param.names
173             # Block changes until all are finalized
174             stack.enter_context(param.treeChangeBlocker())
175         else:
176             names = param
177         for opt in names:
178             # Booleans have different naming convention
179             if isinstance(param[opt], bool):
180                 attrName = f'is{opt.title()}'
181             else:
182                 attrName = opt
183             param[opt] = getattr(pen, attrName)()
184         stack.close()
185
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/pyqtgraph/parametertree/parameterTypes/pen.py b/pyqtgraph/parametertree/parameterTypes/pen.py
--- a/pyqtgraph/parametertree/parameterTypes/pen.py
+++ b/pyqtgraph/parametertree/parameterTypes/pen.py
@@ -1,26 +1,52 @@
 import re
 from contextlib import ExitStack
 
-from . import GroupParameterItem
+from . import GroupParameterItem, WidgetParameterItem
 from .basetypes import GroupParameter, Parameter, ParameterItem
 from .qtenum import QtEnumParameter
 from ... import functions as fn
-from ...Qt import QtCore
+from ...Qt import QtCore, QtWidgets
 from ...SignalProxy import SignalProxy
 from ...widgets.PenPreviewLabel import PenPreviewLabel
 
 class PenParameterItem(GroupParameterItem):
     def __init__(self, param, depth):
+        self.defaultBtn = self.makeDefaultButton()
         super().__init__(param, depth)
+        self.itemWidget = QtWidgets.QWidget()
+        layout = QtWidgets.QHBoxLayout()
+        layout.setContentsMargins(0, 0, 0, 0)
+        layout.setSpacing(2)
+
         self.penLabel = PenPreviewLabel(param)
+        for child in self.penLabel, self.defaultBtn:
+            layout.addWidget(child)
+        self.itemWidget.setLayout(layout)
+
+    def optsChanged(self, param, opts):
+        if "enabled" in opts or "readonly" in opts:
+            self.updateDefaultBtn()
 
     def treeWidgetChanged(self):
         ParameterItem.treeWidgetChanged(self)
         tw = self.treeWidget()
         if tw is None:
             return
-        tw.setItemWidget(self, 1, self.penLabel
-                         )
+        tw.setItemWidget(self, 1, self.itemWidget)
+
+    defaultClicked = WidgetParameterItem.defaultClicked
+    makeDefaultButton = WidgetParameterItem.makeDefaultButton
+
+    def valueChanged(self, param, val):
+        self.updateDefaultBtn()
+
+    def updateDefaultBtn(self):
+        self.defaultBtn.setEnabled(
+            not self.param.valueIsDefault()
+            and self.param.opts["enabled"]
+            and self.param.writable()
+        )
+
 
 class PenParameter(GroupParameter):
     """
@@ -49,7 +75,21 @@
         self.valChangingProxy = SignalProxy(self.sigValueChanging, delay=1.0, slot=self._childrenFinishedChanging)
 
     def _childrenFinishedChanging(self, paramAndValue):
-        self.sigValueChanged.emit(*paramAndValue)
+        self.setValue(self.pen)
+
+    def setDefault(self, val):
+        pen = self._interpretValue(val)
+        with self.treeChangeBlocker():
+            # Block changes until all are finalized
+            for opt in self.names:
+                # Booleans have different naming convention
+                if isinstance(self[opt], bool):
+                    attrName = f'is{opt.title()}'
+                else:
+                    attrName = opt
+                self.child(opt).setDefault(getattr(pen, attrName)())
+            out = super().setDefault(val)
+        return out
 
     def saveState(self, filter=None):
         state = super().saveState(filter)

{"golden_diff": "diff --git a/pyqtgraph/parametertree/parameterTypes/pen.py b/pyqtgraph/parametertree/parameterTypes/pen.py\n--- a/pyqtgraph/parametertree/parameterTypes/pen.py\n+++ b/pyqtgraph/parametertree/parameterTypes/pen.py\n@@ -1,26 +1,52 @@\n import re\n from contextlib import ExitStack\n \n-from . import GroupParameterItem\n+from . import GroupParameterItem, WidgetParameterItem\n from .basetypes import GroupParameter, Parameter, ParameterItem\n from .qtenum import QtEnumParameter\n from ... import functions as fn\n-from ...Qt import QtCore\n+from ...Qt import QtCore, QtWidgets\n from ...SignalProxy import SignalProxy\n from ...widgets.PenPreviewLabel import PenPreviewLabel\n \n class PenParameterItem(GroupParameterItem):\n     def __init__(self, param, depth):\n+        self.defaultBtn = self.makeDefaultButton()\n         super().__init__(param, depth)\n+        self.itemWidget = QtWidgets.QWidget()\n+        layout = QtWidgets.QHBoxLayout()\n+        layout.setContentsMargins(0, 0, 0, 0)\n+        layout.setSpacing(2)\n+\n         self.penLabel = PenPreviewLabel(param)\n+        for child in self.penLabel, self.defaultBtn:\n+            layout.addWidget(child)\n+        self.itemWidget.setLayout(layout)\n+\n+    def optsChanged(self, param, opts):\n+        if \"enabled\" in opts or \"readonly\" in opts:\n+            self.updateDefaultBtn()\n \n     def treeWidgetChanged(self):\n         ParameterItem.treeWidgetChanged(self)\n         tw = self.treeWidget()\n         if tw is None:\n             return\n-        tw.setItemWidget(self, 1, self.penLabel\n-                         )\n+        tw.setItemWidget(self, 1, self.itemWidget)\n+\n+    defaultClicked = WidgetParameterItem.defaultClicked\n+    makeDefaultButton = WidgetParameterItem.makeDefaultButton\n+\n+    def valueChanged(self, param, val):\n+        self.updateDefaultBtn()\n+\n+    def updateDefaultBtn(self):\n+        self.defaultBtn.setEnabled(\n+            not self.param.valueIsDefault()\n+            and self.param.opts[\"enabled\"]\n+            and self.param.writable()\n+        )\n+\n \n class PenParameter(GroupParameter):\n     \"\"\"\n@@ -49,7 +75,21 @@\n         self.valChangingProxy = SignalProxy(self.sigValueChanging, delay=1.0, slot=self._childrenFinishedChanging)\n \n     def _childrenFinishedChanging(self, paramAndValue):\n-        self.sigValueChanged.emit(*paramAndValue)\n+        self.setValue(self.pen)\n+\n+    def setDefault(self, val):\n+        pen = self._interpretValue(val)\n+        with self.treeChangeBlocker():\n+            # Block changes until all are finalized\n+            for opt in self.names:\n+                # Booleans have different naming convention\n+                if isinstance(self[opt], bool):\n+                    attrName = f'is{opt.title()}'\n+                else:\n+                    attrName = opt\n+                self.child(opt).setDefault(getattr(pen, attrName)())\n+            out = super().setDefault(val)\n+        return out\n \n     def saveState(self, filter=None):\n         state = super().saveState(filter)\n", "issue": "`pen` parameter fires `sigValueChanged` without setting value\nThis line should be `setValue` rather than emitting `sigValueChanged`:\r\nhttps://github.com/pyqtgraph/pyqtgraph/blob/8be2d6a88edc1e26b1f6f85c47a72c400db9a28b/pyqtgraph/parametertree/parameterTypes/pen.py#L52\r\n\r\nIn all other parameters, the signal doesn't fire until after the value is set.\n`pen` parameter fires `sigValueChanged` without setting value\nThis line should be `setValue` rather than emitting `sigValueChanged`:\r\nhttps://github.com/pyqtgraph/pyqtgraph/blob/8be2d6a88edc1e26b1f6f85c47a72c400db9a28b/pyqtgraph/parametertree/parameterTypes/pen.py#L52\r\n\r\nIn all other parameters, the signal doesn't fire until after the value is set.\n", "before_files": [{"content": "import re\nfrom contextlib import ExitStack\n\nfrom . import GroupParameterItem\nfrom .basetypes import GroupParameter, Parameter, ParameterItem\nfrom .qtenum import QtEnumParameter\nfrom ... import functions as fn\nfrom ...Qt import QtCore\nfrom ...SignalProxy import SignalProxy\nfrom ...widgets.PenPreviewLabel import PenPreviewLabel\n\nclass PenParameterItem(GroupParameterItem):\n    def __init__(self, param, depth):\n        super().__init__(param, depth)\n        self.penLabel = PenPreviewLabel(param)\n\n    def treeWidgetChanged(self):\n        ParameterItem.treeWidgetChanged(self)\n        tw = self.treeWidget()\n        if tw is None:\n            return\n        tw.setItemWidget(self, 1, self.penLabel\n                         )\n\nclass PenParameter(GroupParameter):\n    \"\"\"\n    Controls the appearance of a QPen value.\n\n    When `saveState` is called, the value is encoded as (color, width, style, capStyle, joinStyle, cosmetic)\n\n    ============== ========================================================\n    **Options:**\n    color          pen color, can be any argument accepted by :func:`~pyqtgraph.mkColor` (defaults to black)\n    width          integer width >= 0 (defaults to 1)\n    style          String version of QPenStyle enum, i.e. 'SolidLine' (default), 'DashLine', etc.\n    capStyle       String version of QPenCapStyle enum, i.e. 'SquareCap' (default), 'RoundCap', etc.\n    joinStyle      String version of QPenJoinStyle enum, i.e. 'BevelJoin' (default), 'RoundJoin', etc.\n    cosmetic       Boolean, whether or not the pen is cosmetic (defaults to True)\n    ============== ========================================================\n    \"\"\"\n    itemClass = PenParameterItem\n\n    def __init__(self, **opts):\n        self.pen = fn.mkPen(**opts)\n        children = self._makeChildren(self.pen)\n        if 'children' in opts:\n            raise KeyError('Cannot set \"children\" argument in Pen Parameter opts')\n        super().__init__(**opts, children=list(children))\n        self.valChangingProxy = SignalProxy(self.sigValueChanging, delay=1.0, slot=self._childrenFinishedChanging)\n\n    def _childrenFinishedChanging(self, paramAndValue):\n        self.sigValueChanged.emit(*paramAndValue)\n\n    def saveState(self, filter=None):\n        state = super().saveState(filter)\n        opts = state.pop('children')\n        state['value'] = tuple(o['value'] for o in opts.values())\n        return state\n\n    def restoreState(self, state, recursive=True, addChildren=True, removeChildren=True, blockSignals=True):\n        return super().restoreState(state, recursive=False, addChildren=False, removeChildren=False, blockSignals=blockSignals)\n\n    def _interpretValue(self, v):\n        return self.mkPen(v)\n\n    def setValue(self, value, blockSignal=None):\n        if not fn.eq(value, self.pen):\n            value = self.mkPen(value)\n            self.updateFromPen(self, value)\n        return super().setValue(self.pen, blockSignal)\n\n    def applyOptsToPen(self, **opts):\n        # Transform opts into a value for the current pen\n        paramNames = set(opts).intersection(self.names)\n        # Value should be overridden by opts\n        with self.treeChangeBlocker():\n            if 'value' in opts:\n                pen = self.mkPen(opts.pop('value'))\n                if not fn.eq(pen, self.pen):\n                    self.updateFromPen(self, pen)\n            penOpts = {}\n            for kk in paramNames:\n                penOpts[kk] = opts[kk]\n                self[kk] = opts[kk]\n        return penOpts\n\n    def setOpts(self, **opts):\n        # Transform opts into a value\n        penOpts = self.applyOptsToPen(**opts)\n        if penOpts:\n            self.setValue(self.pen)\n        return super().setOpts(**opts)\n\n    def mkPen(self, *args, **kwargs):\n        \"\"\"Thin wrapper around fn.mkPen which accepts the serialized state from saveState\"\"\"\n        if len(args) == 1 and isinstance(args[0], tuple) and len(args[0]) == len(self.childs):\n            opts = dict(zip(self.names, args[0]))\n            self.applyOptsToPen(**opts)\n            args = (self.pen,)\n            kwargs = {}\n        return fn.mkPen(*args, **kwargs)\n\n    def _makeChildren(self, boundPen=None):\n        cs = QtCore.Qt.PenCapStyle\n        js = QtCore.Qt.PenJoinStyle\n        ps = QtCore.Qt.PenStyle\n        param = Parameter.create(\n            name='Params', type='group', children=[\n                dict(name='color', type='color', value='k'),\n                dict(name='width', value=1, type='int', limits=[0, None]),\n                QtEnumParameter(ps, name='style', value='SolidLine'),\n                QtEnumParameter(cs, name='capStyle'),\n                QtEnumParameter(js, name='joinStyle'),\n                dict(name='cosmetic', type='bool', value=True)\n            ]\n            )\n\n        optsPen = boundPen or fn.mkPen()\n        for p in param:\n            name = p.name()\n            # Qt naming scheme uses isXXX for booleans\n            if isinstance(p.value(), bool):\n                attrName = f'is{name.title()}'\n            else:\n                attrName = name\n            default = getattr(optsPen, attrName)()\n            replace = r'\\1 \\2'\n            name = re.sub(r'(\\w)([A-Z])', replace, name)\n            name = name.title().strip()\n            p.setOpts(title=name, default=default)\n\n        def penPropertyWrapper(propertySetter):\n            def tiePenPropToParam(_, value):\n                propertySetter(value)\n                self.sigValueChanging.emit(self, self.pen)\n\n            return tiePenPropToParam\n\n        if boundPen is not None:\n            self.updateFromPen(param, boundPen)\n            for p in param:\n                setter, setName = self._setterForParam(p.name(), boundPen, returnName=True)\n                # Instead, set the parameter which will signal the old setter\n                setattr(boundPen, setName, p.setValue)\n                newSetter = penPropertyWrapper(setter)\n                # Edge case: color picker uses a dialog with user interaction, so wait until full change there\n                if p.type() != 'color':\n                    p.sigValueChanging.connect(newSetter)\n                # Force children to emulate self's value instead of being part of a tree like normal\n                p.sigValueChanged.disconnect(p._emitValueChanged)\n                # Some widgets (e.g. checkbox, combobox) don't emit 'changing' signals, so tie to 'changed' as well\n                p.sigValueChanged.connect(newSetter)\n\n        return param\n\n    @staticmethod\n    def _setterForParam(paramName, obj, returnName=False):\n        formatted = paramName[0].upper() + paramName[1:]\n        setter = getattr(obj, f'set{formatted}')\n        if returnName:\n            return setter, formatted\n        return setter\n\n    @staticmethod\n    def updateFromPen(param, pen):\n        \"\"\"\n        Applies settings from a pen to either a Parameter or dict. The Parameter or dict must already\n        be populated with the relevant keys that can be found in `PenSelectorDialog.mkParam`.\n        \"\"\"\n        stack = ExitStack()\n        if isinstance(param, Parameter):\n            names = param.names\n            # Block changes until all are finalized\n            stack.enter_context(param.treeChangeBlocker())\n        else:\n            names = param\n        for opt in names:\n            # Booleans have different naming convention\n            if isinstance(param[opt], bool):\n                attrName = f'is{opt.title()}'\n            else:\n                attrName = opt\n            param[opt] = getattr(pen, attrName)()\n        stack.close()\n", "path": "pyqtgraph/parametertree/parameterTypes/pen.py"}], "after_files": [{"content": "import re\nfrom contextlib import ExitStack\n\nfrom . import GroupParameterItem, WidgetParameterItem\nfrom .basetypes import GroupParameter, Parameter, ParameterItem\nfrom .qtenum import QtEnumParameter\nfrom ... import functions as fn\nfrom ...Qt import QtCore, QtWidgets\nfrom ...SignalProxy import SignalProxy\nfrom ...widgets.PenPreviewLabel import PenPreviewLabel\n\nclass PenParameterItem(GroupParameterItem):\n    def __init__(self, param, depth):\n        self.defaultBtn = self.makeDefaultButton()\n        super().__init__(param, depth)\n        self.itemWidget = QtWidgets.QWidget()\n        layout = QtWidgets.QHBoxLayout()\n        layout.setContentsMargins(0, 0, 0, 0)\n        layout.setSpacing(2)\n\n        self.penLabel = PenPreviewLabel(param)\n        for child in self.penLabel, self.defaultBtn:\n            layout.addWidget(child)\n        self.itemWidget.setLayout(layout)\n\n    def optsChanged(self, param, opts):\n        if \"enabled\" in opts or \"readonly\" in opts:\n            self.updateDefaultBtn()\n\n    def treeWidgetChanged(self):\n        ParameterItem.treeWidgetChanged(self)\n        tw = self.treeWidget()\n        if tw is None:\n            return\n        tw.setItemWidget(self, 1, self.itemWidget)\n\n    defaultClicked = WidgetParameterItem.defaultClicked\n    makeDefaultButton = WidgetParameterItem.makeDefaultButton\n\n    def valueChanged(self, param, val):\n        self.updateDefaultBtn()\n\n    def updateDefaultBtn(self):\n        self.defaultBtn.setEnabled(\n            not self.param.valueIsDefault()\n            and self.param.opts[\"enabled\"]\n            and self.param.writable()\n        )\n\n\nclass PenParameter(GroupParameter):\n    \"\"\"\n    Controls the appearance of a QPen value.\n\n    When `saveState` is called, the value is encoded as (color, width, style, capStyle, joinStyle, cosmetic)\n\n    ============== ========================================================\n    **Options:**\n    color          pen color, can be any argument accepted by :func:`~pyqtgraph.mkColor` (defaults to black)\n    width          integer width >= 0 (defaults to 1)\n    style          String version of QPenStyle enum, i.e. 'SolidLine' (default), 'DashLine', etc.\n    capStyle       String version of QPenCapStyle enum, i.e. 'SquareCap' (default), 'RoundCap', etc.\n    joinStyle      String version of QPenJoinStyle enum, i.e. 'BevelJoin' (default), 'RoundJoin', etc.\n    cosmetic       Boolean, whether or not the pen is cosmetic (defaults to True)\n    ============== ========================================================\n    \"\"\"\n    itemClass = PenParameterItem\n\n    def __init__(self, **opts):\n        self.pen = fn.mkPen(**opts)\n        children = self._makeChildren(self.pen)\n        if 'children' in opts:\n            raise KeyError('Cannot set \"children\" argument in Pen Parameter opts')\n        super().__init__(**opts, children=list(children))\n        self.valChangingProxy = SignalProxy(self.sigValueChanging, delay=1.0, slot=self._childrenFinishedChanging)\n\n    def _childrenFinishedChanging(self, paramAndValue):\n        self.setValue(self.pen)\n\n    def setDefault(self, val):\n        pen = self._interpretValue(val)\n        with self.treeChangeBlocker():\n            # Block changes until all are finalized\n            for opt in self.names:\n                # Booleans have different naming convention\n                if isinstance(self[opt], bool):\n                    attrName = f'is{opt.title()}'\n                else:\n                    attrName = opt\n                self.child(opt).setDefault(getattr(pen, attrName)())\n            out = super().setDefault(val)\n        return out\n\n    def saveState(self, filter=None):\n        state = super().saveState(filter)\n        opts = state.pop('children')\n        state['value'] = tuple(o['value'] for o in opts.values())\n        return state\n\n    def restoreState(self, state, recursive=True, addChildren=True, removeChildren=True, blockSignals=True):\n        return super().restoreState(state, recursive=False, addChildren=False, removeChildren=False, blockSignals=blockSignals)\n\n    def _interpretValue(self, v):\n        return self.mkPen(v)\n\n    def setValue(self, value, blockSignal=None):\n        if not fn.eq(value, self.pen):\n            value = self.mkPen(value)\n            self.updateFromPen(self, value)\n        return super().setValue(self.pen, blockSignal)\n\n    def applyOptsToPen(self, **opts):\n        # Transform opts into a value for the current pen\n        paramNames = set(opts).intersection(self.names)\n        # Value should be overridden by opts\n        with self.treeChangeBlocker():\n            if 'value' in opts:\n                pen = self.mkPen(opts.pop('value'))\n                if not fn.eq(pen, self.pen):\n                    self.updateFromPen(self, pen)\n            penOpts = {}\n            for kk in paramNames:\n                penOpts[kk] = opts[kk]\n                self[kk] = opts[kk]\n        return penOpts\n\n    def setOpts(self, **opts):\n        # Transform opts into a value\n        penOpts = self.applyOptsToPen(**opts)\n        if penOpts:\n            self.setValue(self.pen)\n        return super().setOpts(**opts)\n\n    def mkPen(self, *args, **kwargs):\n        \"\"\"Thin wrapper around fn.mkPen which accepts the serialized state from saveState\"\"\"\n        if len(args) == 1 and isinstance(args[0], tuple) and len(args[0]) == len(self.childs):\n            opts = dict(zip(self.names, args[0]))\n            self.applyOptsToPen(**opts)\n            args = (self.pen,)\n            kwargs = {}\n        return fn.mkPen(*args, **kwargs)\n\n    def _makeChildren(self, boundPen=None):\n        cs = QtCore.Qt.PenCapStyle\n        js = QtCore.Qt.PenJoinStyle\n        ps = QtCore.Qt.PenStyle\n        param = Parameter.create(\n            name='Params', type='group', children=[\n                dict(name='color', type='color', value='k'),\n                dict(name='width', value=1, type='int', limits=[0, None]),\n                QtEnumParameter(ps, name='style', value='SolidLine'),\n                QtEnumParameter(cs, name='capStyle'),\n                QtEnumParameter(js, name='joinStyle'),\n                dict(name='cosmetic', type='bool', value=True)\n            ]\n            )\n\n        optsPen = boundPen or fn.mkPen()\n        for p in param:\n            name = p.name()\n            # Qt naming scheme uses isXXX for booleans\n            if isinstance(p.value(), bool):\n                attrName = f'is{name.title()}'\n            else:\n                attrName = name\n            default = getattr(optsPen, attrName)()\n            replace = r'\\1 \\2'\n            name = re.sub(r'(\\w)([A-Z])', replace, name)\n            name = name.title().strip()\n            p.setOpts(title=name, default=default)\n\n        def penPropertyWrapper(propertySetter):\n            def tiePenPropToParam(_, value):\n                propertySetter(value)\n                self.sigValueChanging.emit(self, self.pen)\n\n            return tiePenPropToParam\n\n        if boundPen is not None:\n            self.updateFromPen(param, boundPen)\n            for p in param:\n                setter, setName = self._setterForParam(p.name(), boundPen, returnName=True)\n                # Instead, set the parameter which will signal the old setter\n                setattr(boundPen, setName, p.setValue)\n                newSetter = penPropertyWrapper(setter)\n                # Edge case: color picker uses a dialog with user interaction, so wait until full change there\n                if p.type() != 'color':\n                    p.sigValueChanging.connect(newSetter)\n                # Force children to emulate self's value instead of being part of a tree like normal\n                p.sigValueChanged.disconnect(p._emitValueChanged)\n                # Some widgets (e.g. checkbox, combobox) don't emit 'changing' signals, so tie to 'changed' as well\n                p.sigValueChanged.connect(newSetter)\n\n        return param\n\n    @staticmethod\n    def _setterForParam(paramName, obj, returnName=False):\n        formatted = paramName[0].upper() + paramName[1:]\n        setter = getattr(obj, f'set{formatted}')\n        if returnName:\n            return setter, formatted\n        return setter\n\n    @staticmethod\n    def updateFromPen(param, pen):\n        \"\"\"\n        Applies settings from a pen to either a Parameter or dict. The Parameter or dict must already\n        be populated with the relevant keys that can be found in `PenSelectorDialog.mkParam`.\n        \"\"\"\n        stack = ExitStack()\n        if isinstance(param, Parameter):\n            names = param.names\n            # Block changes until all are finalized\n            stack.enter_context(param.treeChangeBlocker())\n        else:\n            names = param\n        for opt in names:\n            # Booleans have different naming convention\n            if isinstance(param[opt], bool):\n                attrName = f'is{opt.title()}'\n            else:\n                attrName = opt\n            param[opt] = getattr(pen, attrName)()\n        stack.close()\n", "path": "pyqtgraph/parametertree/parameterTypes/pen.py"}]}