Skip to content

Commit

Permalink
PR: Replace custom implementation with loadUiType from PySide6 (#440)
Browse files Browse the repository at this point in the history
  • Loading branch information
dalthviz authored Jul 12, 2023
2 parents b303b62 + 278d064 commit 9d1f3ed
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 32 deletions.
9 changes: 6 additions & 3 deletions qtpy/tests/test_uic.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@
import warnings

import pytest
from packaging.version import parse

from qtpy import PYSIDE6, PYSIDE2, QtWidgets
from qtpy import PYSIDE6, PYSIDE2, QtWidgets, PYSIDE_VERSION
from qtpy.QtWidgets import QComboBox
from qtpy.tests.utils import using_conda

if PYSIDE2:
pytest.importorskip("pyside2uic", reason="pyside2uic not installed")
Expand Down Expand Up @@ -56,8 +58,9 @@ def test_load_ui(qtbot):


@pytest.mark.skipif(
PYSIDE2 or PYSIDE6,
reason="PySide2uic not consistently installed across platforms/versions")
PYSIDE6 and using_conda() and parse(PYSIDE_VERSION) < parse("6.5")
and (sys.platform in ("darwin", "linux")),
reason="pyside6-uic command not contained in all conda-forge packages.")
def test_load_ui_type(qtbot):
"""
Make sure that the patched loadUiType function behaves as expected with a
Expand Down
60 changes: 31 additions & 29 deletions qtpy/uic.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@
if PYSIDE6:
from PySide6.QtCore import QMetaObject
from PySide6.QtUiTools import QUiLoader
from PySide6.QtUiTools import loadUiType
elif PYSIDE2:
from PySide2.QtCore import QMetaObject
from PySide2.QtUiTools import QUiLoader
Expand Down Expand Up @@ -245,41 +246,42 @@ def loadUi(uifile, baseinstance=None, workingDirectory=None):
QMetaObject.connectSlotsByName(widget)
return widget

def loadUiType(uifile, from_imports=False):
"""Load a .ui file and return the generated form class and
the Qt base class.
if PYSIDE2:
def loadUiType(uifile, from_imports=False):
"""Load a .ui file and return the generated form class and
the Qt base class.
The "loadUiType" command convert the ui file to py code
in-memory first and then execute it in a special frame to
retrieve the form_class.
The "loadUiType" command convert the ui file to py code
in-memory first and then execute it in a special frame to
retrieve the form_class.
Credit: https://stackoverflow.com/a/14195313/15954282
"""
Credit: https://stackoverflow.com/a/14195313/15954282
"""

import sys
from io import StringIO
from xml.etree.ElementTree import ElementTree

from . import QtWidgets
import sys
from io import StringIO
from xml.etree.ElementTree import ElementTree

# Parse the UI file
etree = ElementTree()
ui = etree.parse(uifile)
from . import QtWidgets

# Parse the UI file
etree = ElementTree()
ui = etree.parse(uifile)

widget_class = ui.find('widget').get('class')
form_class = ui.find('class').text
widget_class = ui.find('widget').get('class')
form_class = ui.find('class').text

with open(uifile, encoding="utf-8") as fd:
code_stream = StringIO()
frame = {}
with open(uifile, encoding="utf-8") as fd:
code_stream = StringIO()
frame = {}

compileUi(fd, code_stream, indent=0, from_imports=from_imports)
pyc = compile(code_stream.getvalue(), '<string>', 'exec')
exec(pyc, frame)
compileUi(fd, code_stream, indent=0, from_imports=from_imports)
pyc = compile(code_stream.getvalue(), '<string>', 'exec')
exec(pyc, frame)

# Fetch the base_class and form class based on their type in the
# xml from designer
form_class = frame['Ui_%s' % form_class]
base_class = getattr(QtWidgets, widget_class)
# Fetch the base_class and form class based on their type in the
# xml from designer
form_class = frame['Ui_%s' % form_class]
base_class = getattr(QtWidgets, widget_class)

return form_class, base_class
return form_class, base_class

0 comments on commit 9d1f3ed

Please sign in to comment.