diff --git a/README.rst b/README.rst index 2f3e09021..b93402f56 100644 --- a/README.rst +++ b/README.rst @@ -15,7 +15,7 @@ ARTIQ and its dependencies are available in the form of Nix packages (for Linux) ARTIQ is supported by M-Labs and developed openly. Components, features, fixes, improvements, and extensions are often `funded `_ by and developed for the partnering research groups. -Core technologies employed include `Python `_, `Migen `_, `Migen-AXI `_, `Rust `_, `MiSoC `_/`VexRiscv `_, `LLVM `_/`llvmlite `_, and `Qt5 `_. +Core technologies employed include `Python `_, `Migen `_, `Migen-AXI `_, `Rust `_, `MiSoC `_/`VexRiscv `_, `LLVM `_/`llvmlite `_, and `Qt6 `_. | Website: https://m-labs.hk/experiment-control/artiq | (US-hosted mirror: https://m-labs-intl.com/experiment-control/artiq) diff --git a/artiq/applets/big_number.py b/artiq/applets/big_number.py index 7bf077fe2..58a1d6e4c 100755 --- a/artiq/applets/big_number.py +++ b/artiq/applets/big_number.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 -from PyQt5 import QtWidgets, QtCore, QtGui +from PyQt6 import QtWidgets, QtCore, QtGui from artiq.applets.simple import SimpleApplet from artiq.tools import scale_from_metadata from artiq.gui.tools import LayoutWidget @@ -17,7 +17,7 @@ class QCancellableLineEdit(QtWidgets.QLineEdit): editCancelled = QtCore.pyqtSignal() def keyPressEvent(self, event): - if event.key() == QtCore.Qt.Key_Escape: + if event.key() == QtCore.Qt.Key.Key_Escape: self.editCancelled.emit() else: super().keyPressEvent(event) @@ -44,7 +44,7 @@ class NumberWidget(LayoutWidget): self.edit_widget = QCancellableLineEdit() self.edit_widget.setValidator(QtGui.QDoubleValidator()) - self.edit_widget.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter) + self.edit_widget.setAlignment(QtCore.Qt.AlignmentFlag.AlignRight | QtCore.Qt.AlignmentFlag.AlignVCenter) self.edit_widget.editCancelled.connect(self.cancel_edit) self.edit_widget.returnPressed.connect(self.confirm_edit) self.number_area.addWidget(self.edit_widget) diff --git a/artiq/applets/image.py b/artiq/applets/image.py index 75cecd05a..3948e1552 100755 --- a/artiq/applets/image.py +++ b/artiq/applets/image.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 -import PyQt5 # make sure pyqtgraph imports Qt5 +import PyQt6 # make sure pyqtgraph imports Qt6 import pyqtgraph from artiq.applets.simple import SimpleApplet diff --git a/artiq/applets/plot_hist.py b/artiq/applets/plot_hist.py index 5d386cc6c..03c275bdc 100755 --- a/artiq/applets/plot_hist.py +++ b/artiq/applets/plot_hist.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 -import PyQt5 # make sure pyqtgraph imports Qt5 -from PyQt5.QtCore import QTimer +import PyQt6 # make sure pyqtgraph imports Qt6 +from PyQt6.QtCore import QTimer import pyqtgraph from artiq.applets.simple import TitleApplet diff --git a/artiq/applets/plot_xy.py b/artiq/applets/plot_xy.py index df3dc2aaf..033d2d1cd 100755 --- a/artiq/applets/plot_xy.py +++ b/artiq/applets/plot_xy.py @@ -1,8 +1,8 @@ #!/usr/bin/env python3 import numpy as np -import PyQt5 # make sure pyqtgraph imports Qt5 -from PyQt5.QtCore import QTimer +import PyQt6 # make sure pyqtgraph imports Qt6 +from PyQt6.QtCore import QTimer import pyqtgraph from artiq.applets.simple import TitleApplet diff --git a/artiq/applets/plot_xy_hist.py b/artiq/applets/plot_xy_hist.py index f757b520d..fb916f0bc 100755 --- a/artiq/applets/plot_xy_hist.py +++ b/artiq/applets/plot_xy_hist.py @@ -1,8 +1,8 @@ #!/usr/bin/env python3 import numpy as np -from PyQt5 import QtWidgets -from PyQt5.QtCore import QTimer +from PyQt6 import QtWidgets +from PyQt6.QtCore import QTimer import pyqtgraph from artiq.applets.simple import SimpleApplet diff --git a/artiq/applets/progress_bar.py b/artiq/applets/progress_bar.py index 9ea7db836..cdc6208a8 100644 --- a/artiq/applets/progress_bar.py +++ b/artiq/applets/progress_bar.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 -from PyQt5 import QtWidgets +from PyQt6 import QtWidgets from artiq.applets.simple import SimpleApplet diff --git a/artiq/applets/simple.py b/artiq/applets/simple.py index 837ecfa54..b9e74e90d 100644 --- a/artiq/applets/simple.py +++ b/artiq/applets/simple.py @@ -273,7 +273,7 @@ class SimpleApplet: # HACK: if the window has a frame, there will be garbage # (usually white) displayed at its right and bottom borders # after it is embedded. - self.main_widget.setWindowFlags(QtCore.Qt.FramelessWindowHint) + self.main_widget.setWindowFlags(QtCore.Qt.WindowType.FramelessWindowHint) self.main_widget.show() win_id = int(self.main_widget.winId()) self.loop.run_until_complete(self.ipc.embed(win_id)) diff --git a/artiq/browser/datasets.py b/artiq/browser/datasets.py index 6e5473786..d748ce153 100644 --- a/artiq/browser/datasets.py +++ b/artiq/browser/datasets.py @@ -1,7 +1,7 @@ import logging import asyncio -from PyQt5 import QtCore, QtWidgets +from PyQt6 import QtCore, QtGui, QtWidgets from sipyco.pc_rpc import AsyncioClient as RPCClient @@ -62,8 +62,8 @@ class DatasetsDock(QtWidgets.QDockWidget): def __init__(self, dataset_sub, dataset_ctl): QtWidgets.QDockWidget.__init__(self, "Datasets") self.setObjectName("Datasets") - self.setFeatures(QtWidgets.QDockWidget.DockWidgetMovable | - QtWidgets.QDockWidget.DockWidgetFloatable) + self.setFeatures(QtWidgets.QDockWidget.DockWidgetFeature.DockWidgetMovable | + QtWidgets.QDockWidget.DockWidgetFeature.DockWidgetFloatable) grid = LayoutWidget() self.setWidget(grid) @@ -74,9 +74,9 @@ class DatasetsDock(QtWidgets.QDockWidget): grid.addWidget(self.search, 0, 0) self.table = QtWidgets.QTreeView() - self.table.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows) + self.table.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectionBehavior.SelectRows) self.table.setSelectionMode( - QtWidgets.QAbstractItemView.SingleSelection) + QtWidgets.QAbstractItemView.SelectionMode.SingleSelection) grid.addWidget(self.table, 1, 0) metadata_grid = LayoutWidget() @@ -85,13 +85,13 @@ class DatasetsDock(QtWidgets.QDockWidget): "rid start_time".split()): metadata_grid.addWidget(QtWidgets.QLabel(label), i, 0) v = QtWidgets.QLabel() - v.setTextInteractionFlags(QtCore.Qt.TextSelectableByMouse) + v.setTextInteractionFlags(QtCore.Qt.TextInteractionFlag.TextSelectableByMouse) metadata_grid.addWidget(v, i, 1) self.metadata[label] = v grid.addWidget(metadata_grid, 2, 0) - self.table.setContextMenuPolicy(QtCore.Qt.ActionsContextMenu) - upload_action = QtWidgets.QAction("Upload dataset to master", + self.table.setContextMenuPolicy(QtCore.Qt.ContextMenuPolicy.ActionsContextMenu) + upload_action = QtGui.QAction("Upload dataset to master", self.table) upload_action.triggered.connect(self.upload_clicked) self.table.addAction(upload_action) diff --git a/artiq/browser/experiments.py b/artiq/browser/experiments.py index c5cf9c54c..8cbd81661 100644 --- a/artiq/browser/experiments.py +++ b/artiq/browser/experiments.py @@ -4,7 +4,7 @@ import os from functools import partial from collections import OrderedDict -from PyQt5 import QtCore, QtGui, QtWidgets +from PyQt6 import QtCore, QtGui, QtWidgets import h5py from sipyco import pyon @@ -33,13 +33,13 @@ class _ArgumentEditor(EntryTreeWidget): recompute_arguments = QtWidgets.QPushButton("Recompute all arguments") recompute_arguments.setIcon( QtWidgets.QApplication.style().standardIcon( - QtWidgets.QStyle.SP_BrowserReload)) + QtWidgets.QStyle.StandardPixmap.SP_BrowserReload)) recompute_arguments.clicked.connect(self._recompute_arguments_clicked) load = QtWidgets.QPushButton("Set arguments from HDF5") load.setToolTip("Set arguments from currently selected HDF5 file") load.setIcon(QtWidgets.QApplication.style().standardIcon( - QtWidgets.QStyle.SP_DialogApplyButton)) + QtWidgets.QStyle.StandardPixmap.SP_DialogApplyButton)) load.clicked.connect(self._load_clicked) buttons = LayoutWidget() @@ -86,7 +86,7 @@ class _ExperimentDock(QtWidgets.QMdiSubWindow): self.resize(100*qfm.averageCharWidth(), 30*qfm.lineSpacing()) self.setWindowTitle(expurl) self.setWindowIcon(QtWidgets.QApplication.style().standardIcon( - QtWidgets.QStyle.SP_FileDialogContentsView)) + QtWidgets.QStyle.StandardPixmap.SP_FileDialogContentsView)) self.setAcceptDrops(True) self.layout = QtWidgets.QGridLayout() @@ -126,22 +126,22 @@ class _ExperimentDock(QtWidgets.QMdiSubWindow): run = QtWidgets.QPushButton("Analyze") run.setIcon(QtWidgets.QApplication.style().standardIcon( - QtWidgets.QStyle.SP_DialogOkButton)) + QtWidgets.QStyle.StandardPixmap.SP_DialogOkButton)) run.setToolTip("Run analysis stage (Ctrl+Return)") run.setShortcut("CTRL+RETURN") - run.setSizePolicy(QtWidgets.QSizePolicy.Expanding, - QtWidgets.QSizePolicy.Expanding) + run.setSizePolicy(QtWidgets.QSizePolicy.Policy.Expanding, + QtWidgets.QSizePolicy.Policy.Expanding) self.layout.addWidget(run, 2, 4) run.clicked.connect(self._run_clicked) self._run = run terminate = QtWidgets.QPushButton("Terminate") terminate.setIcon(QtWidgets.QApplication.style().standardIcon( - QtWidgets.QStyle.SP_DialogCancelButton)) + QtWidgets.QStyle.StandardPixmap.SP_DialogCancelButton)) terminate.setToolTip("Terminate analysis (Ctrl+Backspace)") terminate.setShortcut("CTRL+BACKSPACE") - terminate.setSizePolicy(QtWidgets.QSizePolicy.Expanding, - QtWidgets.QSizePolicy.Expanding) + terminate.setSizePolicy(QtWidgets.QSizePolicy.Policy.Expanding, + QtWidgets.QSizePolicy.Policy.Expanding) self.layout.addWidget(terminate, 3, 4) terminate.clicked.connect(self._terminate_clicked) terminate.setEnabled(False) @@ -316,7 +316,7 @@ class ExperimentsArea(QtWidgets.QMdiArea): asyncio.ensure_future(sub.load_hdf5_task(path)) def mousePressEvent(self, ev): - if ev.button() == QtCore.Qt.LeftButton: + if ev.button() == QtCore.Qt.MouseButton.LeftButton: self.select_experiment() def paintEvent(self, event): @@ -406,7 +406,7 @@ class ExperimentsArea(QtWidgets.QMdiArea): exc_info=True) dock = _ExperimentDock(self, expurl, {}) asyncio.ensure_future(dock._recompute_arguments()) - dock.setAttribute(QtCore.Qt.WA_DeleteOnClose) + dock.setAttribute(QtCore.Qt.WidgetAttribute.WA_DeleteOnClose) self.addSubWindow(dock) dock.show() dock.sigClosed.connect(partial(self.on_dock_closed, dock)) diff --git a/artiq/browser/files.py b/artiq/browser/files.py index dd97f45a9..cb457b7fa 100644 --- a/artiq/browser/files.py +++ b/artiq/browser/files.py @@ -3,7 +3,7 @@ import os from datetime import datetime import h5py -from PyQt5 import QtCore, QtWidgets, QtGui +from PyQt6 import QtCore, QtWidgets, QtGui from sipyco import pyon @@ -69,15 +69,15 @@ class ZoomIconView(QtWidgets.QListView): def __init__(self): QtWidgets.QListView.__init__(self) self._char_width = QtGui.QFontMetrics(self.font()).averageCharWidth() - self.setViewMode(self.IconMode) + self.setViewMode(self.ViewMode.IconMode) w = self._char_width*self.default_size self.setIconSize(QtCore.QSize(w, int(w*self.aspect))) - self.setFlow(self.LeftToRight) - self.setResizeMode(self.Adjust) + self.setFlow(self.Flow.LeftToRight) + self.setResizeMode(self.ResizeMode.Adjust) self.setWrapping(True) def wheelEvent(self, ev): - if ev.modifiers() & QtCore.Qt.ControlModifier: + if ev.modifiers() & QtCore.Qt.KeyboardModifier.ControlModifier: a = self._char_width*self.min_size b = self._char_width*self.max_size w = self.iconSize().width()*self.zoom_step**( @@ -88,16 +88,16 @@ class ZoomIconView(QtWidgets.QListView): QtWidgets.QListView.wheelEvent(self, ev) -class Hdf5FileSystemModel(QtWidgets.QFileSystemModel): +class Hdf5FileSystemModel(QtGui.QFileSystemModel): def __init__(self): - QtWidgets.QFileSystemModel.__init__(self) - self.setFilter(QtCore.QDir.Drives | QtCore.QDir.NoDotAndDotDot | - QtCore.QDir.AllDirs | QtCore.QDir.Files) + QtGui.QFileSystemModel.__init__(self) + self.setFilter(QtCore.QDir.Filter.Drives | QtCore.QDir.Filter.NoDotAndDotDot | + QtCore.QDir.Filter.AllDirs | QtCore.QDir.Filter.Files) self.setNameFilterDisables(False) self.setIconProvider(ThumbnailIconProvider()) def data(self, idx, role): - if role == QtCore.Qt.ToolTipRole: + if role == QtCore.Qt.ItemDataRole.ToolTipRole: info = self.fileInfo(idx) h5 = open_h5(info) if h5 is not None: @@ -114,7 +114,7 @@ class Hdf5FileSystemModel(QtWidgets.QFileSystemModel): except: logger.warning("unable to read metadata from %s", info.filePath(), exc_info=True) - return QtWidgets.QFileSystemModel.data(self, idx, role) + return QtGui.QFileSystemModel.data(self, idx, role) class FilesDock(QtWidgets.QDockWidget): @@ -125,7 +125,7 @@ class FilesDock(QtWidgets.QDockWidget): def __init__(self, datasets, browse_root=""): QtWidgets.QDockWidget.__init__(self, "Files") self.setObjectName("Files") - self.setFeatures(self.DockWidgetMovable | self.DockWidgetFloatable) + self.setFeatures(self.DockWidgetFeature.DockWidgetMovable | self.DockWidgetFeature.DockWidgetFloatable) self.splitter = QtWidgets.QSplitter() self.setWidget(self.splitter) @@ -147,8 +147,8 @@ class FilesDock(QtWidgets.QDockWidget): self.rt.setRootIndex(rt_model.mapFromSource( self.model.setRootPath(browse_root))) self.rt.setHeaderHidden(True) - self.rt.setSelectionBehavior(self.rt.SelectRows) - self.rt.setSelectionMode(self.rt.SingleSelection) + self.rt.setSelectionBehavior(self.rt.SelectionBehavior.SelectRows) + self.rt.setSelectionMode(self.rt.SelectionMode.SingleSelection) self.rt.selectionModel().currentChanged.connect( self.tree_current_changed) self.rt.setRootIsDecorated(False) @@ -252,7 +252,7 @@ class FilesDock(QtWidgets.QDockWidget): 100, lambda: self.rt.scrollTo( self.rt.model().mapFromSource(self.model.index(path)), - self.rt.PositionAtCenter) + self.rt.ScrollHint.PositionAtCenter) ) self.model.directoryLoaded.connect(scroll_when_loaded) idx = self.rt.model().mapFromSource(idx) diff --git a/artiq/dashboard/applets_ccb.py b/artiq/dashboard/applets_ccb.py index 29afbbc1d..5b8faa4c9 100644 --- a/artiq/dashboard/applets_ccb.py +++ b/artiq/dashboard/applets_ccb.py @@ -1,7 +1,7 @@ import asyncio import logging -from PyQt5 import QtCore, QtWidgets +from PyQt6 import QtCore, QtGui, QtWidgets from artiq.gui import applets @@ -13,58 +13,58 @@ class AppletsCCBDock(applets.AppletsDock): def __init__(self, *args, **kwargs): applets.AppletsDock.__init__(self, *args, **kwargs) - sep = QtWidgets.QAction(self.table) + sep = QtGui.QAction(self.table) sep.setSeparator(True) self.table.addAction(sep) ccbp_group_menu = QtWidgets.QMenu() - actiongroup = QtWidgets.QActionGroup(self.table) + actiongroup = QtGui.QActionGroup(self.table) actiongroup.setExclusive(True) - self.ccbp_group_none = QtWidgets.QAction("No policy", self.table) + self.ccbp_group_none = QtGui.QAction("No policy", self.table) self.ccbp_group_none.setCheckable(True) self.ccbp_group_none.triggered.connect(lambda: self.set_ccbp("")) ccbp_group_menu.addAction(self.ccbp_group_none) actiongroup.addAction(self.ccbp_group_none) - self.ccbp_group_ignore = QtWidgets.QAction("Ignore requests", self.table) + self.ccbp_group_ignore = QtGui.QAction("Ignore requests", self.table) self.ccbp_group_ignore.setCheckable(True) self.ccbp_group_ignore.triggered.connect(lambda: self.set_ccbp("ignore")) ccbp_group_menu.addAction(self.ccbp_group_ignore) actiongroup.addAction(self.ccbp_group_ignore) - self.ccbp_group_create = QtWidgets.QAction("Create applets", self.table) + self.ccbp_group_create = QtGui.QAction("Create applets", self.table) self.ccbp_group_create.setCheckable(True) self.ccbp_group_create.triggered.connect(lambda: self.set_ccbp("create")) ccbp_group_menu.addAction(self.ccbp_group_create) actiongroup.addAction(self.ccbp_group_create) - self.ccbp_group_enable = QtWidgets.QAction("Create and enable/disable applets", - self.table) + self.ccbp_group_enable = QtGui.QAction("Create and enable/disable applets", + self.table) self.ccbp_group_enable.setCheckable(True) self.ccbp_group_enable.triggered.connect(lambda: self.set_ccbp("enable")) ccbp_group_menu.addAction(self.ccbp_group_enable) actiongroup.addAction(self.ccbp_group_enable) - self.ccbp_group_action = QtWidgets.QAction("Group CCB policy", self.table) + self.ccbp_group_action = QtGui.QAction("Group CCB policy", self.table) self.ccbp_group_action.setMenu(ccbp_group_menu) self.table.addAction(self.ccbp_group_action) self.table.itemSelectionChanged.connect(self.update_group_ccbp_menu) self.update_group_ccbp_menu() ccbp_global_menu = QtWidgets.QMenu() - actiongroup = QtWidgets.QActionGroup(self.table) + actiongroup = QtGui.QActionGroup(self.table) actiongroup.setExclusive(True) - self.ccbp_global_ignore = QtWidgets.QAction("Ignore requests", self.table) + self.ccbp_global_ignore = QtGui.QAction("Ignore requests", self.table) self.ccbp_global_ignore.setCheckable(True) ccbp_global_menu.addAction(self.ccbp_global_ignore) actiongroup.addAction(self.ccbp_global_ignore) - self.ccbp_global_create = QtWidgets.QAction("Create applets", self.table) + self.ccbp_global_create = QtGui.QAction("Create applets", self.table) self.ccbp_global_create.setCheckable(True) self.ccbp_global_create.setChecked(True) ccbp_global_menu.addAction(self.ccbp_global_create) actiongroup.addAction(self.ccbp_global_create) - self.ccbp_global_enable = QtWidgets.QAction("Create and enable/disable applets", - self.table) + self.ccbp_global_enable = QtGui.QAction("Create and enable/disable applets", + self.table) self.ccbp_global_enable.setCheckable(True) ccbp_global_menu.addAction(self.ccbp_global_enable) actiongroup.addAction(self.ccbp_global_enable) - ccbp_global_action = QtWidgets.QAction("Global CCB policy", self.table) + ccbp_global_action = QtGui.QAction("Global CCB policy", self.table) ccbp_global_action.setMenu(ccbp_global_menu) self.table.addAction(ccbp_global_action) @@ -196,7 +196,7 @@ class AppletsCCBDock(applets.AppletsDock): logger.debug("Applet %s already exists and no update required", name) if ccbp == "enable": - applet.setCheckState(0, QtCore.Qt.Checked) + applet.setCheckState(0, QtCore.Qt.CheckState.Checked) def ccb_disable_applet(self, name, group=None): """Disables an applet. @@ -216,7 +216,7 @@ class AppletsCCBDock(applets.AppletsDock): return parent, applet = self.locate_applet(name, group, False) if applet is not None: - applet.setCheckState(0, QtCore.Qt.Unchecked) + applet.setCheckState(0, QtCore.Qt.CheckState.Unchecked) def ccb_disable_applet_group(self, group): """Disables all the applets in a group. @@ -246,7 +246,7 @@ class AppletsCCBDock(applets.AppletsDock): return else: wi = nwi - wi.setCheckState(0, QtCore.Qt.Unchecked) + wi.setCheckState(0, QtCore.Qt.CheckState.Unchecked) def ccb_notify(self, message): try: diff --git a/artiq/dashboard/datasets.py b/artiq/dashboard/datasets.py index 749828d61..5d9befad9 100644 --- a/artiq/dashboard/datasets.py +++ b/artiq/dashboard/datasets.py @@ -2,7 +2,7 @@ import asyncio import logging import numpy as np -from PyQt5 import QtCore, QtWidgets +from PyQt6 import QtCore, QtGui, QtWidgets from sipyco import pyon from artiq.tools import scale_from_metadata, short_format, exc_to_warning @@ -63,11 +63,11 @@ class CreateEditDialog(QtWidgets.QDialog): self.cancel = QtWidgets.QPushButton('&Cancel') self.buttons = QtWidgets.QDialogButtonBox(self) self.buttons.addButton( - self.ok, QtWidgets.QDialogButtonBox.AcceptRole) + self.ok, QtWidgets.QDialogButtonBox.ButtonRole.AcceptRole) self.buttons.addButton( - self.cancel, QtWidgets.QDialogButtonBox.RejectRole) + self.cancel, QtWidgets.QDialogButtonBox.ButtonRole.RejectRole) grid.setRowStretch(6, 1) - grid.addWidget(self.buttons, 7, 0, 1, 3, alignment=QtCore.Qt.AlignHCenter) + grid.addWidget(self.buttons, 7, 0, 1, 3, alignment=QtCore.Qt.AlignmentFlag.AlignHCenter) self.buttons.accepted.connect(self.accept) self.buttons.rejected.connect(self.reject) @@ -125,7 +125,7 @@ class CreateEditDialog(QtWidgets.QDialog): pyon.encode(result) except: pixmap = self.style().standardPixmap( - QtWidgets.QStyle.SP_MessageBoxWarning) + QtWidgets.QStyle.StandardPixmap.SP_MessageBoxWarning) self.data_type.setPixmap(pixmap) self.ok.setEnabled(False) else: @@ -181,8 +181,8 @@ class DatasetsDock(QtWidgets.QDockWidget): def __init__(self, dataset_sub, dataset_ctl): QtWidgets.QDockWidget.__init__(self, "Datasets") self.setObjectName("Datasets") - self.setFeatures(QtWidgets.QDockWidget.DockWidgetMovable | - QtWidgets.QDockWidget.DockWidgetFloatable) + self.setFeatures(QtWidgets.QDockWidget.DockWidgetFeature.DockWidgetMovable | + QtWidgets.QDockWidget.DockWidgetFeature.DockWidgetFloatable) self.dataset_ctl = dataset_ctl grid = LayoutWidget() @@ -194,27 +194,27 @@ class DatasetsDock(QtWidgets.QDockWidget): grid.addWidget(self.search, 0, 0) self.table = QtWidgets.QTreeView() - self.table.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows) + self.table.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectionBehavior.SelectRows) self.table.setSelectionMode( - QtWidgets.QAbstractItemView.SingleSelection) + QtWidgets.QAbstractItemView.SelectionMode.SingleSelection) grid.addWidget(self.table, 1, 0) - self.table.setContextMenuPolicy(QtCore.Qt.ActionsContextMenu) - create_action = QtWidgets.QAction("New dataset", self.table) + self.table.setContextMenuPolicy(QtCore.Qt.ContextMenuPolicy.ActionsContextMenu) + create_action = QtGui.QAction("New dataset", self.table) create_action.triggered.connect(self.create_clicked) create_action.setShortcut("CTRL+N") - create_action.setShortcutContext(QtCore.Qt.WidgetShortcut) + create_action.setShortcutContext(QtCore.Qt.ShortcutContext.WidgetShortcut) self.table.addAction(create_action) - edit_action = QtWidgets.QAction("Edit dataset", self.table) + edit_action = QtGui.QAction("Edit dataset", self.table) edit_action.triggered.connect(self.edit_clicked) edit_action.setShortcut("RETURN") - edit_action.setShortcutContext(QtCore.Qt.WidgetShortcut) + edit_action.setShortcutContext(QtCore.Qt.ShortcutContext.WidgetShortcut) self.table.doubleClicked.connect(self.edit_clicked) self.table.addAction(edit_action) - delete_action = QtWidgets.QAction("Delete dataset", self.table) + delete_action = QtGui.QAction("Delete dataset", self.table) delete_action.triggered.connect(self.delete_clicked) delete_action.setShortcut("DELETE") - delete_action.setShortcutContext(QtCore.Qt.WidgetShortcut) + delete_action.setShortcutContext(QtCore.Qt.ShortcutContext.WidgetShortcut) self.table.addAction(delete_action) self.table_model = Model(dict()) diff --git a/artiq/dashboard/experiments.py b/artiq/dashboard/experiments.py index 10bfa5a0c..53323b2d4 100644 --- a/artiq/dashboard/experiments.py +++ b/artiq/dashboard/experiments.py @@ -4,7 +4,7 @@ import os from functools import partial from collections import OrderedDict -from PyQt5 import QtCore, QtGui, QtWidgets +from PyQt6 import QtCore, QtGui, QtWidgets import h5py from sipyco import pyon @@ -44,12 +44,12 @@ class _ArgumentEditor(EntryTreeWidget): recompute_arguments = QtWidgets.QPushButton("Recompute all arguments") recompute_arguments.setIcon( QtWidgets.QApplication.style().standardIcon( - QtWidgets.QStyle.SP_BrowserReload)) + QtWidgets.QStyle.StandardPixmap.SP_BrowserReload)) recompute_arguments.clicked.connect(dock._recompute_arguments_clicked) load_hdf5 = QtWidgets.QPushButton("Load HDF5") load_hdf5.setIcon(QtWidgets.QApplication.style().standardIcon( - QtWidgets.QStyle.SP_DialogOpenButton)) + QtWidgets.QStyle.StandardPixmap.SP_DialogOpenButton)) load_hdf5.clicked.connect(dock._load_hdf5_clicked) buttons = LayoutWidget() @@ -101,7 +101,7 @@ class _ExperimentDock(QtWidgets.QMdiSubWindow): self.resize(100 * qfm.averageCharWidth(), 30 * qfm.lineSpacing()) self.setWindowTitle(expurl) self.setWindowIcon(QtWidgets.QApplication.style().standardIcon( - QtWidgets.QStyle.SP_FileDialogContentsView)) + QtWidgets.QStyle.StandardPixmap.SP_FileDialogContentsView)) self.layout = QtWidgets.QGridLayout() top_widget = QtWidgets.QWidget() @@ -237,21 +237,21 @@ class _ExperimentDock(QtWidgets.QMdiSubWindow): submit = QtWidgets.QPushButton("Submit") submit.setIcon(QtWidgets.QApplication.style().standardIcon( - QtWidgets.QStyle.SP_DialogOkButton)) + QtWidgets.QStyle.StandardPixmap.SP_DialogOkButton)) submit.setToolTip("Schedule the experiment (Ctrl+Return)") submit.setShortcut("CTRL+RETURN") - submit.setSizePolicy(QtWidgets.QSizePolicy.Expanding, - QtWidgets.QSizePolicy.Expanding) + submit.setSizePolicy(QtWidgets.QSizePolicy.Policy.Expanding, + QtWidgets.QSizePolicy.Policy.Expanding) self.layout.addWidget(submit, 1, 4, 2, 1) submit.clicked.connect(self.submit_clicked) reqterm = QtWidgets.QPushButton("Terminate instances") reqterm.setIcon(QtWidgets.QApplication.style().standardIcon( - QtWidgets.QStyle.SP_DialogCancelButton)) + QtWidgets.QStyle.StandardPixmap.SP_DialogCancelButton)) reqterm.setToolTip("Request termination of instances (Ctrl+Backspace)") reqterm.setShortcut("CTRL+BACKSPACE") - reqterm.setSizePolicy(QtWidgets.QSizePolicy.Expanding, - QtWidgets.QSizePolicy.Expanding) + reqterm.setSizePolicy(QtWidgets.QSizePolicy.Policy.Expanding, + QtWidgets.QSizePolicy.Policy.Expanding) self.layout.addWidget(reqterm, 3, 4) reqterm.clicked.connect(self.reqterm_clicked) @@ -306,7 +306,7 @@ class _ExperimentDock(QtWidgets.QMdiSubWindow): def contextMenuEvent(self, event): menu = QtWidgets.QMenu(self) reset_sched = menu.addAction("Reset scheduler settings") - action = menu.exec_(self.mapToGlobal(event.pos())) + action = menu.exec(self.mapToGlobal(event.pos())) if action == reset_sched: asyncio.ensure_future(self._recompute_sched_options_task()) @@ -423,7 +423,7 @@ class _QuickOpenDialog(QtWidgets.QDialog): QtWidgets.QDialog.done(self, r) def _open_experiment(self, exp_name, modifiers): - if modifiers & QtCore.Qt.ControlModifier: + if modifiers & QtCore.Qt.KeyboardModifier.ControlModifier: try: self.manager.submit(exp_name) except: @@ -467,10 +467,10 @@ class ExperimentManager: self.open_experiments = dict() self.is_quick_open_shown = False - quick_open_shortcut = QtWidgets.QShortcut( - QtCore.Qt.CTRL + QtCore.Qt.Key_P, + quick_open_shortcut = QtGui.QShortcut( + QtGui.QKeySequence("Ctrl+P"), main_window) - quick_open_shortcut.setContext(QtCore.Qt.ApplicationShortcut) + quick_open_shortcut.setContext(QtCore.Qt.ShortcutContext.ApplicationShortcut) quick_open_shortcut.activated.connect(self.show_quick_open) def set_dataset_model(self, model): @@ -589,7 +589,7 @@ class ExperimentManager: del self.submission_arguments[expurl] dock = _ExperimentDock(self, expurl) self.open_experiments[expurl] = dock - dock.setAttribute(QtCore.Qt.WA_DeleteOnClose) + dock.setAttribute(QtCore.Qt.WidgetAttribute.WA_DeleteOnClose) self.main_window.centralWidget().addSubWindow(dock) dock.show() dock.sigClosed.connect(partial(self.on_dock_closed, expurl)) diff --git a/artiq/dashboard/explorer.py b/artiq/dashboard/explorer.py index f8c8df1f0..f13358a31 100644 --- a/artiq/dashboard/explorer.py +++ b/artiq/dashboard/explorer.py @@ -3,7 +3,7 @@ import logging import re from functools import partial -from PyQt5 import QtCore, QtWidgets +from PyQt6 import QtCore, QtGui, QtWidgets from artiq.gui.tools import LayoutWidget from artiq.gui.models import DictSyncTreeSepModel @@ -37,7 +37,8 @@ class _OpenFileDialog(QtWidgets.QDialog): self.file_list.doubleClicked.connect(self.accept) buttons = QtWidgets.QDialogButtonBox( - QtWidgets.QDialogButtonBox.Ok | QtWidgets.QDialogButtonBox.Cancel) + QtWidgets.QDialogButtonBox.StandardButton.Ok | + QtWidgets.QDialogButtonBox.StandardButton.Cancel) grid.addWidget(buttons, 2, 0, 1, 2) buttons.accepted.connect(self.accept) buttons.rejected.connect(self.reject) @@ -52,7 +53,7 @@ class _OpenFileDialog(QtWidgets.QDialog): item = QtWidgets.QListWidgetItem() item.setText("..") item.setIcon(QtWidgets.QApplication.style().standardIcon( - QtWidgets.QStyle.SP_FileDialogToParent)) + QtWidgets.QStyle.StandardPixmap.SP_FileDialogToParent)) self.file_list.addItem(item) try: @@ -64,9 +65,9 @@ class _OpenFileDialog(QtWidgets.QDialog): return for name in sorted(contents, key=lambda x: (x[-1] not in "\\/", x)): if name[-1] in "\\/": - icon = QtWidgets.QStyle.SP_DirIcon + icon = QtWidgets.QStyle.StandardPixmap.SP_DirIcon else: - icon = QtWidgets.QStyle.SP_FileIcon + icon = QtWidgets.QStyle.StandardPixmap.SP_FileIcon if name[-3:] != ".py": continue item = QtWidgets.QListWidgetItem() @@ -163,8 +164,8 @@ class ExplorerDock(QtWidgets.QDockWidget): schedule_ctl, experiment_db_ctl, device_db_ctl): QtWidgets.QDockWidget.__init__(self, "Explorer") self.setObjectName("Explorer") - self.setFeatures(QtWidgets.QDockWidget.DockWidgetMovable | - QtWidgets.QDockWidget.DockWidgetFloatable) + self.setFeatures(QtWidgets.QDockWidget.DockWidgetFeature.DockWidgetMovable | + QtWidgets.QDockWidget.DockWidgetFeature.DockWidgetFloatable) top_widget = LayoutWidget() self.setWidget(top_widget) @@ -175,7 +176,7 @@ class ExplorerDock(QtWidgets.QDockWidget): top_widget.addWidget(QtWidgets.QLabel("Revision:"), 0, 0) self.revision = QtWidgets.QLabel() - self.revision.setTextInteractionFlags(QtCore.Qt.TextSelectableByMouse) + self.revision.setTextInteractionFlags(QtCore.Qt.TextInteractionFlag.TextSelectableByMouse) top_widget.addWidget(self.revision, 0, 1) self.stack = QtWidgets.QStackedWidget() @@ -187,14 +188,14 @@ class ExplorerDock(QtWidgets.QDockWidget): self.el = QtWidgets.QTreeView() self.el.setHeaderHidden(True) - self.el.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectItems) + self.el.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectionBehavior.SelectItems) self.el.doubleClicked.connect( partial(self.expname_action, "open_experiment")) self.el_buttons.addWidget(self.el, 0, 0, colspan=2) open = QtWidgets.QPushButton("Open") open.setIcon(QtWidgets.QApplication.style().standardIcon( - QtWidgets.QStyle.SP_DialogOpenButton)) + QtWidgets.QStyle.StandardPixmap.SP_DialogOpenButton)) open.setToolTip("Open the selected experiment (Return)") self.el_buttons.addWidget(open, 1, 0) open.clicked.connect( @@ -202,7 +203,7 @@ class ExplorerDock(QtWidgets.QDockWidget): submit = QtWidgets.QPushButton("Submit") submit.setIcon(QtWidgets.QApplication.style().standardIcon( - QtWidgets.QStyle.SP_DialogOkButton)) + QtWidgets.QStyle.StandardPixmap.SP_DialogOkButton)) submit.setToolTip("Schedule the selected experiment (Ctrl+Return)") self.el_buttons.addWidget(submit, 1, 1) submit.clicked.connect( @@ -211,41 +212,41 @@ class ExplorerDock(QtWidgets.QDockWidget): self.explist_model = Model(dict()) explist_sub.add_setmodel_callback(self.set_model) - self.el.setContextMenuPolicy(QtCore.Qt.ActionsContextMenu) - open_action = QtWidgets.QAction("Open", self.el) + self.el.setContextMenuPolicy(QtCore.Qt.ContextMenuPolicy.ActionsContextMenu) + open_action = QtGui.QAction("Open", self.el) open_action.triggered.connect( partial(self.expname_action, "open_experiment")) open_action.setShortcut("RETURN") - open_action.setShortcutContext(QtCore.Qt.WidgetShortcut) + open_action.setShortcutContext(QtCore.Qt.ShortcutContext.WidgetShortcut) self.el.addAction(open_action) - submit_action = QtWidgets.QAction("Submit", self.el) + submit_action = QtGui.QAction("Submit", self.el) submit_action.triggered.connect( partial(self.expname_action, "submit")) submit_action.setShortcut("CTRL+RETURN") - submit_action.setShortcutContext(QtCore.Qt.WidgetShortcut) + submit_action.setShortcutContext(QtCore.Qt.ShortcutContext.WidgetShortcut) self.el.addAction(submit_action) - reqterm_action = QtWidgets.QAction("Request termination of instances", self.el) + reqterm_action = QtGui.QAction("Request termination of instances", self.el) reqterm_action.triggered.connect( partial(self.expname_action, "request_inst_term")) reqterm_action.setShortcut("CTRL+BACKSPACE") - reqterm_action.setShortcutContext(QtCore.Qt.WidgetShortcut) + reqterm_action.setShortcutContext(QtCore.Qt.ShortcutContext.WidgetShortcut) self.el.addAction(reqterm_action) set_shortcut_menu = QtWidgets.QMenu() for i in range(12): - action = QtWidgets.QAction("F" + str(i + 1), self.el) + action = QtGui.QAction("F" + str(i+1), self.el) action.triggered.connect(partial(self.set_shortcut, i)) set_shortcut_menu.addAction(action) - set_shortcut_action = QtWidgets.QAction("Set shortcut", self.el) + set_shortcut_action = QtGui.QAction("Set shortcut", self.el) set_shortcut_action.setMenu(set_shortcut_menu) self.el.addAction(set_shortcut_action) - sep = QtWidgets.QAction(self.el) + sep = QtGui.QAction(self.el) sep.setSeparator(True) self.el.addAction(sep) - scan_repository_action = QtWidgets.QAction("Scan repository HEAD", + scan_repository_action = QtGui.QAction("Scan repository HEAD", self.el) def scan_repository(): @@ -253,15 +254,14 @@ class ExplorerDock(QtWidgets.QDockWidget): scan_repository_action.triggered.connect(scan_repository) self.el.addAction(scan_repository_action) - scan_ddb_action = QtWidgets.QAction("Scan device database", self.el) - + scan_ddb_action = QtGui.QAction("Scan device database", self.el) def scan_ddb(): asyncio.ensure_future(device_db_ctl.scan()) scan_ddb_action.triggered.connect(scan_ddb) self.el.addAction(scan_ddb_action) self.current_directory = "" - open_file_action = QtWidgets.QAction("Open file outside repository", + open_file_action = QtGui.QAction("Open file outside repository", self.el) open_file_action.triggered.connect( lambda: _OpenFileDialog(self, self.exp_manager, diff --git a/artiq/dashboard/moninj.py b/artiq/dashboard/moninj.py index e314c960b..65b190eac 100644 --- a/artiq/dashboard/moninj.py +++ b/artiq/dashboard/moninj.py @@ -4,7 +4,7 @@ import textwrap from collections import namedtuple from functools import partial -from PyQt5 import QtCore, QtWidgets +from PyQt6 import QtCore, QtWidgets, QtGui from artiq.coredevice.comm_moninj import CommMonInj, TTLOverride, TTLProbe from artiq.coredevice.ad9912_reg import AD9912_SER_CONF @@ -23,7 +23,7 @@ class _CancellableLineEdit(QtWidgets.QLineEdit): def keyPressEvent(self, event): key = event.key() - if key == QtCore.Qt.Key_Escape: + if key == QtCore.Qt.Key.Key_Escape: self.esc_cb(event) QtWidgets.QLineEdit.keyPressEvent(self, event) @@ -31,9 +31,8 @@ class _CancellableLineEdit(QtWidgets.QLineEdit): class _MoninjWidget(QtWidgets.QFrame): def __init__(self, title): QtWidgets.QFrame.__init__(self) - self.setFrameShape(QtWidgets.QFrame.Box) - self.setFrameShape(QtWidgets.QFrame.Box) - self.setFrameShadow(QtWidgets.QFrame.Raised) + self.setFrameShape(QtWidgets.QFrame.Shape.Box) + self.setFrameShadow(QtWidgets.QFrame.Shadow.Raised) self.setFixedHeight(100) self.setFixedWidth(150) self.grid = QtWidgets.QGridLayout() @@ -43,7 +42,9 @@ class _MoninjWidget(QtWidgets.QFrame): self.setLayout(self.grid) title = elide(title, 20) label = QtWidgets.QLabel(title) - label.setAlignment(QtCore.Qt.AlignHCenter | QtCore.Qt.AlignTop) + label.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter) + label.setSizePolicy(QtWidgets.QSizePolicy.Policy.Ignored, + QtWidgets.QSizePolicy.Policy.Preferred) self.grid.addWidget(label, 1, 1) @@ -60,7 +61,7 @@ class _TTLWidget(_MoninjWidget): self.grid.addWidget(self.stack, 2, 1) self.direction = QtWidgets.QLabel() - self.direction.setAlignment(QtCore.Qt.AlignCenter) + self.direction.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter) self.stack.addWidget(self.direction) grid_cb = LayoutWidget() @@ -80,7 +81,7 @@ class _TTLWidget(_MoninjWidget): self.stack.addWidget(grid_cb) self.value = QtWidgets.QLabel() - self.value.setAlignment(QtCore.Qt.AlignCenter) + self.value.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter) self.grid.addWidget(self.value, 3, 1) self.grid.setRowStretch(1, 1) @@ -215,11 +216,11 @@ class _DDSWidget(_MoninjWidget): grid_disp.layout.setVerticalSpacing(0) self.value_label = QtWidgets.QLabel() - self.value_label.setAlignment(QtCore.Qt.AlignCenter) + self.value_label.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter) grid_disp.addWidget(self.value_label, 0, 1, 1, 2) unit = QtWidgets.QLabel("MHz") - unit.setAlignment(QtCore.Qt.AlignCenter) + unit.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter) grid_disp.addWidget(unit, 0, 3, 1, 1) self.data_stack.addWidget(grid_disp) @@ -231,10 +232,10 @@ class _DDSWidget(_MoninjWidget): grid_edit.layout.setVerticalSpacing(0) self.value_edit = _CancellableLineEdit(self) - self.value_edit.setAlignment(QtCore.Qt.AlignRight) + self.value_edit.setAlignment(QtCore.Qt.AlignmentFlag.AlignRight) grid_edit.addWidget(self.value_edit, 0, 1, 1, 2) unit = QtWidgets.QLabel("MHz") - unit.setAlignment(QtCore.Qt.AlignCenter) + unit.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter) grid_edit.addWidget(unit, 0, 3, 1, 1) self.data_stack.addWidget(grid_edit) @@ -799,8 +800,8 @@ class _MonInjDock(QDockWidgetCloseDetect): def __init__(self, name, manager): QtWidgets.QDockWidget.__init__(self, "MonInj") self.setObjectName(name) - self.setFeatures(QtWidgets.QDockWidget.DockWidgetMovable | - QtWidgets.QDockWidget.DockWidgetFloatable) + self.setFeatures(QtWidgets.QDockWidget.DockWidgetFeature.DockWidgetMovable | + QtWidgets.QDockWidget.DockWidgetFeature.DockWidgetFloatable) grid = LayoutWidget() self.setWidget(grid) self.manager = manager diff --git a/artiq/dashboard/schedule.py b/artiq/dashboard/schedule.py index 94c229258..8ea213239 100644 --- a/artiq/dashboard/schedule.py +++ b/artiq/dashboard/schedule.py @@ -3,7 +3,7 @@ import time from functools import partial import logging -from PyQt5 import QtCore, QtWidgets, QtGui +from PyQt6 import QtCore, QtWidgets, QtGui from artiq.gui.models import DictSyncModel from artiq.tools import elide @@ -61,31 +61,31 @@ class ScheduleDock(QtWidgets.QDockWidget): def __init__(self, schedule_ctl, schedule_sub): QtWidgets.QDockWidget.__init__(self, "Schedule") self.setObjectName("Schedule") - self.setFeatures(QtWidgets.QDockWidget.DockWidgetMovable | - QtWidgets.QDockWidget.DockWidgetFloatable) + self.setFeatures(QtWidgets.QDockWidget.DockWidgetFeature.DockWidgetMovable | + QtWidgets.QDockWidget.DockWidgetFeature.DockWidgetFloatable) self.schedule_ctl = schedule_ctl self.table = QtWidgets.QTableView() - self.table.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows) - self.table.setSelectionMode(QtWidgets.QAbstractItemView.SingleSelection) + self.table.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectionBehavior.SelectRows) + self.table.setSelectionMode(QtWidgets.QAbstractItemView.SelectionMode.SingleSelection) self.table.verticalHeader().setSectionResizeMode( - QtWidgets.QHeaderView.ResizeToContents) + QtWidgets.QHeaderView.ResizeMode.ResizeToContents) self.table.verticalHeader().hide() self.setWidget(self.table) - self.table.setContextMenuPolicy(QtCore.Qt.ActionsContextMenu) - request_termination_action = QtWidgets.QAction("Request termination", self.table) + self.table.setContextMenuPolicy(QtCore.Qt.ContextMenuPolicy.ActionsContextMenu) + request_termination_action = QtGui.QAction("Request termination", self.table) request_termination_action.triggered.connect(partial(self.delete_clicked, True)) request_termination_action.setShortcut("DELETE") - request_termination_action.setShortcutContext(QtCore.Qt.WidgetShortcut) + request_termination_action.setShortcutContext(QtCore.Qt.ShortcutContext.WidgetShortcut) self.table.addAction(request_termination_action) - delete_action = QtWidgets.QAction("Delete", self.table) + delete_action = QtGui.QAction("Delete", self.table) delete_action.triggered.connect(partial(self.delete_clicked, False)) delete_action.setShortcut("SHIFT+DELETE") - delete_action.setShortcutContext(QtCore.Qt.WidgetShortcut) + delete_action.setShortcutContext(QtCore.Qt.ShortcutContext.WidgetShortcut) self.table.addAction(delete_action) - terminate_pipeline = QtWidgets.QAction( + terminate_pipeline = QtGui.QAction( "Gracefully terminate all in pipeline", self.table) terminate_pipeline.triggered.connect(self.terminate_pipeline_clicked) self.table.addAction(terminate_pipeline) diff --git a/artiq/dashboard/shortcuts.py b/artiq/dashboard/shortcuts.py index 30217b5f6..cac8c1e54 100644 --- a/artiq/dashboard/shortcuts.py +++ b/artiq/dashboard/shortcuts.py @@ -1,7 +1,7 @@ import logging from functools import partial -from PyQt5 import QtCore, QtWidgets +from PyQt6 import QtCore, QtGui, QtWidgets logger = logging.getLogger(__name__) @@ -11,8 +11,8 @@ class ShortcutsDock(QtWidgets.QDockWidget): def __init__(self, main_window, exp_manager): QtWidgets.QDockWidget.__init__(self, "Shortcuts") self.setObjectName("Shortcuts") - self.setFeatures(QtWidgets.QDockWidget.DockWidgetMovable | - QtWidgets.QDockWidget.DockWidgetFloatable) + self.setFeatures(QtWidgets.QDockWidget.DockWidgetFeature.DockWidgetMovable | + QtWidgets.QDockWidget.DockWidgetFeature.DockWidgetFloatable) layout = QtWidgets.QGridLayout() top_widget = QtWidgets.QWidget() @@ -36,25 +36,25 @@ class ShortcutsDock(QtWidgets.QDockWidget): layout.addWidget(QtWidgets.QLabel("F" + str(i + 1)), row, 0) label = QtWidgets.QLabel() - label.setSizePolicy(QtWidgets.QSizePolicy.Ignored, - QtWidgets.QSizePolicy.Ignored) + label.setSizePolicy(QtWidgets.QSizePolicy.Policy.Ignored, + QtWidgets.QSizePolicy.Policy.Ignored) layout.addWidget(label, row, 1) clear = QtWidgets.QToolButton() clear.setIcon(QtWidgets.QApplication.style().standardIcon( - QtWidgets.QStyle.SP_DialogDiscardButton)) + QtWidgets.QStyle.StandardPixmap.SP_DialogDiscardButton)) layout.addWidget(clear, row, 2) clear.clicked.connect(partial(self.set_shortcut, i, "")) open = QtWidgets.QToolButton() open.setIcon(QtWidgets.QApplication.style().standardIcon( - QtWidgets.QStyle.SP_DialogOpenButton)) + QtWidgets.QStyle.StandardPixmap.SP_DialogOpenButton)) layout.addWidget(open, row, 3) open.clicked.connect(partial(self._open_experiment, i)) submit = QtWidgets.QPushButton("Submit") submit.setIcon(QtWidgets.QApplication.style().standardIcon( - QtWidgets.QStyle.SP_DialogOkButton)) + QtWidgets.QStyle.StandardPixmap.SP_DialogOkButton)) layout.addWidget(submit, row, 4) submit.clicked.connect(partial(self._activated, i)) @@ -68,8 +68,8 @@ class ShortcutsDock(QtWidgets.QDockWidget): "open": open, "submit": submit } - shortcut = QtWidgets.QShortcut("F" + str(i + 1), main_window) - shortcut.setContext(QtCore.Qt.ApplicationShortcut) + shortcut = QtGui.QShortcut("F" + str(i+1), main_window) + shortcut.setContext(QtCore.Qt.ShortcutContext.ApplicationShortcut) shortcut.activated.connect(partial(self._activated, i)) def _activated(self, nr): diff --git a/artiq/examples/no_hardware/repository/custom_applet.py b/artiq/examples/no_hardware/repository/custom_applet.py index 0bc124325..78eb5618c 100644 --- a/artiq/examples/no_hardware/repository/custom_applet.py +++ b/artiq/examples/no_hardware/repository/custom_applet.py @@ -1,4 +1,4 @@ -from PyQt5 import QtWidgets +from PyQt6 import QtWidgets from artiq.applets.simple import SimpleApplet diff --git a/artiq/frontend/artiq_browser.py b/artiq/frontend/artiq_browser.py index 751c57d2e..c6c5d1b76 100755 --- a/artiq/frontend/artiq_browser.py +++ b/artiq/frontend/artiq_browser.py @@ -7,7 +7,7 @@ import os import logging import sys -from PyQt5 import QtCore, QtGui, QtWidgets +from PyQt6 import QtCore, QtGui, QtWidgets from qasync import QEventLoop from sipyco.asyncio_tools import atexit_register_coroutine @@ -68,9 +68,9 @@ class Browser(QtWidgets.QMainWindow): browse_root, dataset_sub) smgr.register(self.experiments) self.experiments.setHorizontalScrollBarPolicy( - QtCore.Qt.ScrollBarAsNeeded) + QtCore.Qt.ScrollBarPolicy.ScrollBarAsNeeded) self.experiments.setVerticalScrollBarPolicy( - QtCore.Qt.ScrollBarAsNeeded) + QtCore.Qt.ScrollBarPolicy.ScrollBarAsNeeded) self.setCentralWidget(self.experiments) self.files = files.FilesDock(dataset_sub, browse_root) @@ -91,29 +91,29 @@ class Browser(QtWidgets.QMainWindow): self.log = log.LogDock(None, "log") smgr.register(self.log) - self.log.setFeatures(self.log.DockWidgetMovable | - self.log.DockWidgetFloatable) + self.log.setFeatures(self.log.DockWidgetFeature.DockWidgetMovable | + self.log.DockWidgetFeature.DockWidgetFloatable) - self.addDockWidget(QtCore.Qt.LeftDockWidgetArea, self.files) - self.addDockWidget(QtCore.Qt.BottomDockWidgetArea, self.applets) - self.addDockWidget(QtCore.Qt.RightDockWidgetArea, self.datasets) - self.addDockWidget(QtCore.Qt.BottomDockWidgetArea, self.log) + self.addDockWidget(QtCore.Qt.DockWidgetArea.LeftDockWidgetArea, self.files) + self.addDockWidget(QtCore.Qt.DockWidgetArea.BottomDockWidgetArea, self.applets) + self.addDockWidget(QtCore.Qt.DockWidgetArea.RightDockWidgetArea, self.datasets) + self.addDockWidget(QtCore.Qt.DockWidgetArea.BottomDockWidgetArea, self.log) g = self.menuBar().addMenu("&Experiment") - a = QtWidgets.QAction("&Open", self) + a = QtGui.QAction("&Open", self) a.setIcon(QtWidgets.QApplication.style().standardIcon( - QtWidgets.QStyle.SP_DialogOpenButton)) - a.setShortcuts(QtGui.QKeySequence.Open) + QtWidgets.QStyle.StandardPixmap.SP_DialogOpenButton)) + a.setShortcuts(QtGui.QKeySequence.StandardKey.Open) a.setStatusTip("Open an experiment") a.triggered.connect(self.experiments.select_experiment) g.addAction(a) g = self.menuBar().addMenu("&View") - a = QtWidgets.QAction("Cascade", self) + a = QtGui.QAction("Cascade", self) a.setStatusTip("Cascade experiment windows") a.triggered.connect(self.experiments.cascadeSubWindows) g.addAction(a) - a = QtWidgets.QAction("Tile", self) + a = QtGui.QAction("Tile", self) a.setStatusTip("Tile experiment windows") a.triggered.connect(self.experiments.tileSubWindows) g.addAction(a) diff --git a/artiq/frontend/artiq_dashboard.py b/artiq/frontend/artiq_dashboard.py index a0606c391..297081ac3 100755 --- a/artiq/frontend/artiq_dashboard.py +++ b/artiq/frontend/artiq_dashboard.py @@ -7,7 +7,7 @@ import importlib import os import logging -from PyQt5 import QtCore, QtGui, QtWidgets +from PyQt6 import QtCore, QtGui, QtWidgets from qasync import QEventLoop from sipyco.pc_rpc import AsyncioClient, Client @@ -186,8 +186,8 @@ def main(): main_window = MainWindow(args.server if server_name is None else server_name) smgr.register(main_window) mdi_area = MdiArea() - mdi_area.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded) - mdi_area.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded) + mdi_area.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarPolicy.ScrollBarAsNeeded) + mdi_area.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarPolicy.ScrollBarAsNeeded) main_window.setCentralWidget(mdi_area) # create UI components @@ -257,10 +257,10 @@ def main(): d_datasets, d_applets, d_waveform, d_interactive_args ] - main_window.addDockWidget(QtCore.Qt.RightDockWidgetArea, right_docks[0]) + main_window.addDockWidget(QtCore.Qt.DockWidgetArea.RightDockWidgetArea, right_docks[0]) for d1, d2 in zip(right_docks, right_docks[1:]): main_window.tabifyDockWidget(d1, d2) - main_window.addDockWidget(QtCore.Qt.BottomDockWidgetArea, d_schedule) + main_window.addDockWidget(QtCore.Qt.DockWidgetArea.BottomDockWidgetArea, d_schedule) # load/initialize state if os.name == "nt": diff --git a/artiq/gui/applets.py b/artiq/gui/applets.py index 9609fbac0..36e826a7d 100644 --- a/artiq/gui/applets.py +++ b/artiq/gui/applets.py @@ -9,7 +9,7 @@ from functools import partial from itertools import count from types import SimpleNamespace -from PyQt5 import QtCore, QtGui, QtWidgets +from PyQt6 import QtCore, QtGui, QtWidgets from sipyco.pipe_ipc import AsyncioParentComm from sipyco.logging_tools import LogParser @@ -388,8 +388,8 @@ class _CompleterDelegate(QtWidgets.QStyledItemDelegate): completer = QtWidgets.QCompleter() completer.splitPath = lambda path: path.replace("/", ".").split(".") completer.setModelSorting( - QtWidgets.QCompleter.CaseSensitivelySortedModel) - completer.setCompletionRole(QtCore.Qt.DisplayRole) + QtWidgets.QCompleter.ModelSorting.CaseSensitivelySortedModel) + completer.setCompletionRole(QtCore.Qt.ItemDataRole.DisplayRole) if hasattr(self, "model"): # "TODO: Optimize updates in the source model" # - Qt (qcompleter.cpp), never ceasing to disappoint. @@ -420,8 +420,8 @@ class AppletsDock(QtWidgets.QDockWidget): """ QtWidgets.QDockWidget.__init__(self, "Applets") self.setObjectName("Applets") - self.setFeatures(QtWidgets.QDockWidget.DockWidgetMovable | - QtWidgets.QDockWidget.DockWidgetFloatable) + self.setFeatures(QtWidgets.QDockWidget.DockWidgetFeature.DockWidgetMovable | + QtWidgets.QDockWidget.DockWidgetFeature.DockWidgetFloatable) self.main_window = main_window self.dataset_sub = dataset_sub @@ -435,18 +435,18 @@ class AppletsDock(QtWidgets.QDockWidget): self.table = QtWidgets.QTreeWidget() self.table.setColumnCount(2) self.table.setHeaderLabels(["Name", "Command"]) - self.table.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows) - self.table.setSelectionMode(QtWidgets.QAbstractItemView.SingleSelection) + self.table.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectionBehavior.SelectRows) + self.table.setSelectionMode(QtWidgets.QAbstractItemView.SelectionMode.SingleSelection) self.table.header().setStretchLastSection(True) self.table.header().setSectionResizeMode( - QtWidgets.QHeaderView.ResizeToContents) - self.table.setTextElideMode(QtCore.Qt.ElideNone) + QtWidgets.QHeaderView.ResizeMode.ResizeToContents) + self.table.setTextElideMode(QtCore.Qt.TextElideMode.ElideNone) self.table.setDragEnabled(True) self.table.viewport().setAcceptDrops(True) self.table.setDropIndicatorShown(True) - self.table.setDragDropMode(QtWidgets.QAbstractItemView.InternalMove) + self.table.setDragDropMode(QtWidgets.QAbstractItemView.DragDropMode.InternalMove) self.setWidget(self.table) @@ -454,44 +454,44 @@ class AppletsDock(QtWidgets.QDockWidget): self.table.setItemDelegateForColumn(1, completer_delegate) dataset_sub.add_setmodel_callback(completer_delegate.set_model) - self.table.setContextMenuPolicy(QtCore.Qt.ActionsContextMenu) - new_action = QtWidgets.QAction("New applet", self.table) + self.table.setContextMenuPolicy(QtCore.Qt.ContextMenuPolicy.ActionsContextMenu) + new_action = QtGui.QAction("New applet", self.table) new_action.triggered.connect(partial(self.new_with_parent, self.new)) self.table.addAction(new_action) templates_menu = QtWidgets.QMenu() for name, template in _templates: spec = {"ty": "command", "command": template} - action = QtWidgets.QAction(name, self.table) + action = QtGui.QAction(name, self.table) action.triggered.connect(partial( self.new_with_parent, self.new, spec=spec)) templates_menu.addAction(action) - restart_action = QtWidgets.QAction("New applet from template", self.table) + restart_action = QtGui.QAction("New applet from template", self.table) restart_action.setMenu(templates_menu) self.table.addAction(restart_action) - restart_action = QtWidgets.QAction("Restart selected applet or group", self.table) + restart_action = QtGui.QAction("Restart selected applet or group", self.table) restart_action.setShortcut("CTRL+R") - restart_action.setShortcutContext(QtCore.Qt.WidgetShortcut) + restart_action.setShortcutContext(QtCore.Qt.ShortcutContext.WidgetShortcut) restart_action.triggered.connect(self.restart) self.table.addAction(restart_action) - delete_action = QtWidgets.QAction("Delete selected applet or group", self.table) + delete_action = QtGui.QAction("Delete selected applet or group", self.table) delete_action.setShortcut("DELETE") - delete_action.setShortcutContext(QtCore.Qt.WidgetShortcut) + delete_action.setShortcutContext(QtCore.Qt.ShortcutContext.WidgetShortcut) delete_action.triggered.connect(self.delete) self.table.addAction(delete_action) - close_nondocked_action = QtWidgets.QAction("Close non-docked applets", self.table) + close_nondocked_action = QtGui.QAction("Close non-docked applets", self.table) close_nondocked_action.setShortcut("CTRL+ALT+W") - close_nondocked_action.setShortcutContext(QtCore.Qt.ApplicationShortcut) + close_nondocked_action.setShortcutContext(QtCore.Qt.ShortcutContext.ApplicationShortcut) close_nondocked_action.triggered.connect(self.close_nondocked) self.table.addAction(close_nondocked_action) - new_group_action = QtWidgets.QAction("New group", self.table) + new_group_action = QtGui.QAction("New group", self.table) new_group_action.triggered.connect(partial(self.new_with_parent, self.new_group)) self.table.addAction(new_group_action) self.table.itemChanged.connect(self.item_changed) # HACK - self.table.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers) + self.table.setEditTriggers(QtWidgets.QAbstractItemView.EditTrigger.NoEditTriggers) self.table.itemDoubleClicked.connect(self.open_editor) def open_editor(self, item, column): @@ -518,7 +518,7 @@ class AppletsDock(QtWidgets.QDockWidget): del item.applet_code elif spec["ty"] == "code": item.setIcon(1, QtWidgets.QApplication.style().standardIcon( - QtWidgets.QStyle.SP_FileIcon)) + QtWidgets.QStyle.StandardPixmap.SP_FileIcon)) item.applet_code = spec["code"] else: raise ValueError @@ -530,7 +530,7 @@ class AppletsDock(QtWidgets.QDockWidget): def create(self, item, name, spec): dock = _AppletDock(self.dataset_sub, self.dataset_ctl, self.expmgr, item.applet_uid, name, spec, self.extra_substitutes) - self.main_window.addDockWidget(QtCore.Qt.RightDockWidgetArea, dock) + self.main_window.addDockWidget(QtCore.Qt.DockWidgetArea.RightDockWidgetArea, dock) dock.setFloating(True) asyncio.ensure_future(dock.start(), loop=self._loop) dock.sigClosed.connect(partial(self.on_dock_closed, item, dock)) @@ -547,7 +547,7 @@ class AppletsDock(QtWidgets.QDockWidget): dock.spec = self.get_spec(item) if column == 0: - if item.checkState(0) == QtCore.Qt.Checked: + if item.checkState(0) == QtCore.Qt.CheckState.Checked: if item.applet_dock is None: name = item.text(0) spec = self.get_spec(item) @@ -572,7 +572,7 @@ class AppletsDock(QtWidgets.QDockWidget): def on_dock_closed(self, item, dock): item.applet_geometry = dock.saveGeometry() asyncio.ensure_future(dock.terminate(), loop=self._loop) - item.setCheckState(0, QtCore.Qt.Unchecked) + item.setCheckState(0, QtCore.Qt.CheckState.Unchecked) def get_untitled(self): existing_names = set() @@ -602,18 +602,18 @@ class AppletsDock(QtWidgets.QDockWidget): name = self.get_untitled() item = QtWidgets.QTreeWidgetItem([name, ""]) item.ty = "applet" - item.setFlags(QtCore.Qt.ItemIsSelectable | - QtCore.Qt.ItemIsUserCheckable | - QtCore.Qt.ItemIsEditable | - QtCore.Qt.ItemIsDragEnabled | - QtCore.Qt.ItemNeverHasChildren | - QtCore.Qt.ItemIsEnabled) - item.setCheckState(0, QtCore.Qt.Unchecked) + item.setFlags(QtCore.Qt.ItemFlag.ItemIsSelectable | + QtCore.Qt.ItemFlag.ItemIsUserCheckable | + QtCore.Qt.ItemFlag.ItemIsEditable | + QtCore.Qt.ItemFlag.ItemIsDragEnabled | + QtCore.Qt.ItemFlag.ItemNeverHasChildren | + QtCore.Qt.ItemFlag.ItemIsEnabled) + item.setCheckState(0, QtCore.Qt.CheckState.Unchecked) item.applet_uid = uid item.applet_dock = None item.applet_geometry = None item.setIcon(0, QtWidgets.QApplication.style().standardIcon( - QtWidgets.QStyle.SP_ComputerIcon)) + QtWidgets.QStyle.StandardPixmap.SP_ComputerIcon)) self.set_spec(item, spec) if parent is None: self.table.addTopLevelItem(item) @@ -626,15 +626,15 @@ class AppletsDock(QtWidgets.QDockWidget): name = self.get_untitled() item = QtWidgets.QTreeWidgetItem([name, attr]) item.ty = "group" - item.setFlags(QtCore.Qt.ItemIsSelectable | - QtCore.Qt.ItemIsEditable | - QtCore.Qt.ItemIsUserCheckable | - QtCore.Qt.ItemIsTristate | - QtCore.Qt.ItemIsDragEnabled | - QtCore.Qt.ItemIsDropEnabled | - QtCore.Qt.ItemIsEnabled) + item.setFlags(QtCore.Qt.ItemFlag.ItemIsSelectable | + QtCore.Qt.ItemFlag.ItemIsEditable | + QtCore.Qt.ItemFlag.ItemIsUserCheckable | + QtCore.Qt.ItemFlag.ItemIsAutoTristate | + QtCore.Qt.ItemFlag.ItemIsDragEnabled | + QtCore.Qt.ItemFlag.ItemIsDropEnabled | + QtCore.Qt.ItemFlag.ItemIsEnabled) item.setIcon(0, QtWidgets.QApplication.style().standardIcon( - QtWidgets.QStyle.SP_DirIcon)) + QtWidgets.QStyle.StandardPixmap.SP_DirIcon)) if parent is None: self.table.addTopLevelItem(item) else: @@ -712,7 +712,7 @@ class AppletsDock(QtWidgets.QDockWidget): cwi = wi.child(row) if cwi.ty == "applet": uid = cwi.applet_uid - enabled = cwi.checkState(0) == QtCore.Qt.Checked + enabled = cwi.checkState(0) == QtCore.Qt.CheckState.Checked name = cwi.text(0) spec = self.get_spec(cwi) geometry = cwi.applet_geometry @@ -744,7 +744,7 @@ class AppletsDock(QtWidgets.QDockWidget): geometry = QtCore.QByteArray(geometry) item.applet_geometry = geometry if enabled: - item.setCheckState(0, QtCore.Qt.Checked) + item.setCheckState(0, QtCore.Qt.CheckState.Checked) elif wis[0] == "group": _, name, attr, expanded, state_child = wis item = self.new_group(name, attr, parent=parent) @@ -761,11 +761,11 @@ class AppletsDock(QtWidgets.QDockWidget): for i in range(wi.childCount()): cwi = wi.child(i) if cwi.ty == "applet": - if cwi.checkState(0) == QtCore.Qt.Checked: + if cwi.checkState(0) == QtCore.Qt.CheckState.Checked: if cwi.applet_dock is not None: if not cwi.applet_dock.isFloating(): continue - cwi.setCheckState(0, QtCore.Qt.Unchecked) + cwi.setCheckState(0, QtCore.Qt.CheckState.Unchecked) elif cwi.ty == "group": walk(cwi) walk(self.table.invisibleRootItem()) diff --git a/artiq/gui/entries.py b/artiq/gui/entries.py index 43daa7a5b..0a726a77e 100644 --- a/artiq/gui/entries.py +++ b/artiq/gui/entries.py @@ -2,7 +2,7 @@ import logging from collections import OrderedDict from functools import partial -from PyQt5 import QtCore, QtGui, QtWidgets +from PyQt6 import QtCore, QtGui, QtWidgets from artiq.gui.tools import LayoutWidget, disable_scroll_wheel, WheelFilter from artiq.gui.scanwidget import ScanWidget @@ -540,7 +540,8 @@ class _ExplicitScan(LayoutWidget): float_regexp = r"(([+-]?\d+(\.\d*)?|\.\d+)([eE][+-]?\d+)?)" regexp = "(float)?( +float)* *".replace("float", float_regexp) - self.value.setValidator(QtGui.QRegExpValidator(QtCore.QRegExp(regexp))) + self.value.setValidator(QtGui.QRegularExpressionValidator( + QtCore.QRegularExpression(regexp))) self.value.setText(" ".join([str(x) for x in state["sequence"]])) def update(text): diff --git a/artiq/gui/flowlayout.py b/artiq/gui/flowlayout.py index da6973d90..d597197e0 100644 --- a/artiq/gui/flowlayout.py +++ b/artiq/gui/flowlayout.py @@ -39,8 +39,8 @@ ############################################################################# -from PyQt5.QtCore import QPoint, QRect, QSize, Qt -from PyQt5.QtWidgets import (QApplication, QLayout, QPushButton, QSizePolicy, +from PyQt6.QtCore import QPoint, QRect, QSize, Qt +from PyQt6.QtWidgets import (QApplication, QLayout, QPushButton, QSizePolicy, QWidget) @@ -113,8 +113,8 @@ class FlowLayout(QLayout): for item in self.itemList: wid = item.widget() - spaceX = self.spacing() + wid.style().layoutSpacing(QSizePolicy.PushButton, QSizePolicy.PushButton, Qt.Horizontal) - spaceY = self.spacing() + wid.style().layoutSpacing(QSizePolicy.PushButton, QSizePolicy.PushButton, Qt.Vertical) + spaceX = self.spacing() + wid.style().layoutSpacing(QSizePolicy.ControlType.PushButton, QSizePolicy.ControlType.PushButton, Qt.Orientation.Horizontal) + spaceY = self.spacing() + wid.style().layoutSpacing(QSizePolicy.ControlType.PushButton, QSizePolicy.ControlType.PushButton, Qt.Orientation.Vertical) nextX = x + item.sizeHint().width() + spaceX if nextX - spaceX > rect.right() and lineHeight > 0: x = rect.x() diff --git a/artiq/gui/fuzzy_select.py b/artiq/gui/fuzzy_select.py index fe1daa668..36d8db2d3 100644 --- a/artiq/gui/fuzzy_select.py +++ b/artiq/gui/fuzzy_select.py @@ -2,7 +2,7 @@ import re from functools import partial from typing import List, Tuple -from PyQt5 import QtCore, QtWidgets +from PyQt6 import QtCore, QtGui, QtWidgets from artiq.gui.tools import LayoutWidget @@ -19,7 +19,7 @@ class FuzzySelectWidget(LayoutWidget): #: Raised when an entry has been selected, giving the label of the user #: choice and any additional QEvent.modifiers() (e.g. Ctrl key pressed). - finished = QtCore.pyqtSignal(str, int) + finished = QtCore.pyqtSignal(str, QtCore.Qt.KeyboardModifier) def __init__(self, choices: List[Tuple[str, int]] = [], @@ -138,16 +138,16 @@ class FuzzySelectWidget(LayoutWidget): first_action = None last_action = None for choice in filtered_choices: - action = QtWidgets.QAction(choice, self.menu) + action = QtGui.QAction(choice, self.menu) action.triggered.connect(partial(self._finish, action, choice)) - action.modifiers = 0 + action.modifiers = QtCore.Qt.KeyboardModifier.NoModifier self.menu.addAction(action) if not first_action: first_action = action last_action = action if num_omitted > 0: - action = QtWidgets.QAction("<{} not shown>".format(num_omitted), + action = QtGui.QAction("<{} not shown>".format(num_omitted), self.menu) action.setEnabled(False) self.menu.addAction(action) @@ -239,9 +239,9 @@ class _FocusEventFilter(QtCore.QObject): focus_lost = QtCore.pyqtSignal() def eventFilter(self, obj, event): - if event.type() == QtCore.QEvent.FocusIn: + if event.type() == QtCore.QEvent.Type.FocusIn: self.focus_gained.emit() - elif event.type() == QtCore.QEvent.FocusOut: + elif event.type() == QtCore.QEvent.Type.FocusOut: self.focus_lost.emit() return False @@ -251,8 +251,8 @@ class _EscapeKeyFilter(QtCore.QObject): escape_pressed = QtCore.pyqtSignal() def eventFilter(self, obj, event): - if event.type() == QtCore.QEvent.KeyPress: - if event.key() == QtCore.Qt.Key_Escape: + if event.type() == QtCore.QEvent.Type.KeyPress: + if event.key() == QtCore.Qt.Key.Key_Escape: self.escape_pressed.emit() return False @@ -266,13 +266,13 @@ class _UpDownKeyFilter(QtCore.QObject): self.last_item = last_item def eventFilter(self, obj, event): - if event.type() == QtCore.QEvent.KeyPress: - if event.key() == QtCore.Qt.Key_Down: + if event.type() == QtCore.QEvent.Type.KeyPress: + if event.key() == QtCore.Qt.Key.Key_Down: self.menu.setActiveAction(self.first_item) self.menu.setFocus() return True - if event.key() == QtCore.Qt.Key_Up: + if event.key() == QtCore.Qt.Key.Key_Up: self.menu.setActiveAction(self.last_item) self.menu.setFocus() return True @@ -286,16 +286,16 @@ class _NonUpDownKeyFilter(QtCore.QObject): self.target = target def eventFilter(self, obj, event): - if event.type() == QtCore.QEvent.KeyPress: + if event.type() == QtCore.QEvent.Type.KeyPress: k = event.key() - if k in (QtCore.Qt.Key_Return, QtCore.Qt.Key_Enter): + if k in (QtCore.Qt.Key.Key_Return, QtCore.Qt.Key.Key_Enter): action = obj.activeAction() if action is not None: action.modifiers = event.modifiers() return False - if (k != QtCore.Qt.Key_Down and k != QtCore.Qt.Key_Up - and k != QtCore.Qt.Key_Enter - and k != QtCore.Qt.Key_Return): + if (k != QtCore.Qt.Key.Key_Down and k != QtCore.Qt.Key.Key_Up + and k != QtCore.Qt.Key.Key_Enter + and k != QtCore.Qt.Key.Key_Return): QtWidgets.QApplication.sendEvent(self.target, event) return True return False diff --git a/artiq/gui/log.py b/artiq/gui/log.py index 3b5095f98..d0f0c147d 100644 --- a/artiq/gui/log.py +++ b/artiq/gui/log.py @@ -3,7 +3,7 @@ import time import re from functools import partial -from PyQt5 import QtCore, QtGui, QtWidgets +from PyQt6 import QtCore, QtGui, QtWidgets from sipyco.logging_tools import SourceFilter from artiq.gui.tools import (LayoutWidget, log_level_to_name, @@ -20,7 +20,7 @@ class _ModelItem: class _LogFilterProxyModel(QtCore.QSortFilterProxyModel): def __init__(self): super().__init__() - self.setFilterCaseSensitivity(QtCore.Qt.CaseInsensitive) + self.setFilterCaseSensitivity(QtCore.Qt.CaseSensitivity.CaseInsensitive) self.setRecursiveFilteringEnabled(True) self.filter_level = 0 @@ -28,13 +28,13 @@ class _LogFilterProxyModel(QtCore.QSortFilterProxyModel): source = self.sourceModel() index0 = source.index(source_row, 0, source_parent) index1 = source.index(source_row, 1, source_parent) - level = source.data(index0, QtCore.Qt.UserRole) + level = source.data(index0, QtCore.Qt.ItemDataRole.UserRole) if level >= self.filter_level: - regex = self.filterRegExp() - index0_text = source.data(index0, QtCore.Qt.DisplayRole) - msg_text = source.data(index1, QtCore.Qt.DisplayRole) - return (regex.indexIn(index0_text) != -1 or regex.indexIn(msg_text) != -1) + regex = self.filterRegularExpression() + index0_text = source.data(index0, QtCore.Qt.ItemDataRole.DisplayRole) + msg_text = source.data(index1, QtCore.Qt.ItemDataRole.DisplayRole) + return (regex.match(index0_text).hasMatch() or regex.match(msg_text).hasMatch()) else: return False @@ -57,7 +57,7 @@ class _Model(QtCore.QAbstractItemModel): timer.timeout.connect(self.timer_tick) timer.start(100) - self.fixed_font = QtGui.QFontDatabase.systemFont(QtGui.QFontDatabase.FixedFont) + self.fixed_font = QtGui.QFontDatabase.systemFont(QtGui.QFontDatabase.SystemFont.FixedFont) self.white = QtGui.QBrush(QtGui.QColor(255, 255, 255)) self.black = QtGui.QBrush(QtGui.QColor(0, 0, 0)) @@ -66,8 +66,8 @@ class _Model(QtCore.QAbstractItemModel): self.error_bg = QtGui.QBrush(QtGui.QColor(255, 150, 150)) def headerData(self, col, orientation, role): - if (orientation == QtCore.Qt.Horizontal - and role == QtCore.Qt.DisplayRole): + if (orientation == QtCore.Qt.Orientation.Horizontal + and role == QtCore.Qt.ItemDataRole.DisplayRole): return self.headers[col] return None @@ -155,9 +155,9 @@ class _Model(QtCore.QAbstractItemModel): else: msgnum = item.parent.row - if role == QtCore.Qt.FontRole and index.column() == 1: + if role == QtCore.Qt.ItemDataRole.FontRole and index.column() == 1: return self.fixed_font - elif role == QtCore.Qt.BackgroundRole: + elif role == QtCore.Qt.ItemDataRole.BackgroundRole: level = self.entries[msgnum][0] if level >= logging.ERROR: return self.error_bg @@ -165,13 +165,13 @@ class _Model(QtCore.QAbstractItemModel): return self.warning_bg else: return self.white - elif role == QtCore.Qt.ForegroundRole: + elif role == QtCore.Qt.ItemDataRole.ForegroundRole: level = self.entries[msgnum][0] if level <= logging.DEBUG: return self.debug_fg else: return self.black - elif role == QtCore.Qt.DisplayRole: + elif role == QtCore.Qt.ItemDataRole.DisplayRole: v = self.entries[msgnum] column = index.column() if item.parent is self: @@ -184,7 +184,7 @@ class _Model(QtCore.QAbstractItemModel): return "" else: return v[3][item.row+1] - elif role == QtCore.Qt.ToolTipRole: + elif role == QtCore.Qt.ItemDataRole.ToolTipRole: v = self.entries[msgnum] if item.parent is self: lineno = 0 @@ -193,7 +193,7 @@ class _Model(QtCore.QAbstractItemModel): return (log_level_to_name(v[0]) + ", " + time.strftime("%m/%d %H:%M:%S", time.localtime(v[2])) + "\n" + v[3][lineno]) - elif role == QtCore.Qt.UserRole: + elif role == QtCore.Qt.ItemDataRole.UserRole: return self.entries[msgnum][0] @@ -218,13 +218,13 @@ class LogDock(QDockWidgetCloseDetect): scrollbottom = QtWidgets.QToolButton() scrollbottom.setToolTip("Scroll to bottom") scrollbottom.setIcon(QtWidgets.QApplication.style().standardIcon( - QtWidgets.QStyle.SP_ArrowDown)) + QtWidgets.QStyle.StandardPixmap.SP_ArrowDown)) grid.addWidget(scrollbottom, 0, 3) scrollbottom.clicked.connect(self.scroll_to_bottom) clear = QtWidgets.QToolButton() clear.setIcon(QtWidgets.QApplication.style().standardIcon( - QtWidgets.QStyle.SP_DialogResetButton)) + QtWidgets.QStyle.StandardPixmap.SP_DialogResetButton)) grid.addWidget(clear, 0, 4) clear.clicked.connect(lambda: self.model.clear()) @@ -232,7 +232,7 @@ class LogDock(QDockWidgetCloseDetect): newdock = QtWidgets.QToolButton() newdock.setToolTip("Create new log dock") newdock.setIcon(QtWidgets.QApplication.style().standardIcon( - QtWidgets.QStyle.SP_FileDialogNewFolder)) + QtWidgets.QStyle.StandardPixmap.SP_FileDialogNewFolder)) # note the lambda, the default parameter is overriden otherwise newdock.clicked.connect(lambda: manager.create_new_dock()) grid.addWidget(newdock, 0, 5) @@ -240,27 +240,27 @@ class LogDock(QDockWidgetCloseDetect): self.log = QtWidgets.QTreeView() self.log.setHorizontalScrollMode( - QtWidgets.QAbstractItemView.ScrollPerPixel) + QtWidgets.QAbstractItemView.ScrollMode.ScrollPerPixel) self.log.setVerticalScrollMode( - QtWidgets.QAbstractItemView.ScrollPerPixel) - self.log.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded) + QtWidgets.QAbstractItemView.ScrollMode.ScrollPerPixel) + self.log.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarPolicy.ScrollBarAsNeeded) grid.addWidget(self.log, 1, 0, colspan=6 if manager else 5) self.scroll_at_bottom = False self.scroll_value = 0 - self.log.setContextMenuPolicy(QtCore.Qt.ActionsContextMenu) - copy_action = QtWidgets.QAction("Copy entry to clipboard", self.log) + self.log.setContextMenuPolicy(QtCore.Qt.ContextMenuPolicy.ActionsContextMenu) + copy_action = QtGui.QAction("Copy entry to clipboard", self.log) copy_action.triggered.connect(self.copy_to_clipboard) self.log.addAction(copy_action) - clear_action = QtWidgets.QAction("Clear", self.log) + clear_action = QtGui.QAction("Clear", self.log) clear_action.triggered.connect(lambda: self.model.clear()) self.log.addAction(clear_action) # If Qt worked correctly, this would be nice to have. Alas, resizeSections # is broken when the horizontal scrollbar is enabled. - # sizeheader_action = QtWidgets.QAction("Resize header", self.log) + # sizeheader_action = QtGui.QAction("Resize header", self.log) # sizeheader_action.triggered.connect( - # lambda: self.log.header().resizeSections(QtWidgets.QHeaderView.ResizeToContents)) + # lambda: self.log.header().resizeSections(QtWidgets.QHeaderView.ResizeMode.ResizeToContents)) # self.log.addAction(sizeheader_action) cw = QtGui.QFontMetrics(self.font()).averageCharWidth() @@ -279,7 +279,7 @@ class LogDock(QDockWidgetCloseDetect): self.filter_level.currentIndexChanged.connect(self.apply_level_filter) def apply_text_filter(self): - self.proxy_model.setFilterRegExp(self.filter_freetext.text()) + self.proxy_model.setFilterRegularExpression(self.filter_freetext.text()) def apply_level_filter(self): self.proxy_model.apply_filter_level(self.filter_level.currentText()) @@ -366,7 +366,7 @@ class LogDockManager: dock = LogDock(self, name) self.docks[name] = dock if add_to_area: - self.main_window.addDockWidget(QtCore.Qt.RightDockWidgetArea, dock) + self.main_window.addDockWidget(QtCore.Qt.DockWidgetArea.RightDockWidgetArea, dock) dock.setFloating(True) dock.sigClosed.connect(partial(self.on_dock_closed, name)) self.update_closable() @@ -379,8 +379,8 @@ class LogDockManager: self.update_closable() def update_closable(self): - flags = (QtWidgets.QDockWidget.DockWidgetMovable | - QtWidgets.QDockWidget.DockWidgetFloatable) + flags = (QtWidgets.QDockWidget.DockWidgetFeature.DockWidgetMovable | + QtWidgets.QDockWidget.DockWidgetFeature.DockWidgetFloatable) if len(self.docks) > 1: flags |= QtWidgets.QDockWidget.DockWidgetClosable for dock in self.docks.values(): @@ -396,7 +396,7 @@ class LogDockManager: dock = LogDock(self, name) self.docks[name] = dock dock.restore_state(dock_state) - self.main_window.addDockWidget(QtCore.Qt.RightDockWidgetArea, dock) + self.main_window.addDockWidget(QtCore.Qt.DockWidgetArea.RightDockWidgetArea, dock) dock.sigClosed.connect(partial(self.on_dock_closed, name)) self.update_closable() diff --git a/artiq/gui/models.py b/artiq/gui/models.py index 4d6f19c22..810fa4505 100644 --- a/artiq/gui/models.py +++ b/artiq/gui/models.py @@ -1,4 +1,4 @@ -from PyQt5 import QtCore +from PyQt6 import QtCore from sipyco.sync_struct import Subscriber, process_mod @@ -91,15 +91,15 @@ class DictSyncModel(QtCore.QAbstractTableModel): return len(self.headers) def data(self, index, role): - if not index.isValid() or role != QtCore.Qt.DisplayRole: + if not index.isValid() or role != QtCore.Qt.ItemDataRole.DisplayRole: return None else: k = self.row_to_key[index.row()] return self.convert(k, self.backing_store[k], index.column()) def headerData(self, col, orientation, role): - if (orientation == QtCore.Qt.Horizontal and - role == QtCore.Qt.DisplayRole): + if (orientation == QtCore.Qt.Orientation.Horizontal and + role == QtCore.Qt.ItemDataRole.DisplayRole): return self.headers[col] return None @@ -170,15 +170,15 @@ class ListSyncModel(QtCore.QAbstractTableModel): return len(self.headers) def data(self, index, role): - if not index.isValid() or role != QtCore.Qt.DisplayRole: + if not index.isValid() or role != QtCore.Qt.ItemDataRole.DisplayRole: return None else: return self.convert(self.backing_store[index.row()], index.column()) def headerData(self, col, orientation, role): - if (orientation == QtCore.Qt.Horizontal and - role == QtCore.Qt.DisplayRole): + if (orientation == QtCore.Qt.Orientation.Horizontal and + role == QtCore.Qt.ItemDataRole.DisplayRole): return self.headers[col] return None @@ -271,8 +271,8 @@ class DictSyncTreeSepModel(QtCore.QAbstractItemModel): return len(self.headers) def headerData(self, col, orientation, role): - if (orientation == QtCore.Qt.Horizontal and - role == QtCore.Qt.DisplayRole): + if (orientation == QtCore.Qt.Orientation.Horizontal and + role == QtCore.Qt.ItemDataRole.DisplayRole): return self.headers[col] return None @@ -394,19 +394,19 @@ class DictSyncTreeSepModel(QtCore.QAbstractItemModel): return key def data(self, index, role): - if not index.isValid() or (role != QtCore.Qt.DisplayRole - and role != QtCore.Qt.ToolTipRole): + if not index.isValid() or (role != QtCore.Qt.ItemDataRole.DisplayRole + and role != QtCore.Qt.ItemDataRole.ToolTipRole): return None else: column = index.column() - if column == 0 and role == QtCore.Qt.DisplayRole: + if column == 0 and role == QtCore.Qt.ItemDataRole.DisplayRole: return index.internalPointer().name else: key = self.index_to_key(index) if key is None: return None else: - if role == QtCore.Qt.DisplayRole: + if role == QtCore.Qt.ItemDataRole.DisplayRole: convert = self.convert else: convert = self.convert_tooltip diff --git a/artiq/gui/scanwidget.py b/artiq/gui/scanwidget.py index e3231c6ab..b2aeb8bde 100644 --- a/artiq/gui/scanwidget.py +++ b/artiq/gui/scanwidget.py @@ -1,6 +1,6 @@ import logging -from PyQt5 import QtGui, QtCore, QtWidgets +from PyQt6 import QtGui, QtCore, QtWidgets import numpy as np from .ticker import Ticker @@ -23,15 +23,15 @@ class ScanWidget(QtWidgets.QWidget): self.ticker = Ticker() - self.setContextMenuPolicy(QtCore.Qt.ActionsContextMenu) - action = QtWidgets.QAction("V&iew range", self) + self.setContextMenuPolicy(QtCore.Qt.ContextMenuPolicy.ActionsContextMenu) + action = QtGui.QAction("V&iew range", self) action.setShortcut(QtGui.QKeySequence("CTRL+i")) - action.setShortcutContext(QtCore.Qt.WidgetShortcut) + action.setShortcutContext(QtCore.Qt.ShortcutContext.WidgetShortcut) action.triggered.connect(self.viewRange) self.addAction(action) - action = QtWidgets.QAction("Sna&p range", self) + action = QtGui.QAction("Sna&p range", self) action.setShortcut(QtGui.QKeySequence("CTRL+p")) - action.setShortcutContext(QtCore.Qt.WidgetShortcut) + action.setShortcutContext(QtCore.Qt.ShortcutContext.WidgetShortcut) action.triggered.connect(self.snapRange) self.addAction(action) @@ -143,56 +143,56 @@ class ScanWidget(QtWidgets.QWidget): if ev.buttons() ^ ev.button(): # buttons changed ev.ignore() return - if ev.modifiers() & QtCore.Qt.ShiftModifier: + if ev.modifiers() & QtCore.Qt.KeyboardModifier.ShiftModifier: self._drag = "select" - self.setStart(self._pixelToAxis(ev.x())) + self.setStart(self._pixelToAxis(ev.position().x())) self.setStop(self._start) - elif ev.modifiers() & QtCore.Qt.ControlModifier: + elif ev.modifiers() & QtCore.Qt.KeyboardModifier.ControlModifier: self._drag = "zoom" - self._offset = QtCore.QPoint(ev.x(), 0) + self._offset = QtCore.QPoint(ev.position().x(), 0) self._rubber = QtWidgets.QRubberBand( QtWidgets.QRubberBand.Rectangle, self) self._rubber.setGeometry(QtCore.QRect( - self._offset, QtCore.QPoint(ev.x(), self.height() - 1))) + self._offset, QtCore.QPoint(ev.position().x(), self.height() - 1))) self._rubber.show() else: qfm = QtGui.QFontMetrics(self.font()) - if ev.y() <= 2.5*qfm.lineSpacing(): + if ev.position().y() <= 2.5*qfm.lineSpacing(): self._drag = "axis" - self._offset = ev.x() - self._axisView[0] + self._offset = ev.position().x() - self._axisView[0] # testing should match inverse drawing order for start/stop elif abs(self._axisToPixel(self._stop) - - ev.x()) < qfm.lineSpacing()/2: + ev.position().x()) < qfm.lineSpacing()/2: self._drag = "stop" - self._offset = ev.x() - self._axisToPixel(self._stop) + self._offset = ev.position().x() - self._axisToPixel(self._stop) elif abs(self._axisToPixel(self._start) - - ev.x()) < qfm.lineSpacing()/2: + ev.position().x()) < qfm.lineSpacing()/2: self._drag = "start" - self._offset = ev.x() - self._axisToPixel(self._start) + self._offset = ev.position().x() - self._axisToPixel(self._start) else: self._drag = "both" - self._offset = (ev.x() - self._axisToPixel(self._start), - ev.x() - self._axisToPixel(self._stop)) + self._offset = (ev.position().x() - self._axisToPixel(self._start), + ev.position().x() - self._axisToPixel(self._stop)) def mouseMoveEvent(self, ev): if not self._drag: ev.ignore() return if self._drag == "select": - self.setStop(self._pixelToAxis(ev.x())) + self.setStop(self._pixelToAxis(ev.position().x())) elif self._drag == "zoom": self._rubber.setGeometry(QtCore.QRect( - self._offset, QtCore.QPoint(ev.x(), self.height() - 1) + self._offset, QtCore.QPoint(ev.position().x(), self.height() - 1) ).normalized()) elif self._drag == "axis": - self._setView(ev.x() - self._offset, self._axisView[1]) + self._setView(ev.position().x() - self._offset, self._axisView[1]) elif self._drag == "start": - self.setStart(self._pixelToAxis(ev.x() - self._offset)) + self.setStart(self._pixelToAxis(ev.position().x() - self._offset)) elif self._drag == "stop": - self.setStop(self._pixelToAxis(ev.x() - self._offset)) + self.setStop(self._pixelToAxis(ev.position().x() - self._offset)) elif self._drag == "both": - self.setStart(self._pixelToAxis(ev.x() - self._offset[0])) - self.setStop(self._pixelToAxis(ev.x() - self._offset[1])) + self.setStart(self._pixelToAxis(ev.position().x() - self._offset[0])) + self.setStop(self._pixelToAxis(ev.position().x() - self._offset[1])) def mouseReleaseEvent(self, ev): if self._drag == "zoom": @@ -217,10 +217,10 @@ class ScanWidget(QtWidgets.QWidget): y = round(ev.angleDelta().y()/120.) if not y: return - if ev.modifiers() & QtCore.Qt.ShiftModifier: + if ev.modifiers() & QtCore.Qt.KeyboardModifier.ShiftModifier: self.setNum(max(1, self._num + y)) else: - self._zoom(self.zoomFactor**y, ev.x()) + self._zoom(self.zoomFactor**y, ev.position().x()) def resizeEvent(self, ev): if not ev.oldSize().isValid() or not ev.oldSize().width(): @@ -245,8 +245,8 @@ class ScanWidget(QtWidgets.QWidget): ticks, prefix, labels = self.ticker(self._pixelToAxis(0), self._pixelToAxis(self.width())) rect = QtCore.QRect(0, 0, self.width(), lineSpacing) - painter.drawText(rect, QtCore.Qt.AlignLeft, prefix) - painter.drawText(rect, QtCore.Qt.AlignRight, self.suffix) + painter.drawText(rect, QtCore.Qt.AlignmentFlag.AlignLeft, prefix) + painter.drawText(rect, QtCore.Qt.AlignmentFlag.AlignRight, self.suffix) painter.translate(0, lineSpacing + ascent) @@ -264,7 +264,7 @@ class ScanWidget(QtWidgets.QWidget): painter.drawLine(int(p), 0, int(p), int(lineSpacing/2)) painter.translate(0, int(lineSpacing/2)) - for x, c in (self._start, QtCore.Qt.blue), (self._stop, QtCore.Qt.red): + for x, c in (self._start, QtCore.Qt.GlobalColor.blue), (self._stop, QtCore.Qt.GlobalColor.red): x = self._axisToPixel(x) painter.setPen(c) painter.setBrush(c) diff --git a/artiq/gui/scientific_spinbox.py b/artiq/gui/scientific_spinbox.py index fcbf48c29..7faedae02 100644 --- a/artiq/gui/scientific_spinbox.py +++ b/artiq/gui/scientific_spinbox.py @@ -1,6 +1,6 @@ import re from math import inf, copysign -from PyQt5 import QtCore, QtGui, QtWidgets +from PyQt6 import QtCore, QtGui, QtWidgets _float_acceptable = re.compile( @@ -16,8 +16,8 @@ class ScientificSpinBox(QtWidgets.QDoubleSpinBox): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.setGroupSeparatorShown(False) - self.setInputMethodHints(QtCore.Qt.ImhNone) - self.setCorrectionMode(self.CorrectToPreviousValue) + self.setInputMethodHints(QtCore.Qt.InputMethodHint.ImhNone) + self.setCorrectionMode(self.CorrectionMode.CorrectToPreviousValue) # singleStep: resolution for step, buttons, accelerators # decimals: absolute rounding granularity # sigFigs: number of significant digits shown @@ -69,11 +69,11 @@ class ScientificSpinBox(QtWidgets.QDoubleSpinBox): clean = clean.rsplit(self.suffix(), 1)[0] try: float(clean) # faster than matching - return QtGui.QValidator.Acceptable, text, pos + return QtGui.QValidator.State.Acceptable, text, pos except ValueError: if re.fullmatch(_float_intermediate, clean): - return QtGui.QValidator.Intermediate, text, pos - return QtGui.QValidator.Invalid, text, pos + return QtGui.QValidator.State.Intermediate, text, pos + return QtGui.QValidator.State.Invalid, text, pos def stepBy(self, s): if abs(s) < 10: # unaccelerated buttons, keys, wheel/trackpad diff --git a/artiq/gui/tools.py b/artiq/gui/tools.py index 957823780..2b277c3e7 100644 --- a/artiq/gui/tools.py +++ b/artiq/gui/tools.py @@ -1,7 +1,7 @@ import asyncio import logging -from PyQt5 import QtCore, QtWidgets +from PyQt6 import QtCore, QtWidgets class DoubleClickLineEdit(QtWidgets.QLineEdit): @@ -56,9 +56,9 @@ class WheelFilter(QtCore.QObject): self.ignore_with_modifier = ignore_with_modifier def eventFilter(self, obj, event): - if event.type() != QtCore.QEvent.Wheel: + if event.type() != QtCore.QEvent.Type.Wheel: return False - has_modifier = event.modifiers() != QtCore.Qt.NoModifier + has_modifier = event.modifiers() != QtCore.Qt.KeyboardModifier.NoModifier if has_modifier == self.ignore_with_modifier: event.ignore() return True @@ -66,7 +66,7 @@ class WheelFilter(QtCore.QObject): def disable_scroll_wheel(widget): - widget.setFocusPolicy(QtCore.Qt.StrongFocus) + widget.setFocusPolicy(QtCore.Qt.FocusPolicy.StrongFocus) widget.installEventFilter(WheelFilter(widget)) @@ -91,8 +91,8 @@ class LayoutWidget(QtWidgets.QWidget): async def get_open_file_name(parent, caption, dir, filter): """like QtWidgets.QFileDialog.getOpenFileName(), but a coroutine""" dialog = QtWidgets.QFileDialog(parent, caption, dir, filter) - dialog.setFileMode(dialog.ExistingFile) - dialog.setAcceptMode(dialog.AcceptOpen) + dialog.setFileMode(dialog.FileMode.ExistingFile) + dialog.setAcceptMode(dialog.AcceptMode.AcceptOpen) fut = asyncio.Future() def on_accept(): @@ -124,7 +124,7 @@ async def get_save_file_name(parent, caption, dir, filter, suffix=None): # http://stackoverflow.com/questions/250890/using-qsortfilterproxymodel-with-a-tree-model class QRecursiveFilterProxyModel(QtCore.QSortFilterProxyModel): def filterAcceptsRow(self, source_row, source_parent): - regexp = self.filterRegExp() + regexp = self.filterRegularExpression() if not regexp.isEmpty(): source_index = self.sourceModel().index( source_row, self.filterKeyColumn(), source_parent) @@ -133,6 +133,6 @@ class QRecursiveFilterProxyModel(QtCore.QSortFilterProxyModel): if self.filterAcceptsRow(i, source_index): return True key = self.sourceModel().data(source_index, self.filterRole()) - return regexp.indexIn(key) != -1 + return regexp.match(key).hasMatch() return QtCore.QSortFilterProxyModel.filterAcceptsRow( self, source_row, source_parent) diff --git a/artiq/gui/waitingspinnerwidget.py b/artiq/gui/waitingspinnerwidget.py index 6967e6dea..0e3097b40 100644 --- a/artiq/gui/waitingspinnerwidget.py +++ b/artiq/gui/waitingspinnerwidget.py @@ -27,9 +27,9 @@ SOFTWARE. import math -from PyQt5.QtCore import * -from PyQt5.QtGui import * -from PyQt5.QtWidgets import * +from PyQt6.QtCore import * +from PyQt6.QtGui import * +from PyQt6.QtWidgets import * class QtWaitingSpinner(QWidget): @@ -37,7 +37,7 @@ class QtWaitingSpinner(QWidget): super().__init__() # WAS IN initialize() - self._color = QColor(Qt.black) + self._color = Qt.GlobalColor.black self._roundness = 100.0 self._minimumTrailOpacity = 3.14159265358979323846 self._trailFadePercentage = 80.0 @@ -54,17 +54,17 @@ class QtWaitingSpinner(QWidget): self.updateTimer() # END initialize() - self.setAttribute(Qt.WA_TranslucentBackground) + self.setAttribute(Qt.WidgetAttribute.WA_TranslucentBackground) def paintEvent(self, QPaintEvent): painter = QPainter(self) - painter.fillRect(self.rect(), Qt.transparent) - painter.setRenderHint(QPainter.Antialiasing, True) + painter.fillRect(self.rect(), Qt.GlobalColor.transparent) + painter.setRenderHint(QPainter.RenderHint.Antialiasing, True) if self._currentCounter >= self._numberOfLines: self._currentCounter = 0 - painter.setPen(Qt.NoPen) + painter.setPen(Qt.PenStyle.NoPen) for i in range(0, self._numberOfLines): painter.save() painter.translate(self._innerRadius + self._lineLength, self._innerRadius + self._lineLength) @@ -76,7 +76,7 @@ class QtWaitingSpinner(QWidget): self._minimumTrailOpacity, self._color) painter.setBrush(color) painter.drawRoundedRect(QRect(0, int(-self._lineWidth / 2), self._lineLength, self._lineWidth), self._roundness, - self._roundness, Qt.RelativeSize) + self._roundness, Qt.SizeMode.RelativeSize) painter.restore() def start(self): @@ -136,7 +136,7 @@ class QtWaitingSpinner(QWidget): def setRoundness(self, roundness): self._roundness = max(0.0, min(100.0, roundness)) - def setColor(self, color=Qt.black): + def setColor(self, color=Qt.GlobalColor.black): self._color = QColor(color) def setRevolutionsPerSecond(self, revolutionsPerSecond): diff --git a/doc/manual/conf.py b/doc/manual/conf.py index e25a3b927..50300b782 100644 --- a/doc/manual/conf.py +++ b/doc/manual/conf.py @@ -37,7 +37,7 @@ mock_modules = ["artiq.gui.waitingspinnerwidget", "artiq.dashboard.waveform", "artiq.dashboard.interactive_args", "qasync", "pyqtgraph", "matplotlib", "lmdb", - "numpy", "dateutil", "dateutil.parser", "prettytable", "PyQt5", + "numpy", "dateutil", "dateutil.parser", "prettytable", "PyQt6", "h5py", "serial", "scipy", "scipy.interpolate", "llvmlite", "Levenshtein", "pythonparser", "sipyco", "sipyco.pc_rpc", "sipyco.sync_struct", diff --git a/doc/manual/introduction.rst b/doc/manual/introduction.rst index a6983e74d..809b58daf 100644 --- a/doc/manual/introduction.rst +++ b/doc/manual/introduction.rst @@ -16,7 +16,7 @@ ARTIQ and its dependencies are available in the form of Nix packages (for Linux) ARTIQ is supported by M-Labs and developed openly. Components, features, fixes, improvements, and extensions are often `funded `_ by and developed for the partnering research groups. -Core technologies employed include `Python `_, `Migen `_, `Migen-AXI `_, `Rust `_, `MiSoC `_/`VexRiscv `_, `LLVM `_/`llvmlite `_, and `Qt5 `_. +Core technologies employed include `Python `_, `Migen `_, `Migen-AXI `_, `Rust `_, `MiSoC `_/`VexRiscv `_, `LLVM `_/`llvmlite `_, and `Qt6 `_. | Website: https://m-labs.hk/experiment-control/artiq | (US-hosted mirror: https://m-labs-intl.com/experiment-control/artiq) diff --git a/flake.nix b/flake.nix index f8c05604c..36ac02ace 100644 --- a/flake.nix +++ b/flake.nix @@ -76,7 +76,7 @@ rev = "v${version}"; sha256 = "sha256-DAzmobw+c29Pt/URGO3bWXHBxgu9bDHhdTUBE9QJDe4="; }; - propagatedBuildInputs = [ pkgs.python3Packages.pyqt5 ]; + propagatedBuildInputs = [ pkgs.python3Packages.pyqt6 ]; nativeCheckInputs = [ pkgs.python3Packages.pytest-runner pkgs.python3Packages.pytestCheckHook ]; disabledTestPaths = [ "tests/test_qeventloop.py" ]; }; @@ -132,10 +132,10 @@ export VERSIONEER_REV=${artiqRev} ''; - nativeBuildInputs = [ pkgs.qt5.wrapQtAppsHook ]; + nativeBuildInputs = [ pkgs.qt6.wrapQtAppsHook ]; # keep llvm_x and lld_x in sync with llvmlite - propagatedBuildInputs = [ pkgs.llvm_15 pkgs.lld_15 sipyco.packages.x86_64-linux.sipyco pythonparser llvmlite-new pkgs.qt5.qtsvg artiq-comtools.packages.x86_64-linux.artiq-comtools ] - ++ (with pkgs.python3Packages; [ pyqtgraph pygit2 numpy dateutil scipy prettytable pyserial levenshtein h5py pyqt5 qasync tqdm lmdb jsonschema ]); + propagatedBuildInputs = [ pkgs.llvm_15 pkgs.lld_15 sipyco.packages.x86_64-linux.sipyco pythonparser llvmlite-new pkgs.qt6.qtsvg artiq-comtools.packages.x86_64-linux.artiq-comtools ] + ++ (with pkgs.python3Packages; [ pyqtgraph pygit2 numpy dateutil scipy prettytable pyserial levenshtein h5py pyqt6 qasync tqdm lmdb jsonschema ]); dontWrapQtApps = true; postFixup = '' @@ -413,8 +413,8 @@ ]; shellHook = '' export LIBARTIQ_SUPPORT=`libartiq-support` - export QT_PLUGIN_PATH=${pkgs.qt5.qtbase}/${pkgs.qt5.qtbase.dev.qtPluginPrefix}:${pkgs.qt5.qtsvg.bin}/${pkgs.qt5.qtbase.dev.qtPluginPrefix} - export QML2_IMPORT_PATH=${pkgs.qt5.qtbase}/${pkgs.qt5.qtbase.dev.qtQmlPrefix} + export QT_PLUGIN_PATH=${pkgs.qt6.qtbase}/${pkgs.qt6.qtbase.dev.qtPluginPrefix}:${pkgs.qt6.qtsvg}/${pkgs.qt6.qtbase.dev.qtPluginPrefix} + export QML2_IMPORT_PATH=${pkgs.qt6.qtbase}/${pkgs.qt6.qtbase.dev.qtQmlPrefix} export PYTHONPATH=`git rev-parse --show-toplevel`:$PYTHONPATH ''; }; diff --git a/setup.py b/setup.py index f7436f582..78b0eb206 100755 --- a/setup.py +++ b/setup.py @@ -10,7 +10,7 @@ if sys.version_info[:2] < (3, 7): raise Exception("You need Python 3.7+") -# Depends on PyQt5, but setuptools cannot check for it. +# Depends on PyQt6, but setuptools cannot check for it. requirements = [ "numpy", "scipy", "python-dateutil", "prettytable", "h5py", "lmdb",