Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Execute import qiskit_metal without PySide2 #713

Draft
wants to merge 4 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
149 changes: 81 additions & 68 deletions qiskit_metal/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,77 +41,86 @@
)
raise

def is_cloud():
# Check that the os is linux
if os.name == 'posix':
return True
return False

###########################################################################
### Basic Setups
## Setup Qt
def __setup_Qt_backend(): # pylint: disable=invalid-name
"""Setup matplotlib to use Qt5's visualization.

This function needs to remain in the __init__ of the library's root
to prevent Qt windows from hanging.
"""
# pylint: disable=import-outside-toplevel
os.environ["QT_API"] = "pyside2"

from PySide2 import QtCore #, QtWidgets
from PySide2.QtCore import Qt

def set_attribute(name: str, value=True):
"""Describes attributes that change the behavior of application-wide
features."""
if hasattr(Qt, name):
# Does Qt have this attribute
attr = getattr(Qt, name)
if not QtCore.QCoreApplication.testAttribute(attr) == value:
# Only set if not already set
QtCore.QCoreApplication.setAttribute(attr, value)

if 1:

if QtCore.QCoreApplication.instance() is None:
# No application launched yet

# zkm: The following seems to fix warning.
# For example if user ran %gui qt already.
# Qt WebEngine seems to be initialized from a plugin.
# Please set Qt::AA_ShareOpenGLContexts using QCoreApplication::setAttribute
# before constructing QGuiApplication.
# https://stackoverflow.com/questions/56159475/qt-webengine-seems-to-be-initialized
# Enables resource sharing between the OpenGL contexts used by classes
# like QOpenGLWidget and QQuickWidget.
# Has to do with render mode 'gles'. There is also desktop and software.
# QCoreApplication.setAttribute(QtCore.Qt.AA_UseOpenGLES)
# QCoreApplication.setAttribute(QtCore.Qt.AA_ShareOpenGLContexts)
# QCoreApplication.setAttribute(QtCore.Qt.AA_DisableShaderDiskCache)
set_attribute('AA_ShareOpenGLContexts')

# Enables high-DPI scaling in Qt on supported platforms (see also High DPI Displays).
# Supported platforms are X11, Windows and Android.
# Enabling makes Qt scale the main (device independent) coordinate
# system according to display scale factors provided by the
# operating system.
set_attribute('AA_EnableHighDpiScaling')

# Make QIcon::pixmap() generate high-dpi pixmaps that can be larger than
# the requested size.
set_attribute('AA_UseHighDpiPixmaps')

# Other options of interest:
# AA_DontUseNativeMenuBar
# AA_MacDontSwapCtrlAndMeta

if not os.getenv('QISKIT_METAL_HEADLESS', None):
# pylint: disable=import-outside-toplevel
import matplotlib as mpl
mpl.use("Qt5Agg")
# pylint: disable=redefined-outer-name
import matplotlib.pyplot as plt
plt.ion() # interactive

if not is_cloud():

def __setup_Qt_backend(): # pylint: disable=invalid-name
"""Setup matplotlib to use Qt5's visualization.

This function needs to remain in the __init__ of the library's root
to prevent Qt windows from hanging.
"""
# pylint: disable=import-outside-toplevel
os.environ["QT_API"] = "pyside2"

from PySide2 import QtCore #, QtWidgets
from PySide2.QtCore import Qt

def set_attribute(name: str, value=True):
"""Describes attributes that change the behavior of application-wide
features."""
if hasattr(Qt, name):
# Does Qt have this attribute
attr = getattr(Qt, name)
if not QtCore.QCoreApplication.testAttribute(attr) == value:
# Only set if not already set
QtCore.QCoreApplication.setAttribute(attr, value)

if 1:

if QtCore.QCoreApplication.instance() is None:
# No application launched yet

# zkm: The following seems to fix warning.
# For example if user ran %gui qt already.
# Qt WebEngine seems to be initialized from a plugin.
# Please set Qt::AA_ShareOpenGLContexts using QCoreApplication::setAttribute
# before constructing QGuiApplication.
# https://stackoverflow.com/questions/56159475/qt-webengine-seems-to-be-initialized
# Enables resource sharing between the OpenGL contexts used by classes
# like QOpenGLWidget and QQuickWidget.
# Has to do with render mode 'gles'. There is also desktop and software.
# QCoreApplication.setAttribute(QtCore.Qt.AA_UseOpenGLES)
# QCoreApplication.setAttribute(QtCore.Qt.AA_ShareOpenGLContexts)
# QCoreApplication.setAttribute(QtCore.Qt.AA_DisableShaderDiskCache)
set_attribute('AA_ShareOpenGLContexts')

# Enables high-DPI scaling in Qt on supported platforms (see also High DPI Displays).
# Supported platforms are X11, Windows and Android.
# Enabling makes Qt scale the main (device independent) coordinate
# system according to display scale factors provided by the
# operating system.
set_attribute('AA_EnableHighDpiScaling')

# Make QIcon::pixmap() generate high-dpi pixmaps that can be larger than
# the requested size.
set_attribute('AA_UseHighDpiPixmaps')

# Other options of interest:
# AA_DontUseNativeMenuBar
# AA_MacDontSwapCtrlAndMeta

if not os.getenv('QISKIT_METAL_HEADLESS', None):
# pylint: disable=import-outside-toplevel
import matplotlib as mpl
mpl.use("Qt5Agg")
# pylint: disable=redefined-outer-name
import matplotlib.pyplot as plt
plt.ion() # interactive


__setup_Qt_backend()
del __setup_Qt_backend

__setup_Qt_backend()
del __setup_Qt_backend

## Setup logging
from . import config
Expand All @@ -125,6 +134,7 @@ def set_attribute(name: str, value=True):

###########################################################################
### User-accessible scope
# For executing well on cloud; Insert three if statements

# Metal Dict
from .toolbox_python.attr_dict import Dict
Expand All @@ -139,16 +149,19 @@ def set_attribute(name: str, value=True):
from . import draw
from . import renderers
from . import qgeometries
from . import analyses
if not is_cloud():
from . import analyses
from . import toolbox_python
from . import toolbox_metal

# Metal GUI
from ._gui.main_window import MetalGUI
if not is_cloud():
from ._gui.main_window import MetalGUI

# Utility modules
# For plotting in matplotlib; May be superseded by a renderer?
from .renderers.renderer_mpl import mpl_toolbox as plt
if not is_cloud():
from .renderers.renderer_mpl import mpl_toolbox as plt

# Utility functions
from .toolbox_python.display import Headings
Expand Down
9 changes: 7 additions & 2 deletions qiskit_metal/draw/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,15 @@

from . import basic
from . import utility
from . import mpl

# For executing well on cloud
from qiskit_metal import is_cloud
if not is_cloud():
from . import mpl

# Useful functions
from .utility import get_poly_pts, Vector
from .basic import rectangle, is_rectangle, flip_merge, rotate, translate, scale, buffer,\
rotate_position, _iter_func_geom_, union, subtract
from .mpl import render, figure_spawn
if not is_cloud():
from .mpl import render, figure_spawn
6 changes: 4 additions & 2 deletions qiskit_metal/toolbox_metal/about.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,10 @@ def about():
str: About message
"""
import qiskit_metal
from PySide2.QtCore import __version__ as QT_VERSION_STR
from PySide2 import __version__ as PYSIDE_VERSION_STR
# For executing well on cloud
if not qiskit_metal.is_cloud():
from PySide2.QtCore import __version__ as QT_VERSION_STR
from PySide2 import __version__ as PYSIDE_VERSION_STR

try:
import matplotlib
Expand Down
63 changes: 33 additions & 30 deletions qiskit_metal/toolbox_python/display.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,37 +97,40 @@ def h1(cls, text):


# TODO: Move to module for GUI programming
def get_screenshot(self: 'QMainWindow',
name='shot.png',
type_='png',
do_display=True,
disp_ops=None):
"""Grad a screenshot of the main window, save to file, and then copy to
clipboard.

Args:
self (QMainWindow): Window to take the screenshot of.
name (str): File to save the screenshot to. Defaults to 'shot.png'.
type (str): Type of file to save. Defaults to 'png'.
do_display (bool): True to display the file. Defaults to True.
disp_ops (dict): Disctionary of options. Defaults to None.
"""
from PySide2.QtWidgets import QApplication, QMainWindow

path = Path(name).resolve()

# just grab the main window
screenshot = self.grab() # type: QtGui.QPixelMap
screenshot.save(str(path), type_) # Save

QApplication.clipboard().setPixmap(screenshot) # To clipboard
#print(f'Screenshot copied to clipboard and saved to:\n {path}')

if do_display:
_disp_ops = dict(width=500)
_disp_ops.update(disp_ops or {})
display(Image(filename=str(path), **_disp_ops))

# For executing well on cloud
from qiskit_metal import is_cloud
if not is_cloud():
def get_screenshot(self: 'QMainWindow',
name='shot.png',
type_='png',
do_display=True,
disp_ops=None):
"""Grad a screenshot of the main window, save to file, and then copy to
clipboard.

Args:
self (QMainWindow): Window to take the screenshot of.
name (str): File to save the screenshot to. Defaults to 'shot.png'.
type (str): Type of file to save. Defaults to 'png'.
do_display (bool): True to display the file. Defaults to True.
disp_ops (dict): Disctionary of options. Defaults to None.
"""
from PySide2.QtWidgets import QApplication, QMainWindow

path = Path(name).resolve()

# just grab the main window
screenshot = self.grab() # type: QtGui.QPixelMap
screenshot.save(str(path), type_) # Save

QApplication.clipboard().setPixmap(screenshot) # To clipboard
#print(f'Screenshot copied to clipboard and saved to:\n {path}')

if do_display:
_disp_ops = dict(width=500)
_disp_ops.update(disp_ops or {})
display(Image(filename=str(path), **_disp_ops))

##########################################################################
# Shell print
Expand Down