简体   繁体   中英

PyQt5 to PySide2, loading UI-Files in different classes

I have a python application which runs under python3.6 and is using PyQt5 for loading Ui windows. These windows were created with Qt Designer 5.9.4. The Code below shows a working example with PyQt5.

Now i want to have exactly the same functionality but with PySide2. For now, I couldn't work out how to load an Ui File and use its objects (buttons, tables etc.) in a separate class. For example: by clicking a button in the first window/class, a second window apears which functions are defined in a separate class, see example. All examples that I found, just load an Ui-Window but don't show how to work with it. Can anyone help?

#!/usr/bin/env python
# -*- coding:utf-8 -*-

from PyQt5.uic import loadUiType  
from PyQt5 import QtGui, QtCore

Ui_FirstWindow, QFirstWindow = loadUiType('first_window.ui')
Ui_SecondWindow, QSecondWindow = loadUiType('second_window.ui')


class First(Ui_FirstWindow, QFirstWindow):

    def __init__(self):  
        super(First, self).__init__()
        self.setupUi(self)

        self.button.clicked.connect(self.show_second_window)

    def show_second_window(self):

        self.Second = Second()
        self.Second.show()


class Second(Ui_SecondWindow, QSecondWindow):

    def __init__(self):  
        super(Second, self).__init__()
        self.setupUi(self)


if __name__ == '__main__':

    app = QtWidgets.QApplication(sys.argv)

    main = First()
    main.show()

    sys.exit(app.exec_())

PySide does not offer these methods, but one solution is to modify the source code of the PyQt uic module by changing the imports from PyQt5 to PySide2, for legal terms do not modify the license, in addition to the code that will keep the PyQt licenses.

To do this, download the source code from the following link and unzip it.

And execute the following script:

convert_pyqt5_to_pyside2.py

import os
import fileinput
import argparse
import shutil

def modify_source_code(directory, text_to_search, replacement_text):
    for path, subdirs, files in os.walk(directory):
        for name in files:
            filename = os.path.join(path, name)
            with fileinput.FileInput(filename, inplace=True) as file:
                for line in file:
                    if line.startswith('#'):
                        # not change on comments
                        print(line, end='')
                    else:
                        print(line.replace(text_to_search, replacement_text), end='')

def main():
    parser = argparse.ArgumentParser()
    parser.add_argument("-i", "--input", help="Input directory")
    parser.add_argument("-o", "--output", help="Output directory")
    args = parser.parse_args()
    if args.input and args.output:
        input_dir = os.path.join(os.path.abspath(args.input), "pyuic", "uic")
        output_dir = os.path.abspath(args.output)
        shutil.copytree(input_dir, output_dir)
        modify_source_code(output_dir, 'PyQt5', 'PySide2')

if __name__ == '__main__':
    main()

Using the following command:

python convert_pyqt5_to_pyside2.py -i /path/of/PyQt5-folder -o fakeuic

Then you can use the loadUiType method from fakeuic:

from fakeuic import loadUiType  
from PySide2 import QtCore, QtGui, QtWidgets

Ui_FirstWindow, QFirstWindow = loadUiType('first_window.ui')
Ui_SecondWindow, QSecondWindow = loadUiType('second_window.ui')

class First(QFirstWindow, Ui_FirstWindow):
    def __init__(self):  
        super(First, self).__init__()
        self.setupUi(self)
        self.button.clicked.connect(self.show_second_window)

    def show_second_window(self):
        self.Second = Second()
        self.Second.show()

class Second(QSecondWindow, Ui_SecondWindow):
    def __init__(self):  
        super(Second, self).__init__()
        self.setupUi(self)

if __name__ == '__main__':
    import sys
    app = QtWidgets.QApplication(sys.argv)
    main = First()
    main.show()
    sys.exit(app.exec_())

You can find the complete example here

Follow these simple steps:

  1. Assuming the ui file from qt designer is mycode.ui, convert this to the py file using the pyside2 ui converter by typing "pyside2-uic mycode.ui -o mycode.py" without the quotes. (Note use the pyside2 converter of pyside2-uic and not pyqt5 converter of pyuic5)

  2. With mycode.py generated by pyside2 format, just replace all the headers for the PyQt5 code to "import sys" and "from mycode import *"

  3. You are done...Hope this helps

PySide2 brought back loadUiType in May 2020 . So if you updgrade, you can get a drop-in replacement. The only difference is the import:

from PySide2.QtUiTools import loadUiType

Syntax is the same (you will use loadUiType(<file>)[0] )

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM