Repository: pymeasure/pymeasure

Issue:
Python 3.10: ManagedWindow TypeError
Hi all,
I am trying to use pymeasure for the first time. But when running the example "ManagedWindow" I get the following error message as soon as I press the "queue" button in the GUI and nothing will be plotted. 

```
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
C:\Program Files\Python 3.10\lib\site-packages\pymeasure\display\manager.py in _update_progress(self, progress)
    158     def _update_progress(self, progress):
    159         if self.is_running():
--> 160             self._running_experiment.browser_item.setProgress(progress)
    161 
    162     def _update_status(self, status):

C:\Program Files\Python 3.10\lib\site-packages\pymeasure\display\browser.py in setProgress(self, progress)
     73 
     74     def setProgress(self, progress):
---> 75         self.progressbar.setValue(progress)
     76 
     77 class Browser(QtGui.QTreeWidget):

TypeError: setValue(self, int): argument 1 has unexpected type 'float'---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
C:\Program Files\Python 3.10\lib\site-packages\pymeasure\display\manager.py in _finish(self)
    253         experiment = self._running_experiment
    254         self._clean_up()
--> 255         experiment.browser_item.setProgress(100.)
    256         experiment.curve.update()
    257         self.finished.emit(experiment)

C:\Program Files\Python 3.10\lib\site-packages\pymeasure\display\browser.py in setProgress(self, progress)
     73 
     74     def setProgress(self, progress):
---> 75         self.progressbar.setValue(progress)
     76 
     77 class Browser(QtGui.QTreeWidget):

TypeError: setValue(self, int): argument 1 has unexpected type 'float'An exception has occurred, use %tb to see the full traceback.
```

I'm using Windows and Python 3.10.

Do you have an idea what is wrong? Probably something with the data type of progress. But what should I change? 
Thanks for your help.


Discussion:
Are you using PyQt or PySide2 as Qt bindings ? Which version ?

Thank your for your help.
I'm using PyQt5. 
It seems that the `setValue` method of `QProgressBar()` refuse to accept `float` value. This is indeed very strange since, it should be automatically converted to `int`. I could suggest to have a look at link:
  https://www.geeksforgeeks.org/pyqt5-how-to-display-decimal-values-in-progress-bar/ (indeed this link discuss how the opposite problem, but it contains a simple example on how to use a `QProgressBar`).
I could suggest to run a simple `PyQt` code with `QProgressBar` passing a float value to `setValue` and check if it works.
I tried different things, it is working now without the progressbar.
First I tried the progressbar function as you suggested. The following code works completely fine:

```
import sys
import time

from PyQt5.QtWidgets import QApplication, QDialog, QProgressBar, QPushButton

TIME_LIMIT = 100

class Actions(QDialog):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        self.setWindowTitle('Progress Bar')
        self.progress = QProgressBar(self)
        self.progress.setGeometry(0, 0, 300, 25)
        self.progress.setMaximum(100)
        self.button = QPushButton('Start', self)
        self.button.move(0, 30)
        self.show()

        self.button.clicked.connect(self.onButtonClick)

    def onButtonClick(self):
        count = 0
        while count < TIME_LIMIT:
            count += 1
            time.sleep(0.1)
            self.progress.setValue(count)

if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = Actions()
    sys.exit(app.exec_())
```

If I change the count value from "0" to "0.", it doesn't work anymore. So it looks like the progressbar doesn't like float values.

The code from the [PyMeasure Tutorial](https://pymeasure.readthedocs.io/en/latest/tutorial/graphical.html#using-the-managedwindow) still doesn't work. So instead of the pymeasure.display.Qt library I used the PyQt5 library and changed the code from
`from pymeasure.display.Qt import QtGui` to `from PyQt5.QtWidgets import QApplication, QProgressBar`
Also I had to change the following line:
`app = QtGui.QApplication(sys.argv)` to `app = QApplication(sys.argv)`.

But I got the same error as mentioned above as soon as I click on "queue" in the created window.

The next step was changing the setprogress value from "100." to "100". Also you have to change the following line in manager.py
from `self._running_experiment.browser_item.setProgress(progress)` to `self._running_experiment.browser_item.setProgress(int(progress))`.
Now all errors are gone, but the progressbar now only switches between 0% and 100%.
I don't know what is wrong or anything. But at least it's usable at the moment.

The program that you linked doesn't work too. If I change the "75.55" to "75" it works. The error message is:
```
[Command: python -u E:\Projekte\Atom\34410A\progressbar.py]
Traceback (most recent call last):
  File "E:\Projekte\Atom\34410A\progressbar.py", line 59, in <module>
    window = Window()
  File "E:\Projekte\Atom\34410A\progressbar.py", line 22, in __init__
    self.UiComponents()
  File "E:\Projekte\Atom\34410A\progressbar.py", line 46, in UiComponents
    bar.setValue(value * n)
TypeError: setValue(self, int): argument 1 has unexpected type 'float'
[Finished in 0.092s]
```

If you look into the [documentation for the progressbar class](https://doc.qt.io/qt-5/qprogressbar.html), it's mentioned that only an int value is allowed. Does it work for you? I couldn't find my problem after a short Google search. 
I will double check on my side, but I am 100% sure the example in the tutorial works in Windows. I will get back to you. It could be interesting to know the version of PyQt5 you are using or send the output of: `python -m pip list`
Thank you for your effort, I appreciate it.
Here is my output of the pip list command:
```
Package           Version
----------------- -------
backcall          0.2.0
colorama          0.4.4
debugpy           1.5.1
decorator         5.1.0
entrypoints       0.3
ipykernel         6.5.1
ipython           7.29.0
jedi              0.18.1
jupyter-client    7.1.0
jupyter-core      4.9.1
matplotlib-inline 0.1.3
nest-asyncio      1.5.1
numpy             1.21.4
pandas            1.3.4
parso             0.8.2
pickleshare       0.7.5
pip               21.3.1
prompt-toolkit    3.0.22
Pygments          2.10.0
PyMeasure         0.9.0
PyQt5             5.15.6
PyQt5-Qt5         5.15.2
PyQt5-sip         12.9.0
pyqtgraph         0.12.3
pyserial          3.5
PySide6           6.2.1
python-dateutil   2.8.2
pytz              2021.3
PyVISA            1.11.3
pywin32           302
pyzmq             22.3.0
setuptools        57.4.0
shiboken6         6.2.1
six               1.16.0
tornado           6.1
traitlets         5.1.1
typing_extensions 4.0.0
wcwidth           0.2.5
```

Ok, I think the problem is the version of python. Since in 3.10 the implicit conversion from float to integers has been forbidden (earlier on was a warning), full reference in https://bugs.python.org/issue36048.
I wonder if you can make a quick check with python 3.9.x and confirm. On my side python 3.9.2 in Windows is working OK.
I installed Python 3.9.7 and tried the [progressbar example](https://www.geeksforgeeks.org/pyqt5-how-to-display-decimal-values-in-progress-bar/). This works fine with Python 3.9.7 and PyQt5. But not with Python 3.10 as you already thought.

After that I tried the [ManagedWindow example](https://pymeasure.readthedocs.io/en/latest/tutorial/graphical.html#using-the-managedwindow) from PyMeasure. It works with Python 3.9.7, but the progressbar is 0% for each data point/loop iteration and after the last data point the bar jumps to 100%. So it is the same outcome as my workaround with the int instead of the float value.
I don't care about the progressbar at the moment. I don't know if it's a problem from PyQt, Python or PyMeasure, but something is not right.
Here are two screenshots. The first while running (~60%) and the second one after it's finished.
![python39_xs2MKRHC9C](https://user-images.githubusercontent.com/94990257/143586249-260c879e-d060-4c8b-ae74-7dd5a1895d29.png)
![python39_pmsynwI5Sn](https://user-images.githubusercontent.com/94990257/143586277-705f9115-2d62-4205-abc7-e7a1f215a34d.png)


The fact that the progressbar doesn't update during the experiment is actually "expected behavior" in the example on the docs pages, as the progress is not updated/emitted during the measurement (this needs to be done explicitly in the loop using a line like `self​.​emit​(​'progress'​, ​100​*​i​/​self​.​iterations​)`). In the example 'gui.py' in the examples directory of the git it is actually implemented.

As I recall, this is not the first confusion about this progress bar, so maybe we should make some remark about it in the tutorial (or just add the line to the example).
@CasperSchippers I think your suggestion to update the tutorial is very relevant. I was running the gui.py example instead and I was puzzled why  @Mommes had issues with progress bar updates.
@Mommes, if you want you could try to run the scripts in the example directory https://github.com/pymeasure/pymeasure/tree/v0.9/examples/. They should work out of the box 🙂
Thank you for the really helpful support @msmttchr and @CasperSchippers 
Most of the stuff is working now as intended including the progress bar updates. Only some minor issues with Python 3.10 and float values. With the 3.10 version there are also issues in the Github examples while using the context menu. For example, if you change the axis scaling from automatic to manual and back in gui_sequencer.py you will get an error like this:

```
Traceback (most recent call last):
  File "C:\Program Files\Python 3.10\lib\site-packages\pyqtgraph\graphicsItems\ViewBox\ViewBoxMenu.py", line 101, in viewStateChanged
    self.updateState()
  File "C:\Program Files\Python 3.10\lib\site-packages\pyqtgraph\graphicsItems\ViewBox\ViewBoxMenu.py", line 119, in updateState
    self.ctrl[i].autoPercentSpin.setValue(state['autoRange'][i]*100)
TypeError: setValue(self, int): argument 1 has unexpected type 'float'
```
But the issue exists with all examples that use the library. The examples work with Python 3.9 and it's because of the linked float issue mentioned by @msmttchr.  Just for your information if you want to fix this or if you want to tell the people that they should use Python 3.9.7 instead of Python 3.10.

@CasperSchippers Right now pytest runs cleanly on python 3.9 without any warnings because we are not covering that code. Is there an easy way to add a test that triggers this? There are some qt-related tests already in tests/display, and we have a virtual framebuffer configured in CI.
Or should we just make a quick fix of this and be done with it?
I do think that it would be good to also test qt-related parts; I do have to say that my experience with testing is rather limited so-far that I don't know how to do it (yet). I'm willing to look into it when I have time.
Simultaneously, it might be good to fix this asap, such that python 3.10 can be supported sooner.

Resolving patch:
diff --git a/pymeasure/display/browser.py b/pymeasure/display/browser.py
--- a/pymeasure/display/browser.py
+++ b/pymeasure/display/browser.py
@@ -74,7 +74,7 @@ def setStatus(self, status):
             """)
 
     def setProgress(self, progress):
-        self.progressbar.setValue(progress)
+        self.progressbar.setValue(int(progress))
 
 
 class Browser(QtGui.QTreeWidget):
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -71,6 +71,7 @@
         "Programming Language :: Python :: 3.7",
         "Programming Language :: Python :: 3.8",
         "Programming Language :: Python :: 3.9",
+        "Programming Language :: Python :: 3.10",
         "Topic :: Scientific/Engineering",
     ],
     keywords="measure instrument experiment control automate graph plot"


Test patch: