PythonQwt 0.14.6__py3-none-any.whl → 0.16.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: PythonQwt
3
- Version: 0.14.6
3
+ Version: 0.16.0
4
4
  Summary: Qt plotting widgets for Python
5
5
  Author-email: Pierre Raybaut <pierre.raybaut@gmail.com>
6
6
  License: PythonQwt License Agreement
@@ -666,12 +666,11 @@ License: PythonQwt License Agreement
666
666
  Project-URL: Homepage, https://github.com/PlotPyStack/PythonQwt/
667
667
  Project-URL: Documentation, https://PythonQwt.readthedocs.io/en/latest/
668
668
  Classifier: Topic :: Scientific/Engineering
669
+ Classifier: Topic :: Scientific/Engineering :: Human Machine Interfaces
669
670
  Classifier: Topic :: Scientific/Engineering :: Visualization
670
671
  Classifier: Topic :: Software Development :: Widget Sets
671
672
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
672
673
  Classifier: Topic :: Utilities
673
- Classifier: Topic :: Scientific/Engineering
674
- Classifier: Topic :: Scientific/Engineering :: Human Machine Interfaces
675
674
  Classifier: Topic :: Software Development :: User Interfaces
676
675
  Classifier: Operating System :: MacOS
677
676
  Classifier: Operating System :: Microsoft :: Windows
@@ -683,15 +682,18 @@ Classifier: Programming Language :: Python :: 3.10
683
682
  Classifier: Programming Language :: Python :: 3.11
684
683
  Classifier: Programming Language :: Python :: 3.12
685
684
  Classifier: Programming Language :: Python :: 3.13
685
+ Classifier: Programming Language :: Python :: 3.14
686
686
  Requires-Python: <4,>=3.9
687
687
  Description-Content-Type: text/markdown
688
688
  License-File: LICENSE
689
- Requires-Dist: NumPy>=1.19
689
+ Requires-Dist: NumPy>=1.21
690
690
  Requires-Dist: QtPy>=1.9
691
691
  Provides-Extra: dev
692
+ Requires-Dist: build; extra == "dev"
692
693
  Requires-Dist: ruff; extra == "dev"
693
694
  Requires-Dist: pylint; extra == "dev"
694
695
  Requires-Dist: Coverage; extra == "dev"
696
+ Requires-Dist: pre-commit; extra == "dev"
695
697
  Provides-Extra: doc
696
698
  Requires-Dist: PyQt5; extra == "doc"
697
699
  Requires-Dist: sphinx>6; extra == "doc"
@@ -736,8 +738,8 @@ plot.insertLegend(qwt.QwtLegend(), qwt.QwtPlot.BottomLegend)
736
738
 
737
739
  # Create two curves and attach them to plot
738
740
  x = np.linspace(-10, 10, 500)
739
- qwt.QwtPlotCurve.make(x, np.cos(x), "Cosinus", plot, linecolor="red", antialiased=True)
740
- qwt.QwtPlotCurve.make(x, np.sin(x), "Sinus", plot, linecolor="blue", antialiased=True)
741
+ qwt.QwtPlotCurve.make(x, np.cos(x), "Cosine", plot, linecolor="red", antialiased=True)
742
+ qwt.QwtPlotCurve.make(x, np.sin(x), "Sine", plot, linecolor="blue", antialiased=True)
741
743
 
742
744
  # Resize and show plot
743
745
  plot.resize(600, 300)
@@ -760,7 +762,7 @@ tests.run()
760
762
  or from the command line:
761
763
 
762
764
  ```bash
763
- PythonQwt
765
+ PythonQwt-tests
764
766
  ```
765
767
 
766
768
  Tests may also be executed in unattended mode:
@@ -773,9 +775,9 @@ PythonQwt-tests --mode unattended
773
775
 
774
776
  The `qwt` package is a pure Python implementation of `Qwt` C++ library with the following limitations.
775
777
 
776
- The following `Qwt` classes won't be reimplemented in `qwt` because more powerful features already exist in `guiqwt`: `QwtPlotZoomer`, `QwtCounter`, `QwtEventPattern`, `QwtPicker`, `QwtPlotPicker`.
778
+ The following `Qwt` classes won't be reimplemented in `qwt` because more powerful features already exist in `PlotPy`: `QwtPlotZoomer`, `QwtCounter`, `QwtEventPattern`, `QwtPicker`, `QwtPlotPicker`.
777
779
 
778
- Only the following plot items are currently implemented in `qwt` (the only plot items needed by `guiqwt`): `QwtPlotItem` (base class), `QwtPlotItem`, `QwtPlotMarker`, `QwtPlotSeriesItem` and `QwtPlotCurve`.
780
+ Only the following plot items are currently implemented in `qwt` (the only plot items needed by `PlotPy`): `QwtPlotItem` (base class), `QwtPlotGrid`, `QwtPlotMarker`, `QwtPlotSeriesItem` and `QwtPlotCurve`.
779
781
 
780
782
  See "Overview" section in [documentation](https://pythonqwt.readthedocs.io/en/latest/) for more details on API limitations when comparing to Qwt.
781
783
 
@@ -798,14 +800,14 @@ Compatibility table:
798
800
 
799
801
  | PythonQwt version | PyQt5 | PyQt6 | PySide2 | PySide6 |
800
802
  |-------------------|-------|-------|---------|---------|
801
- | 0.16 and earlier | ✅ | ⚠️ | ❌ | ⚠️ |
803
+ | 0.15 and earlier | ✅ | ⚠️ | ❌ | ⚠️ |
802
804
  | Latest | ✅ | ✅ | ❌ | ✅ |
803
805
 
804
806
  ### Requirements
805
807
 
806
808
  - Python >=3.9
807
- - QtPy >= 1.3 (and a Python-to-Qt binding library, see above)
808
- - NumPy >= 1.5
809
+ - QtPy >= 1.9 (and a Python-to-Qt binding library, see above)
810
+ - NumPy >= 1.21
809
811
 
810
812
  ### Optional dependencies
811
813
 
@@ -814,12 +816,22 @@ Compatibility table:
814
816
 
815
817
  ### Installation
816
818
 
819
+ From PyPI:
820
+
821
+ ```bash
822
+ pip install PythonQwt
823
+ ```
824
+
817
825
  From the source package:
818
826
 
819
827
  ```bash
820
828
  python -m build
821
829
  ```
822
830
 
831
+ ## Performance investigation
832
+
833
+ Tooling for performance benchmarks, profiling and visual-regression checks across PyQt5/PyQt6/PySide6 lives in [`scripts/`](scripts/README.md). See [`doc/issue93_optimization_summary.md`](doc/issue93_optimization_summary.md) for a worked example.
834
+
823
835
  ## Copyrights
824
836
 
825
837
  ### Main code base
@@ -1,17 +1,17 @@
1
- pythonqwt-0.14.6.dist-info/licenses/LICENSE,sha256=qjEk8TRuXmFS7QC-omINvD1UPGqWaOs6CzcCZoMEhdI,33457
2
- qwt/__init__.py,sha256=a5liD3yS-S6ffFpj_10aBaFi-Bsia91c0kYYHWZUnZA,5905
1
+ pythonqwt-0.16.0.dist-info/licenses/LICENSE,sha256=qjEk8TRuXmFS7QC-omINvD1UPGqWaOs6CzcCZoMEhdI,33457
2
+ qwt/__init__.py,sha256=wOp2xyXj0loXQntSFHwu_OzVj09zvQ6n-BLp46BXy68,5990
3
3
  qwt/_math.py,sha256=fNcPJcaK-ldCCFB20T2N58LEkQ1lwZY1-q5veXXhwl8,1501
4
4
  qwt/color_map.py,sha256=fLRpymqOXtLrhuPrbbCxTvNINbr2GH7pYBG4fZidrcs,11812
5
5
  qwt/column_symbol.py,sha256=0aFyQ05ryTKbaSTctkhtXa0pB_tWG444zlH3991_bt0,5760
6
6
  qwt/dyngrid_layout.py,sha256=wgff6mZ1okNhQRRbwaw1I__vOXqGdUG0uafkShuns08,13477
7
- qwt/graphic.py,sha256=lISwinyParPXoJCL8D_9x9Q0JyJVeykrTWSm1Ubluzo,28177
7
+ qwt/graphic.py,sha256=rSxvgIAm9ctcyszvZrN_03KpBhKSHabbPYdcrztSta8,28962
8
8
  qwt/interval.py,sha256=PMrCQxV9NXGk2JG0MNjJ3zGTNTSSRfa_noxbpm-Okns,12287
9
9
  qwt/legend.py,sha256=GBUim67HWgwLat5tOWDpK98fWcFxV-RkxWjoyWd9Gao,31313
10
- qwt/null_paintdevice.py,sha256=AAVyQCVgZKyIw7i-J9ElB0_-8KRV9OXDr140TwMxLSs,9144
10
+ qwt/null_paintdevice.py,sha256=1pgbcvyRTVN32RGzuPzUOm0iUImjvPQ4l5OfJVyA3hg,9375
11
11
  qwt/painter.py,sha256=k345puF4MAoTye0WBveiTNpCNWXx1K2o62_I0PZYlIA,16536
12
- qwt/painter_command.py,sha256=b_uZb56YlzYFG3ZmB5ykjkBQQAadQD8epknsQSEai54,6957
13
- qwt/plot.py,sha256=v2q7VU2GIGrssKexYGEilH9ToKL4_ekubOno_qxt43M,75665
14
- qwt/plot_canvas.py,sha256=PiIRrdZsK1YcV5cQkIpz6H5H6A-dTr2HUJ5MHvDHDG0,30312
12
+ qwt/painter_command.py,sha256=7D3goNsX_2Ufr5kCpC3Cr1t8GoD5Yz0G1oIZJKvoGBY,8501
13
+ qwt/plot.py,sha256=d8rf4F-fpQgdpTTqNKQFJh7B0FlQ4WlquooeJQRn_eo,75660
14
+ qwt/plot_canvas.py,sha256=INRcxB17dvyGI7Jqi2FX4gm16EG4gzJKULj9inHkibA,30309
15
15
  qwt/plot_curve.py,sha256=ThlfxUjB4yiP_Dh96P7PXusyqUfDWcRcyt31OHvu2vk,37059
16
16
  qwt/plot_directpainter.py,sha256=JCWNhCC21L1A1HZnxd-C95QNlrVJbLztmGab-X8gCGc,10165
17
17
  qwt/plot_grid.py,sha256=h-cDTzibEzQyX2g25SBg5ysyXwmONmMFy9NcuzFySYc,16607
@@ -20,22 +20,22 @@ qwt/plot_marker.py,sha256=6vDHdMsyGClMruWLA4lChUCpoLzmxGNkvmICm0KjP6I,21284
20
20
  qwt/plot_renderer.py,sha256=v-fSwicMGQBa_kQx4hJJptlVNpNsKbgWk9jjqG-r_1g,27201
21
21
  qwt/plot_series.py,sha256=Wa_Wunu-t_L8vl95RJq6__k-XA8UV2YNIsc8yNGpTT8,10654
22
22
  qwt/qthelpers.py,sha256=GpvLr96Ip8SIGwyFfs0f7ocHyKPB7PEjHBQyrpw84xw,1405
23
- qwt/scale_div.py,sha256=2Ay5mgduXgSm4OrDMcaEWIzenAiBuEASZRoX99PWEE4,9276
24
- qwt/scale_draw.py,sha256=DvknvoOpEerVqplH-fbEtXQlXrFebUGz-1eS5qJdDWI,36760
25
- qwt/scale_engine.py,sha256=HOw5rLriO81p6CyeG9FdZzb0OVBkO9Y4-AQz33GZj-0,30002
26
- qwt/scale_map.py,sha256=WobkNna6_RPXYZjGK7gZLykNxN_kYnrcB6fEaWgnL2w,9182
23
+ qwt/scale_div.py,sha256=_iI5cy4s8H6wigE8xsn7W44T2-DqVADqdjQ31uJPa_I,9266
24
+ qwt/scale_draw.py,sha256=iO39q7nXJRuFTYan3m5taAGqvmzCq2JX0PhySWtAYVo,41007
25
+ qwt/scale_engine.py,sha256=7KQB5k-JXuJMsEMQXBJBNppCN-rTN97UKQCYXdazvqQ,36674
26
+ qwt/scale_map.py,sha256=rHmPv7e9voEFuAIInQJq60mTtIGrLMViNlgJYu20znA,9605
27
27
  qwt/scale_widget.py,sha256=p202DrRgMraGbVcubzkatvVXOLbO9CPho729hz6gqa0,27125
28
28
  qwt/symbol.py,sha256=DIXtIOgniO70pScKF-H_mee8GgBuycW3YcsopvfCRGY,39147
29
- qwt/text.py,sha256=az72KWz_zODR4gIFvHlN3fODe0yQRZMK8ymu3Y2AeEc,42197
29
+ qwt/text.py,sha256=isLS7UmbJrAmOoxhszPwrkJSRTh5WFmqVkbz_npIi94,48099
30
30
  qwt/toqimage.py,sha256=H2u_qDt32n7HGZakWvs3Ve0G3u04Uk2ZQYp8MuZkkmU,1723
31
31
  qwt/transform.py,sha256=bFkdmI2wDjOJrUZU6E9-sAvwoo_umXycxq6LPvD6N_c,6078
32
32
  qwt/tests/__init__.py,sha256=diBkA_H_Xuxb84tNelsNU4djTlUnKJ5HZNZr02EwnjE,1102
33
33
  qwt/tests/comparative_benchmarks.py,sha256=hlLFkyWzadbUyUX2vka_l2bdcGe8U9sOKBDny3o3U40,1821
34
- qwt/tests/conftest.py,sha256=akpTe2ofWLsMKqpbxqYURpLOmCdEdXa8MccB1E0GG5M,1690
34
+ qwt/tests/conftest.py,sha256=LwqVA58_Cv7Fitpcn9bGdhbWDBwID_3gaZg2LkJQtGQ,2196
35
35
  qwt/tests/test_backingstore.py,sha256=AIiRPqcNPY1riXSQXU43tqB2_z02PhxmK1zA4OxQixM,524
36
- qwt/tests/test_bodedemo.py,sha256=bOIApjBQA1J4aZkVBnzByiKqhqEcmQpag1TvIfsuHMs,9386
36
+ qwt/tests/test_bodedemo.py,sha256=A9iZ4FmTmn96YAwxeIQIPBwIZtj4Jk_ftB78bJAIV_c,9367
37
37
  qwt/tests/test_cartesian.py,sha256=0VCrvclqbQJSEGhWpZLq6brA9Qm9oRIgluEBbxOTOds,3855
38
- qwt/tests/test_cpudemo.py,sha256=E2kwRO6sUh9WSZ08FABmQBhfH2bQ49JCYXPUpoonAS0,12846
38
+ qwt/tests/test_cpudemo.py,sha256=1XECvuJwOzMjI5JWCBUwvnQ6dCkcDEqZlhQ7KU8N-Rs,12853
39
39
  qwt/tests/test_curvebenchmark1.py,sha256=a53CvA149Ng1Vj4oruKo4Gp952-0A5gLXvRPOiNSYQk,5891
40
40
  qwt/tests/test_curvebenchmark2.py,sha256=5TYkVuWuP8-Tp7gphsaF_ys3cufHkzKstFDHb9BCOAg,2720
41
41
  qwt/tests/test_curvedemo1.py,sha256=3jAq_pQ52F2HyO3WlDWUn43vNVw8q_g5OQ_hcseaD4s,4181
@@ -49,7 +49,7 @@ qwt/tests/test_loadtest.py,sha256=ZTHatcGAbLyvS0BpbOWbzPD2Bjz4rckF7oxZsUVQ5KM,18
49
49
  qwt/tests/test_logcurve.py,sha256=XOtR0asSqFfzc0VL0qfXN0fXNvxvLnz5fxmNZ2gzQWk,1129
50
50
  qwt/tests/test_mapdemo.py,sha256=e7rvB8IPKYVVii8UgdHSbOHLc3i7eB21EQNKZ151Kc8,3423
51
51
  qwt/tests/test_multidemo.py,sha256=YS-P08qcakD41OJy6ZI53ofKOnUvD-2_uum0yOLiIRc,2530
52
- qwt/tests/test_relativemargin.py,sha256=E2PqK4e8Ml-NZGuhslBlCsIPEcFm08nLwsn0jZT_h70,2093
52
+ qwt/tests/test_relativemargin.py,sha256=Shn0aE7UeETSSaQFpt4DrMOFeMN3p4rmEHKqPhXfQTI,2097
53
53
  qwt/tests/test_simple.py,sha256=4opQp_-RkcVdpRyYSh89ddBkeXCPrppB-_2KTiu5vjI,2347
54
54
  qwt/tests/test_stylesheet.py,sha256=cuL1iY4pp5ZoMX4OI86amJA6R5SzQsH1JUWLtEiitZ4,950
55
55
  qwt/tests/test_symbols.py,sha256=YcGM0_Em8QtcbqpLSU98PxvGo7BIIYviP2o_4Fg2LbI,5607
@@ -77,8 +77,8 @@ qwt/tests/data/symbol.svg,sha256=ONkkohVqpg3OO2-XEZge7UZLqqNyOQXbSpLgHXcTBFU,127
77
77
  qwt/tests/data/symbols.png,sha256=wiqRBc2MJluJ-am9LtZ0K9DHV9BnreYMiEvfzJUFzCk,55586
78
78
  qwt/tests/data/testlauncher.png,sha256=WmucObp30QYYKsVRBs5-6t1aEN0FbIWRmOVFN1gt-vQ,139676
79
79
  qwt/tests/data/vertical.png,sha256=EvyG6q6rZm6pTT08Y_nzdBYCnqmoX1QDuEQtp2pyGlw,34076
80
- pythonqwt-0.14.6.dist-info/METADATA,sha256=-YHQhSyIvk9fATfIWno1n-IEp27v-UYBrhHPq4LzCe4,45099
81
- pythonqwt-0.14.6.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
82
- pythonqwt-0.14.6.dist-info/entry_points.txt,sha256=pdPda-YcYigCi00hR4tMxWKu6byxM2x3zA8BQFDYvwI,46
83
- pythonqwt-0.14.6.dist-info/top_level.txt,sha256=KB1IBdWRWnaItyJMaECwZiEi1jWt3IvqCrRVVhMjTu8,4
84
- pythonqwt-0.14.6.dist-info/RECORD,,
80
+ pythonqwt-0.16.0.dist-info/METADATA,sha256=jjr2ZDxH0abEGbmHoFLQsXEbk8X-3FLRTRqajqSnqDk,45515
81
+ pythonqwt-0.16.0.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
82
+ pythonqwt-0.16.0.dist-info/entry_points.txt,sha256=pdPda-YcYigCi00hR4tMxWKu6byxM2x3zA8BQFDYvwI,46
83
+ pythonqwt-0.16.0.dist-info/top_level.txt,sha256=KB1IBdWRWnaItyJMaECwZiEi1jWt3IvqCrRVVhMjTu8,4
84
+ pythonqwt-0.16.0.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.9.0)
2
+ Generator: setuptools (82.0.1)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
qwt/__init__.py CHANGED
@@ -22,8 +22,8 @@ External resources:
22
22
  * Project page on GitHub: `GitHubPage`_
23
23
  * Bug reports and feature requests: `GitHub`_
24
24
 
25
- .. _PyPI: https://pypi.python.org/pypi/PythonQwt
26
- .. _GitHubPage: http://pierreraybaut.github.io/PythonQwt
25
+ .. _PyPI: https://pypi.org/project/PythonQwt/
26
+ .. _GitHubPage: https://github.com/PlotPyStack/PythonQwt
27
27
  .. _GitHub: https://github.com/PlotPyStack/PythonQwt
28
28
  """
29
29
 
@@ -48,14 +48,22 @@ from qwt.plot_series import ( # noqa: F401
48
48
  QwtSeriesStore,
49
49
  )
50
50
  from qwt.scale_div import QwtScaleDiv # noqa: F401
51
- from qwt.scale_draw import QwtAbstractScaleDraw, QwtScaleDraw # noqa: F401
52
- from qwt.scale_engine import QwtLinearScaleEngine, QwtLogScaleEngine # noqa: F401
51
+ from qwt.scale_draw import ( # noqa: F401
52
+ QwtAbstractScaleDraw,
53
+ QwtDateTimeScaleDraw,
54
+ QwtScaleDraw,
55
+ )
56
+ from qwt.scale_engine import ( # noqa: F401
57
+ QwtDateTimeScaleEngine,
58
+ QwtLinearScaleEngine,
59
+ QwtLogScaleEngine,
60
+ )
53
61
  from qwt.scale_map import QwtScaleMap # noqa: F401
54
62
  from qwt.symbol import QwtSymbol as QSbl # see deprecated section
55
63
  from qwt.text import QwtText # noqa: F401
56
64
  from qwt.toqimage import array_to_qimage as toQImage # noqa: F401
57
65
 
58
- __version__ = "0.14.6"
66
+ __version__ = "0.16.0"
59
67
  QWT_VERSION_STR = "6.1.5"
60
68
 
61
69
 
qwt/graphic.py CHANGED
@@ -26,7 +26,23 @@ from qtpy.QtGui import (
26
26
  )
27
27
 
28
28
  from qwt.null_paintdevice import QwtNullPaintDevice
29
- from qwt.painter_command import QwtPainterCommand
29
+ from qwt.painter_command import QwtPainterCommand, _flag_int
30
+
31
+ # See painter_command.py for the rationale: cache the QPaintEngine.DirtyXxx
32
+ # flags as plain ints so the State-replay branch below does plain int bitwise
33
+ # tests instead of going through Python's enum.Flag.__and__ on PyQt6.
34
+ _DIRTY_PEN = _flag_int(QPaintEngine.DirtyPen)
35
+ _DIRTY_BRUSH = _flag_int(QPaintEngine.DirtyBrush)
36
+ _DIRTY_BRUSH_ORIGIN = _flag_int(QPaintEngine.DirtyBrushOrigin)
37
+ _DIRTY_FONT = _flag_int(QPaintEngine.DirtyFont)
38
+ _DIRTY_BACKGROUND = _flag_int(QPaintEngine.DirtyBackground)
39
+ _DIRTY_TRANSFORM = _flag_int(QPaintEngine.DirtyTransform)
40
+ _DIRTY_CLIP_ENABLED = _flag_int(QPaintEngine.DirtyClipEnabled)
41
+ _DIRTY_CLIP_REGION = _flag_int(QPaintEngine.DirtyClipRegion)
42
+ _DIRTY_CLIP_PATH = _flag_int(QPaintEngine.DirtyClipPath)
43
+ _DIRTY_HINTS = _flag_int(QPaintEngine.DirtyHints)
44
+ _DIRTY_COMPOSITION_MODE = _flag_int(QPaintEngine.DirtyCompositionMode)
45
+ _DIRTY_OPACITY = _flag_int(QPaintEngine.DirtyOpacity)
30
46
 
31
47
 
32
48
  def qwtHasScalablePen(painter):
@@ -83,35 +99,36 @@ def qwtExecCommand(painter, cmd, renderHints, transform, initialTransform):
83
99
  painter.drawImage(data.rect, data.image, data.subRect, data.flags)
84
100
  elif cmd.type() == QwtPainterCommand.State:
85
101
  data = cmd.stateData()
86
- if data.flags & QPaintEngine.DirtyPen:
102
+ flags = _flag_int(data.flags)
103
+ if flags & _DIRTY_PEN:
87
104
  painter.setPen(data.pen)
88
- if data.flags & QPaintEngine.DirtyBrush:
105
+ if flags & _DIRTY_BRUSH:
89
106
  painter.setBrush(data.brush)
90
- if data.flags & QPaintEngine.DirtyBrushOrigin:
107
+ if flags & _DIRTY_BRUSH_ORIGIN:
91
108
  painter.setBrushOrigin(data.brushOrigin)
92
- if data.flags & QPaintEngine.DirtyFont:
109
+ if flags & _DIRTY_FONT:
93
110
  painter.setFont(data.font)
94
- if data.flags & QPaintEngine.DirtyBackground:
111
+ if flags & _DIRTY_BACKGROUND:
95
112
  painter.setBackgroundMode(data.backgroundMode)
96
113
  painter.setBackground(data.backgroundBrush)
97
- if data.flags & QPaintEngine.DirtyTransform:
114
+ if flags & _DIRTY_TRANSFORM:
98
115
  painter.setTransform(data.transform)
99
- if data.flags & QPaintEngine.DirtyClipEnabled:
116
+ if flags & _DIRTY_CLIP_ENABLED:
100
117
  painter.setClipping(data.isClipEnabled)
101
- if data.flags & QPaintEngine.DirtyClipRegion:
118
+ if flags & _DIRTY_CLIP_REGION:
102
119
  painter.setClipRegion(data.clipRegion, data.clipOperation)
103
- if data.flags & QPaintEngine.DirtyClipPath:
120
+ if flags & _DIRTY_CLIP_PATH:
104
121
  painter.setClipPath(data.clipPath, data.clipOperation)
105
- if data.flags & QPaintEngine.DirtyHints:
122
+ if flags & _DIRTY_HINTS:
106
123
  for hint in (
107
124
  QPainter.Antialiasing,
108
125
  QPainter.TextAntialiasing,
109
126
  QPainter.SmoothPixmapTransform,
110
127
  ):
111
128
  painter.setRenderHint(hint, bool(data.renderHints & hint))
112
- if data.flags & QPaintEngine.DirtyCompositionMode:
129
+ if flags & _DIRTY_COMPOSITION_MODE:
113
130
  painter.setCompositionMode(data.compositionMode)
114
- if data.flags & QPaintEngine.DirtyOpacity:
131
+ if flags & _DIRTY_OPACITY:
115
132
  painter.setOpacity(data.opacity)
116
133
 
117
134
 
qwt/null_paintdevice.py CHANGED
@@ -272,8 +272,12 @@ class QwtNullPaintDevice(QPaintDevice):
272
272
  * 25.4
273
273
  / self.metric(QPaintDevice.PdmDpiY)
274
274
  )
275
+ elif deviceMetric == QPaintDevice.PdmDevicePixelRatio:
276
+ value = 1
277
+ elif deviceMetric == QPaintDevice.PdmDevicePixelRatioScaled:
278
+ value = 1
275
279
  else:
276
- value = 0
280
+ value = super(QwtNullPaintDevice, self).metric(deviceMetric)
277
281
  return value
278
282
 
279
283
  def drawRects(self, rects, rectCount):
qwt/painter_command.py CHANGED
@@ -18,6 +18,40 @@ import copy
18
18
  from qtpy.QtGui import QPaintEngine, QPainterPath
19
19
 
20
20
 
21
+ def _flag_int(flag):
22
+ """Return the integer value of a Qt enum/flag (PyQt5 and PyQt6).
23
+
24
+ PyQt5 exposes Qt enums as plain ints (``int(flag)`` works). PyQt6 wraps
25
+ them as ``enum.Flag`` instances which are not ``int`` subclasses, so
26
+ ``int(flag)`` raises -- the value must be read from ``flag.value``.
27
+ """
28
+ try:
29
+ return flag.value
30
+ except AttributeError:
31
+ return int(flag)
32
+
33
+
34
+ # Cache QPaintEngine.DirtyXxx flags as plain Python ints once at import time.
35
+ # On PyQt6, Qt enums are full ``enum.Flag`` instances and every ``flags &
36
+ # Member`` test goes through Python's ``enum.__and__`` machinery (~6 us each).
37
+ # In ``QwtPainterCommand.__init__`` below, the State branch performs twelve
38
+ # successive flag tests per painter command -- on PyQt6 alone this accounted
39
+ # for ~20 ms of the residual perf gap on the load test. Casting once to int
40
+ # and bitwise-testing against int constants brings each test back to ~50 ns.
41
+ _DIRTY_PEN = _flag_int(QPaintEngine.DirtyPen)
42
+ _DIRTY_BRUSH = _flag_int(QPaintEngine.DirtyBrush)
43
+ _DIRTY_BRUSH_ORIGIN = _flag_int(QPaintEngine.DirtyBrushOrigin)
44
+ _DIRTY_FONT = _flag_int(QPaintEngine.DirtyFont)
45
+ _DIRTY_BACKGROUND = _flag_int(QPaintEngine.DirtyBackground)
46
+ _DIRTY_TRANSFORM = _flag_int(QPaintEngine.DirtyTransform)
47
+ _DIRTY_CLIP_ENABLED = _flag_int(QPaintEngine.DirtyClipEnabled)
48
+ _DIRTY_CLIP_REGION = _flag_int(QPaintEngine.DirtyClipRegion)
49
+ _DIRTY_CLIP_PATH = _flag_int(QPaintEngine.DirtyClipPath)
50
+ _DIRTY_HINTS = _flag_int(QPaintEngine.DirtyHints)
51
+ _DIRTY_COMPOSITION_MODE = _flag_int(QPaintEngine.DirtyCompositionMode)
52
+ _DIRTY_OPACITY = _flag_int(QPaintEngine.DirtyOpacity)
53
+
54
+
21
55
  class PixmapData(object):
22
56
  def __init__(self):
23
57
  self.rect = None
@@ -125,32 +159,35 @@ class QwtPainterCommand(object):
125
159
  self.__type = self.State
126
160
  self.__stateData = StateData()
127
161
  self.__stateData.flags = state.state()
128
- if self.__stateData.flags & QPaintEngine.DirtyPen:
162
+ # Cast to int once: subsequent bitwise tests are done against
163
+ # the cached _DIRTY_* int constants (see top of module).
164
+ flags = _flag_int(self.__stateData.flags)
165
+ if flags & _DIRTY_PEN:
129
166
  self.__stateData.pen = state.pen()
130
- if self.__stateData.flags & QPaintEngine.DirtyBrush:
167
+ if flags & _DIRTY_BRUSH:
131
168
  self.__stateData.brush = state.brush()
132
- if self.__stateData.flags & QPaintEngine.DirtyBrushOrigin:
169
+ if flags & _DIRTY_BRUSH_ORIGIN:
133
170
  self.__stateData.brushOrigin = state.brushOrigin()
134
- if self.__stateData.flags & QPaintEngine.DirtyFont:
171
+ if flags & _DIRTY_FONT:
135
172
  self.__stateData.font = state.font()
136
- if self.__stateData.flags & QPaintEngine.DirtyBackground:
173
+ if flags & _DIRTY_BACKGROUND:
137
174
  self.__stateData.backgroundMode = state.backgroundMode()
138
175
  self.__stateData.backgroundBrush = state.backgroundBrush()
139
- if self.__stateData.flags & QPaintEngine.DirtyTransform:
176
+ if flags & _DIRTY_TRANSFORM:
140
177
  self.__stateData.transform = state.transform()
141
- if self.__stateData.flags & QPaintEngine.DirtyClipEnabled:
178
+ if flags & _DIRTY_CLIP_ENABLED:
142
179
  self.__stateData.isClipEnabled = state.isClipEnabled()
143
- if self.__stateData.flags & QPaintEngine.DirtyClipRegion:
180
+ if flags & _DIRTY_CLIP_REGION:
144
181
  self.__stateData.clipRegion = state.clipRegion()
145
182
  self.__stateData.clipOperation = state.clipOperation()
146
- if self.__stateData.flags & QPaintEngine.DirtyClipPath:
183
+ if flags & _DIRTY_CLIP_PATH:
147
184
  self.__stateData.clipPath = state.clipPath()
148
185
  self.__stateData.clipOperation = state.clipOperation()
149
- if self.__stateData.flags & QPaintEngine.DirtyHints:
186
+ if flags & _DIRTY_HINTS:
150
187
  self.__stateData.renderHints = state.renderHints()
151
- if self.__stateData.flags & QPaintEngine.DirtyCompositionMode:
188
+ if flags & _DIRTY_COMPOSITION_MODE:
152
189
  self.__stateData.compositionMode = state.compositionMode()
153
- if self.__stateData.flags & QPaintEngine.DirtyOpacity:
190
+ if flags & _DIRTY_OPACITY:
154
191
  self.__stateData.opacity = state.opacity()
155
192
  elif len(args) == 3:
156
193
  rect, pixmap, subRect = args
qwt/plot.py CHANGED
@@ -132,8 +132,8 @@ class QwtPlot(QFrame):
132
132
  x = np.linspace(-10, 10, 500)
133
133
  plot = qwt.QwtPlot("Trigonometric functions")
134
134
  plot.insertLegend(qwt.QwtLegend(), qwt.QwtPlot.BottomLegend)
135
- qwt.QwtPlotCurve.make(x, np.cos(x), "Cosinus", plot, linecolor="red", antialiased=True)
136
- qwt.QwtPlotCurve.make(x, np.sin(x), "Sinus", plot, linecolor="blue", antialiased=True)
135
+ qwt.QwtPlotCurve.make(x, np.cos(x), "Cosine", plot, linecolor="red", antialiased=True)
136
+ qwt.QwtPlotCurve.make(x, np.sin(x), "Sine", plot, linecolor="blue", antialiased=True)
137
137
  plot.resize(600, 300)
138
138
  plot.show()
139
139
 
@@ -2137,7 +2137,7 @@ class QwtPlotItem(object):
2137
2137
  import warnings
2138
2138
 
2139
2139
  warnings.warn(
2140
- "`setAxis` has been removed in Qwt6: " "please use `setAxes` instead",
2140
+ "`setAxis` has been removed in Qwt6: please use `setAxes` instead",
2141
2141
  RuntimeWarning,
2142
2142
  )
2143
2143
  self.setAxes(xAxis, yAxis)
qwt/plot_canvas.py CHANGED
@@ -787,7 +787,7 @@ class QwtPlotCanvas(QFrame):
787
787
  import warnings
788
788
 
789
789
  warnings.warn(
790
- "`invalidatePaintCache` has been removed: " "please use `replot` instead",
790
+ "`invalidatePaintCache` has been removed: please use `replot` instead",
791
791
  RuntimeWarning,
792
792
  )
793
793
  self.replot()
qwt/scale_div.py CHANGED
@@ -235,9 +235,11 @@ class QwtScaleDiv(object):
235
235
  :param float value: Value
236
236
  :return: True/False
237
237
  """
238
- min_ = min([self.__lowerBound, self.__upperBound])
239
- max_ = max([self.__lowerBound, self.__upperBound])
240
- return value >= min_ and value <= max_
238
+ lb = self.__lowerBound
239
+ ub = self.__upperBound
240
+ if lb <= ub:
241
+ return lb <= value <= ub
242
+ return ub <= value <= lb
241
243
 
242
244
  def invert(self):
243
245
  """