0
0
mirror of https://github.com/bec-project/bec_widgets.git synced 2025-07-14 11:41:49 +02:00

refactor: migration to qtpy

This commit is contained in:
wyzula-jan
2023-11-13 18:37:32 +01:00
parent 7957d2c566
commit b6f6bc5b20
30 changed files with 108 additions and 100 deletions

View File

@ -5,7 +5,7 @@ from typing import Callable
from bec_lib import BECClient, messages, ServiceConfig from bec_lib import BECClient, messages, ServiceConfig
from bec_lib.redis_connector import RedisConsumerThreaded from bec_lib.redis_connector import RedisConsumerThreaded
from PyQt5.QtCore import QObject, pyqtSignal from qtpy.QtCore import QObject, Signal as pyqtSignal
# Adding a new pyqt signal requres a class factory, as they must be part of the class definition # Adding a new pyqt signal requres a class factory, as they must be part of the class definition
# and cannot be dynamically added as class attributes after the class has been defined. # and cannot be dynamically added as class attributes after the class has been defined.

View File

@ -1,38 +1,39 @@
import signal # TODO haven't found yet how to deal with QAbstractSocket in qtpy
import socket # import signal
from PyQt5.QtNetwork import QAbstractSocket # import socket
# from PyQt5.QtNetwork import QAbstractSocket
#
def setup(app): #
app.signalwatchdog = SignalWatchdog() # need to store to keep socket pair alive # def setup(app):
signal.signal(signal.SIGINT, make_quit_handler(app)) # app.signalwatchdog = SignalWatchdog() # need to store to keep socket pair alive
# signal.signal(signal.SIGINT, make_quit_handler(app))
#
def make_quit_handler(app): #
def handler(*args): # def make_quit_handler(app):
print() # make ^C appear on its own line # def handler(*args):
app.quit() # print() # make ^C appear on its own line
# app.quit()
return handler #
# return handler
#
class SignalWatchdog(QAbstractSocket): #
def __init__(self): # class SignalWatchdog(QAbstractSocket):
""" # def __init__(self):
Propagates system signals from Python to QEventLoop # """
adapted from https://stackoverflow.com/a/65802260/655404 # Propagates system signals from Python to QEventLoop
""" # adapted from https://stackoverflow.com/a/65802260/655404
super().__init__(QAbstractSocket.SctpSocket, None) # """
# super().__init__(QAbstractSocket.SctpSocket, None)
self.writer, self.reader = writer, reader = socket.socketpair() #
writer.setblocking(False) # self.writer, self.reader = writer, reader = socket.socketpair()
# writer.setblocking(False)
fd_writer = writer.fileno() #
fd_reader = reader.fileno() # fd_writer = writer.fileno()
# fd_reader = reader.fileno()
signal.set_wakeup_fd(fd_writer) # Python hook #
self.setSocketDescriptor(fd_reader) # Qt hook # signal.set_wakeup_fd(fd_writer) # Python hook
# self.setSocketDescriptor(fd_reader) # Qt hook
self.readyRead.connect( #
lambda: None # self.readyRead.connect(
) # dummy function call that lets the Python interpreter run # lambda: None
# ) # dummy function call that lets the Python interpreter run

View File

@ -1,7 +1,7 @@
import os import os
import sys import sys
from PyQt5 import QtWidgets, uic from qtpy import QtWidgets, uic
class UI(QtWidgets.QWidget): class UI(QtWidgets.QWidget):

View File

@ -6,10 +6,10 @@ import h5py
import numpy as np import numpy as np
import pyqtgraph as pg import pyqtgraph as pg
import zmq import zmq
from PyQt5.QtCore import pyqtSignal from qtpy.QtCore import Signal as pyqtSignal
from PyQt5.QtCore import pyqtSlot from qtpy.QtCore import Slot as pyqtSlot
from PyQt5.QtGui import QKeySequence from qtpy.QtGui import QKeySequence
from PyQt5.QtWidgets import ( from qtpy.QtWidgets import (
QWidget, QWidget,
QFileDialog, QFileDialog,
QShortcut, QShortcut,
@ -290,7 +290,7 @@ class EigerPlot(QWidget):
if __name__ == "__main__": if __name__ == "__main__":
import sys import sys
from PyQt5.QtWidgets import QApplication from qtpy.QtWidgets import QApplication
app = QApplication(sys.argv) app = QApplication(sys.argv)
plot = EigerPlot() plot = EigerPlot()

View File

@ -5,8 +5,10 @@ import os
import pyqtgraph import pyqtgraph
import pyqtgraph as pg import pyqtgraph as pg
from PyQt5.QtCore import pyqtSignal, pyqtSlot
from PyQt5.QtWidgets import ( from qtpy.QtCore import Signal as pyqtSignal, Slot as pyqtSlot
from qtpy.QtWidgets import (
QApplication, QApplication,
QWidget, QWidget,
QTableWidgetItem, QTableWidgetItem,

View File

@ -1,8 +1,8 @@
# import simulation_progress as SP # import simulation_progress as SP
import numpy as np import numpy as np
import pyqtgraph as pg import pyqtgraph as pg
from PyQt5.QtCore import pyqtSignal, pyqtSlot from qtpy.QtCore import Signal as pyqtSignal, Slot as pyqtSlot
from PyQt5.QtWidgets import ( from qtpy.QtWidgets import (
QApplication, QApplication,
QVBoxLayout, QVBoxLayout,
QWidget, QWidget,

View File

@ -1,7 +1,7 @@
import os import os
from PyQt5 import uic from qtpy import uic
from PyQt5.QtWidgets import QMainWindow, QApplication, QVBoxLayout from qtpy.QtWidgets import QMainWindow, QApplication, QVBoxLayout
from bec_widgets.widgets.monitor import BECMonitor from bec_widgets.widgets.monitor import BECMonitor

View File

@ -5,12 +5,12 @@ from functools import partial
import numpy as np import numpy as np
import pyqtgraph as pg import pyqtgraph as pg
from PyQt5 import QtGui from qtpy import QtGui
from PyQt5.QtCore import QThread, pyqtSlot from qtpy.QtCore import QThread, Slot as pyqtSlot
from PyQt5.QtCore import pyqtSignal, Qt from qtpy.QtCore import Signal as pyqtSignal, Qt
from PyQt5.QtGui import QDoubleValidator from qtpy.QtGui import QDoubleValidator
from PyQt5.QtGui import QKeySequence from qtpy.QtGui import QKeySequence
from PyQt5.QtWidgets import ( from qtpy.QtWidgets import (
QApplication, QApplication,
QWidget, QWidget,
QFileDialog, QFileDialog,
@ -20,8 +20,8 @@ from PyQt5.QtWidgets import (
QPushButton, QPushButton,
QFrame, QFrame,
) )
from PyQt5.QtWidgets import QMessageBox from qtpy.QtWidgets import QMessageBox
from PyQt5.QtWidgets import QShortcut from qtpy.QtWidgets import QShortcut
from pyqtgraph.Qt import QtWidgets, uic, QtCore from pyqtgraph.Qt import QtWidgets, uic, QtCore
from bec_lib import MessageEndpoints, messages from bec_lib import MessageEndpoints, messages

View File

@ -1,11 +1,11 @@
import os import os
import numpy as np import numpy as np
import PyQt5.QtWidgets import qtpy.QtWidgets
import pyqtgraph as pg import pyqtgraph as pg
from bec_lib import MessageEndpoints from bec_lib import MessageEndpoints
from PyQt5.QtCore import pyqtSignal, pyqtSlot from qtpy.QtCore import Signal as pyqtSignal, Slot as pyqtSlot
from PyQt5.QtWidgets import QApplication, QTableWidgetItem, QWidget from qtpy.QtWidgets import QApplication, QTableWidgetItem, QWidget
from pyqtgraph import mkBrush, mkColor, mkPen from pyqtgraph import mkBrush, mkColor, mkPen
from pyqtgraph.Qt import QtCore, uic from pyqtgraph.Qt import QtCore, uic
@ -123,7 +123,7 @@ class PlotApp(QWidget):
) )
def update_table( def update_table(
self, table_widget: PyQt5.QtWidgets.QTableWidget, x: float, y_values: list, column: int self, table_widget: qtpy.QtWidgets.QTableWidget, x: float, y_values: list, column: int
) -> None: ) -> None:
for i, y in enumerate(y_values): for i, y in enumerate(y_values):
table_widget.setItem(i, column, QTableWidgetItem(f"({x}, {y})")) table_widget.setItem(i, column, QTableWidgetItem(f"({x}, {y})"))

View File

@ -1,6 +1,6 @@
import numpy as np import numpy as np
import pyqtgraph as pg import pyqtgraph as pg
from PyQt5.QtWidgets import ( from qtpy.QtWidgets import (
QApplication, QApplication,
QVBoxLayout, QVBoxLayout,
QLabel, QLabel,

View File

@ -9,8 +9,8 @@ import pyqtgraph
import pyqtgraph as pg import pyqtgraph as pg
from bec_lib import messages, MessageEndpoints from bec_lib import messages, MessageEndpoints
from bec_lib.redis_connector import MessageObject, RedisConnector from bec_lib.redis_connector import MessageObject, RedisConnector
from PyQt5.QtCore import pyqtSlot from qtpy.QtCore import Slot as pyqtSlot
from PyQt5.QtWidgets import QCheckBox, QTableWidgetItem from qtpy.QtWidgets import QCheckBox, QTableWidgetItem
from pyqtgraph import mkBrush, mkColor, mkPen from pyqtgraph import mkBrush, mkColor, mkPen
from pyqtgraph.Qt import QtCore, QtWidgets, uic from pyqtgraph.Qt import QtCore, QtWidgets, uic
from pyqtgraph.Qt.QtCore import pyqtSignal from pyqtgraph.Qt.QtCore import pyqtSignal
@ -305,7 +305,7 @@ class StreamPlot(QtWidgets.QWidget):
if __name__ == "__main__": if __name__ == "__main__":
import argparse import argparse
from bec_widgets import ctrl_c # from bec_widgets import ctrl_c # TODO uncomment when ctrl_c is ready to be compatible with qtpy
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
parser.add_argument( parser.add_argument(
@ -319,7 +319,7 @@ if __name__ == "__main__":
client = bec_dispatcher.client client = bec_dispatcher.client
app = QtWidgets.QApplication([]) app = QtWidgets.QApplication([])
ctrl_c.setup(app) # ctrl_c.setup(app) # TODO uncomment when ctrl_c is ready to be compatible with qtpy
plot = StreamPlot(y_value_list=value.signals, client=client) plot = StreamPlot(y_value_list=value.signals, client=client)
bec_dispatcher.connect_slot(plot.new_proj, "px_stream/proj_nr") bec_dispatcher.connect_slot(plot.new_proj, "px_stream/proj_nr")

View File

@ -1,5 +1,5 @@
from PyQt5.QtWidgets import QTableWidget from qtpy.QtWidgets import QTableWidget
from PyQt5.QtCore import Qt from qtpy.QtCore import Qt
class BECTable(QTableWidget): class BECTable(QTableWidget):

View File

@ -1,6 +1,8 @@
import numpy as np import numpy as np
import pyqtgraph as pg import pyqtgraph as pg
from PyQt5.QtCore import QObject, pyqtSignal
# from qtpy.QtCore import QObject, pyqtSignal
from qtpy.QtCore import QObject, Signal as pyqtSignal
class Crosshair(QObject): class Crosshair(QObject):

View File

@ -1,5 +1,8 @@
from PyQt5.QtGui import QDoubleValidator # from qtpy.QtGui import QDoubleValidator
from PyQt5.QtWidgets import QStyledItemDelegate, QLineEdit # from qtpy.QtWidgets import QStyledItemDelegate, QLineEdit
from qtpy.QtGui import QDoubleValidator
from qtpy.QtWidgets import QStyledItemDelegate, QLineEdit
class DoubleValidationDelegate(QStyledItemDelegate): class DoubleValidationDelegate(QStyledItemDelegate):

View File

@ -1,4 +1,4 @@
from PyQt5.QtWidgets import ( from qtpy.QtWidgets import (
QApplication, QApplication,
QWidget, QWidget,
QLineEdit, QLineEdit,

View File

@ -1,5 +1,5 @@
import yaml import yaml
from PyQt5.QtWidgets import QFileDialog from qtpy.QtWidgets import QFileDialog
def load_yaml(instance) -> dict: def load_yaml(instance) -> dict:

View File

@ -1,5 +1,5 @@
from PyQt5.QtDesigner import QPyDesignerCustomWidgetPlugin from qtpy.QtDesigner import QPyDesignerCustomWidgetPlugin
from PyQt5.QtGui import QIcon from qtpy.QtGui import QIcon
from bec_widgets.scan2d_plot import BECScanPlot2D from bec_widgets.scan2d_plot import BECScanPlot2D

View File

@ -1,5 +1,5 @@
from PyQt5.QtDesigner import QPyDesignerCustomWidgetPlugin from qtpy.QtDesigner import QPyDesignerCustomWidgetPlugin
from PyQt5.QtGui import QIcon from qtpy.QtGui import QIcon
from bec_widgets.scan_plot import BECScanPlot from bec_widgets.scan_plot import BECScanPlot

View File

@ -4,7 +4,7 @@ import numpy as np
import pyqtgraph as pg import pyqtgraph as pg
from bec_lib import MessageEndpoints from bec_lib import MessageEndpoints
from bec_lib.logger import bec_logger from bec_lib.logger import bec_logger
from PyQt5.QtCore import pyqtProperty, pyqtSlot from qtpy.QtCore import Property as pyqtProperty, Slot as pyqtSlot
from bec_widgets.bec_dispatcher import bec_dispatcher from bec_widgets.bec_dispatcher import bec_dispatcher
@ -139,7 +139,7 @@ class BECScanPlot2D(pg.GraphicsView):
if __name__ == "__main__": if __name__ == "__main__":
import sys import sys
from PyQt5.QtWidgets import QApplication from qtpy.QtWidgets import QApplication
app = QApplication(sys.argv) app = QApplication(sys.argv)

View File

@ -4,7 +4,7 @@ from threading import RLock
import pyqtgraph as pg import pyqtgraph as pg
from bec_lib import MessageEndpoints from bec_lib import MessageEndpoints
from bec_lib.logger import bec_logger from bec_lib.logger import bec_logger
from PyQt5.QtCore import pyqtProperty, pyqtSlot from qtpy.QtCore import Property as pyqtProperty, Slot as pyqtSlot
from bec_widgets.bec_dispatcher import bec_dispatcher from bec_widgets.bec_dispatcher import bec_dispatcher
@ -138,7 +138,7 @@ class BECScanPlot(pg.GraphicsView):
if __name__ == "__main__": if __name__ == "__main__":
import sys import sys
from PyQt5.QtWidgets import QApplication from qtpy.QtWidgets import QApplication
app = QApplication(sys.argv) app = QApplication(sys.argv)

View File

@ -1,8 +1,8 @@
import os import os
from PyQt5 import uic from qtpy import uic
from PyQt5.QtCore import pyqtSignal from qtpy.QtCore import Signal as pyqtSignal
from PyQt5.QtWidgets import ( from qtpy.QtWidgets import (
QApplication, QApplication,
QWidget, QWidget,
QVBoxLayout, QVBoxLayout,

View File

@ -5,11 +5,11 @@ import pyqtgraph as pg
from pydantic import ValidationError from pydantic import ValidationError
from bec_lib import MessageEndpoints from bec_lib import MessageEndpoints
from PyQt5 import QtCore from qtpy import QtCore
from PyQt5.QtCore import pyqtSignal, pyqtSlot from qtpy.QtCore import Signal as pyqtSignal, Slot as pyqtSlot
from PyQt5.QtWidgets import QApplication, QTableWidgetItem, QWidget, QMessageBox from qtpy.QtWidgets import QApplication, QTableWidgetItem, QWidget, QMessageBox
from pyqtgraph import mkPen, mkBrush from pyqtgraph import mkPen, mkBrush
from PyQt5 import uic from qtpy import uic
from bec_widgets.bec_dispatcher import bec_dispatcher from bec_widgets.bec_dispatcher import bec_dispatcher
from bec_widgets.qt_utils import Crosshair, Colors from bec_widgets.qt_utils import Crosshair, Colors

View File

@ -1,5 +1,5 @@
import msgpack import msgpack
from PyQt5.QtWidgets import ( from qtpy.QtWidgets import (
QApplication, QApplication,
QWidget, QWidget,
QComboBox, QComboBox,

View File

@ -4,7 +4,7 @@ __version__ = "0.31.0"
if __name__ == "__main__": if __name__ == "__main__":
setup( setup(
install_requires=["pydantic", "pyqt5", "pyqtgraph", "bec_lib", "zmq", "h5py"], install_requires=["pydantic", "PyQt6>=6.0", "qtpy", "pyqtgraph", "bec_lib", "zmq", "h5py"],
extras_require={"dev": ["pytest", "pytest-random-order", "coverage", "pytest-qt", "black"]}, extras_require={"dev": ["pytest", "pytest-random-order", "coverage", "pytest-qt", "black"]},
version=__version__, version=__version__,
) )

View File

@ -2,7 +2,7 @@ import os
import yaml import yaml
import pytest import pytest
from PyQt5.QtWidgets import QTabWidget, QTableWidgetItem from qtpy.QtWidgets import QTabWidget, QTableWidgetItem
from bec_widgets.widgets import ConfigDialog from bec_widgets.widgets import ConfigDialog

View File

@ -1,6 +1,6 @@
import numpy as np import numpy as np
import pyqtgraph as pg import pyqtgraph as pg
from PyQt5.QtCore import QPointF from qtpy.QtCore import QPointF
from bec_widgets.qt_utils import Crosshair from bec_widgets.qt_utils import Crosshair

View File

@ -3,7 +3,7 @@ from unittest.mock import MagicMock, patch
import pyqtgraph as pg import pyqtgraph as pg
import pytest import pytest
from PyQt5.QtWidgets import QMessageBox from qtpy.QtWidgets import QMessageBox
from bec_widgets.examples.extreme.extreme import PlotApp, ErrorHandler from bec_widgets.examples.extreme.extreme import PlotApp, ErrorHandler

View File

@ -4,7 +4,7 @@ from unittest.mock import MagicMock
import msgpack import msgpack
import pytest import pytest
from PyQt5.QtWidgets import QLineEdit from qtpy.QtWidgets import QLineEdit
from bec_widgets.widgets import ScanControl from bec_widgets.widgets import ScanControl
from bec_widgets.qt_utils.widget_io import WidgetIO from bec_widgets.qt_utils.widget_io import WidgetIO

View File

@ -1,5 +1,5 @@
import pytest import pytest
from PyQt5.QtWidgets import ( from qtpy.QtWidgets import (
QWidget, QWidget,
QVBoxLayout, QVBoxLayout,
QLineEdit, QLineEdit,

View File

@ -3,7 +3,7 @@ import tempfile
from unittest.mock import patch from unittest.mock import patch
import pytest import pytest
import yaml import yaml
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QPushButton from qtpy.QtWidgets import QWidget, QVBoxLayout, QPushButton
from bec_widgets.qt_utils.yaml_dialog import load_yaml, save_yaml from bec_widgets.qt_utils.yaml_dialog import load_yaml, save_yaml
@ -38,7 +38,7 @@ def test_load_yaml(qtbot, example_widget):
example_widget.import_button.clicked.connect(load_yaml_wrapper) example_widget.import_button.clicked.connect(load_yaml_wrapper)
# Mock user selecting the file in the dialog # Mock user selecting the file in the dialog
with patch("PyQt5.QtWidgets.QFileDialog.getOpenFileName", return_value=(temp_file.name, "")): with patch("qtpy.QtWidgets.QFileDialog.getOpenFileName", return_value=(temp_file.name, "")):
example_widget.import_button.click() example_widget.import_button.click()
assert example_widget.config == {"name": "test", "value": 42} assert example_widget.config == {"name": "test", "value": 42}
@ -59,7 +59,7 @@ def test_save_yaml(qtbot, example_widget):
example_widget.export_button.clicked.connect(save_yaml_wrapper) example_widget.export_button.clicked.connect(save_yaml_wrapper)
# Mock user selecting the file in the dialog # Mock user selecting the file in the dialog
with patch("PyQt5.QtWidgets.QFileDialog.getSaveFileName", return_value=(temp_file_path, "")): with patch("qtpy.QtWidgets.QFileDialog.getSaveFileName", return_value=(temp_file_path, "")):
example_widget.export_button.click() example_widget.export_button.click()
# Check if the data was saved correctly # Check if the data was saved correctly