Page MenuHomePhabricator

[electrum] Qt6 transition, step 2: minimal changes to make the app start with PyQt6
ClosedPublic

Authored by PiRK on Jul 2 2025, 11:47.

Details

Summary

This diff is the minimum required to make Electrum ABC successfully start and stop without raising any errors. There are likely more runtime errors that we will discover with more testing.

To the best of my effort I picked solutions that work with both Qt5 and Qt6. In the case of the QtMultimedia related code, it would have been too messy to do so, so I duplicated some code and made it specific to Qt5 or Qt6.

Summary of changes:

  • the QtMultimedia API is very different between Qt5 and Qt6 and it seems qtpy makes no effort at trying to offer any compatibility layer
  • in camera_dialog.py we remove a method that is only used to provide a custor error message for old versions of PyQt5 that we haven't used for releases in a long while. This removes a PYQT_VERSION usages that would not work with PySide
  • the QtWidgets.qApp does not exist in Qt6. The QApplication.instance().quit()method, available both in Qt5 and Qt6, is calling the static method QApplication.quit(), so use this directly
  • QRegExp is deprecated in Qt5 and not available by default in Qt6, we can use the newer and better QRegularExpression instead (see D18178)
  • QWidget.setFocus(bool) is undocumented even in Qt5, probably a leftover from Qt4. Remove the unneeded arg.
  • The QMenu.addAction(...) call that takes a keyboard shortcut has changed in Qt6. Let's use a signature that works in both Qt5 and Qt6, and set the shortcut on the returned QAction (which is already done in main_window.py for other actions, so this makes the code more consistent)
  • QCompleter.setCaseSensitivity(...) takes an enum. In Qt5 it seems like it was possible to pass the 0 value as a bool or int, but this errors now in Qt6. Use the explicit enum instead.
  • the QSvgWidget class is now part of a new QtSvgWidgets library (a sub-part of QtSvg)
  • qtpy tries to offer a compat layer for most of the enum/flags changes in Qt6, but is is not perfect, so QPalette.Background does not work in Qt6

The new QtMultimedia related code is backported from:
https://github.com/spesmilo/electrum/pull/9189/commits/cfe8502f9677266cb50d9b2e450ced4611f37e25

Test Plan

Install PyQt6 and all necessary subpackages (ubuntu: sudo apt install python3-pyqt6 python3-pyqt6.qtmultimedia python3-pyqt6.qtsvg)
Try the features related to the touched code: keyboard shortcuts, webcam scanning features...

./electrum-abc
QT_API=pyqt6 ./electrum-abc

Diff Detail

Repository
rABC Bitcoin ABC
Lint
Lint Not Applicable
Unit
Tests Not Applicable

Event Timeline

PiRK requested review of this revision.Jul 2 2025, 11:47

I didn't properly test the scanning of QR codes via the webcam with Qt6, there is still some work left on that front

PiRK planned changes to this revision.Jul 2 2025, 11:52
PiRK edited the test plan for this revision. (Show Details)

fix camera (tested by succesfully scanning a CashTab QRCode via a webcam)

electrum/electrumabc_gui/qt/util.py
878–883 ↗(On Diff #54650)

There is a change in behavior here: this dark theme detector is not properly working on Ubuntu with PyQt5 but it is now working with PyQt6 (Electrum ABC now follows the OS settings when ColorTheme = Default) .

Fabien requested changes to this revision.Jul 2 2025, 13:49
Fabien added a subscriber: Fabien.

I have to trust the camera change is ok here

electrum/electrumabc_gui/qt/main_window.py
802 ↗(On Diff #54650)

Can't you just chain the calls like below ?

863 ↗(On Diff #54650)

Ultimately you might want to make it easier to read/maintain and have a wrapper function that takes a list of menu items

886 ↗(On Diff #54650)

ditto

electrum/electrumabc_gui/qt/qrreader/camera_dialog.py
81–83 ↗(On Diff #54650)
This revision now requires changes to proceed.Jul 2 2025, 13:49
electrum/electrumabc_gui/qt/main_window.py
802 ↗(On Diff #54650)

Yes. This is a leftover from a previous iteration .

863 ↗(On Diff #54650)

There are a few rare special cases that would need special care, but yes for most actions we could just use:

def add_actions_to_menu(menu: QMenu, actions: tuple[str, Callable, Optional[QKeySequence):
    for name, functor, shortcut in actions:
        a = menu.addAction(name, functor)
        if shortcut is not None:
            a.setShortcut(shortcut)

Probably best to keep this separate from this diff, though

886 ↗(On Diff #54650)

For this one we need the ref to the action for the code below (setSortcut does not return a qaction)

Fabien added inline comments.
electrum/electrumabc_gui/qt/main_window.py
863 ↗(On Diff #54650)

Yes this should be another diff

This revision is now accepted and ready to land.Jul 2 2025, 22:01