qtpy
qtpy copied to clipboard
Advice on compiling .ui files/Improve support for .ui files
Hi,
I'm the author of this project that uses PySide2.
I would like to migrate completely to qtpy
but I'm facing some issues when compiling the .ui
files.
I've noticed that If I compile the .ui
files with the commands provided by PySide2, then change the .py
includes to use qtpy
and then run the project with PySide6, some elements do not transfer well.
I think that the main issue is that I do not have a cross-qt compiler of the .ui
files to .py
that are fully compatible with qtpy
.
Is there some advise on how to handle this?
@dalthviz ?
Hi @SanPen, quite nice project! About your question, well that's kind of tricky, I haven't used .ui files to be honest and I think there is no way at the moment to parse the .ui files into a qtpy supported version, sorry :/ (Maybe @ccordoba12 knows better).
Also, are you trying to drop generating the GUI by using .ui files and trying to move the last generated files to use qtpy then? If that is the case maybe we could try to help you checking the errors that you are seeing when running with PySide6 (maybe some of them are caused due to missing things on the qtpy side (missing imports that are not being exposed here yet or namespace errors due to a name difference between qtpy and PySide6, etc).
Just in case, on qtpy.uic
we expose some methods to parse .ui files but at the end those will call either the PyQt or the PySide version methods.
Anyhow If there is something we can help or you see that we can add in qtpy fix things appearing in your migration process let us know!
Edit: Checking we have some issues regarding the uic methods like https://github.com/spyder-ide/qtpy/issues/104 putting a reference here to that just in case
Just in case, maybe this could be interesting: https://github.com/hmaarrfk/qtpy-tools/
I also use a lot of ui
files for PyQt5/6, but I always recompile them on CI without pushing the generated code to Git. So that also means that switching the underlying binding (pyqt5/6, pyside) is easy because the UI files are already binding-independent.
I've recently added a little library that compiles multiple UI files recursively and generates code compatible with pyqt5/6 or pyside2/6 - depending on what you have on the path. It's only me using it atm, so obviously it needs some work, doc, and better tests. But it's actually pretty simple: https://github.com/plotlyst/qt-uic/blob/main/qtuic/init.py The usage would be:
from qtuic import compile_dir
compile_dir('ui', 'qtuic/generated', recursive=True)
...so then it picks up every UI file from the ui
directory and compiles them under qtuic/generated
(by keeping the nested folder hierarchy). I've added a simple check too for the modification stamps, so it lazily only compiles those files that were updated. Take a look if you wish. I extended it with pyside support recently; I don't use that, but the tests seem to pass :) https://github.com/plotlyst/qt-uic/actions/runs/3203257853
(I'll also add a CLI later, as I need that too for my project)
It is partially based on qtpy
because I use compileUi
from qtpy.uic
which means that, thanks to qtpy
, it supports PyQt5 or PyQt6 out of the box. That's great. For Pyside I had to do the switch myself and run the command pyside[2,6]-uic
.
So how could qtpy
make this better? Well, now I have to check the underlying binding myself because, for example, I cannot even import compileUi
with Pyside. Could perhaps qtpy
implement that tiny interface for pyside? I don't think it has to; if something is missing from pyside then something is missing :). But of course it would be a nice addition if I could use qtpy.uic.compileUi
for any binding.
Oh, btw, this approach probably works best if you store all the UI files in one location. I do that in my GUI: https://github.com/plotlyst/plotlyst-app/tree/main/ui. Then all the compiled .py
files go under .../view/generated
which is ignored in .gitignore.
Hi @zkovari thank you for sharing the work you have been doing to manage ui files! I believe that we have some level of compileUi
support for PySide2. Checking we had an issue for that https://github.com/spyder-ide/qtpy/issues/190 but indeed seems like the current approach we have to make available compileUi
only works for PySide2/PySide2 installations that have pyside2uic
available 🤔
However, seems like the missing thing on qtpy
is the logic you have at:
https://github.com/plotlyst/qt-uic/blob/9cd6dca9dc6fc1ea32a209ffb54825626d38b593/qtuic/init.py#L52-L55
If you want, I think you can open a PR adding those lines to qtpy
at:
https://github.com/spyder-ide/qtpy/blob/936e0c9f46f803e20772e3299839019f6965dd61/qtpy/uic.py#L81-L102
What do you think? Let us know if doing the PR sounds good to you!
Hi @dalthviz, yeah, I could take a look.
Btw, I don't think this properly supports PySide2 either. It seems to me that pyside2uic.compileUi
was only available until 5.13.2. Someone mentioned in the linked issue that pytside2-uic
was brought back in 5.14.2.2, and I assume that's true (I don't know PySide that much). The latest PySide version indeed has the pytside2-uic
CLI, but it doesn't have the compileUi
API.
So I wonder if there are multiple issues, as qtpy uic.compileUi
behaves differently per each version:
- PySide2 < 5.14: works fine
- PySide2 >= 5.14: doesn't work because the module is missing (although
pytside2-uic
is available, perhaps only from 5.14.2.2 - to be checked) - PySide6: no attempt to support atm, so it doesn't work
But I could take a deeper look later.
Thanks for the new info @zkovari ! And then this could be quite more involved than I though 🤔 Just in case, I would say the final goal will be to offer qtpy.uic.compileUi
for PySide2 >= 5.12 and PySide6 >= 6.2 (the oldest PySide2/6 versions we actively support). Probably we will need to implement some logic with try-catch or validations using qtpy.PYSIDE_VERSION
to execute the different ways compileUi
could be exposed (importing a module or running the CLI for example).
Any new info or help with this is greatly appreciated and if you need any help let us know :)