# Date 1648830684 14400
# Fri Apr 01 12:31:24 2022 -0400
# Node ID bf9d055265735411ecd7de6d54da16da9e8b47e0
# Parent d34e7e5cbc3b60dd0d23902dc2b4c9c7c9bc63f5
# EXP-Topic pyqt6
qtcompat: add support for PyQt6
The changes to `setup.py` are likely incomplete. Where PyQt4 was previously
referenced, PyQt6 has been swapped in. Support for PyQt4 was dropped in
261da91d3495, and these were left as a search convenience to find the places to
update.
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -346,7 +346,8 @@
def _findrcc(self):
from tortoisehg.hgqt.qtcore import QT_API
try:
- rcc = {'PyQt4': 'pyrcc4', 'PyQt5': 'pyrcc5'}[QT_API]
+ # TODO: Figure out how to handle the removal of pyrcc
+ rcc = {'PyQt5': 'pyrcc5'}[QT_API]
except KeyError:
raise RuntimeError('unsupported Qt API: %s' % QT_API)
if
os.name != 'nt' or QT_API == 'PyQt5':
@@ -406,16 +407,10 @@
def _build_translations(self, basepath):
"""Build translations_rc.py which inclues qt_xx.qm"""
from tortoisehg.hgqt.qtcore import QT_API
- if QT_API == 'PyQt4':
- if
os.name == 'nt':
- import PyQt4
- trpath = os.path.join(
- os.path.dirname(PyQt4.__file__), 'translations')
- else:
- from PyQt4.QtCore import QLibraryInfo
- # TODO: use QLibraryInfo.LibraryPath.TranslationsPath with PyQt6
- trpath = unicode(
- QLibraryInfo.location(QLibraryInfo.TranslationsPath))
+ if QT_API == 'PyQt6':
+ from PyQt6.QtCore import QLibraryInfo
+ trpath = unicode(
+ QLibraryInfo.location(QLibraryInfo.LibraryPath.TranslationsPath))
else:
if
os.name == 'nt' and sys.version_info[0] == 2:
import PyQt5
@@ -569,12 +564,15 @@
if f.endswith('.ico') or f == 'README.txt']))
# for PyQt, see
http://www.py2exe.org/index.cgi/Py2exeAndPyQt
- includes = ['PyQt5.sip']
+ if QT_API == 'PyQt6':
+ includes = ['PyQt6.sip']
+ else:
+ includes = ['PyQt5.sip']
# Qt4 plugins, see
http://stackoverflow.com/questions/2206406/
- def qt4_plugins(subdir, *dlls):
- import PyQt4
- pluginsdir = os.path.join(os.path.dirname(PyQt4.__file__), 'plugins')
+ def qt6_plugins(subdir, *dlls):
+ from PyQt6.QtCore import QLibraryInfo
+ pluginsdir = QLibraryInfo.location(QLibraryInfo.LibraryPath.PluginsPath)
return subdir, [os.path.join(pluginsdir, subdir, e) for e in dlls]
def qt5_plugins(subdir, *dlls):
@@ -589,9 +587,12 @@
return subdir, [os.path.join(pluginsdir, subdir, e) for e in dlls]
from tortoisehg.hgqt.qtcore import QT_API
- if QT_API == 'PyQt4':
- _data_files.append(qt4_plugins('imageformats',
- 'qico4.dll', 'qsvg4.dll'))
+ if QT_API == 'PyQt6':
+ _data_files.append(qt6_plugins('platforms', 'qwindows.dll'))
+ _data_files.append(qt6_plugins('imageformats',
+ 'qico.dll', 'qsvg.dll', 'qjpeg.dll',
+ 'qgif.dll', 'qicns.dll', 'qtga.dll',
+ 'qtiff.dll', 'qwbmp.dll', 'qwebp.dll'))
else:
_data_files.append(qt5_plugins('platforms', 'qwindows.dll'))
_data_files.append(qt5_plugins('imageformats',
@@ -670,10 +671,19 @@
# PyQt 5.13.2/Qt 5.9.9
pluginsdir = QLibraryInfo.location(QLibraryInfo.PluginsPath)
return subdir, [os.path.join(pluginsdir, subdir, e) for e in dlls]
+ def qt6_plugins(subdir, *dlls):
+ from PyQt6.QtCore import QLibraryInfo
+ pluginsdir = QLibraryInfo.location(QLibraryInfo.LibraryPath.PluginsPath)
+ return subdir, [os.path.join(pluginsdir, subdir, e) for e in dlls]
+
from tortoisehg.hgqt.qtcore import QT_API
- _data_files.append(qt5_plugins('platforms', 'libqcocoa.dylib'))
- _data_files.append(qt5_plugins('imageformats', 'libqsvg.dylib'))
+ if QT_API == 'PyQt6':
+ _data_files.append(qt6_plugins('platforms', 'libqcocoa.dylib'))
+ _data_files.append(qt6_plugins('imageformats', 'libqsvg.dylib'))
+ else:
+ _data_files.append(qt5_plugins('platforms', 'libqcocoa.dylib'))
+ _data_files.append(qt5_plugins('imageformats', 'libqsvg.dylib'))
_py2app_options = {
'arch': 'x86_64',
diff --git a/tortoisehg/hgqt/qsci.py b/tortoisehg/hgqt/qsci.py
--- a/tortoisehg/hgqt/qsci.py
+++ b/tortoisehg/hgqt/qsci.py
@@ -1,4 +1,4 @@
-# qsci.py - PyQt4/5 compatibility wrapper
+# qsci.py - PyQt5/6 compatibility wrapper
#
# Copyright 2015 Yuya Nishihara <
yu...@tcha.org>
#
@@ -11,9 +11,9 @@
from .qtcore import QT_API
-if QT_API == 'PyQt4':
- from PyQt4.Qsci import * # pytype: disable=import-error
+if QT_API == 'PyQt6':
+ from PyQt6.Qsci import * # pytype: disable=import-error
elif QT_API == 'PyQt5':
- from PyQt5.Qsci import *
+ from PyQt5.Qsci import * # pytype: disable=import-error
else:
raise RuntimeError('unsupported Qt API: %s' % QT_API)
diff --git a/tortoisehg/hgqt/qtcore.py b/tortoisehg/hgqt/qtcore.py
--- a/tortoisehg/hgqt/qtcore.py
+++ b/tortoisehg/hgqt/qtcore.py
@@ -1,4 +1,4 @@
-# qtcore.py - PyQt4/5 compatibility wrapper
+# qtcore.py - PyQt5/6 compatibility wrapper
#
# Copyright 2015 Yuya Nishihara <
yu...@tcha.org>
#
@@ -13,7 +13,7 @@
import sys
def _detectapi():
- candidates = ['PyQt5']
+ candidates = ['PyQt5', 'PyQt6']
if not getattr(sys, 'frozen', False):
api = os.environ.get('THG_QT_API')
if api:
@@ -32,7 +32,9 @@
except (AttributeError, ImportError):
QT_API = _detectapi()
-if QT_API == 'PyQt5':
- from PyQt5.QtCore import *
+if QT_API == 'PyQt6':
+ from PyQt6.QtCore import * # pytype: disable=import-error
+elif QT_API == 'PyQt5':
+ from PyQt5.QtCore import * # pytype: disable=import-error
else:
raise RuntimeError('unsupported Qt API: %s' % QT_API)
diff --git a/tortoisehg/hgqt/qtgui.py b/tortoisehg/hgqt/qtgui.py
--- a/tortoisehg/hgqt/qtgui.py
+++ b/tortoisehg/hgqt/qtgui.py
@@ -1,18 +1,21 @@
-# qtgui.py - PyQt4/5 compatibility wrapper
+# qtgui.py - PyQt5/6 compatibility wrapper
#
# Copyright 2015 Yuya Nishihara <
yu...@tcha.org>
#
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-"""Thin compatibility wrapper for QtGui and QtWidgets of Qt5"""
+"""Thin compatibility wrapper for QtGui and QtWidgets of Qt5/6"""
from __future__ import absolute_import
from .qtcore import QT_API
-if QT_API == 'PyQt5':
- from PyQt5.QtGui import *
- from PyQt5.QtWidgets import *
+if QT_API == 'PyQt6':
+ from PyQt6.QtGui import * # pytype: disable=import-error
+ from PyQt6.QtWidgets import * # pytype: disable=import-error
+elif QT_API == 'PyQt5':
+ from PyQt5.QtGui import * # pytype: disable=import-error
+ from PyQt5.QtWidgets import * # pytype: disable=import-error
else:
raise RuntimeError('unsupported Qt API: %s' % QT_API)
diff --git a/tortoisehg/hgqt/qtlib.py b/tortoisehg/hgqt/qtlib.py
--- a/tortoisehg/hgqt/qtlib.py
+++ b/tortoisehg/hgqt/qtlib.py
@@ -12,7 +12,6 @@
import posixpath
import re
import shutil
-import sip
import stat
import subprocess
import sys
@@ -30,6 +29,7 @@
QSize,
QUrl,
QT_VERSION,
+ QT_API,
Qt,
pyqtSignal,
pyqtSlot,
@@ -63,6 +63,11 @@
QWidget,
)
+if QT_API == "PyQt6":
+ import PyQt6.sip as sip # pytype: disable=import-error
+else:
+ import sip # pytype: disable=import-error
+
from mercurial import (
color,
encoding,
diff --git a/tortoisehg/hgqt/qtnetwork.py b/tortoisehg/hgqt/qtnetwork.py
--- a/tortoisehg/hgqt/qtnetwork.py
+++ b/tortoisehg/hgqt/qtnetwork.py
@@ -1,4 +1,4 @@
-# qtnetwork.py - PyQt4/5 compatibility wrapper
+# qtnetwork.py - PyQt5/6 compatibility wrapper
#
# Copyright 2015 Yuya Nishihara <
yu...@tcha.org>
#
@@ -11,9 +11,9 @@
from .qtcore import QT_API
-if QT_API == 'PyQt4':
- from PyQt4.QtNetwork import * # pytype: disable=import-error
+if QT_API == 'PyQt6':
+ from PyQt6.QtNetwork import * # pytype: disable=import-error
elif QT_API == 'PyQt5':
- from PyQt5.QtNetwork import *
+ from PyQt5.QtNetwork import * # pytype: disable=import-error