Qt5 to Qt6 Qml/Pyside 2 to 6 Porting Adventures

Here are a few things noticed during a port of a Pyside2 project and associated Qml to Pyside6 (6.2.1).

Injection of parameters into signal handlers is deprecated.

If you hit the following warning, it is formatting quirk now being enforced by Qt 6.

Injection of parameters into signal handlers is deprecated. Use JavaScript functions with form al parameters instead.

In our case it came about in this snippet of Qt5/Qml code on the Main Window’s onClosing handling to avoid closing on a certain condition. As the documentations quotes, you are allowed to set closing.accepted to true or false: Window QML Type | Qt Quick 6.2.1

ApplicationWindow {
    id: application
    onClosing: {
        ...
        if (condition) {
            close.accepted = false
            userDialog.open()
        } else {
            close.accepted = true
        }
    }

The fix is fortunately simple through the addition of the function(close). Refer for more details: Signal and Handler Event System | Qt QML 6.3.0

ApplicationWindow {
    id: application
    onClosing: function(close) {
        ...
        if (condition) {
            close.accepted = false
            userDialog.open()
        } else {
            close.accepted = true
        }
    }

Qml ComboBox indicator is null

Leaving the indicator element as the “default” one by not providing it in Qml in Qt5 (5.12 at least) “worked” in that a sub component could reference its with indicator.width. However porting the Qml to PySide6 resulted in a null dereference.

The contentItem’s rightPadding below references control.indicator.width, which threw the null dereference in PySide6 but not PySide2.

import QtQuick.Controls 2.12
ComboBox {
    id: control
    ...
    contentItem: Text {
        leftPadding: 0
        rightPadding: control.indicator.width + control.spacing
        ...
    }
    delegate: ItemDelegate {
        width: control.width
        ...
    }
    background: Rectangle {
        border.width: 1
        ...
    }
}

Simply adding a dummy Canvas worked around this problem, but naturally that is a bad work around.

import QtQuick.Controls 2.12
ComboBox {
    id: control
    ...
    all the above content
    ...
    indicator: Canvas {
    }
}

It seems that this issue was specific to the 2.12 import, changing the import to leave out the version selection or using 2.5, which was the installed version for PySide6, resolved the null de-refence.

import QtQuick.Controls 2.5

QtQuick.Dialogs 1.2 not installed

The modal dialog import in the main window resulted in an error

module “QtQuick.Dialogs” version 1.2 is not installed

Removing the 1.2 version removes the error, but introduces a new Dialog which results in the next error with the dialog being opened in the Top Left of the parent.

import QtQuick.Dialogs

Qml Dialog is centered Top Left of window

QtQuick.Dialogs 1.2 seemed to center the Modal Dialog to your window. In moving to 2.x version, it inherits from Popup which has x,y coordinates, which default to top left. Alternatively you can use anchors to center the dialog.

anchors.centerIn: Overlay.overlay

Refer popup documentation for use of anchoring or x,y positioning: Popup QML Type | Qt Quick Controls 6.3.0

Qt 6 Qml seems not to have a TreeView

A small set back for our project was what seems to be a lack of the TreeView from QtQuick.Controls 1.4, which was dropped at least initially in version 6. It seems it can be obtained from the Qt Marketplace, but the license is GPLv3 or proprietary, which makes one concerned to use it, if your own project is one of the permissive free software licenses, which many QML projects seem to be.

In our particular case an alternate implementation using ListView was adopted to avoid licensing complications.


Qt ® is a registered trademark of The Qt Company Ltd. and its subsidiaries.

Python ® is a registered trademark of the Python Software Foundation.