From 2d286cbe93717bd03f4f39244d3391d302b1b779 Mon Sep 17 00:00:00 2001 From: Atika-Syeda Date: Thu, 14 Sep 2023 14:30:32 -0400 Subject: [PATCH 1/9] Change to qtpy/pyqt6 --- .gitignore | 2 +- environment.yml | 3 +-- facemap/gui/cluster.py | 6 +++--- facemap/gui/gui.py | 12 ++++-------- facemap/gui/guiparts.py | 6 +++--- facemap/gui/help_windows.py | 11 +++++------ facemap/gui/io.py | 2 +- facemap/gui/menus.py | 7 ++++--- facemap/gui/neural_activity_window.py | 10 +++++----- facemap/pose/model_training.py | 2 +- facemap/pose/pose_gui.py | 7 +++---- facemap/pose/pose_helper_functions.py | 4 ++-- facemap/pose/refine_pose.py | 9 ++++----- facemap/roi.py | 2 +- setup.py | 5 +++-- 15 files changed, 41 insertions(+), 47 deletions(-) diff --git a/.gitignore b/.gitignore index e2a14af..3249732 100644 --- a/.gitignore +++ b/.gitignore @@ -37,7 +37,7 @@ FaceMap/ops_user.npy *.sh *.pkl *.h5 - +*.mp4 # # ========================= # Operating System Files diff --git a/environment.yml b/environment.yml index eb9afe2..29fe7b5 100644 --- a/environment.yml +++ b/environment.yml @@ -16,7 +16,6 @@ dependencies: - torch>=1.9 - h5py - pyqtgraph>=0.12.0 - - pyqt5 - - pyqt5.sip + - qtpy - umap-learn diff --git a/facemap/gui/cluster.py b/facemap/gui/cluster.py index 28e2f04..ee4fc2b 100644 --- a/facemap/gui/cluster.py +++ b/facemap/gui/cluster.py @@ -19,9 +19,9 @@ # import hdbscan from matplotlib import cm -from PyQt5 import QtCore, QtWidgets -from PyQt5.QtGui import QFont -from PyQt5.QtWidgets import ( +from qtpy import QtCore, QtWidgets +from qtpy.QtGui import QFont +from qtpy.QtWidgets import ( QButtonGroup, QCheckBox, QLabel, diff --git a/facemap/gui/gui.py b/facemap/gui/gui.py index 0c139c0..f96ae76 100644 --- a/facemap/gui/gui.py +++ b/facemap/gui/gui.py @@ -5,22 +5,18 @@ import sys from pathlib import Path -import cv2 import h5py -import matplotlib import matplotlib.pyplot as plt import numpy as np import pyqtgraph as pg -import scipy.io as sio import torch from matplotlib import cm -from PyQt5 import QtCore, QtWidgets -from PyQt5.QtGui import QFont, QIcon, QPainterPath -from PyQt5.QtWidgets import ( +from qtpy import QtCore, QtWidgets, QtGui +from qtpy.QtGui import QFont, QIcon, QPainterPath +from qtpy.QtWidgets import ( QButtonGroup, QCheckBox, QComboBox, - QDesktopWidget, QFileDialog, QGridLayout, QGroupBox, @@ -125,7 +121,7 @@ def __init__( self.scene_grid_layout = QGridLayout() self.central_widget.setLayout(self.scene_grid_layout) # --- cells image - self.sizeObject = QDesktopWidget().screenGeometry(-1) + self.sizeObject = QtGui.QGuiApplication.primaryScreen().availableGeometry() self.resize(self.sizeObject.width(), self.sizeObject.height()) self.video_window = pg.GraphicsLayoutWidget() diff --git a/facemap/gui/guiparts.py b/facemap/gui/guiparts.py index cccf832..0024771 100644 --- a/facemap/gui/guiparts.py +++ b/facemap/gui/guiparts.py @@ -3,8 +3,8 @@ """ import numpy as np import pyqtgraph as pg -from PyQt5 import QtCore, QtGui, QtWidgets -from PyQt5.QtWidgets import ( +from qtpy import QtCore, QtGui, QtWidgets +from qtpy.QtWidgets import ( QAbstractItemView, QButtonGroup, QDialog, @@ -232,7 +232,7 @@ class ImageDraw(pg.ImageItem): for controlling the levels and lookup table used to display the image. """ - sigImageChanged = QtCore.pyqtSignal() + sigImageChanged = QtCore.Signal() def __init__(self, image=None, viewbox=None, parent=None, **kargs): super(ImageDraw, self).__init__() diff --git a/facemap/gui/help_windows.py b/facemap/gui/help_windows.py index 46cecaf..fbd1fc0 100644 --- a/facemap/gui/help_windows.py +++ b/facemap/gui/help_windows.py @@ -5,11 +5,10 @@ import typing import numpy as np -from PyQt5 import QtCore -from PyQt5.QtCore import Qt -from PyQt5.QtGui import QPixmap -from PyQt5.QtWidgets import ( - QDesktopWidget, +from qtpy import QtCore +from qtpy.QtCore import Qt +from qtpy.QtGui import QPixmap, QGuiApplication +from qtpy.QtWidgets import ( QDialog, QGroupBox, QHBoxLayout, @@ -510,7 +509,7 @@ def __init__(self, gui, window_title): super().__init__(gui) self.gui = gui self.setWindowTitle(window_title) - window_size = QDesktopWidget().screenGeometry(-1) + window_size = QGuiApplication.primaryScreen().availableGeometry() self.setFixedSize( int(np.floor(window_size.width() * 0.31)), int(np.floor(window_size.height() * 0.31 * 0.5)), diff --git a/facemap/gui/io.py b/facemap/gui/io.py index f7e40e0..c34ed6d 100644 --- a/facemap/gui/io.py +++ b/facemap/gui/io.py @@ -7,7 +7,7 @@ import numpy as np from natsort import natsorted -from PyQt5.QtWidgets import QFileDialog, QMessageBox +from qtpy.QtWidgets import QFileDialog, QMessageBox from facemap import roi, utils diff --git a/facemap/gui/menus.py b/facemap/gui/menus.py index af2e7b6..3d5e8af 100644 --- a/facemap/gui/menus.py +++ b/facemap/gui/menus.py @@ -1,7 +1,8 @@ """ Copright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Atika Syeda. """ -from PyQt5.QtWidgets import QAction, QDesktopWidget +from qtpy.QtWidgets import QAction +from qtpy.QtGui import QGuiApplication from . import help_windows, io @@ -116,8 +117,8 @@ def mainmenu(parent): def launch_user_manual(parent): - help_windows.MainWindowHelp(parent, QDesktopWidget().screenGeometry(-1)) + help_windows.MainWindowHelp(parent, QGuiApplication.primaryScreen().availableGeometry()) def show_about(parent): - help_windows.AboutWindow(parent, QDesktopWidget().screenGeometry(-1)) + help_windows.AboutWindow(parent, QGuiApplication.primaryScreen().availableGeometry()) diff --git a/facemap/gui/neural_activity_window.py b/facemap/gui/neural_activity_window.py index 4471900..8c616a8 100644 --- a/facemap/gui/neural_activity_window.py +++ b/facemap/gui/neural_activity_window.py @@ -5,9 +5,9 @@ import pyqtgraph as pg import scipy.io as sio from matplotlib import cm -from PyQt5 import QtCore, QtGui, QtWidgets -from PyQt5.QtCore import Qt, QUrl -from PyQt5.QtWidgets import * +from qtpy import QtCore, QtGui, QtWidgets +from qtpy.QtCore import Qt, QUrl +from qtpy.QtWidgets import * from facemap import utils from facemap.gui import guiparts, help_windows, io @@ -21,7 +21,7 @@ def __init__(self, parent=None, window_size=None): self.parent = parent # Set the size of the window if window_size is None: - self.sizeObject = QtWidgets.QDesktopWidget().screenGeometry(-1) + self.sizeObject = QtGui.QGuiApplication.primaryScreen().availableGeometry() else: self.sizeObject = window_size self.resize(np.floor(self.sizeObject.width() / 1.5).astype(int), np.floor(self.sizeObject.height() / 2).astype(int)) @@ -41,7 +41,7 @@ def __init__(self, parent=None, window_size=None): def center(self): qr = self.frameGeometry() - cp = QtWidgets.QDesktopWidget().availableGeometry().center() + cp = QtGui.QGuiApplication.primaryScreen().availableGeometry().center() qr.moveCenter(cp) self.move(qr.topLeft()) diff --git a/facemap/pose/model_training.py b/facemap/pose/model_training.py index fe14af3..34df575 100644 --- a/facemap/pose/model_training.py +++ b/facemap/pose/model_training.py @@ -55,7 +55,7 @@ def train( Whether to save the best model. The default is False. checkpoint_path : str, optional The path to save the best model. The default is None. - gui : PyQt5.QMainWindow + gui : qtpy.QMainWindow The main window of the application. gui_obj : QtWidgets The gui object of the application. diff --git a/facemap/pose/pose_gui.py b/facemap/pose/pose_gui.py index ba9d9d4..d470d4f 100644 --- a/facemap/pose/pose_gui.py +++ b/facemap/pose/pose_gui.py @@ -4,9 +4,8 @@ import numpy as np import pyqtgraph as pg from matplotlib import cm -from PyQt5 import QtCore -from PyQt5.QtWidgets import ( - QDesktopWidget, +from qtpy import QtCore, QtGui +from qtpy.QtWidgets import ( QDialog, QHBoxLayout, QPushButton, @@ -113,7 +112,7 @@ def adjust_bbox(self): class ROI_popup(QDialog): def __init__(self, frame, video_id, gui, pose, last_video): super().__init__() - window_max_size = QDesktopWidget().screenGeometry(-1) + window_max_size = QtGui.QGuiApplication.primaryScreen().availableGeometry() fraction = 0.5 aspect_ratio = 1.5 self.resize( diff --git a/facemap/pose/pose_helper_functions.py b/facemap/pose/pose_helper_functions.py index 13a7636..82ad9e6 100644 --- a/facemap/pose/pose_helper_functions.py +++ b/facemap/pose/pose_helper_functions.py @@ -12,8 +12,8 @@ import numpy as np import pyqtgraph as pg import torch # pytorch -from PyQt5 import QtWidgets -from PyQt5.QtWidgets import QDialog, QPushButton +from qtpy import QtWidgets +from qtpy.QtWidgets import QDialog, QPushButton from scipy.ndimage import gaussian_filter # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~Global variables~~~~~~~~~~~~~~~~~~~~~~~~~~~~~` diff --git a/facemap/pose/refine_pose.py b/facemap/pose/refine_pose.py index 5c1ae9a..ae773a9 100644 --- a/facemap/pose/refine_pose.py +++ b/facemap/pose/refine_pose.py @@ -10,13 +10,12 @@ import pyqtgraph as pg import torch from matplotlib import cm -from PyQt5 import QtCore -from PyQt5.QtGui import QColor -from PyQt5.QtWidgets import ( +from qtpy import QtCore, QtGui +from qtpy.QtGui import QColor +from qtpy.QtWidgets import ( QButtonGroup, QCheckBox, QComboBox, - QDesktopWidget, QDialog, QFormLayout, QGridLayout, @@ -93,7 +92,7 @@ def __init__(self, gui): self.verticalLayout = QVBoxLayout(self) # Set window size that is adjusted to the size of the window - self.window_max_size = QDesktopWidget().screenGeometry(-1) + self.window_max_size = QtGui.QGuiApplication.primaryScreen().availableGeometry() self.show_choose_folder() self.setLayout(self.verticalLayout) diff --git a/facemap/roi.py b/facemap/roi.py index ba8b234..c8782ca 100644 --- a/facemap/roi.py +++ b/facemap/roi.py @@ -3,7 +3,7 @@ """ import numpy as np import pyqtgraph as pg -from PyQt5 import QtCore +from qtpy import QtCore from facemap import pupil, utils diff --git a/setup.py b/setup.py index 145b5d0..dbb2fec 100644 --- a/setup.py +++ b/setup.py @@ -21,8 +21,9 @@ ] gui_deps = [ "pyqtgraph>=0.12.0", - "pyqt5", - "pyqt5.sip", + "pyqt6", + "pyqt6.sip", + "qtpy", "matplotlib", ] From 4ea6fd10af422c1c3bb665be2bbf9c6e505f664e Mon Sep 17 00:00:00 2001 From: Atika-Syeda Date: Fri, 15 Sep 2023 10:20:44 -0400 Subject: [PATCH 2/9] Update recent change to qtpy/pyqt6 --- docs/installation.md | 2 +- docs/installation.rst | 4 ++-- environment.yml | 1 + 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/docs/installation.md b/docs/installation.md index 6fd565a..836b00a 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -23,7 +23,7 @@ The software has been heavily tested on Ubuntu 18.04, and less well tested on Wi Facemap python relies on these awesome packages: - [pyqtgraph](http://pyqtgraph.org/) -- [PyQt5](http://pyqt.sourceforge.net/Docs/PyQt5/) +- [PyQt6](http://pyqt.sourceforge.net/Docs/PyQt6/) - [numpy](http://www.numpy.org/) (>=1.13.0) - [scipy](https://www.scipy.org/) - [opencv](https://opencv.org/) diff --git a/docs/installation.rst b/docs/installation.rst index 53e83f9..9025fac 100644 --- a/docs/installation.rst +++ b/docs/installation.rst @@ -28,7 +28,7 @@ Dependencies Facemap (python package) relies on these awesome packages: - `pyqtgraph`_ -- `pyqt5`_ +- `pyqt6`_ - `numpy`_ (>=1.13.0) - `scipy`_ - `opencv`_ @@ -40,7 +40,7 @@ Facemap (python package) relies on these awesome packages: - `UMAP`_ .. _pyqtgraph: http://pyqtgraph.org/ -.. _pyqt5: http://pyqt.sourceforge.net/Docs/PyQt5/ +.. _pyqt6: http://pyqt.sourceforge.net/Docs/PyQt6/ .. _numpy: http://www.numpy.org/ .. _scipy: https://www.scipy.org/ .. _opencv: https://opencv.org/ diff --git a/environment.yml b/environment.yml index 29fe7b5..e48702f 100644 --- a/environment.yml +++ b/environment.yml @@ -17,5 +17,6 @@ dependencies: - h5py - pyqtgraph>=0.12.0 - qtpy + - pyqt6 - umap-learn From 3574a44943a1cb8e59ae9f4bf550d3a5b3a236d8 Mon Sep 17 00:00:00 2001 From: Atika-Syeda Date: Fri, 15 Sep 2023 16:34:45 -0400 Subject: [PATCH 3/9] Update test for pyqt6 on linux --- facemap/.github/workflows/test_and_deploy.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/facemap/.github/workflows/test_and_deploy.yml b/facemap/.github/workflows/test_and_deploy.yml index a9b61b6..9f22735 100755 --- a/facemap/.github/workflows/test_and_deploy.yml +++ b/facemap/.github/workflows/test_and_deploy.yml @@ -36,9 +36,11 @@ jobs: - name: Install Linux libraries if: runner.os == 'Linux' run: | + sudo apt-get update sudo apt-get install -y libdbus-1-3 libxkbcommon-x11-0 libxcb-icccm4 \ libxcb-image0 libxcb-keysyms1 libxcb-randr0 libxcb-render-util0 \ - libxcb-xinerama0 libxcb-xinput0 libxcb-xfixes0 + libxcb-xinerama0 libxcb-xinput0 libxcb-xfixes0 pkg-config libhdf5-103 libhdf5-dev \ + libegl1 # strategy borrowed from vispy for installing opengl libs on windows - name: Install Windows OpenGL if: runner.os == 'Windows' From 6631262ee721d83e6c7af38467df1e75eddf236a Mon Sep 17 00:00:00 2001 From: Atika-Syeda Date: Fri, 15 Sep 2023 16:41:46 -0400 Subject: [PATCH 4/9] Update test for pyqt6 on linux --- facemap/.github/workflows/test_and_deploy.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/facemap/.github/workflows/test_and_deploy.yml b/facemap/.github/workflows/test_and_deploy.yml index 9f22735..c3d70ab 100755 --- a/facemap/.github/workflows/test_and_deploy.yml +++ b/facemap/.github/workflows/test_and_deploy.yml @@ -36,11 +36,10 @@ jobs: - name: Install Linux libraries if: runner.os == 'Linux' run: | - sudo apt-get update sudo apt-get install -y libdbus-1-3 libxkbcommon-x11-0 libxcb-icccm4 \ libxcb-image0 libxcb-keysyms1 libxcb-randr0 libxcb-render-util0 \ - libxcb-xinerama0 libxcb-xinput0 libxcb-xfixes0 pkg-config libhdf5-103 libhdf5-dev \ - libegl1 + libxcb-xinerama0 libxcb-xinput0 libxcb-xfixes0 + sudo apt-get install '^libxcb.*-dev' libx11-xcb-dev libglu1-mesa-dev libxrender-dev libxi-dev libxkbcommon-dev libxkbcommon-x11-dev # strategy borrowed from vispy for installing opengl libs on windows - name: Install Windows OpenGL if: runner.os == 'Windows' From 55c474125650635ca1c1e39f43ed8ad06d0eebcb Mon Sep 17 00:00:00 2001 From: Atika-Syeda Date: Wed, 20 Sep 2023 09:35:49 -0400 Subject: [PATCH 5/9] Update test for pyqt6 on linux --- facemap/.github/workflows/test_and_deploy.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/facemap/.github/workflows/test_and_deploy.yml b/facemap/.github/workflows/test_and_deploy.yml index c3d70ab..39b0118 100755 --- a/facemap/.github/workflows/test_and_deploy.yml +++ b/facemap/.github/workflows/test_and_deploy.yml @@ -36,9 +36,11 @@ jobs: - name: Install Linux libraries if: runner.os == 'Linux' run: | + sudo apt-get update sudo apt-get install -y libdbus-1-3 libxkbcommon-x11-0 libxcb-icccm4 \ libxcb-image0 libxcb-keysyms1 libxcb-randr0 libxcb-render-util0 \ - libxcb-xinerama0 libxcb-xinput0 libxcb-xfixes0 + libxcb-xinerama0 libxcb-xinput0 libxcb-xfixes0 pkg-config libhdf5-103 libhdf5-dev \ + libegl1 sudo apt-get install '^libxcb.*-dev' libx11-xcb-dev libglu1-mesa-dev libxrender-dev libxi-dev libxkbcommon-dev libxkbcommon-x11-dev # strategy borrowed from vispy for installing opengl libs on windows - name: Install Windows OpenGL From b862ef9f928c1e129672306c9c40d1b6845061f5 Mon Sep 17 00:00:00 2001 From: Atika-Syeda Date: Wed, 20 Sep 2023 09:53:53 -0400 Subject: [PATCH 6/9] Update test for pyqt6 on linux --- facemap/.github/workflows/test_and_deploy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/facemap/.github/workflows/test_and_deploy.yml b/facemap/.github/workflows/test_and_deploy.yml index 39b0118..1fb3ff4 100755 --- a/facemap/.github/workflows/test_and_deploy.yml +++ b/facemap/.github/workflows/test_and_deploy.yml @@ -40,7 +40,7 @@ jobs: sudo apt-get install -y libdbus-1-3 libxkbcommon-x11-0 libxcb-icccm4 \ libxcb-image0 libxcb-keysyms1 libxcb-randr0 libxcb-render-util0 \ libxcb-xinerama0 libxcb-xinput0 libxcb-xfixes0 pkg-config libhdf5-103 libhdf5-dev \ - libegl1 + libegl1 libgl1 sudo apt-get install '^libxcb.*-dev' libx11-xcb-dev libglu1-mesa-dev libxrender-dev libxi-dev libxkbcommon-dev libxkbcommon-x11-dev # strategy borrowed from vispy for installing opengl libs on windows - name: Install Windows OpenGL From 0b894d6ed514df26fabdf23cfaed69f4ab21e116 Mon Sep 17 00:00:00 2001 From: Atika-Syeda Date: Wed, 20 Sep 2023 11:49:08 -0400 Subject: [PATCH 7/9] Update test for pyqt6 on linux --- .github/workflows/test_and_deploy.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test_and_deploy.yml b/.github/workflows/test_and_deploy.yml index ba3a463..e3466db 100644 --- a/.github/workflows/test_and_deploy.yml +++ b/.github/workflows/test_and_deploy.yml @@ -36,9 +36,11 @@ jobs: - name: Install Linux libraries if: runner.os == 'Linux' run: | + sudo apt-get update sudo apt-get install -y libdbus-1-3 libxkbcommon-x11-0 libxcb-icccm4 \ libxcb-image0 libxcb-keysyms1 libxcb-randr0 libxcb-render-util0 \ - libxcb-xinerama0 libxcb-xinput0 libxcb-xfixes0 + libxcb-xinerama0 libxcb-xinput0 libxcb-xfixes0 pkg-config libhdf5-103 libhdf5-dev \ + libegl1 - name: Install dependencies run: | python -m pip install --upgrade pip From 2fc19e933904f18e8bc277f1e0d6418e208cf577 Mon Sep 17 00:00:00 2001 From: Atika-Syeda Date: Wed, 20 Sep 2023 17:41:21 -0400 Subject: [PATCH 8/9] Add WA_AcceptTouchEvents=False for mac --- facemap/gui/gui.py | 4 ++++ facemap/gui/neural_activity_window.py | 1 + facemap/gui/ops_user.npy | Bin 416 -> 396 bytes facemap/pose/pose_gui.py | 4 +++- facemap/pose/pose_helper_functions.py | 3 ++- facemap/pose/refine_pose.py | 2 ++ 6 files changed, 12 insertions(+), 2 deletions(-) diff --git a/facemap/gui/gui.py b/facemap/gui/gui.py index f96ae76..4f17589 100644 --- a/facemap/gui/gui.py +++ b/facemap/gui/gui.py @@ -125,14 +125,18 @@ def __init__( self.resize(self.sizeObject.width(), self.sizeObject.height()) self.video_window = pg.GraphicsLayoutWidget() + self.video_window.viewport().setAttribute(QtCore.Qt.WidgetAttribute.WA_AcceptTouchEvents, False) + self.scene_grid_layout.addWidget(self.video_window, 0, 2, 5, 5) # Create a window for embedding and ROI plot self.roi_embed_window = pg.GraphicsLayoutWidget() + self.roi_embed_window.viewport().setAttribute(QtCore.Qt.WidgetAttribute.WA_AcceptTouchEvents, False) self.scene_grid_layout.addWidget(self.roi_embed_window, 0, 7, 5, 5) # Create a window for plots self.plots_window = pg.GraphicsLayoutWidget() + self.plots_window.viewport().setAttribute(QtCore.Qt.WidgetAttribute.WA_AcceptTouchEvents, False) self.scene_grid_layout.addWidget(self.plots_window, 5, 2, 4, 10) # A plot area (ViewBox + axes) for displaying the image diff --git a/facemap/gui/neural_activity_window.py b/facemap/gui/neural_activity_window.py index 8c616a8..f27c630 100644 --- a/facemap/gui/neural_activity_window.py +++ b/facemap/gui/neural_activity_window.py @@ -123,6 +123,7 @@ def setup_ui(self): # Add a plots window neural data visualization plots_window = pg.GraphicsLayoutWidget() + plots_window.viewport().setAttribute(QtCore.Qt.WidgetAttribute.WA_AcceptTouchEvents, False) self.neural_activity_plot = plots_window.addPlot( name="neural_activity_plot", row=0, col=0, title="Neural activity" diff --git a/facemap/gui/ops_user.npy b/facemap/gui/ops_user.npy index 6082c5ad605ff97cd2672e42f052b5d3527cd8fb..c538d1f42153e1e23dfb5ed7dd22779efc4c7e54 100755 GIT binary patch delta 36 rcmZ3$+{3)VhfzX=fq_9kv^ce>SiiV3H6<}o-#5Q3Gqref1)~N4y*>*W delta 56 zcmeBSUckJ;hfzm^fq_9kBR@A)zqq6*GcP?SF-hMgwK%&Zzd*mF!qhCjI5D>%CpA7L Lu_SSF3Zn)9`N|U7 diff --git a/facemap/pose/pose_gui.py b/facemap/pose/pose_gui.py index d470d4f..0a06fe7 100644 --- a/facemap/pose/pose_gui.py +++ b/facemap/pose/pose_gui.py @@ -4,7 +4,7 @@ import numpy as np import pyqtgraph as pg from matplotlib import cm -from qtpy import QtCore, QtGui +from qtpy import QtCore, QtGui, QtWidgets from qtpy.QtWidgets import ( QDialog, QHBoxLayout, @@ -128,6 +128,7 @@ def __init__(self, frame, video_id, gui, pose, last_video): # Add image and ROI bbox self.verticalLayout = QVBoxLayout(self) self.win = pg.GraphicsLayoutWidget() + self.win.viewport().setAttribute(QtCore.Qt.WidgetAttribute.WA_AcceptTouchEvents, False) self.win.setObjectName("Dialog " + str(video_id + 1)) # fix image in ROI window ROI_win = self.win.addViewBox(invertY=True, lockAspect=True, enableMouse=False) @@ -232,6 +233,7 @@ def __init__(self, gui, video_id, pose, frame_idx, bodyparts): # Add image and pose prediction self.verticalLayout = QtWidgets.QVBoxLayout(self) self.win = pg.GraphicsLayoutWidget() + self.win.viewport().setAttribute(QtCore.Qt.WidgetAttribute.WA_AcceptTouchEvents, False) self.win.setObjectName("Dialog " + str(video_id + 1)) frame_win = self.win.addViewBox(invertY=True) self.current_frame_idx = 0 diff --git a/facemap/pose/pose_helper_functions.py b/facemap/pose/pose_helper_functions.py index 82ad9e6..eab627d 100644 --- a/facemap/pose/pose_helper_functions.py +++ b/facemap/pose/pose_helper_functions.py @@ -12,7 +12,7 @@ import numpy as np import pyqtgraph as pg import torch # pytorch -from qtpy import QtWidgets +from qtpy import QtWidgets, QtCore from qtpy.QtWidgets import QDialog, QPushButton from scipy.ndimage import gaussian_filter @@ -248,6 +248,7 @@ def __init__(self, frame, gui, title="Test Popup"): # Add image and ROI bbox self.win = pg.GraphicsLayoutWidget() + self.win.viewport().setAttribute(QtCore.Qt.WidgetAttribute.WA_AcceptTouchEvents, False) ROI_win = self.win.addViewBox(invertY=True) self.img = pg.ImageItem(self.frame) ROI_win.addItem(self.img) diff --git a/facemap/pose/refine_pose.py b/facemap/pose/refine_pose.py index ae773a9..147f873 100644 --- a/facemap/pose/refine_pose.py +++ b/facemap/pose/refine_pose.py @@ -794,6 +794,7 @@ def show_refinement_options( self.frame_group = QGroupBox() self.frame_group.setLayout(QHBoxLayout()) self.win = pg.GraphicsLayoutWidget() + self.win.viewport().setAttribute(QtCore.Qt.WidgetAttribute.WA_AcceptTouchEvents, False) self.win.setObjectName("Keypoints refinement") self.keypoints_scatterplot = KeypointsGraph(parent=self) self.frame_win = KeypointsViewBox( @@ -1337,6 +1338,7 @@ def visualize_model_predictions(self): for j in range(cols): frame = imgs[i * rows + j] self.win = pg.GraphicsLayoutWidget() + self.win.viewport().setAttribute(QtCore.Qt.WidgetAttribute.WA_AcceptTouchEvents, False) frame_win = self.win.addViewBox(invertY=True) frame_win.setAspectLocked(True) frame_win.addItem( From d13bfb7034da835334ba7d917496dd61bdb4b478 Mon Sep 17 00:00:00 2001 From: Atika-Syeda Date: Thu, 21 Sep 2023 12:09:10 -0400 Subject: [PATCH 9/9] Update buttons for mac --- facemap/gui/cluster.py | 8 ++++---- facemap/gui/gui.py | 18 +++++++++--------- facemap/gui/io.py | 16 ++++++++-------- facemap/gui/neural_activity_window.py | 8 ++++---- facemap/pose/refine_pose.py | 17 +++++++++++------ 5 files changed, 36 insertions(+), 31 deletions(-) diff --git a/facemap/gui/cluster.py b/facemap/gui/cluster.py index ee4fc2b..8aaba8b 100644 --- a/facemap/gui/cluster.py +++ b/facemap/gui/cluster.py @@ -408,9 +408,9 @@ def run(self, clicked, parent): else: self.data_type = None msg = QMessageBox(parent) - msg.setIcon(QMessageBox.Warning) + msg.setIcon(QMessageBox.Icon.Warning) msg.setText("Please select data for clustering") - msg.setStandardButtons(QMessageBox.Ok) + msg.setStandardButtons(QMessageBox.StandardButton.Ok) msg.exec_() return if self.cluster_method == "UMAP": @@ -718,9 +718,9 @@ def ok_save(self, dialogBox, parent): pass else: msg = QMessageBox(parent) - msg.setIcon(QMessageBox.Warning) + msg.setIcon(QMessageBox.Icon.Warning) msg.setText("Please generate cluster labels for saving cluster videos") - msg.setStandardButtons(QMessageBox.Ok) + msg.setStandardButtons(QMessageBox.StandardButton.Ok) msg.exec_() if dialogBox.data_checkbox.isChecked(): self.save_cluster_output(parent) diff --git a/facemap/gui/gui.py b/facemap/gui/gui.py index 4f17589..5981d87 100644 --- a/facemap/gui/gui.py +++ b/facemap/gui/gui.py @@ -833,17 +833,17 @@ def add_pose_model(self, pose_model_path=None): break # Display QMessage box to inform user that the model was successfully added msg = QMessageBox() - msg.setIcon(QMessageBox.Information) + msg.setIcon(QMessageBox.Icon.Information) msg.setText("Pose model successfully added.") msg.setWindowTitle("Pose model added") - msg.setStandardButtons(QMessageBox.Ok) + msg.setStandardButtons(QMessageBox.StandardButton.Ok) msg.exec_() except Exception as e: msg = QMessageBox() - msg.setIcon(QMessageBox.Error) + msg.setIcon(QMessageBox.Icon.Critical) msg.setText("Pose model not added. Error: " + str(e)) msg.setWindowTitle("Eror") - msg.setStandardButtons(QMessageBox.Ok) + msg.setStandardButtons(QMessageBox.StandardButton.Ok) msg.exec_() @@ -2255,7 +2255,7 @@ def load_video_popup(self): # Open a qmessage box to notify the user that the video is not loaded msg = QtWidgets.QMessageBox() # Error icon in the top left corner - msg.setIcon(QtWidgets.QMessageBox.Critical) + msg.setIcon(QtWidgets.QMessageBox.Icon.Critical) msg.setText("Please load a video first.") msg.setWindowTitle("No video loaded") msg.exec_() @@ -2269,16 +2269,16 @@ def invalid_trace_popup(self): def invalid_roi_popup(self): msg = QMessageBox(self) - msg.setIcon(QMessageBox.Warning) + msg.setIcon(QMessageBox.Icon.Warning) msg.setText("only pupil ROI allowed during online mode") - msg.setStandardButtons(QMessageBox.Ok) + msg.setStandardButtons(QMessageBox.StandardButton.Ok) msg.exec_() def show_roi_selection_error(self): msg = QMessageBox(self) - msg.setIcon(QMessageBox.Warning) + msg.setIcon(QMessageBox.Icon.Warning) msg.setText("Please select a ROI") - msg.setStandardButtons(QMessageBox.Ok) + msg.setStandardButtons(QMessageBox.StandardButton.Ok) msg.exec_() def model_loaded_popup(self, model_path): diff --git a/facemap/gui/io.py b/facemap/gui/io.py index c34ed6d..6b2a443 100644 --- a/facemap/gui/io.py +++ b/facemap/gui/io.py @@ -279,7 +279,7 @@ def get_folder_path(parent): else: # Open a qmessagebox to inform the user that the path does not exist msg = QMessageBox() - msg.setIcon(QMessageBox.Warning) + msg.setIcon(QMessageBox.Icon.Warning) msg.setText("The path does not exist") msg.setWindowTitle("Warning") msg.exec_() @@ -367,7 +367,7 @@ def load_npy_file(parent, allow_mat=False): else: # Open a qmessagebox to inform the user that the path does not exist msg = QMessageBox() - msg.setIcon(QMessageBox.Warning) + msg.setIcon(QMessageBox.Icon.Warning) msg.setText("The path does not exist") msg.setWindowTitle("Warning") msg.exec_() @@ -423,9 +423,9 @@ def load_cluster_labels(parent): return except Exception as e: msg = QMessageBox(parent) - msg.setIcon(QMessageBox.Warning) + msg.setIcon(QMessageBox.Icon.Warning) msg.setText("Error: not a supported filetype") - msg.setStandardButtons(QMessageBox.Ok) + msg.setStandardButtons(QMessageBox.StandardButton.Ok) msg.exec_() print(e) @@ -457,9 +457,9 @@ def load_umap(parent): return embedded_data except Exception as e: msg = QMessageBox(parent) - msg.setIcon(QMessageBox.Warning) + msg.setIcon(QMessageBox.Icon.Warning) msg.setText("Error: not a supported filetype") - msg.setStandardButtons(QMessageBox.Ok) + msg.setStandardButtons(QMessageBox.StandardButton.Ok) msg.exec_() print(e) @@ -480,9 +480,9 @@ def load_trace_data(parent): return dat except Exception as e: msg = QMessageBox(parent) - msg.setIcon(QMessageBox.Warning) + msg.setIcon(QMessageBox.Icon.Warning) msg.setText("Error: not a supported filetype") - msg.setStandardButtons(QMessageBox.Ok) + msg.setStandardButtons(QMessageBox.StandardButton.Ok) msg.exec_() print(e) diff --git a/facemap/gui/neural_activity_window.py b/facemap/gui/neural_activity_window.py index f27c630..0af7d81 100644 --- a/facemap/gui/neural_activity_window.py +++ b/facemap/gui/neural_activity_window.py @@ -306,7 +306,7 @@ def load_neural_predictions_file(self, neural_predictions_filepath=None): print("error", e) # Show error message msg = QtWidgets.QMessageBox() - msg.setIcon(QtWidgets.QMessageBox.Critical) + msg.setIcon(QtWidgets.QMessageBox.Icon.Critical) msg.setText("Invalid neural predictions file.") msg.setInformativeText( "The selected file is not a valid neural predictions file." @@ -600,7 +600,7 @@ def run_neural_predictions(self, clicked, dialog): if self.neural_activity.data is None: msg = QtWidgets.QMessageBox() - msg.setIcon(QtWidgets.QMessageBox.Critical) + msg.setIcon(QtWidgets.QMessageBox.Icon.Critical) msg.setText("Neural activity not loaded") msg.setInformativeText( "Please load neural activity data before running neural predictions" @@ -614,7 +614,7 @@ def run_neural_predictions(self, clicked, dialog): # Check if keypoints are loaded if self.parent.poseFilepath[0] is None: msg = QtWidgets.QMessageBox() - msg.setIcon(QtWidgets.QMessageBox.Critical) + msg.setIcon(QtWidgets.QMessageBox.Icon.Critical) msg.setText("Keypoints not loaded") msg.setInformativeText( "Please load keypoints before running neural predictions" @@ -688,7 +688,7 @@ def run_neural_predictions(self, clicked, dialog): x_input = self.movSVDs[0] except: msg = QtWidgets.QMessageBox() - msg.setIcon(QtWidgets.QMessageBox.Critical) + msg.setIcon(QtWidgets.QMessageBox.Icon.Critical) msg.setText("SVDs not loaded") msg.setInformativeText( "Please load SVDs (proc file) before running neural predictions" diff --git a/facemap/pose/refine_pose.py b/facemap/pose/refine_pose.py index 147f873..24caf4a 100644 --- a/facemap/pose/refine_pose.py +++ b/facemap/pose/refine_pose.py @@ -105,6 +105,11 @@ def update_window_size(self, frac=0.5, aspect_ratio=1.0): int(np.floor(self.window_max_size.width() * frac)), int(np.floor(self.window_max_size.height() * frac * aspect_ratio)), ) + # center window on screen + centerPoint = QtGui.QGuiApplication.primaryScreen().availableGeometry().center() + qtRectangle = self.frameGeometry() + qtRectangle.moveCenter(centerPoint) + self.move(qtRectangle.topLeft()) def clear_window(self): # Clear the window @@ -173,13 +178,11 @@ def set_output_folder_path(self): ### ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Step 2: Choose training files ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ### def show_choose_training_files(self): - self.update_window_size(0.4, aspect_ratio=0.5) - self.output_folder_path = self.output_folder_path_box.text() # Check if path exists if not os.path.exists(self.output_folder_path): msg = QMessageBox(self) - msg.setIcon(QMessageBox.Warning) + msg.setIcon(QMessageBox.Icon.Warning) msg.setStyleSheet("QLabel{ color: white}") msg.setText("Please set a valid output folder path first") msg.setWindowTitle("Warning") @@ -471,6 +474,8 @@ def show_choose_training_files(self): ) self.verticalLayout.addWidget(self.buttons_groupbox) + + self.update_window_size(0.4, aspect_ratio=1.5) def show_data_files(self, yes_selected): """ @@ -639,11 +644,11 @@ def update_user_training_options(self): if self.output_model_name == "facemap_model_state": # Open a QMessageBox to warn the user that the model name is not allowed msg = QMessageBox(self) - msg.setIcon(QMessageBox.Warning) + msg.setIcon(QMessageBox.Icon.Warning) msg.setText("Output model name cannot be 'facemap_model_state'") msg.setStyleSheet("QLabel{ color: white}") msg.setWindowTitle("Warning") - msg.setStandardButtons(QMessageBox.Ok) + msg.setStandardButtons(QMessageBox.StandardButton.Ok) msg.exec_() return # Get the selected videos @@ -668,7 +673,7 @@ def show_step_3(self): else: # Show error message self.error_message = QMessageBox() - self.error_message.setIcon(QMessageBox.Critical) + self.error_message.setIcon(QMessageBox.Icon.Critical) self.error_message.setText("Please select at least one video for training.") self.error_message.setWindowTitle("Error") self.error_message.exec_()