1
0
mirror of https://gitlab.com/openlp/openlp.git synced 2024-12-25 11:14:07 +00:00

Migrate from PyQt5 to PySide6

This commit is contained in:
Tomas Groth 2024-08-26 20:57:54 +00:00 committed by Tim Bentley
parent 9646242881
commit 169212c812
274 changed files with 3108 additions and 6048 deletions

View File

@ -47,7 +47,8 @@ test-fedora:
image: $IMAGE_BASE/fedora
script:
- sh scripts/generate_resources.sh
- xvfb-run -s '-screen 0 1024x768x24' pytest-3 --color=no --disable-warnings
# - xvfb-run -s '-screen 0 1024x768x24' pytest-3 --color=no --disable-warnings
- xwfb-run -c weston -s \\-geometry -s 1024x768x24 -- pytest
test-arch:
stage: test

View File

@ -31,7 +31,7 @@ install:
# Update pip
- python -m pip install --upgrade pip
# Install generic dependencies from pypi.
- python -m pip install sqlalchemy alembic platformdirs chardet beautifulsoup4 lxml Mako mysql-connector-python pytest mock psycopg2-binary websockets waitress six requests QtAwesome PyQt5 PyQtWebEngine pymediainfo PyMuPDF QDarkStyle python-vlc flask-cors pytest-qt pyenchant pysword qrcode flask packaging
- python -m pip install sqlalchemy alembic platformdirs chardet beautifulsoup4 lxml Mako mysql-connector-python pytest mock psycopg2-binary websockets waitress six requests QtAwesome PySide6 PyMuPDF QDarkStyle python-vlc flask-cors pytest-qt pyenchant pysword qrcode flask packaging
# Install Windows only dependencies
- cmd: python -m pip install pyodbc pypiwin32
- cmd: choco install vlc %CHOCO_VLC_ARG% --no-progress --limit-output

View File

@ -29,7 +29,7 @@ Ignore the version file and pull the version directly
from Bazaar
.TP
\fB\-s\fR STYLE, \fB\-\-style\fR=\fISTYLE\fR
Set the Qt5 style (passed directly to Qt5).
Set the Qt6 style (passed directly to Qt6).
.TP
\fB\-\-testing\fR
Run by testing framework

View File

@ -27,7 +27,7 @@ import re
from datetime import date
from zipfile import ZipFile
from PyQt5 import QtCore
from PySide6 import QtCore
from openlp.core.common.applocation import AppLocation
from openlp.core.common.httputils import download_file, get_web_page, get_openlp_user_agent
@ -45,8 +45,8 @@ class RemoteVersionWorker(ThreadWorker):
A worker class to fetch the version of the web remote. This is run from within a thread so that it
doesn't affect the loading time of OpenLP.
"""
new_version = QtCore.pyqtSignal(str)
no_internet = QtCore.pyqtSignal()
new_version = QtCore.Signal(str)
no_internet = QtCore.Signal()
def __init__(self, current_version):
"""

View File

@ -27,7 +27,7 @@ from qrcode.image.svg import SvgPathFillImage
from time import sleep
from PyQt5 import QtCore, QtGui, QtWidgets
from PySide6 import QtCore, QtGui, QtWidgets
from openlp.core.api.deploy import download_and_install, download_version_info, get_installed_version
from openlp.core.common import get_network_interfaces
@ -65,8 +65,8 @@ class ApiTab(SettingsTab):
self.server_settings_layout.addRow(self.address_label)
self.address_edit = QtWidgets.QLineEdit(self.server_settings_group_box)
self.address_edit.setSizePolicy(QtWidgets.QSizePolicy.Policy.Preferred, QtWidgets.QSizePolicy.Policy.Fixed)
self.address_edit.setValidator(QtGui.QRegExpValidator(QtCore.QRegExp(r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}'),
self))
self.address_edit.setValidator(QtGui.QRegularExpressionValidator(QtCore.QRegularExpression(
r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}'), self))
self.address_edit.setObjectName('address_edit')
self.address_revert_button = QtWidgets.QToolButton(self.server_settings_group_box)
self.address_revert_button.setObjectName('address_revert_button')
@ -165,7 +165,7 @@ class ApiTab(SettingsTab):
self.app_qr_layout.setObjectName('app_qr_layout')
self.app_qr_code_label = QtWidgets.QLabel(self.app_group_box)
self.app_qr_code_label.setPixmap(QtGui.QPixmap(':/remotes/app_qr.svg'))
self.app_qr_code_label.setAlignment(QtCore.Qt.AlignCenter)
self.app_qr_code_label.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)
self.app_qr_code_label.setObjectName('app_qr_code_label')
self.app_qr_layout.addWidget(self.app_qr_code_label)
self.app_qr_description_label = QtWidgets.QLabel(self.app_group_box)
@ -372,7 +372,7 @@ class ApiTab(SettingsTab):
"""
self.twelve_hour = False
# we have a set value convert to True/False
if check_state == QtCore.Qt.Checked:
if check_state == QtCore.Qt.CheckState.Checked:
self.twelve_hour = True
def on_thumbnails_check_box_changed(self, check_state):
@ -381,7 +381,7 @@ class ApiTab(SettingsTab):
"""
self.thumbnails = False
# we have a set value convert to True/False
if check_state == QtCore.Qt.Checked:
if check_state == QtCore.Qt.CheckState.Checked:
self.thumbnails = True
def on_check_for_updates_button_clicked(self):

View File

@ -19,7 +19,7 @@
# along with this program. If not, see <https://www.gnu.org/licenses/>. #
##########################################################################
from flask import jsonify, Blueprint
from PyQt5 import QtCore
from PySide6 import QtCore
from openlp.core.api.lib import old_auth, old_success_response
from openlp.core.common.registry import Registry
@ -57,6 +57,7 @@ def plugin_list():
def main_image():
live_controller = Registry().get('live_controller')
img_data = live_controller.staticMetaObject.invokeMethod(
live_controller, 'grab_maindisplay', QtCore.Qt.BlockingQueuedConnection, QtCore.Q_RETURN_ARG(str))
live_controller, 'grab_maindisplay', QtCore.Qt.ConnectionType.BlockingQueuedConnection,
QtCore.Q_RETURN_ARG(str))
img = 'data:image/jpeg;base64,{}'.format(img_data)
return jsonify({'slide_image': img})

View File

@ -21,7 +21,7 @@
import logging
from flask import jsonify, request, abort, Blueprint
from PyQt5 import QtCore
from PySide6 import QtCore
from openlp.core.api.lib import login_required
from openlp.core.common.i18n import LanguageManager
@ -109,6 +109,7 @@ def login():
def main_image():
live_controller = Registry().get('live_controller')
img_data = live_controller.staticMetaObject.invokeMethod(
live_controller, 'grab_maindisplay', QtCore.Qt.BlockingQueuedConnection, QtCore.Q_RETURN_ARG(str))
live_controller, 'grab_maindisplay', QtCore.Qt.ConnectionType.BlockingQueuedConnection,
QtCore.Q_RETURN_ARG(str))
img = 'data:image/jpeg;base64,{}'.format(img_data)
return jsonify({'binary_image': img})

View File

@ -24,7 +24,7 @@ import json
import re
from flask import abort, request, Blueprint, jsonify, Response
from PyQt5 import QtCore
from PySide6 import QtCore
from openlp.core.api.lib import login_required, extract_request, old_success_response, old_auth
from openlp.core.lib.plugin import PluginStatus
@ -46,7 +46,7 @@ def search(plugin_name, text):
if hasattr(plugin.media_item.search, '__pyqtSignature__'):
# If this method has a signature, it means that it should be called from the parent thread
results = plugin.media_item.staticMetaObject.invokeMethod(
plugin.media_item, 'search', QtCore.Qt.BlockingQueuedConnection,
plugin.media_item, 'search', QtCore.Qt.ConnectionType.BlockingQueuedConnection,
QtCore.Q_RETURN_ARG(list), QtCore.Q_ARG(str, text), QtCore.Q_ARG(bool, False))
else:
# Fall back to original behaviour

View File

@ -30,7 +30,7 @@ from dataclasses import asdict, dataclass
from typing import Optional, Union
import time
from PyQt5 import QtCore
from PySide6 import QtCore
from websockets import serve
from openlp.core.common.mixins import LogMixin, RegistryProperties
@ -207,7 +207,7 @@ class WebSocketServer(RegistryBase, RegistryProperties, QtCore.QObject, LogMixin
"""
Wrapper round a server instance
"""
_send_message_signal = QtCore.pyqtSignal(WebSocketMessage)
_send_message_signal = QtCore.Signal(WebSocketMessage)
def __init__(self):
"""
@ -231,7 +231,7 @@ class WebSocketServer(RegistryBase, RegistryProperties, QtCore.QObject, LogMixin
# Only hooking poller signals after all UI is available
Registry().register_function('bootstrap_completion', self.try_poller_hook_signals)
@QtCore.pyqtSlot()
@QtCore.Slot()
def handle_poller_signal(self):
if self.worker is not None:
self.worker.add_state_to_queues(poller.get_state())

View File

@ -18,7 +18,7 @@
# You should have received a copy of the GNU General Public License #
# along with this program. If not, see <https://www.gnu.org/licenses/>. #
##########################################################################
from PyQt5 import QtCore
from PySide6 import QtCore
from openlp.core.common.mixins import RegistryProperties
@ -27,7 +27,7 @@ class WebSocketPoller(QtCore.QObject, RegistryProperties):
Accessed by web sockets to get status type information from the application
"""
poller_changed = QtCore.pyqtSignal()
poller_changed = QtCore.Signal()
def __init__(self):
"""
@ -67,9 +67,9 @@ class WebSocketPoller(QtCore.QObject, RegistryProperties):
except Exception:
pass
@QtCore.pyqtSlot(list)
@QtCore.pyqtSlot(str)
@QtCore.pyqtSlot()
@QtCore.Slot(list)
@QtCore.Slot(str)
@QtCore.Slot()
def on_signal_received(self):
self._state = self.create_state()
self.poller_changed.emit()

View File

@ -35,7 +35,7 @@ from pathlib import Path
from shutil import copytree, move
from traceback import format_exception
from PyQt5 import QtCore, QtGui, QtWebEngineWidgets, QtWidgets # noqa
from PySide6 import QtCore, QtGui, QtWebEngineCore, QtWidgets # noqa
from openlp.core.api.deploy import check_for_remote_update
from openlp.core.common.applocation import AppLocation
@ -43,7 +43,7 @@ from openlp.core.common.enum import HiDPIMode
from openlp.core.common.i18n import LanguageManager, UiStrings, translate
from openlp.core.common.mixins import LogMixin
from openlp.core.common.path import create_paths, resolve
from openlp.core.common.platform import is_macosx, is_win
from openlp.core.common.platform import is_macosx, is_wayland_compositor, is_win
from openlp.core.common.registry import Registry
from openlp.core.common.settings import Settings
from openlp.core.display.screens import ScreenList
@ -110,7 +110,7 @@ class OpenLP(QtCore.QObject, LogMixin):
if not has_run_wizard:
ftw = FirstTimeForm()
ftw.initialize(screens)
if ftw.exec() == QtWidgets.QDialog.Accepted:
if ftw.exec() == QtWidgets.QDialog.DialogCode.Accepted:
self.settings.setValue('core/has run wizard', True)
else:
QtCore.QCoreApplication.exit()
@ -124,7 +124,9 @@ class OpenLP(QtCore.QObject, LogMixin):
# Check if OpenLP has been upgrade and if a backup of data should be created
self.backup_on_upgrade(has_run_wizard, can_show_splash)
# start the main app window
Registry().toggle_suppressing()
loader()
Registry().toggle_suppressing()
# Set the darkmode based on theme
set_default_theme(app)
self.main_window = MainWindow()
@ -162,7 +164,7 @@ class OpenLP(QtCore.QObject, LogMixin):
Tell the user there is a 2nd instance running.
"""
QtWidgets.QMessageBox.critical(None, UiStrings().Error, UiStrings().OpenLPStart,
QtWidgets.QMessageBox.StandardButtons(QtWidgets.QMessageBox.Ok))
QtWidgets.QMessageBox.StandardButton(QtWidgets.QMessageBox.StandardButton.Ok))
def is_data_path_missing(self):
"""
@ -180,9 +182,10 @@ class OpenLP(QtCore.QObject, LogMixin):
'current location available.\n\nDo you want to reset to the default data location? '
'If not, OpenLP will be closed so you can try to fix the problem.')
.format(path=data_folder_path),
QtWidgets.QMessageBox.StandardButtons(QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No),
QtWidgets.QMessageBox.No)
if status == QtWidgets.QMessageBox.No:
QtWidgets.QMessageBox.StandardButton(QtWidgets.QMessageBox.StandardButton.Yes |
QtWidgets.QMessageBox.StandardButton.No),
QtWidgets.QMessageBox.StandardButton.No)
if status == QtWidgets.QMessageBox.StandardButton.No:
# If answer was "No", return "True", it will shutdown OpenLP in def main
log.info('User requested termination')
return True
@ -230,10 +233,11 @@ class OpenLP(QtCore.QObject, LogMixin):
elif data_version != openlp_version:
if can_show_splash and self.splash.isVisible():
self.splash.hide()
if QtWidgets.QMessageBox.question(None, translate('OpenLP', 'Backup'),
translate('OpenLP', 'OpenLP has been upgraded, do you want to create\n'
'a backup of the old data folder?'),
defaultButton=QtWidgets.QMessageBox.Yes) == QtWidgets.QMessageBox.Yes:
if (QtWidgets.QMessageBox.question(None, translate('OpenLP', 'Backup'),
translate('OpenLP', 'OpenLP has been upgraded, do you want to create\n'
'a backup of the old data folder?'),
defaultButton=QtWidgets.QMessageBox.StandardButton.Yes) ==
QtWidgets.QMessageBox.StandardButton.Yes):
# Create copy of data folder
data_folder_path = AppLocation.get_data_path()
timestamp = time.strftime("%Y%m%d-%H%M%S")
@ -266,7 +270,7 @@ class OpenLP(QtCore.QObject, LogMixin):
"""
Sets the Busy Cursor for the Application
"""
QtWidgets.QApplication.setOverrideCursor(QtCore.Qt.BusyCursor)
QtWidgets.QApplication.setOverrideCursor(QtCore.Qt.CursorShape.BusyCursor)
QtWidgets.QApplication.processEvents()
@staticmethod
@ -329,7 +333,7 @@ def set_up_web_engine_cache(web_cache_path):
:param Path web_cache_path: The folder for the web engine files
:rtype: None
"""
web_engine_profile = QtWebEngineWidgets.QWebEngineProfile.defaultProfile()
web_engine_profile = QtWebEngineCore.QWebEngineProfile.defaultProfile()
web_engine_profile.setCachePath(str(web_cache_path))
web_engine_profile.setPersistentStoragePath(str(web_cache_path))
@ -359,9 +363,10 @@ def backup_if_version_changed(settings):
'OpenLP will start with a fresh install as downgrading data is not supported. Any existing data '
'will be backed up to:\n\n{data_folder_backup_path}\n\n'
'Do you want to continue?').format(data_folder_backup_path=data_folder_backup_path),
QtWidgets.QMessageBox.StandardButtons(QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No),
QtWidgets.QMessageBox.No)
if close_result == QtWidgets.QMessageBox.No:
QtWidgets.QMessageBox.StandardButton(QtWidgets.QMessageBox.StandardButton.Yes |
QtWidgets.QMessageBox.StandardButton.No),
QtWidgets.QMessageBox.StandardButton.No)
if close_result == QtWidgets.QMessageBox.StandardButton.No:
# Return false as backup failed.
return False
# Backup the settings
@ -410,14 +415,6 @@ def apply_dpi_adjustments_stage_qt(hidpi_mode, qt_args):
qt_args[platform_index + 1] += ' windows:dpiawareness=0'
except ValueError:
qt_args.extend(['-platform', 'windows:dpiawareness=0'])
else:
QtWidgets.QApplication.setAttribute(QtCore.Qt.ApplicationAttribute.AA_EnableHighDpiScaling)
if hidpi_mode == HiDPIMode.Default:
no_custom_factor_rounding = not ('QT_SCALE_FACTOR_ROUNDING_POLICY' in os.environ
and bool(os.environ['QT_SCALE_FACTOR_ROUNDING_POLICY'].strip()))
if no_custom_factor_rounding:
# TODO Won't be needed on PyQt6, PassThrough is the default
os.environ['QT_SCALE_FACTOR_ROUNDING_POLICY'] = 'PassThrough'
def apply_dpi_adjustments_stage_application(hidpi_mode: HiDPIMode, application: QtWidgets.QApplication):
@ -428,20 +425,12 @@ def apply_dpi_adjustments_stage_application(hidpi_mode: HiDPIMode, application:
:param settings: The settings object
:param stage: The stage of app
"""
if hidpi_mode == HiDPIMode.Default:
no_custom_factor_rounding = not ('QT_SCALE_FACTOR_ROUNDING_POLICY' in os.environ
and bool(os.environ['QT_SCALE_FACTOR_ROUNDING_POLICY'].strip()))
if no_custom_factor_rounding and hasattr(QtWidgets.QApplication, 'setHighDpiScaleFactorRoundingPolicy'):
# TODO Won't be needed on PyQt6, PassThrough is the default
application.setHighDpiScaleFactorRoundingPolicy(QtCore.Qt.HighDpiScaleFactorRoundingPolicy.PassThrough)
if is_win() and application.devicePixelRatio() > 1.0:
# Increasing font size to match pixel ratio (Windows only)
# TODO: Review on PyQt6 migration
font = application.font()
font.setPointSizeF(font.pointSizeF() * application.devicePixelRatio())
application.setFont(font)
if hidpi_mode != HiDPIMode.Windows_Unaware:
application.setAttribute(QtCore.Qt.AA_UseHighDpiPixmaps, True)
if hidpi_mode == HiDPIMode.Default and is_win() and application.devicePixelRatio() > 1.0:
# Increasing font size to match pixel ratio (Windows only)
# TODO: Review on Qt6 migration
font = application.font()
font.setPointSizeF(font.pointSizeF() * application.devicePixelRatio())
application.setFont(font)
def setup_portable_settings(portable_path: Path | str | None) -> Settings:
@ -485,17 +474,15 @@ def main():
# support dark mode on windows 10. This makes the titlebar dark, the rest is setup later
# by calling set_windows_darkmode
qt_args.extend(['-platform', 'windows:darkmode=1'])
elif is_macosx() and getattr(sys, 'frozen', False):
elif is_macosx() and getattr(sys, 'frozen', False) and not os.environ.get('QTWEBENGINEPROCESS_PATH'):
# Set the location to the QtWebEngineProcess binary, normally set by PyInstaller, but it moves around...
os.environ['QTWEBENGINEPROCESS_PATH'] = str((AppLocation.get_directory(AppLocation.AppDir) / '..' /
'Frameworks' / 'QtWebEngineCore.framework' / 'Versions' / '5' /
'Helpers' / 'QtWebEngineProcess.app' / 'Contents' / 'MacOS' /
'QtWebEngineProcess').resolve())
no_custom_factor_rounding = not ('QT_SCALE_FACTOR_ROUNDING_POLICY' in os.environ
and bool(os.environ['QT_SCALE_FACTOR_ROUNDING_POLICY'].strip()))
if no_custom_factor_rounding:
# TODO Won't be needed on PyQt6
os.environ['QT_SCALE_FACTOR_ROUNDING_POLICY'] = 'PassThrough'
os.environ['QTWEBENGINEPROCESS_PATH'] = str((AppLocation.get_directory(AppLocation.AppDir) / 'PySide6' /
'Qt6' / 'lib' / 'QtWebEngineCore.framework' / 'Versions' /
'6' / 'Helpers' / 'QtWebEngineProcess.app' / 'Contents' /
'MacOS' / 'QtWebEngineProcess').resolve())
# Prevent the use of wayland, use xcb instead
if is_wayland_compositor():
qt_args.extend(['-platform', 'xcb'])
# Initialise the resources
qInitResources()
# Initialise OpenLP
@ -518,12 +505,9 @@ def main():
# Instantiating QCoreApplication
init_webview_custom_schemes()
application = QtWidgets.QApplication(qt_args)
application.setAttribute(QtCore.Qt.AA_DontCreateNativeWidgetSiblings, True)
application.setAttribute(QtCore.Qt.ApplicationAttribute.AA_DontCreateNativeWidgetSiblings, True)
# Doing HiDPI adjustments that need to be done after QCoreApplication instantiation.
apply_dpi_adjustments_stage_application(hidpi_mode, application)
if no_custom_factor_rounding and hasattr(QtWidgets.QApplication, 'setHighDpiScaleFactorRoundingPolicy'):
# TODO: Check won't be needed on PyQt6
application.setHighDpiScaleFactorRoundingPolicy(QtCore.Qt.HighDpiScaleFactorRoundingPolicy.PassThrough)
if is_win() and application.devicePixelRatio() > 1.0:
# Increasing font size to match pixel ratio (Windows only)
font = application.font()

View File

@ -33,9 +33,9 @@ from ipaddress import IPv4Address, IPv6Address, AddressValueError
from pathlib import Path
from shutil import which
from PyQt5 import QtGui
from PyQt5.QtCore import QCryptographicHash as QHash
from PyQt5.QtNetwork import QAbstractSocket, QHostAddress, QNetworkInterface
from PySide6 import QtGui
from PySide6.QtCore import QCryptographicHash as QHash
from PySide6.QtNetwork import QAbstractSocket, QHostAddress, QNetworkInterface
from chardet.universaldetector import UniversalDetector
log = logging.getLogger(__name__ + '.__init__')
@ -68,21 +68,21 @@ def get_network_interfaces():
log.debug('Filtering out interfaces we don\'t care about: {name}'.format(name=interface_name))
continue
log.debug('Checking for isValid and flags == IsUP | IsRunning')
if not interface.isValid() or not (interface.flags() & (QNetworkInterface.IsUp | QNetworkInterface.IsRunning)):
if not interface.isValid() or not (interface.flags() & (QNetworkInterface.InterfaceFlag.IsUp |
QNetworkInterface.InterfaceFlag.IsRunning)):
continue
log.debug('Checking address(es) protocol')
for address in interface.addressEntries():
ip = address.ip()
log.debug('Checking for protocol == IPv4Protocol')
if ip.protocol() == QAbstractSocket.IPv4Protocol:
if ip.protocol() == QAbstractSocket.NetworkLayerProtocol.IPv4Protocol:
log.debug('Getting interface information')
interfaces[interface_name] = {
'ip': ip.toString(),
'broadcast': address.broadcast().toString(),
'netmask': address.netmask().toString(),
'prefix': address.prefixLength(),
'localnet': QHostAddress(address.netmask().toIPv4Address() &
ip.toIPv4Address()).toString()
'localnet': QHostAddress(address.netmask().toIPv4Address() & ip.toIPv4Address()).toString()
}
log.debug('Adding {interface} to active list'.format(interface=interface.name()))
if len(interfaces) == 0:
@ -298,7 +298,7 @@ def sha256_file_hash(filename):
def qmd5_hash(salt=None, data=None):
"""
Returns the hashed output of MD5Sum on salt, data
using PyQt5.QCryptographicHash. Function returns a
using PySide6.QCryptographicHash. Function returns a
QByteArray instead of a text string.
If you need a string instead, call with

View File

@ -24,7 +24,7 @@ by the shortcuts system.
"""
import logging
from PyQt5 import QtCore, QtGui, QtWidgets
from PySide6 import QtCore, QtGui
from openlp.core.common.registry import Registry
@ -352,17 +352,19 @@ class ActionList(object):
:param existing_actions: A list of actions which already use a particular shortcut.
:param action: The action which wants to use a particular shortcut.
"""
global_context = action.shortcutContext() in [QtCore.Qt.WindowShortcut, QtCore.Qt.ApplicationShortcut]
global_context = action.shortcutContext() in [QtCore.Qt.ShortcutContext.WindowShortcut,
QtCore.Qt.ShortcutContext.ApplicationShortcut]
affected_actions = []
if global_context:
affected_actions = [a for a in self.get_all_child_objects(action.parent()) if isinstance(a,
QtWidgets.QAction)]
QtGui.QAction)]
for existing_action in existing_actions:
if action is existing_action:
continue
if existing_action in affected_actions:
return False
if existing_action.shortcutContext() in [QtCore.Qt.WindowShortcut, QtCore.Qt.ApplicationShortcut]:
if existing_action.shortcutContext() in [QtCore.Qt.ShortcutContext.WindowShortcut,
QtCore.Qt.ShortcutContext.ApplicationShortcut]:
return False
elif action in self.get_all_child_objects(existing_action.parent()):
return False

View File

@ -26,7 +26,7 @@ from contextlib import contextmanager
from pathlib import Path
from typing import Optional
from PyQt5 import QtWidgets
from PySide6 import QtWidgets
from openlp.core.common.i18n import translate

View File

@ -30,7 +30,7 @@ from random import randint
from tempfile import gettempdir
import requests
from PyQt5 import QtCore
from PySide6 import QtCore
from openlp.core.common import trace_error_handler
from openlp.core.common.registry import Registry
@ -249,8 +249,8 @@ class DownloadWorker(ThreadWorker):
"""
This worker allows a file to be downloaded in a thread
"""
download_failed = QtCore.pyqtSignal()
download_succeeded = QtCore.pyqtSignal(Path)
download_failed = QtCore.Signal()
download_succeeded = QtCore.Signal(Path)
def __init__(self, base_url, file_name):
"""
@ -283,7 +283,7 @@ class DownloadWorker(ThreadWorker):
time.sleep(1)
self.quit.emit()
@QtCore.pyqtSlot()
@QtCore.Slot()
def cancel_download(self):
"""
A slot to allow the download to be cancelled from outside of the thread

View File

@ -27,7 +27,7 @@ import logging
import re
from collections import namedtuple
from PyQt5 import QtCore, QtWidgets
from PySide6 import QtCore, QtWidgets
from openlp.core.common import Singleton
from openlp.core.common.applocation import AppLocation
@ -40,7 +40,7 @@ log = logging.getLogger(__name__)
# Due to dependency issues, this HAS to be at the top of the file
def translate(context, text, comment=None, qt_translate=QtCore.QCoreApplication.translate):
"""
A special shortcut method to wrap around the Qt5 translation functions. This abstracts the translation procedure so
A special shortcut method to wrap around the Qt6 translation functions. This abstracts the translation procedure so
that we can change it if at a later date if necessary, without having to redo the whole of OpenLP.
:param context: The translation context, used to give each string a context or a namespace.
@ -231,8 +231,8 @@ class LanguageManager(object):
log.info(f"Language: '{language}' loaded.")
# A translator for buttons and other default strings provided by Qt.
if not is_win() and not is_macosx():
lang_path = QtCore.QLibraryInfo.location(QtCore.QLibraryInfo.TranslationsPath)
# As of Qt5, the core translations come in 2 files per language
lang_path = QtCore.QLibraryInfo.location(QtCore.QLibraryInfo.LibraryPath.TranslationsPath)
# As of Qt6, the core translations come in 2 files per language
default_translator = QtCore.QTranslator()
default_translator.load('qt_%s' % language, lang_path)
base_translator = QtCore.QTranslator()
@ -246,7 +246,7 @@ class LanguageManager(object):
"""
log.debug('Translation files: {files}'.format(files=AppLocation.get_directory(AppLocation.LanguageDir)))
trans_dir = QtCore.QDir(str(AppLocation.get_directory(AppLocation.LanguageDir)))
file_names = trans_dir.entryList(['*.qm'], QtCore.QDir.Filter.Files, QtCore.QDir.Name)
file_names = trans_dir.entryList(['*.qm'], QtCore.QDir.Filter.Files, QtCore.QDir.SortFlag.Name)
# Remove qm files from the list which start with "qt".
file_names = [file_ for file_ in file_names if not file_.startswith('qt')]
return list(map(trans_dir.filePath, file_names))
@ -310,7 +310,7 @@ class LanguageManager(object):
LanguageManager.__qm_list__ = {}
qm_files = LanguageManager.find_qm_files()
for counter, qmf in enumerate(qm_files):
reg_ex = QtCore.QRegExp("^.*i18n/(.*).qm")
reg_ex = QtCore.QRegularExpression("^.*i18n/(.*).qm")
if reg_ex.exactMatch(qmf):
name = '{regex}'.format(regex=reg_ex.cap(1))
LanguageManager.__qm_list__[

View File

@ -27,10 +27,12 @@ import logging
from openlp.core.common import trace_error_handler
from openlp.core.common.platform import is_win
from openlp.core.common.registry import Registry
from openlp.core.common.settings import Settings
DO_NOT_TRACE_EVENTS = ['timerEvent', 'paintEvent', 'drag_enter_event', 'drop_event', 'on_controller_size_changed',
'preview_size_changed', 'resizeEvent', 'eventFilter', 'tick', 'resize', 'update_ui']
'preview_size_changed', 'resizeEvent', 'eventFilter', 'tick', 'resize', 'update_ui',
'get_time']
class LogMixin(object):
@ -240,7 +242,7 @@ class RegistryProperties(object):
return self._projector_manager
@property
def settings(self):
def settings(self) -> Settings:
"""
Adds the settings object to the class dynamically
"""

View File

@ -110,7 +110,7 @@ def is_xorg_platform():
:return: True if the Qt is running on X.org/XWayland display server (Linux/*nix), otherwise False.
"""
from PyQt5 import QtGui
from PySide6 import QtGui
return QtGui.QGuiApplication.platformName() == 'xcb'
@ -120,5 +120,5 @@ def is_wayland_platform():
:return: True if the OpenLP/Qt instance is running in a Wayland compositor, otherwise False
"""
from PyQt5 import QtGui
from PySide6 import QtGui
return QtGui.QGuiApplication.platformName() == 'wayland'

View File

@ -54,6 +54,12 @@ class Registry(metaclass=Singleton):
registry._is_suppressing = False
return registry
def toggle_suppressing(self) -> None:
"""
Switch error message suppression during initialisation
"""
self._is_suppressing = not self._is_suppressing
def get(self, key: str) -> Any | None:
"""
Extracts the registry value from the list based on the key passed in
@ -62,6 +68,8 @@ class Registry(metaclass=Singleton):
"""
if key in self.service_list:
return self.service_list[key]
elif self._is_suppressing:
return None
else:
warn(f'Service "{key}" not found in list', stacklevel=2)
return None

View File

@ -29,7 +29,7 @@ from enum import IntEnum
from pathlib import Path
from tempfile import gettempdir
from PyQt5 import QtCore, QtGui
from PySide6 import QtCore, QtGui
from openlp.core.common import SlideLimits, ThemeLevel
from openlp.core.common.enum import AlertLocation, BibleSearch, CustomSearch, HiDPIMode, ImageThemeMode, LayoutStyle, \
@ -301,7 +301,7 @@ class Settings(QtCore.QSettings):
'media/status': PluginStatus.Inactive,
'media/media files': [],
'media/last directory': None,
'media/media auto start': QtCore.Qt.Unchecked,
'media/media auto start': QtCore.Qt.CheckState.Unchecked,
'media/vlc arguments': '',
'media/live volume': 50,
'media/preview volume': 0,
@ -317,18 +317,18 @@ class Settings(QtCore.QSettings):
'planningcenter/application_id': '',
'planningcenter/secret': '',
'presentations/status': PluginStatus.Inactive,
'presentations/override app': QtCore.Qt.Unchecked,
'presentations/maclo': QtCore.Qt.Checked,
'presentations/Impress': QtCore.Qt.Checked,
'presentations/Powerpoint': QtCore.Qt.Checked,
'presentations/Pdf': QtCore.Qt.Checked,
'presentations/Keynote': QtCore.Qt.Checked,
'presentations/PowerPointMac': QtCore.Qt.Checked,
'presentations/override app': QtCore.Qt.CheckState.Unchecked,
'presentations/maclo': QtCore.Qt.CheckState.Checked,
'presentations/Impress': QtCore.Qt.CheckState.Checked,
'presentations/Powerpoint': QtCore.Qt.CheckState.Checked,
'presentations/Pdf': QtCore.Qt.CheckState.Checked,
'presentations/Keynote': QtCore.Qt.CheckState.Checked,
'presentations/PowerPointMac': QtCore.Qt.CheckState.Checked,
'presentations/presentations files': [],
'presentations/thumbnail_scheme': '',
'presentations/powerpoint slide click advance': QtCore.Qt.Unchecked,
'presentations/powerpoint control window': QtCore.Qt.Unchecked,
'presentations/impress use display setting': QtCore.Qt.Unchecked,
'presentations/powerpoint slide click advance': QtCore.Qt.CheckState.Unchecked,
'presentations/powerpoint control window': QtCore.Qt.CheckState.Unchecked,
'presentations/impress use display setting': QtCore.Qt.CheckState.Unchecked,
'presentations/last directory': None,
'presentations/db type': 'sqlite',
'presentations/db username': '',
@ -535,17 +535,18 @@ class Settings(QtCore.QSettings):
def init_default_shortcuts(self):
# Add shortcuts here so QKeySequence has a QApplication instance to use.
Settings.__default_settings__.update({
'shortcuts/aboutItem': [QtGui.QKeySequence(QtCore.Qt.CTRL + QtCore.Qt.Key_F1)],
'shortcuts/aboutItem': [QtGui.QKeySequence(QtCore.Qt.Key.Key_Control + QtCore.Qt.Key.Key_F1)],
'shortcuts/addToService': [],
'shortcuts/audioPauseItem': [],
'shortcuts/displayTagItem': [],
'shortcuts/blankScreen': [QtGui.QKeySequence(QtCore.Qt.Key_Period)],
'shortcuts/collapse': [QtGui.QKeySequence(QtCore.Qt.Key_Minus)],
'shortcuts/desktopScreen': [QtGui.QKeySequence(QtCore.Qt.Key_D), QtGui.QKeySequence(QtCore.Qt.Key_Escape)],
'shortcuts/blankScreen': [QtGui.QKeySequence(QtCore.Qt.Key.Key_Period)],
'shortcuts/collapse': [QtGui.QKeySequence(QtCore.Qt.Key.Key_Minus)],
'shortcuts/desktopScreen': [QtGui.QKeySequence(QtCore.Qt.Key.Key_D),
QtGui.QKeySequence(QtCore.Qt.Key.Key_Escape)],
'shortcuts/delete': [QtGui.QKeySequence(QtGui.QKeySequence.StandardKey.Delete)],
'shortcuts/down': [QtGui.QKeySequence(QtCore.Qt.Key_Down)],
'shortcuts/down': [QtGui.QKeySequence(QtCore.Qt.Key.Key_Down)],
'shortcuts/editSong': [],
'shortcuts/expand': [QtGui.QKeySequence(QtCore.Qt.Key_Plus)],
'shortcuts/expand': [QtGui.QKeySequence(QtCore.Qt.Key.Key_Plus)],
'shortcuts/exportThemeItem': [],
'shortcuts/fileNewItem': [QtGui.QKeySequence(QtGui.QKeySequence.StandardKey.New)],
'shortcuts/fileSaveAsItem': [QtGui.QKeySequence(QtGui.QKeySequence.StandardKey.SaveAs)],
@ -557,82 +558,85 @@ class Settings(QtCore.QSettings):
'shortcuts/importThemeItem': [],
'shortcuts/importBibleItem': [],
'shortcuts/listViewBiblesDeleteItem': [QtGui.QKeySequence(QtGui.QKeySequence.StandardKey.Delete)],
'shortcuts/listViewBiblesPreviewItem': [QtGui.QKeySequence(QtCore.Qt.Key_Return),
QtGui.QKeySequence(QtCore.Qt.Key_Enter)],
'shortcuts/listViewBiblesLiveItem': [QtGui.QKeySequence(QtCore.Qt.SHIFT + QtCore.Qt.Key_Return),
QtGui.QKeySequence(QtCore.Qt.SHIFT + QtCore.Qt.Key_Enter)],
'shortcuts/listViewBiblesServiceItem': [QtGui.QKeySequence(QtCore.Qt.Key_Plus),
QtGui.QKeySequence(QtCore.Qt.Key_Equal)],
'shortcuts/listViewBiblesPreviewItem': [QtGui.QKeySequence(QtCore.Qt.Key.Key_Return),
QtGui.QKeySequence(QtCore.Qt.Key.Key_Enter)],
'shortcuts/listViewBiblesLiveItem': [QtGui.QKeySequence(QtCore.Qt.Key.Key_Shift + QtCore.Qt.Key.Key_Return),
QtGui.QKeySequence(QtCore.Qt.Key.Key_Shift + QtCore.Qt.Key.Key_Enter)],
'shortcuts/listViewBiblesServiceItem': [QtGui.QKeySequence(QtCore.Qt.Key.Key_Plus),
QtGui.QKeySequence(QtCore.Qt.Key.Key_Equal)],
'shortcuts/listViewCustomDeleteItem': [QtGui.QKeySequence(QtGui.QKeySequence.StandardKey.Delete)],
'shortcuts/listViewCustomPreviewItem': [QtGui.QKeySequence(QtCore.Qt.Key_Return),
QtGui.QKeySequence(QtCore.Qt.Key_Enter)],
'shortcuts/listViewCustomLiveItem': [QtGui.QKeySequence(QtCore.Qt.SHIFT + QtCore.Qt.Key_Return),
QtGui.QKeySequence(QtCore.Qt.SHIFT + QtCore.Qt.Key_Enter)],
'shortcuts/listViewCustomServiceItem': [QtGui.QKeySequence(QtCore.Qt.Key_Plus),
QtGui.QKeySequence(QtCore.Qt.Key_Equal)],
'shortcuts/listViewCustomPreviewItem': [QtGui.QKeySequence(QtCore.Qt.Key.Key_Return),
QtGui.QKeySequence(QtCore.Qt.Key.Key_Enter)],
'shortcuts/listViewCustomLiveItem': [QtGui.QKeySequence(QtCore.Qt.Key.Key_Shift + QtCore.Qt.Key.Key_Return),
QtGui.QKeySequence(QtCore.Qt.Key.Key_Shift + QtCore.Qt.Key.Key_Enter)],
'shortcuts/listViewCustomServiceItem': [QtGui.QKeySequence(QtCore.Qt.Key.Key_Plus),
QtGui.QKeySequence(QtCore.Qt.Key.Key_Equal)],
'shortcuts/listViewImagesDeleteItem': [QtGui.QKeySequence(QtGui.QKeySequence.StandardKey.Delete)],
'shortcuts/listViewImagesPreviewItem': [QtGui.QKeySequence(QtCore.Qt.Key_Return),
QtGui.QKeySequence(QtCore.Qt.Key_Enter)],
'shortcuts/listViewImagesLiveItem': [QtGui.QKeySequence(QtCore.Qt.SHIFT + QtCore.Qt.Key_Return),
QtGui.QKeySequence(QtCore.Qt.SHIFT + QtCore.Qt.Key_Enter)],
'shortcuts/listViewImagesServiceItem': [QtGui.QKeySequence(QtCore.Qt.Key_Plus),
QtGui.QKeySequence(QtCore.Qt.Key_Equal)],
'shortcuts/listViewImagesPreviewItem': [QtGui.QKeySequence(QtCore.Qt.Key.Key_Return),
QtGui.QKeySequence(QtCore.Qt.Key.Key_Enter)],
'shortcuts/listViewImagesLiveItem': [QtGui.QKeySequence(QtCore.Qt.Key.Key_Shift + QtCore.Qt.Key.Key_Return),
QtGui.QKeySequence(QtCore.Qt.Key.Key_Shift + QtCore.Qt.Key.Key_Enter)],
'shortcuts/listViewImagesServiceItem': [QtGui.QKeySequence(QtCore.Qt.Key.Key_Plus),
QtGui.QKeySequence(QtCore.Qt.Key.Key_Equal)],
'shortcuts/listViewMediaDeleteItem': [QtGui.QKeySequence(QtGui.QKeySequence.StandardKey.Delete)],
'shortcuts/listViewMediaPreviewItem': [QtGui.QKeySequence(QtCore.Qt.Key_Return),
QtGui.QKeySequence(QtCore.Qt.Key_Enter)],
'shortcuts/listViewMediaLiveItem': [QtGui.QKeySequence(QtCore.Qt.SHIFT + QtCore.Qt.Key_Return),
QtGui.QKeySequence(QtCore.Qt.SHIFT + QtCore.Qt.Key_Enter)],
'shortcuts/listViewMediaServiceItem': [QtGui.QKeySequence(QtCore.Qt.Key_Plus),
QtGui.QKeySequence(QtCore.Qt.Key_Equal)],
'shortcuts/listViewMediaPreviewItem': [QtGui.QKeySequence(QtCore.Qt.Key.Key_Return),
QtGui.QKeySequence(QtCore.Qt.Key.Key_Enter)],
'shortcuts/listViewMediaLiveItem': [QtGui.QKeySequence(QtCore.Qt.Key.Key_Shift + QtCore.Qt.Key.Key_Return),
QtGui.QKeySequence(QtCore.Qt.Key.Key_Shift + QtCore.Qt.Key.Key_Enter)],
'shortcuts/listViewMediaServiceItem': [QtGui.QKeySequence(QtCore.Qt.Key.Key_Plus),
QtGui.QKeySequence(QtCore.Qt.Key.Key_Equal)],
'shortcuts/listViewPresentationsDeleteItem': [QtGui.QKeySequence(QtGui.QKeySequence.StandardKey.Delete)],
'shortcuts/listViewPresentationsPreviewItem': [QtGui.QKeySequence(QtCore.Qt.Key_Return),
QtGui.QKeySequence(QtCore.Qt.Key_Enter)],
'shortcuts/listViewPresentationsLiveItem': [QtGui.QKeySequence(QtCore.Qt.SHIFT + QtCore.Qt.Key_Return),
QtGui.QKeySequence(QtCore.Qt.SHIFT + QtCore.Qt.Key_Enter)],
'shortcuts/listViewPresentationsServiceItem': [QtGui.QKeySequence(QtCore.Qt.Key_Plus),
QtGui.QKeySequence(QtCore.Qt.Key_Equal)],
'shortcuts/listViewPresentationsPreviewItem': [QtGui.QKeySequence(QtCore.Qt.Key.Key_Return),
QtGui.QKeySequence(QtCore.Qt.Key.Key_Enter)],
'shortcuts/listViewPresentationsLiveItem': [QtGui.QKeySequence(QtCore.Qt.Key.Key_Shift +
QtCore.Qt.Key.Key_Return),
QtGui.QKeySequence(QtCore.Qt.Key.Key_Shift +
QtCore.Qt.Key.Key_Enter)],
'shortcuts/listViewPresentationsServiceItem': [QtGui.QKeySequence(QtCore.Qt.Key.Key_Plus),
QtGui.QKeySequence(QtCore.Qt.Key.Key_Equal)],
'shortcuts/listViewSongsDeleteItem': [QtGui.QKeySequence(QtGui.QKeySequence.StandardKey.Delete)],
'shortcuts/listViewSongsPreviewItem': [QtGui.QKeySequence(QtCore.Qt.Key_Return),
QtGui.QKeySequence(QtCore.Qt.Key_Enter)],
'shortcuts/listViewSongsLiveItem': [QtGui.QKeySequence(QtCore.Qt.SHIFT + QtCore.Qt.Key_Return),
QtGui.QKeySequence(QtCore.Qt.SHIFT + QtCore.Qt.Key_Enter)],
'shortcuts/listViewSongsServiceItem': [QtGui.QKeySequence(QtCore.Qt.Key_Plus),
QtGui.QKeySequence(QtCore.Qt.Key_Equal)],
'shortcuts/listViewSongsPreviewItem': [QtGui.QKeySequence(QtCore.Qt.Key.Key_Return),
QtGui.QKeySequence(QtCore.Qt.Key.Key_Enter)],
'shortcuts/listViewSongsLiveItem': [QtGui.QKeySequence(QtCore.Qt.Key.Key_Shift + QtCore.Qt.Key.Key_Return),
QtGui.QKeySequence(QtCore.Qt.Key.Key_Shift + QtCore.Qt.Key.Key_Enter)],
'shortcuts/listViewSongsServiceItem': [QtGui.QKeySequence(QtCore.Qt.Key.Key_Plus),
QtGui.QKeySequence(QtCore.Qt.Key.Key_Equal)],
'shortcuts/lockPanel': [],
'shortcuts/modeDefaultItem': [],
'shortcuts/modeLiveItem': [],
'shortcuts/make_live': [QtGui.QKeySequence(QtCore.Qt.Key_Return), QtGui.QKeySequence(QtCore.Qt.Key_Enter)],
'shortcuts/moveUp': [QtGui.QKeySequence(QtCore.Qt.Key_PageUp)],
'shortcuts/moveTop': [QtGui.QKeySequence(QtCore.Qt.Key_Home)],
'shortcuts/make_live': [QtGui.QKeySequence(QtCore.Qt.Key.Key_Return),
QtGui.QKeySequence(QtCore.Qt.Key.Key_Enter)],
'shortcuts/moveUp': [QtGui.QKeySequence(QtCore.Qt.Key.Key_PageUp)],
'shortcuts/moveTop': [QtGui.QKeySequence(QtCore.Qt.Key.Key_Home)],
'shortcuts/modeSetupItem': [],
'shortcuts/moveBottom': [QtGui.QKeySequence(QtCore.Qt.Key_End)],
'shortcuts/moveDown': [QtGui.QKeySequence(QtCore.Qt.Key_PageDown)],
'shortcuts/moveBottom': [QtGui.QKeySequence(QtCore.Qt.Key.Key_End)],
'shortcuts/moveDown': [QtGui.QKeySequence(QtCore.Qt.Key.Key_PageDown)],
'shortcuts/nextTrackItem': [],
'shortcuts/nextItem_live': [QtGui.QKeySequence(QtCore.Qt.Key_Down),
QtGui.QKeySequence(QtCore.Qt.Key_PageDown)],
'shortcuts/nextItem_preview': [QtGui.QKeySequence(QtCore.Qt.Key_Down),
QtGui.QKeySequence(QtCore.Qt.Key_PageDown)],
'shortcuts/nextService': [QtGui.QKeySequence(QtCore.Qt.Key_Right)],
'shortcuts/nextItem_live': [QtGui.QKeySequence(QtCore.Qt.Key.Key_Down),
QtGui.QKeySequence(QtCore.Qt.Key.Key_PageDown)],
'shortcuts/nextItem_preview': [QtGui.QKeySequence(QtCore.Qt.Key.Key_Down),
QtGui.QKeySequence(QtCore.Qt.Key.Key_PageDown)],
'shortcuts/nextService': [QtGui.QKeySequence(QtCore.Qt.Key.Key_Right)],
'shortcuts/newService': [],
'shortcuts/openService': [],
'shortcuts/saveService': [],
'shortcuts/previousItem_live': [QtGui.QKeySequence(QtCore.Qt.Key_Up),
QtGui.QKeySequence(QtCore.Qt.Key_PageUp)],
'shortcuts/previousItem_live': [QtGui.QKeySequence(QtCore.Qt.Key.Key_Up),
QtGui.QKeySequence(QtCore.Qt.Key.Key_PageUp)],
'shortcuts/playbackPause': [],
'shortcuts/playbackPlay': [],
'shortcuts/playbackStop': [],
'shortcuts/playSlidesLoop': [],
'shortcuts/playSlidesOnce': [],
'shortcuts/previousService': [QtGui.QKeySequence(QtCore.Qt.Key_Left)],
'shortcuts/previousItem_preview': [QtGui.QKeySequence(QtCore.Qt.Key_Up),
QtGui.QKeySequence(QtCore.Qt.Key_PageUp)],
'shortcuts/previousService': [QtGui.QKeySequence(QtCore.Qt.Key.Key_Left)],
'shortcuts/previousItem_preview': [QtGui.QKeySequence(QtCore.Qt.Key.Key_Up),
QtGui.QKeySequence(QtCore.Qt.Key.Key_PageUp)],
'shortcuts/printServiceItem': [QtGui.QKeySequence(QtGui.QKeySequence.StandardKey.Print)],
'shortcuts/songExportItem': [],
'shortcuts/songUsageStatus': [QtGui.QKeySequence(QtCore.Qt.Key_F4)],
'shortcuts/songUsageStatus': [QtGui.QKeySequence(QtCore.Qt.Key.Key_F4)],
'shortcuts/searchShortcut': [QtGui.QKeySequence(QtGui.QKeySequence.StandardKey.Find)],
'shortcuts/settingsShortcutsItem': [],
'shortcuts/settingsImportItem': [],
'shortcuts/settingsPluginListItem': [QtGui.QKeySequence(QtCore.Qt.ALT + QtCore.Qt.Key_F7)],
'shortcuts/settingsPluginListItem': [QtGui.QKeySequence(QtCore.Qt.Key.Key_Alt + QtCore.Qt.Key.Key_F7)],
'shortcuts/songUsageDelete': [],
'shortcuts/settingsConfigureItem': [QtGui.QKeySequence(QtGui.QKeySequence.StandardKey.Preferences)],
'shortcuts/shortcutAction_B': [QtGui.QKeySequence(QtCore.Qt.Key_B)],
@ -656,22 +660,22 @@ class Settings(QtCore.QSettings):
'shortcuts/settingsExportItem': [],
'shortcuts/songUsageReport': [],
'shortcuts/songImportItem': [],
'shortcuts/themeScreen': [QtGui.QKeySequence(QtCore.Qt.Key_T)],
'shortcuts/themeScreen': [QtGui.QKeySequence(QtCore.Qt.Key.Key_T)],
'shortcuts/toolsReindexItem': [],
'shortcuts/toolsFindDuplicates': [],
'shortcuts/toolsSongListReport': [],
'shortcuts/toolsAlertItem': [QtGui.QKeySequence(QtCore.Qt.Key_F7)],
'shortcuts/toolsAlertItem': [QtGui.QKeySequence(QtCore.Qt.Key.Key_F7)],
'shortcuts/toolsFirstTimeWizard': [],
'shortcuts/toolsOpenDataFolder': [],
'shortcuts/toolsAddToolItem': [],
'shortcuts/updateThemeImages': [],
'shortcuts/up': [QtGui.QKeySequence(QtCore.Qt.Key_Up)],
'shortcuts/viewProjectorManagerItem': [QtGui.QKeySequence(QtCore.Qt.Key_F6)],
'shortcuts/viewThemeManagerItem': [QtGui.QKeySequence(QtCore.Qt.Key_F10)],
'shortcuts/viewMediaManagerItem': [QtGui.QKeySequence(QtCore.Qt.Key_F8)],
'shortcuts/viewPreviewPanel': [QtGui.QKeySequence(QtCore.Qt.Key_F11)],
'shortcuts/viewLivePanel': [QtGui.QKeySequence(QtCore.Qt.Key_F12)],
'shortcuts/viewServiceManagerItem': [QtGui.QKeySequence(QtCore.Qt.Key_F9)],
'shortcuts/up': [QtGui.QKeySequence(QtCore.Qt.Key.Key_Up)],
'shortcuts/viewProjectorManagerItem': [QtGui.QKeySequence(QtCore.Qt.Key.Key_F6)],
'shortcuts/viewThemeManagerItem': [QtGui.QKeySequence(QtCore.Qt.Key.Key_F10)],
'shortcuts/viewMediaManagerItem': [QtGui.QKeySequence(QtCore.Qt.Key.Key_F8)],
'shortcuts/viewPreviewPanel': [QtGui.QKeySequence(QtCore.Qt.Key.Key_F11)],
'shortcuts/viewLivePanel': [QtGui.QKeySequence(QtCore.Qt.Key.Key_F12)],
'shortcuts/viewServiceManagerItem': [QtGui.QKeySequence(QtCore.Qt.Key.Key_F9)],
'shortcuts/webSiteItem': []
})

View File

@ -28,7 +28,7 @@ import math
import os
import re
from PyQt5 import QtWidgets, QtGui
from PySide6 import QtWidgets, QtGui
from openlp.core.common import ThemeLevel
from openlp.core.common.enum import ServiceItemType

View File

@ -26,7 +26,7 @@ import logging
import copy
from functools import cmp_to_key
from PyQt5 import QtCore, QtWidgets
from PySide6 import QtCore, QtWidgets
from openlp.core.common import Singleton
from openlp.core.common.i18n import translate
@ -299,7 +299,8 @@ class ScreenList(metaclass=Singleton):
'There is a mismatch between screens and screen settings. '
'OpenLP will try to automatically select a display screen, but '
'you should consider updating the screen settings.'),
QtWidgets.QMessageBox.StandardButtons(QtWidgets.QMessageBox.Ok))
QtWidgets.QMessageBox.StandardButton(
QtWidgets.QMessageBox.StandardButton.Ok))
self.find_new_display_screen()
else:
# if no settings we need to set a display

View File

@ -25,7 +25,7 @@ Heavily inspired by https://stackoverflow.com/questions/33467776/qt-qwebengine-r
import logging
import os.path
from PyQt5 import QtCore, QtWebEngineWidgets, QtWidgets, QtWebEngineCore
from PySide6 import QtCore, QtWebEngineCore, QtWebEngineWidgets, QtWidgets
from typing import Tuple
from openlp.core.common import Singleton
@ -35,16 +35,16 @@ from openlp.core.common.platform import is_win
LOG_LEVELS = {
QtWebEngineWidgets.QWebEnginePage.InfoMessageLevel: logging.INFO,
QtWebEngineWidgets.QWebEnginePage.WarningMessageLevel: logging.WARNING,
QtWebEngineWidgets.QWebEnginePage.ErrorMessageLevel: logging.ERROR
QtWebEngineCore.QWebEnginePage.JavaScriptConsoleMessageLevel.InfoMessageLevel: logging.INFO,
QtWebEngineCore.QWebEnginePage.JavaScriptConsoleMessageLevel.WarningMessageLevel: logging.WARNING,
QtWebEngineCore.QWebEnginePage.JavaScriptConsoleMessageLevel.ErrorMessageLevel: logging.ERROR
}
log = logging.getLogger(__name__)
class WebEnginePage(QtWebEngineWidgets.QWebEnginePage):
class WebEnginePage(QtWebEngineCore.QWebEnginePage):
"""
A custom WebEngine page to capture Javascript console logging
"""
@ -68,7 +68,7 @@ class WebEngineView(QtWebEngineWidgets.QWebEngineView):
and set some attributtes.
"""
_child = None # QtWidgets.QOpenGLWidget or QWidget?
delegatePaint = QtCore.pyqtSignal()
delegatePaint = QtCore.Signal()
def __init__(self, parent=None):
"""
@ -76,22 +76,26 @@ class WebEngineView(QtWebEngineWidgets.QWebEngineView):
"""
super(WebEngineView, self).__init__(parent)
self.setPage(WebEnginePage(self))
self.settings().setAttribute(QtWebEngineWidgets.QWebEngineSettings.LocalStorageEnabled, True)
self.settings().setAttribute(QtWebEngineWidgets.QWebEngineSettings.LocalContentCanAccessFileUrls, True)
self.settings().setAttribute(QtWebEngineWidgets.QWebEngineSettings.LocalContentCanAccessRemoteUrls, True)
self.page().settings().setAttribute(QtWebEngineWidgets.QWebEngineSettings.LocalStorageEnabled, True)
self.page().settings().setAttribute(QtWebEngineWidgets.QWebEngineSettings.LocalContentCanAccessFileUrls, True)
self.page().settings().setAttribute(QtWebEngineWidgets.QWebEngineSettings.LocalContentCanAccessRemoteUrls, True)
self.setContextMenuPolicy(QtCore.Qt.PreventContextMenu)
self.settings().setAttribute(QtWebEngineCore.QWebEngineSettings.WebAttribute.LocalStorageEnabled, True)
self.settings().setAttribute(
QtWebEngineCore.QWebEngineSettings.WebAttribute.LocalContentCanAccessFileUrls, True)
self.settings().setAttribute(
QtWebEngineCore.QWebEngineSettings.WebAttribute.LocalContentCanAccessRemoteUrls, True)
self.page().settings().setAttribute(QtWebEngineCore.QWebEngineSettings.WebAttribute.LocalStorageEnabled, True)
self.page().settings().setAttribute(
QtWebEngineCore.QWebEngineSettings.WebAttribute.LocalContentCanAccessFileUrls, True)
self.page().settings().setAttribute(
QtWebEngineCore.QWebEngineSettings.WebAttribute.LocalContentCanAccessRemoteUrls, True)
self.setContextMenuPolicy(QtCore.Qt.ContextMenuPolicy.PreventContextMenu)
def eventFilter(self, obj, ev):
"""
Emit delegatePaint on paint event of the last added QOpenGLWidget child
"""
if obj == self._child:
if ev.type() == QtCore.QEvent.MouseButtonPress or ev.type() == QtCore.QEvent.TouchBegin:
if ev.type() == QtCore.QEvent.Type.MouseButtonPress or ev.type() == QtCore.QEvent.Type.TouchBegin:
self.display_clicked()
if ev.type() == QtCore.QEvent.Paint:
if ev.type() == QtCore.QEvent.Type.Paint:
self.delegatePaint.emit()
return super(WebEngineView, self).eventFilter(obj, ev)
@ -105,7 +109,7 @@ class WebEngineView(QtWebEngineWidgets.QWebEngineView):
"""
Handle events
"""
if ev.type() == QtCore.QEvent.ChildAdded:
if ev.type() == QtCore.QEvent.Type.ChildAdded:
# Only use QWidget child (used to be QOpenGLWidget)
w = ev.child()
if w and isinstance(w, QtWidgets.QWidget):
@ -217,7 +221,7 @@ class WebViewCustomScheme(QtCore.QObject):
def init_handler(self, profile=None):
if profile is None:
profile = QtWebEngineWidgets.QWebEngineProfile.defaultProfile()
profile = QtWebEngineCore.QWebEngineProfile.defaultProfile()
handler = profile.urlSchemeHandler(self.scheme_name)
if handler is not None:
profile.removeUrlSchemeHandler(handler)

View File

@ -27,7 +27,7 @@ import os
import copy
import re
from PyQt5 import QtCore, QtWebChannel, QtWidgets
from PySide6 import QtCore, QtWebChannel, QtWidgets
from openlp.core.common.enum import ServiceItemType
from openlp.core.common.i18n import translate
@ -49,7 +49,7 @@ class DisplayWatcher(QtCore.QObject):
"""
This facilitates communication from the Display object in the browser back to the Python
"""
initialised = QtCore.pyqtSignal(bool)
initialised = QtCore.Signal(bool)
def __init__(self, parent, window_title=None):
super().__init__()