Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Advice on compiling .ui files/Improve support for .ui files #339

Open
SanPen opened this issue Apr 23, 2022 · 7 comments
Open

Advice on compiling .ui files/Improve support for .ui files #339

SanPen opened this issue Apr 23, 2022 · 7 comments

Comments

@SanPen
Copy link

SanPen commented Apr 23, 2022

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 .uifiles with the commands provided by PySide2, then change the .pyincludes 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 .uifiles to .py that are fully compatible with qtpy.

Is there some advise on how to handle this?

@CAM-Gerlach
Copy link
Member

@dalthviz ?

@dalthviz
Copy link
Member

dalthviz commented Apr 25, 2022

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 #104 putting a reference here to that just in case

@dalthviz
Copy link
Member

Just in case, maybe this could be interesting: https://github.com/hmaarrfk/qtpy-tools/

@CAM-Gerlach CAM-Gerlach changed the title Advise on compiling .ui files Advice on compiling .ui files Jun 24, 2022
@zkovari
Copy link

zkovari commented Oct 10, 2022

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.

@dalthviz
Copy link
Member

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 #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:

qtpy/qtpy/uic.py

Lines 81 to 102 in 936e0c9

if PYSIDE6:
from PySide6.QtCore import QMetaObject
from PySide6.QtUiTools import QUiLoader
elif PYSIDE2:
from PySide2.QtCore import QMetaObject
from PySide2.QtUiTools import QUiLoader
try:
from pyside2uic import compileUi
# Patch UIParser as xml.etree.Elementree.Element.getiterator
# was deprecated since Python 3.2 and removed in Python 3.9
# https://docs.python.org/3.9/whatsnew/3.9.html#removed
from pyside2uic.uiparser import UIParser
from xml.etree.ElementTree import Element
class ElemPatched(Element):
def getiterator(self, *args, **kwargs):
return self.iter(*args, **kwargs)
def readResources(self, elem):
return self._readResources(ElemPatched(elem))
UIParser._readResources = UIParser.readResources
UIParser.readResources = readResources
except ImportError:
pass

What do you think? Let us know if doing the PR sounds good to you!

@dalthviz dalthviz changed the title Advice on compiling .ui files Advice on compiling .ui files - improve support for .ui files Oct 10, 2022
@dalthviz dalthviz changed the title Advice on compiling .ui files - improve support for .ui files Advice on compiling .ui files/Improve support for .ui files Oct 10, 2022
@dalthviz dalthviz added this to the v2.3.0 milestone Oct 10, 2022
@zkovari
Copy link

zkovari commented Oct 11, 2022

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.

@dalthviz
Copy link
Member

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 :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants