Supporting Qt 6 - What's needed?

For a bit of fun, and figuring that if I am going to learn stuff it might as well be good future stuff …

I am attempting build with Qt6.31, Pyside6, Shiboken6, Python3.10, C++20.

Seems like a reasonable goal!!

Of course I’m hitting bumps all over the place. Anyone wanna talk about it? (very quiet here lately)

VTK is not python3.10, but close.

Bunch of deprecations in Qt6 which are used quite a bit in FC

Are you using the Clazy-Qt6 checks? That would be an easy place to start – I mean, it’s going to mean a lot of code, but conceptually anyway it’s not difficult, we just have to make sure to continue to support Qt 5.9, so lots of preprocessor directives in C++, and probably hasattr in Python (at least, that’s how I’ve handled the QRegExp/QRegularExpression stuff).

We can start committing this stuff anytime, since we aren’t removing support for older Qt versions, just adding support for the new one, and it doesn’t have to happen all at once. Once we have enough we’ll turn on the Clazy-Qt6 stuff in our own CI.

make sure to continue to support Qt 5.9

For how long?

Is this the accepted plan, or your thoughts?

so lots of preprocessor directives in C++

That would be horrible!

how I’ve handled the QRegExp/QRegularExpression stuff

Twice, and duplicated the code.

Have you looked at Qt6 Core5Compat?

Until Ubuntu 18.04 LTS end of life (so something like six months from now) as I recall. We discussed this when we were releasing 0.20, but maybe wmayer would care to weigh in. It would make life a lot easier if we could advance that (since I think it’s unlikely that 1.0 will be ready before 18.04 is EOL).

so lots of preprocessor directives in C++

That would be horrible!

Yes, having to support two versions of Qt is ugly, but there isn’t a way around it. Even if we were to advance all the way to 5.15 as the minimum (and I think 5.12 is more likely) I believe there are still some things that will have to be conditionally compiled in C++. As far as I’m concerned the situation in Python is even worse, because it’s not as well documented, and PySide6 does things like drop support for the Qt resource system entirely.

how I’ve handled the QRegExp/QRegularExpression stuff

Twice, and duplicated the code.

Right – if I have to do it a third time I guess I’ll get around to refactoring :slight_smile:.

Have you looked at Qt6 Core5Compat?

I knew it existed, but I haven’t used it for anything.

I see no point in supporting 18.04 in git master, it’s not going to be released before it reaches EOL and the daily ppa is broken anyways. Plus nowadays the rare users of it can resort to appimage/snap/flatpak/conda

PySide6 does things like drop support for the Qt resource system entirely.

Apparently that is no longer the problem it was:

https://stackoverflow.com/questions/66099225/how-can-resources-be-provided-in-pyqt6-which-has-no-pyrcc

I don’t know if this was an issue for pyside too but note that the stackoverflow question and answer are about pyqt, FreeCAD uses pyside, not pyqt

Oops. Thanks for pointing that out! Back to Mr Google ..

PySide6 does things like drop support for the Qt resource system entirely

In my searching I’m not seeing an issue. Could someone expand on this a bit?

Until Ubuntu 18.04 LTS end of life (so something like six months from now) as I recall. We discussed this when we were releasing 0.20, but maybe @wmayer would care to weigh in. It would make life a lot easier if we could advance that (since I think it’s unlikely that 1.0 will be ready before 18.04 is EOL).

Sure, I can upgrade to Ubuntu 20.04 but this will take me some time to do that.

Yes, having to support two versions of Qt is ugly, but there isn’t a way around it.

That is a fact we always have to deal with independent if the lowest Qt version is 5.9 or 5.12 because between two Qt versions there is always an API change. And if we support Qt5 and Qt6 then there will be even more #ifdef’s. To reduce them in our code base we can implement some convenience functions. AFAIK in Qt 5.15 all classes or functions are marked deprecated that will be removed in Qt6 and therefore a couple of convenience functions have been implemented e.g. Base/Mutex.h, Base/QtTools, Gui/Tools.h, …

and PySide6 does things like drop support for the Qt resource system entirely.

Is there a reason for it? And what about Qt itself? Or is it rather that the Qt tools can be directly used for Python code?

Have you looked at Qt6 Core5Compat?

The question is how useful it is. I remember that for the move from Qt3 to Qt4 there also was a support library but its main purpose was that you didn’t get compile errors but functionality-wise pretty much everything was broken. So, there was no alternative than fully porting to Qt4 as soon as possible.

Allow me for a moment to focus on the "if " in that comment.

Remember we are making decisions on what will be in the future, not as things are right now.

Especially given that all the stuff being talked about here won’t go truly live for quite a while, I suspect min six months is not unreasonable, what is it that demands continuing support for qt5? Sorry, I just don’t know the answer. If it is truly necessary I understand (there is much I don’t know), but …

From what I’m seeing, therre is a LOT of specific (literal) shiboken2, pyside2, qt5 stuff in the codebase. I’m still finding them. There is even a bunch of pre qt5 stuff (even though 4 was killed off) through conditionals. Perhaps a lot of that is due to poor implementation (specificity). The effort to support 5 AND 6 simultaneously will, I suspect be huge and complicated, and take a long time to implement.

If 5 support is a 1, and 6 support is a 1, what is the cost of supporting both? I suspect more like 5. But this is just a suspicion.

What is the cost/benefit tradeoff of keeping Qt5 while supporting Qt6?

Remember we are making decisions on what will be in the future, not as things are right now.

Then define future. In a few years we of course will only support Qt6 but in the meantime there are a lot of releases of various distributions that only provide Qt5.

When I look at the Ubuntu repository then 22.04 is the very first release that provides Qt6 packages and choosing this as the minimum supported release (and all other distributions accordingly) is simply not feasible.

The effort to support 5 AND 6 simultaneously will, I suspect be huge and complicated, and take a long time to implement.

No, I don’t think so. I guess it’s around the same amount of work we had to support Qt4 and Qt5. It was << 5% of Qt-related code that needed an #ifdef.

When I think back the move from Qt3 and Qt4 was huge and effectively it was not possible to support both versions at the same time. Due to the massive changes almost all Qt-related code had to be re-written.

No, I think I’m wrong about this – I thought I was looking at the page about PySide6, but can now only find reference to the issue in the PyQt6 documentation, so I probably made the mistake that adrianinsaval pointed out above.

I’m stumbling along into the great unknown which is cmake.

Qt suggest that to get Core5Compat you:

    find_package(Qt6 REQUIRED COMPONENTS Core5Compat)
    target_link_libraries(==tba== PRIVATE Qt6::Core5Compat) # Qt suggested

The first line I get, and it works, but how does one get the second line to work? It’s not one I see much in FC.

Help?!

I would not even try to use the Core5Compat module. Have a look at the classes that it provides: https://doc.qt.io/qt-6/qtcore5compat-module.html

From this list we only use the two classes QTextCodec and QRegExp. It’s better to directly port the corresponding code to Qt6. A replacement for QRegExp is the class QRegularExpression and already exists since Qt 5.0. According to some forums the equivalent class for QTextCodec in Qt6 is the class QStringConverter or its sub-classes.

Then there is this guide to replace deprecated classes and functions in Qt 5.15: https://doc.qt.io/qt-6/portingguide.html

f9f201373f

QRegExp is actually a little harder because even though QRegularExpression existed, they hadn’t updated all the class that use it. Maybe that wasn’t true in C++, but it has bitten me in Python a couple of times.

Could you expand (for the dummies like me) what this means and how it affects FC?

It means we can’t just change every use of QRegExp to QRegularExpression (even though that class itself exists). In cases where we are using another Qt class that uses QRegularExpression (e.g. QRegularExpressionValidator) we first have to double-check to make sure PySide2 actually implemented that class in our oldest supported version.

Gee, on that basis the Compat thing (if, and only if, it works as advertised here) is starting to like attractive as it would allow Qt6 build and sort out those fine details later.