Source code for qts._core

import importlib.util
import typing

import attr

import qts


[docs]@attr.frozen class Wrapper: """A representation of a specific wrapper that can be used to access a specific version of Qt. """ family: str """The wrapper family. ``"PyQt"`` or ``"PySide"``.""" name: str """The name of the specific wrapper, including the version number. Such as ``"PySide6"``.""" major_version: int """The major version of the wrapped Qt library. Such as ``6``.""" module_name: str """The name used to import the module. Such as ``"PySide6"``."""
pyqt_5_wrapper = Wrapper( family="PyQt", name="PyQt5", major_version=5, module_name="PyQt5" ) """The PyQt/Qt5 wrapper object.""" pyqt_6_wrapper = Wrapper( family="PyQt", name="PyQt6", major_version=6, module_name="PyQt6" ) """The PyQt/Qt6 wrapper object.""" pyside_5_wrapper = Wrapper( family="PySide", name="PySide2", major_version=5, module_name="PySide2" ) """The PySide/Qt5 wrapper object.""" pyside_6_wrapper = Wrapper( family="PySide", name="PySide6", major_version=6, module_name="PySide6" ) """The PySide/Qt6 wrapper object.""" supported_wrappers = [ pyqt_5_wrapper, pyqt_6_wrapper, pyside_5_wrapper, pyside_6_wrapper, ] """A list of all the supported wrapper objects.""" _wrappers_by_name = {wrapper.name.casefold(): wrapper for wrapper in supported_wrappers}
[docs]def set_wrapper(wrapper: Wrapper) -> None: """Set the wrapper you want to back the Qt modules accessed through qts. :raises qts.WrapperAlreadySelectedError: When called and a wrapper has already been set. :raises qts.InvalidWrapperError: When called with an invalid wrapper. """ # This could accept the new wrapper if it matches the existing selection, but this # seems like it would mostly just encourage coding that hazards setting to a # different wrapper in some other case. May as well complain early so that # developers get early warning and can adjust their design. if qts.wrapper is not None: raise qts.WrapperAlreadySelectedError( existing_wrapper=qts.wrapper, requested_wrapper=wrapper, ) if wrapper not in supported_wrappers: raise qts.InvalidWrapperError(wrapper=wrapper) qts.wrapper = wrapper qts.is_pyqt_5_wrapper = wrapper == pyqt_5_wrapper qts.is_pyqt_6_wrapper = wrapper == pyqt_6_wrapper qts.is_pyside_5_wrapper = wrapper == pyside_5_wrapper qts.is_pyside_6_wrapper = wrapper == pyside_6_wrapper
[docs]def available_wrappers( wrappers: typing.Optional[typing.Iterable[Wrapper]] = None, ) -> typing.Sequence[Wrapper]: """Get a sequence of the wrappers that are available for use. If ``wrappers`` is passed, only wrappers that are both available and in the passed iterable will be returned. :returns: The wrappers that are installed and available for use. """ if wrappers is None: wrappers = supported_wrappers available = [ wrapper for wrapper in wrappers if importlib.util.find_spec(wrapper.module_name) ] return available
[docs]def available_wrapper( wrappers: typing.Optional[typing.Iterable[Wrapper]] = None, ) -> Wrapper: """Get the available wrapper when there is only one. :return: The wrapper object for the single available wrapper. :raises qts.NoWrapperAvailableError: When no wrappers are available. :raises qts.MultipleWrappersAvailableError: If more than one wrapper is available. """ if wrappers is None: wrappers = supported_wrappers all_available = available_wrappers(wrappers=wrappers) if len(all_available) == 0: raise qts.NoWrapperAvailableError(wrappers=wrappers) elif len(all_available) > 1: raise qts.MultipleWrappersAvailableError(searched=wrappers, found=all_available) [the_one] = all_available return the_one
[docs]def wrapper_by_name(name: str) -> Wrapper: """Get a wrapper object by its name. The name is checked case insensitively. :returns: The wrapper that goes by the passed name. """ return _wrappers_by_name[name.casefold()]