0
0
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:
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.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.

View File

@ -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

View File

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

View File

@ -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()

View File

@ -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,

View File

@ -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,

View File

@ -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

View File

@ -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

View File

@ -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})"))

View File

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

View File

@ -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")

View File

@ -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):

View File

@ -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):

View File

@ -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):

View File

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

View File

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

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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)

View File

@ -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,

View File

@ -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

View File

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

View File

@ -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__,
)

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

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

View File

@ -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