mirror of
https://github.com/bec-project/bec_widgets.git
synced 2025-07-14 03:31:50 +02:00
refactor: migration to qtpy
This commit is contained in:
@ -5,7 +5,7 @@ from typing import Callable
|
||||
|
||||
from bec_lib import BECClient, messages, ServiceConfig
|
||||
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
|
||||
# and cannot be dynamically added as class attributes after the class has been defined.
|
||||
|
@ -1,38 +1,39 @@
|
||||
import signal
|
||||
import socket
|
||||
from PyQt5.QtNetwork import QAbstractSocket
|
||||
|
||||
|
||||
def setup(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):
|
||||
print() # make ^C appear on its own line
|
||||
app.quit()
|
||||
|
||||
return handler
|
||||
|
||||
|
||||
class SignalWatchdog(QAbstractSocket):
|
||||
def __init__(self):
|
||||
"""
|
||||
Propagates system signals from Python to QEventLoop
|
||||
adapted from https://stackoverflow.com/a/65802260/655404
|
||||
"""
|
||||
super().__init__(QAbstractSocket.SctpSocket, None)
|
||||
|
||||
self.writer, self.reader = writer, reader = socket.socketpair()
|
||||
writer.setblocking(False)
|
||||
|
||||
fd_writer = writer.fileno()
|
||||
fd_reader = reader.fileno()
|
||||
|
||||
signal.set_wakeup_fd(fd_writer) # Python hook
|
||||
self.setSocketDescriptor(fd_reader) # Qt hook
|
||||
|
||||
self.readyRead.connect(
|
||||
lambda: None
|
||||
) # dummy function call that lets the Python interpreter run
|
||||
# TODO haven't found yet how to deal with QAbstractSocket in qtpy
|
||||
# import signal
|
||||
# import socket
|
||||
# from PyQt5.QtNetwork import QAbstractSocket
|
||||
#
|
||||
#
|
||||
# def setup(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):
|
||||
# print() # make ^C appear on its own line
|
||||
# app.quit()
|
||||
#
|
||||
# return handler
|
||||
#
|
||||
#
|
||||
# class SignalWatchdog(QAbstractSocket):
|
||||
# def __init__(self):
|
||||
# """
|
||||
# Propagates system signals from Python to QEventLoop
|
||||
# adapted from https://stackoverflow.com/a/65802260/655404
|
||||
# """
|
||||
# super().__init__(QAbstractSocket.SctpSocket, None)
|
||||
#
|
||||
# self.writer, self.reader = writer, reader = socket.socketpair()
|
||||
# writer.setblocking(False)
|
||||
#
|
||||
# fd_writer = writer.fileno()
|
||||
# fd_reader = reader.fileno()
|
||||
#
|
||||
# signal.set_wakeup_fd(fd_writer) # Python hook
|
||||
# self.setSocketDescriptor(fd_reader) # Qt hook
|
||||
#
|
||||
# self.readyRead.connect(
|
||||
# lambda: None
|
||||
# ) # dummy function call that lets the Python interpreter run
|
||||
|
@ -1,7 +1,7 @@
|
||||
import os
|
||||
import sys
|
||||
|
||||
from PyQt5 import QtWidgets, uic
|
||||
from qtpy import QtWidgets, uic
|
||||
|
||||
|
||||
class UI(QtWidgets.QWidget):
|
||||
|
@ -6,10 +6,10 @@ import h5py
|
||||
import numpy as np
|
||||
import pyqtgraph as pg
|
||||
import zmq
|
||||
from PyQt5.QtCore import pyqtSignal
|
||||
from PyQt5.QtCore import pyqtSlot
|
||||
from PyQt5.QtGui import QKeySequence
|
||||
from PyQt5.QtWidgets import (
|
||||
from qtpy.QtCore import Signal as pyqtSignal
|
||||
from qtpy.QtCore import Slot as pyqtSlot
|
||||
from qtpy.QtGui import QKeySequence
|
||||
from qtpy.QtWidgets import (
|
||||
QWidget,
|
||||
QFileDialog,
|
||||
QShortcut,
|
||||
@ -290,7 +290,7 @@ class EigerPlot(QWidget):
|
||||
|
||||
if __name__ == "__main__":
|
||||
import sys
|
||||
from PyQt5.QtWidgets import QApplication
|
||||
from qtpy.QtWidgets import QApplication
|
||||
|
||||
app = QApplication(sys.argv)
|
||||
plot = EigerPlot()
|
||||
|
@ -5,8 +5,10 @@ import os
|
||||
|
||||
import pyqtgraph
|
||||
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,
|
||||
QWidget,
|
||||
QTableWidgetItem,
|
||||
|
@ -1,8 +1,8 @@
|
||||
# import simulation_progress as SP
|
||||
import numpy as np
|
||||
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,
|
||||
QVBoxLayout,
|
||||
QWidget,
|
||||
|
@ -1,7 +1,7 @@
|
||||
import os
|
||||
|
||||
from PyQt5 import uic
|
||||
from PyQt5.QtWidgets import QMainWindow, QApplication, QVBoxLayout
|
||||
from qtpy import uic
|
||||
from qtpy.QtWidgets import QMainWindow, QApplication, QVBoxLayout
|
||||
|
||||
from bec_widgets.widgets.monitor import BECMonitor
|
||||
|
||||
|
@ -5,12 +5,12 @@ from functools import partial
|
||||
|
||||
import numpy as np
|
||||
import pyqtgraph as pg
|
||||
from PyQt5 import QtGui
|
||||
from PyQt5.QtCore import QThread, pyqtSlot
|
||||
from PyQt5.QtCore import pyqtSignal, Qt
|
||||
from PyQt5.QtGui import QDoubleValidator
|
||||
from PyQt5.QtGui import QKeySequence
|
||||
from PyQt5.QtWidgets import (
|
||||
from qtpy import QtGui
|
||||
from qtpy.QtCore import QThread, Slot as pyqtSlot
|
||||
from qtpy.QtCore import Signal as pyqtSignal, Qt
|
||||
from qtpy.QtGui import QDoubleValidator
|
||||
from qtpy.QtGui import QKeySequence
|
||||
from qtpy.QtWidgets import (
|
||||
QApplication,
|
||||
QWidget,
|
||||
QFileDialog,
|
||||
@ -20,8 +20,8 @@ from PyQt5.QtWidgets import (
|
||||
QPushButton,
|
||||
QFrame,
|
||||
)
|
||||
from PyQt5.QtWidgets import QMessageBox
|
||||
from PyQt5.QtWidgets import QShortcut
|
||||
from qtpy.QtWidgets import QMessageBox
|
||||
from qtpy.QtWidgets import QShortcut
|
||||
from pyqtgraph.Qt import QtWidgets, uic, QtCore
|
||||
|
||||
from bec_lib import MessageEndpoints, messages
|
||||
|
@ -1,11 +1,11 @@
|
||||
import os
|
||||
|
||||
import numpy as np
|
||||
import PyQt5.QtWidgets
|
||||
import qtpy.QtWidgets
|
||||
import pyqtgraph as pg
|
||||
from bec_lib import MessageEndpoints
|
||||
from PyQt5.QtCore import pyqtSignal, pyqtSlot
|
||||
from PyQt5.QtWidgets import QApplication, QTableWidgetItem, QWidget
|
||||
from qtpy.QtCore import Signal as pyqtSignal, Slot as pyqtSlot
|
||||
from qtpy.QtWidgets import QApplication, QTableWidgetItem, QWidget
|
||||
from pyqtgraph import mkBrush, mkColor, mkPen
|
||||
from pyqtgraph.Qt import QtCore, uic
|
||||
|
||||
@ -123,7 +123,7 @@ class PlotApp(QWidget):
|
||||
)
|
||||
|
||||
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:
|
||||
for i, y in enumerate(y_values):
|
||||
table_widget.setItem(i, column, QTableWidgetItem(f"({x}, {y})"))
|
||||
|
@ -1,6 +1,6 @@
|
||||
import numpy as np
|
||||
import pyqtgraph as pg
|
||||
from PyQt5.QtWidgets import (
|
||||
from qtpy.QtWidgets import (
|
||||
QApplication,
|
||||
QVBoxLayout,
|
||||
QLabel,
|
||||
|
@ -9,8 +9,8 @@ import pyqtgraph
|
||||
import pyqtgraph as pg
|
||||
from bec_lib import messages, MessageEndpoints
|
||||
from bec_lib.redis_connector import MessageObject, RedisConnector
|
||||
from PyQt5.QtCore import pyqtSlot
|
||||
from PyQt5.QtWidgets import QCheckBox, QTableWidgetItem
|
||||
from qtpy.QtCore import Slot as pyqtSlot
|
||||
from qtpy.QtWidgets import QCheckBox, QTableWidgetItem
|
||||
from pyqtgraph import mkBrush, mkColor, mkPen
|
||||
from pyqtgraph.Qt import QtCore, QtWidgets, uic
|
||||
from pyqtgraph.Qt.QtCore import pyqtSignal
|
||||
@ -305,7 +305,7 @@ class StreamPlot(QtWidgets.QWidget):
|
||||
if __name__ == "__main__":
|
||||
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.add_argument(
|
||||
@ -319,7 +319,7 @@ if __name__ == "__main__":
|
||||
client = bec_dispatcher.client
|
||||
|
||||
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)
|
||||
|
||||
bec_dispatcher.connect_slot(plot.new_proj, "px_stream/proj_nr")
|
||||
|
@ -1,5 +1,5 @@
|
||||
from PyQt5.QtWidgets import QTableWidget
|
||||
from PyQt5.QtCore import Qt
|
||||
from qtpy.QtWidgets import QTableWidget
|
||||
from qtpy.QtCore import Qt
|
||||
|
||||
|
||||
class BECTable(QTableWidget):
|
||||
|
@ -1,6 +1,8 @@
|
||||
import numpy as np
|
||||
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):
|
||||
|
@ -1,5 +1,8 @@
|
||||
from PyQt5.QtGui import QDoubleValidator
|
||||
from PyQt5.QtWidgets import QStyledItemDelegate, QLineEdit
|
||||
# from qtpy.QtGui import QDoubleValidator
|
||||
# from qtpy.QtWidgets import QStyledItemDelegate, QLineEdit
|
||||
|
||||
from qtpy.QtGui import QDoubleValidator
|
||||
from qtpy.QtWidgets import QStyledItemDelegate, QLineEdit
|
||||
|
||||
|
||||
class DoubleValidationDelegate(QStyledItemDelegate):
|
||||
|
@ -1,4 +1,4 @@
|
||||
from PyQt5.QtWidgets import (
|
||||
from qtpy.QtWidgets import (
|
||||
QApplication,
|
||||
QWidget,
|
||||
QLineEdit,
|
||||
|
@ -1,5 +1,5 @@
|
||||
import yaml
|
||||
from PyQt5.QtWidgets import QFileDialog
|
||||
from qtpy.QtWidgets import QFileDialog
|
||||
|
||||
|
||||
def load_yaml(instance) -> dict:
|
||||
|
@ -1,5 +1,5 @@
|
||||
from PyQt5.QtDesigner import QPyDesignerCustomWidgetPlugin
|
||||
from PyQt5.QtGui import QIcon
|
||||
from qtpy.QtDesigner import QPyDesignerCustomWidgetPlugin
|
||||
from qtpy.QtGui import QIcon
|
||||
|
||||
from bec_widgets.scan2d_plot import BECScanPlot2D
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
from PyQt5.QtDesigner import QPyDesignerCustomWidgetPlugin
|
||||
from PyQt5.QtGui import QIcon
|
||||
from qtpy.QtDesigner import QPyDesignerCustomWidgetPlugin
|
||||
from qtpy.QtGui import QIcon
|
||||
|
||||
from bec_widgets.scan_plot import BECScanPlot
|
||||
|
||||
|
@ -4,7 +4,7 @@ import numpy as np
|
||||
import pyqtgraph as pg
|
||||
from bec_lib import MessageEndpoints
|
||||
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
|
||||
|
||||
@ -139,7 +139,7 @@ class BECScanPlot2D(pg.GraphicsView):
|
||||
if __name__ == "__main__":
|
||||
import sys
|
||||
|
||||
from PyQt5.QtWidgets import QApplication
|
||||
from qtpy.QtWidgets import QApplication
|
||||
|
||||
app = QApplication(sys.argv)
|
||||
|
||||
|
@ -4,7 +4,7 @@ from threading import RLock
|
||||
import pyqtgraph as pg
|
||||
from bec_lib import MessageEndpoints
|
||||
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
|
||||
|
||||
@ -138,7 +138,7 @@ class BECScanPlot(pg.GraphicsView):
|
||||
if __name__ == "__main__":
|
||||
import sys
|
||||
|
||||
from PyQt5.QtWidgets import QApplication
|
||||
from qtpy.QtWidgets import QApplication
|
||||
|
||||
app = QApplication(sys.argv)
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
import os
|
||||
|
||||
from PyQt5 import uic
|
||||
from PyQt5.QtCore import pyqtSignal
|
||||
from PyQt5.QtWidgets import (
|
||||
from qtpy import uic
|
||||
from qtpy.QtCore import Signal as pyqtSignal
|
||||
from qtpy.QtWidgets import (
|
||||
QApplication,
|
||||
QWidget,
|
||||
QVBoxLayout,
|
||||
|
@ -5,11 +5,11 @@ import pyqtgraph as pg
|
||||
from pydantic import ValidationError
|
||||
|
||||
from bec_lib import MessageEndpoints
|
||||
from PyQt5 import QtCore
|
||||
from PyQt5.QtCore import pyqtSignal, pyqtSlot
|
||||
from PyQt5.QtWidgets import QApplication, QTableWidgetItem, QWidget, QMessageBox
|
||||
from qtpy import QtCore
|
||||
from qtpy.QtCore import Signal as pyqtSignal, Slot as pyqtSlot
|
||||
from qtpy.QtWidgets import QApplication, QTableWidgetItem, QWidget, QMessageBox
|
||||
from pyqtgraph import mkPen, mkBrush
|
||||
from PyQt5 import uic
|
||||
from qtpy import uic
|
||||
|
||||
from bec_widgets.bec_dispatcher import bec_dispatcher
|
||||
from bec_widgets.qt_utils import Crosshair, Colors
|
||||
|
@ -1,5 +1,5 @@
|
||||
import msgpack
|
||||
from PyQt5.QtWidgets import (
|
||||
from qtpy.QtWidgets import (
|
||||
QApplication,
|
||||
QWidget,
|
||||
QComboBox,
|
||||
|
2
setup.py
2
setup.py
@ -4,7 +4,7 @@ __version__ = "0.31.0"
|
||||
|
||||
if __name__ == "__main__":
|
||||
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"]},
|
||||
version=__version__,
|
||||
)
|
||||
|
@ -2,7 +2,7 @@ import os
|
||||
import yaml
|
||||
|
||||
import pytest
|
||||
from PyQt5.QtWidgets import QTabWidget, QTableWidgetItem
|
||||
from qtpy.QtWidgets import QTabWidget, QTableWidgetItem
|
||||
|
||||
from bec_widgets.widgets import ConfigDialog
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
import numpy as np
|
||||
import pyqtgraph as pg
|
||||
from PyQt5.QtCore import QPointF
|
||||
from qtpy.QtCore import QPointF
|
||||
|
||||
from bec_widgets.qt_utils import Crosshair
|
||||
|
||||
|
@ -3,7 +3,7 @@ from unittest.mock import MagicMock, patch
|
||||
|
||||
import pyqtgraph as pg
|
||||
import pytest
|
||||
from PyQt5.QtWidgets import QMessageBox
|
||||
from qtpy.QtWidgets import QMessageBox
|
||||
|
||||
from bec_widgets.examples.extreme.extreme import PlotApp, ErrorHandler
|
||||
|
||||
|
@ -4,7 +4,7 @@ from unittest.mock import MagicMock
|
||||
|
||||
import msgpack
|
||||
import pytest
|
||||
from PyQt5.QtWidgets import QLineEdit
|
||||
from qtpy.QtWidgets import QLineEdit
|
||||
|
||||
from bec_widgets.widgets import ScanControl
|
||||
from bec_widgets.qt_utils.widget_io import WidgetIO
|
||||
|
@ -1,5 +1,5 @@
|
||||
import pytest
|
||||
from PyQt5.QtWidgets import (
|
||||
from qtpy.QtWidgets import (
|
||||
QWidget,
|
||||
QVBoxLayout,
|
||||
QLineEdit,
|
||||
|
@ -3,7 +3,7 @@ import tempfile
|
||||
from unittest.mock import patch
|
||||
import pytest
|
||||
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
|
||||
|
||||
@ -38,7 +38,7 @@ def test_load_yaml(qtbot, example_widget):
|
||||
example_widget.import_button.clicked.connect(load_yaml_wrapper)
|
||||
|
||||
# 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()
|
||||
|
||||
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)
|
||||
|
||||
# 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()
|
||||
|
||||
# Check if the data was saved correctly
|
||||
|
Reference in New Issue
Block a user