Mw.reset() throwing "wrapped C/C++ object of type QPushButton has been deleted"

I’m working on updating my add-ons to work with PyQt6 and 2.0.50. It appears that in 2.0.50, when I open a dialog box provided by my add-on that contains an instance of the deck chooser, then do something that calls mw.reset(), I get the following exception:

Caught exception:
Traceback (most recent call last):
  File "/home/soren/.local/share/Anki2/addons21/tiddlyremember/importer.py", line 218, in join_thread
    return self.sync()
  File "/home/soren/.local/share/Anki2/addons21/tiddlyremember/importer.py", line 235, in sync
    self.mw.reset()
  File "aqt.main", line 768, in reset
  File "aqt.main", line 720, in _synthesize_op_did_execute_from_reset
  File "aqt.hooks_gen", line 2951, in __call__
  File "aqt.deckchooser", line 115, in on_operation_did_execute
  File "aqt.deckchooser", line 82, in _update_button_label
RuntimeError: wrapped C/C++ object of type QPushButton has been deleted

(In this case, the exception occurred during a sync operation performed by my add-on, but if I simply open my settings dialog, close it, and then pop open the debug console and run mw.reset(), the same exception is raised.)

I include the deck chooser in my dialog by putting a blank QWidget called deckWidget in the Qt Designer form for the dialog, then constructing a chooser pointing to it during the dialog’s __init__:

self.deckChooser = aqt.deckchooser.DeckChooser(self.mw, self.form.deckWidget, label=False)

I’m aware that mw.reset() is a legacy operation nowadays, but in this case I have a working class-based multithreaded implementation that’s never caused any problems embedded in some fairly complex logic, so I’m not super keen on rewriting it to use QueryOp / CollectionOp during a minor update.

Is this a bug in the beta, or has support been dropped for something I’m doing?


One other question if you have a sec: it says in the notes for 2.0.50 that “If you’re using Qt Designer to generate UI files, the Qt5 and Qt6 versions need to be generated and bundled separately if you want to support both at once.” What’s the proper way to find out what version of Qt is presently in use in aqt.qt so I can import the appropriate form in this case? Do I just directly check aqt.qt.qtmajor?

DeckChooser has a cleanup() method that should be called before you close the window containing it, or it will keep receiving messages even after it has been partially destroyed.

This is how Anki does the version check:

qt/aqt/forms/customstudy.py:

from aqt.qt import qtmajor
if qtmajor > 5:
  from .customstudy_qt6 import *
else:
  from .customstudy_qt5 import *  # type: ignore
1 Like

cleanup() did the trick, thanks!