Skip to content

Commit

Permalink
start migration to pyqt6
Browse files Browse the repository at this point in the history
  • Loading branch information
amorfinv committed Dec 22, 2021
1 parent 4f67079 commit 9ceaa80
Show file tree
Hide file tree
Showing 22 changed files with 115 additions and 99 deletions.
4 changes: 2 additions & 2 deletions bluesky/ui/loadvisuals_txt.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,8 @@ def load_coastline_txt():

# Only try this if BlueSky is started in qtgl gui mode
if bs.gui_type == 'qtgl':
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QApplication, QProgressDialog
from PyQt6.QtCore import Qt
from PyQt6.QtWidgets import QApplication, QProgressDialog
from bluesky.ui.polytools import PolygonSet, BoundingBox


Expand Down
6 changes: 3 additions & 3 deletions bluesky/ui/qtgl/aman.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QPen, QBrush, QColor, QFont
from PyQt5.QtWidgets import QGraphicsView, QGraphicsScene, QGraphicsItemGroup
from PyQt6.QtCore import Qt
from PyQt6.QtGui import QPen, QBrush, QColor, QFont
from PyQt6.QtWidgets import QGraphicsView, QGraphicsScene, QGraphicsItemGroup


class AMANDisplay(QGraphicsView):
Expand Down
13 changes: 7 additions & 6 deletions bluesky/ui/qtgl/console.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
""" Console interface for the QTGL implementation."""
from PyQt5.QtCore import Qt
from PyQt5.Qt import QDesktopServices, QUrl, QApplication
from PyQt5.QtWidgets import QWidget, QTextEdit
from PyQt6.QtCore import Qt, QUrl
from PyQt6.QtGui import QDesktopServices
from PyQt6.QtWidgets import QApplication
from PyQt6.QtWidgets import QWidget, QTextEdit

import bluesky as bs
from bluesky.tools import cachefile
Expand Down Expand Up @@ -255,15 +256,15 @@ class Stackwin(QTextEdit):
def __init__(self, parent=None):
super().__init__(parent)
Console.stackText = self
self.setFocusPolicy(Qt.NoFocus)
self.setFocusPolicy(Qt.FocusPolicy.NoFocus)

def mousePressEvent(self, e):
self.anchor = self.anchorAt(e.pos())
if self.anchor:
QApplication.setOverrideCursor(Qt.PointingHandCursor)
QApplication.setOverrideCursor(Qt.CursorShape.PointingHandCursor)

def mouseReleaseEvent(self, e):
if self.anchor:
QDesktopServices.openUrl(QUrl(self.anchor))
QApplication.setOverrideCursor(Qt.ArrowCursor)
QApplication.setOverrideCursor(Qt.CursorShape.ArrowCursor)
self.anchor = None
2 changes: 1 addition & 1 deletion bluesky/ui/qtgl/customevents.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
""" Definition of custom QEvent objects for QtGL gui. """
from PyQt5.QtCore import QEvent
from PyQt6.QtCore import QEvent


NUMCUSTOMEVENTS = 2
Expand Down
12 changes: 7 additions & 5 deletions bluesky/ui/qtgl/docwindow.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
""" Documentation window for the QTGL version of BlueSky."""
from PyQt5.QtCore import QUrl, QFileInfo
from PyQt5.QtWidgets import QVBoxLayout, QHBoxLayout, QWidget, QPushButton, QLabel
from PyQt6.QtCore import QUrl, QFileInfo
from PyQt6.QtWidgets import QVBoxLayout, QHBoxLayout, QWidget, QPushButton, QLabel
try:
try:
# Within PyQt5 there are different locations for QWebView and QWebPage,
# Within PyQt6 there are different locations for QWebView and QWebPage,
# depending on release version.
from PyQt5.QtWebEngineWidgets import QWebEngineView as QWebView, QWebEnginePage as QWebPage
from PyQt6.QtWebEngineWidgets import QWebEngineView as QWebView
from PyQt6.QtWebEngineCore import QWebEnginePage as QWebPage
except ImportError:
from PyQt5.QtWebKitWidgets import QWebView, QWebPage
from PyQt6.QtWebEngineWidgets import QWebView
from PyQt6.QtWebEngineCore import QWebPage

class DocView(QWebView):
def __init__(self, parent=None):
Expand Down
36 changes: 20 additions & 16 deletions bluesky/ui/qtgl/glhelpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@
from os import path
from collections import namedtuple
from collections import OrderedDict
from PyQt5.QtCore import qCritical
import PyQt6
from PyQt6.QtCore import qCritical

from PyQt5.QtWidgets import QOpenGLWidget
from PyQt6.QtOpenGLWidgets import QOpenGLWidget

try:
from collections.abc import Collection, MutableMapping
Expand All @@ -15,10 +16,11 @@
import ctypes
import numpy as np

from PyQt5.QtGui import (QSurfaceFormat, QOpenGLShader, QOpenGLShaderProgram,
from PyQt6.QtOpenGL import (QOpenGLShader, QOpenGLShaderProgram,
QOpenGLVertexArrayObject, QOpenGLBuffer,
QOpenGLContext, QOpenGLVersionProfile,
QOpenGLTexture, QImage)
QOpenGLVersionProfile, QOpenGLTexture, QAbstractOpenGLFunctions)
from PyQt6.QtGui import QSurfaceFormat, QOpenGLContext, QImage

from bluesky import settings
from bluesky.core import Entity
from bluesky.stack import command
Expand All @@ -35,12 +37,12 @@


def get_profile_settings():
for version in ((4, 5), (4, 4), (4, 3), (4, 2), (4, 1), (4, 0), (3, 3)):
for version in ((4, 1), (2, 1), (2, 0)):
for profile in ('Core', 'Compatibility'):
try:
importlib.import_module(f'PyQt5._QOpenGLFunctions_{version[0]}_{version[1]}_{profile}')
importlib.import_module(f'PyQt6.QtOpenGL', package=f'QOpenGLFunctions_{version[0]}_{version[1]}_{profile}')
print(f'Found Qt-provided OpenGL functions for OpenGL {version} {profile}')
return version, QSurfaceFormat.CoreProfile if profile == 'Core' else QSurfaceFormat.CompatibilityProfile
return version, QSurfaceFormat.OpenGLContextProfile.CoreProfile if profile == 'Core' else QSurfaceFormat.OpenGLContextProfile.CompatibilityProfile
except:
continue
return (4, 1), None
Expand All @@ -55,20 +57,22 @@ def init():
fmt.setVersion(*version)
# profile = QSurfaceFormat.CoreProfile if sys.platform == 'darwin' else QSurfaceFormat.CompatibilityProfile

fmt.setProfile(profile or QSurfaceFormat.CompatibilityProfile)
fmt.setProfile(profile or QSurfaceFormat.OpenGLContextProfile.CompatibilityProfile)
QSurfaceFormat.setDefaultFormat(fmt)

if profile is not None:
# Use a dummy context to get GL functions
glprofile = QOpenGLVersionProfile(fmt)
ctx = QOpenGLContext()
globals()['gl'] = ctx.versionFunctions(glprofile)
# globals()['gl'] = ctx.versionFunctions(glprofile)
globals()['gl'] = QAbstractOpenGLFunctions()
print(dir(gl))
# Check and set OpenGL capabilities
if not glprofile.hasProfiles():
raise RuntimeError(
'No OpenGL version >= 3.3 support detected for this system!')
else:
# If profile was none, PyQt5 is not shipped with any OpenGL function modules. Use PyOpenGL instead
# If profile was none, PyQt6 is not shipped with any OpenGL function modules. Use PyOpenGL instead
print("Couldn't find OpenGL functions in Qt. Falling back to PyOpenGL")
globals()['gl'] = importlib.import_module('OpenGL.GL')

Expand Down Expand Up @@ -513,7 +517,7 @@ def create(self, texture=None, vertex_count=0, n_instances=0, **attribs):

self.set_attribs(**attribs)

def set_attribs(self, usage=QOpenGLBuffer.StaticDraw, instance_divisor=0,
def set_attribs(self, usage=QOpenGLBuffer.UsagePattern.StaticDraw, instance_divisor=0,
datatype=None, stride=0, offset=None, normalize=False,
**attribs):
''' Set attributes for this VAO. '''
Expand Down Expand Up @@ -879,7 +883,7 @@ def create(self, w, h, fill=False):
class GLBuffer(QOpenGLBuffer):
''' Wrapper class for vertex and index buffers. '''

def create(self, size=None, usage=QOpenGLBuffer.StaticDraw, data=None):
def create(self, size=None, usage=QOpenGLBuffer.UsagePattern.StaticDraw, data=None):
''' Create the buffer. '''
if size is None and data is None:
raise ValueError(
Expand Down Expand Up @@ -918,7 +922,7 @@ def __init__(self):
super().__init__(gl.GL_UNIFORM_BUFFER)
self.binding = 0

def create(self, size=None, usage=QOpenGLBuffer.StaticDraw, data=None):
def create(self, size=None, usage=QOpenGLBuffer.UsagePattern.StaticDraw, data=None):
''' Create this UBO. '''
super().create(size, usage, data)
self.binding = UniformBufferObject.ufo_max_binding
Expand All @@ -929,7 +933,7 @@ def create(self, size=None, usage=QOpenGLBuffer.StaticDraw, data=None):

class Texture(QOpenGLTexture):
''' BlueSky OpenGL Texture class. '''
def __init__(self, target=QOpenGLTexture.Target2D):
def __init__(self, target=QOpenGLTexture.Target.Target2D):
super().__init__(target)

def load(self, fname):
Expand Down Expand Up @@ -966,7 +970,7 @@ class Font(Texture):
_fonts = list()

def __init__(self):
super().__init__(QOpenGLTexture.Target2DArray)
super().__init__(QOpenGLTexture.Target.Target2DArray)
self.char_ar = 1.0
self.loc_char_size = 0
self.loc_block_size = 0
Expand Down
23 changes: 12 additions & 11 deletions bluesky/ui/qtgl/gui.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
""" QTGL Gui for BlueSky."""
from PyQt5.QtCore import Qt, QEvent, qInstallMessageHandler, \
QtWarningMsg, QtCriticalMsg, QtFatalMsg, \
from PyQt6.QtCore import Qt, QEvent, qInstallMessageHandler, \
QT_VERSION, QT_VERSION_STR
from PyQt5.QtWidgets import QApplication, QErrorMessage

from PyQt6.QtCore import QtMsgType
from PyQt6.QtWidgets import QApplication, QErrorMessage

import bluesky as bs
from bluesky.ui.qtgl.guiclient import GuiClient
Expand All @@ -12,13 +13,13 @@

print(('Using Qt ' + QT_VERSION_STR + ' for windows and widgets'))


QtMsgType
def gui_msg_handler(msgtype, context, msg):
if msgtype == QtWarningMsg:
if msgtype == QtMsgType.QtWarningMsg:
print('Qt gui warning:', msg)
elif msgtype == QtCriticalMsg:
elif msgtype == QtMsgType.QtCriticalMsg:
print('Qt gui critical error:', msg)
if msgtype == QtFatalMsg:
if msgtype == QtMsgType.QtFatalMsg:
print('Qt gui fatal error:', msg)
exit()

Expand All @@ -33,9 +34,9 @@ def start(mode):
# Start the bluesky network client
client = GuiClient()

# Enable HiDPI support (Qt5 only)
if QT_VERSION >= 0x050000:
app.setAttribute(Qt.AA_UseHighDpiPixmaps)
# # Enable HiDPI support (Qt5 only)
# if QT_VERSION >= 0x050000:
# app.setAttribute(Qt.AA_UseHighDpiPixmaps)

splash = Splash()

Expand All @@ -49,7 +50,7 @@ def start(mode):

# Install error message handler
handler = QErrorMessage.qtHandler()
handler.setWindowFlags(Qt.WindowStaysOnTopHint)
handler.setWindowFlags(Qt.WindowType.WindowStaysOnTopHint)

splash.showMessage('Constructing main window')
app.processEvents()
Expand Down
2 changes: 1 addition & 1 deletion bluesky/ui/qtgl/guiclient.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
''' I/O Client implementation for the QtGL gui. '''
from PyQt5.QtCore import QTimer
from PyQt6.QtCore import QTimer
import numpy as np

from bluesky.ui import palette
Expand Down
4 changes: 2 additions & 2 deletions bluesky/ui/qtgl/infowindow.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
from matplotlib.figure import Figure
from matplotlib.backend_bases import key_press_handler
import matplotlib.pyplot as plt
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QTabWidget, QVBoxLayout, QScrollArea, QWidget
from PyQt6.QtCore import Qt
from PyQt6.QtWidgets import QTabWidget, QVBoxLayout, QScrollArea, QWidget
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas, \
NavigationToolbar2QT as NavigationToolbar

Expand Down
14 changes: 7 additions & 7 deletions bluesky/ui/qtgl/mainwindow.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@
import platform
import os

from PyQt5.QtWidgets import QApplication as app
from PyQt5.QtCore import Qt, pyqtSlot, QTimer, QItemSelectionModel, QSize
from PyQt5.QtGui import QPixmap, QIcon
from PyQt5.QtWidgets import QMainWindow, QSplashScreen, QTreeWidgetItem, \
from PyQt6.QtWidgets import QApplication as app
from PyQt6.QtCore import Qt, pyqtSlot, QTimer, QItemSelectionModel, QSize
from PyQt6.QtGui import QPixmap, QIcon
from PyQt6.QtWidgets import QMainWindow, QSplashScreen, QTreeWidgetItem, \
QPushButton, QFileDialog, QDialog, QTreeWidget, QVBoxLayout, \
QDialogButtonBox
from PyQt5 import uic
from PyQt6 import uic

# Local imports
import bluesky as bs
Expand Down Expand Up @@ -38,7 +38,7 @@
class Splash(QSplashScreen):
""" Splash screen: BlueSky logo during start-up"""
def __init__(self):
super().__init__(QPixmap(os.path.join(bs.settings.gfx_path, 'splash.gif')), Qt.WindowStaysOnTopHint)
super().__init__(QPixmap(os.path.join(bs.settings.gfx_path, 'splash.gif')), Qt.WindowType.WindowStaysOnTopHint)


class DiscoveryDialog(QDialog):
Expand Down Expand Up @@ -173,7 +173,7 @@ def __init__(self, mode):
self.nodetree.setIndentation(0)
self.nodetree.setColumnCount(2)
self.nodetree.setStyleSheet('padding:0px')
self.nodetree.setAttribute(Qt.WA_MacShowFocusRect, False)
self.nodetree.setAttribute(Qt.WidgetAttribute.WA_MacShowFocusRect, False)
self.nodetree.header().resizeSection(0, 130)
self.nodetree.itemClicked.connect(self.nodetreeClicked)
self.maxhostnum = 0
Expand Down
4 changes: 2 additions & 2 deletions bluesky/ui/qtgl/nd.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
""" Navigation display for the QTGL gui."""
from PyQt5.QtCore import qCritical, QTimer
from PyQt5.QtOpenGL import QGLWidget
from PyQt6.QtCore import qCritical, QTimer
from PyQt6.QtOpenGLWidgets import QOpenGLWidget as QGLWidget
import OpenGL.GL as gl
from math import sin, cos, radians
import numpy as np
Expand Down
Loading

0 comments on commit 9ceaa80

Please sign in to comment.