PyQt Custom Widget

pyuic/pyside6-uic

pip install PyQt6 pyqt6-tools

或者

pip install PySide6

假设你的自定义控件时from vtk.test2.testhead import testfaQ

首先拉一个QWidget
右键Promote to…

PyQt Custom Widget_第1张图片
在header file里写上 vtk.test2.testhead(写vtk/test2/testhead.h或者vtk/test2/testhead或者vtk.test2.testhead.h都是可以的)

在promoted class name里写testfaQ

然后点Add,最后Promote
PyQt Custom Widget_第2张图片
最后pyuic/pyside6-uic
可以看到最后那一句就是from vtk.test2.testhead import testfaQ
就实现了自定义控件了
PyQt Custom Widget_第3张图片

原理

miniconda3/envs/qt_test/lib/python3.8/site-packages/PyQt6/uic/uiparser.py
其中header指promoted widgets里的Headfile,
classname指的是promoted widgets里的promoted class name

可以看出来
foo/bar/baz.h->foo.bar.baz
foo.bar.baz.h->foo.bar.baz
foo.bar.baz->foo.bar.baz

class UIParser(object):
    def _handle_custom_widgets(self, el):
        """ Handle the  element. """

        def header2module(header):
            """header2module(header) -> string

            Convert paths to C++ header files to according Python modules
            >>> header2module("foo/bar/baz.h")
            'foo.bar.baz'
            """
            if header.endswith(".h"):
                header = header[:-2]

            mpath = []
            for part in header.split('/'):
                # Ignore any empty parts or those that refer to the current
                # directory.
                if part not in ('', '.'):
                    if part == '..':
                        # We should allow this for Python3.
                        raise SyntaxError("custom widget header file name may not contain '..'.")

                    mpath.append(part)

            return '.'.join(mpath)
    
        for custom_widget in el:
            classname = custom_widget.findtext("class")
            self.factory.addCustomWidget(classname,
                    custom_widget.findtext("extends") or "QWidget",
                    header2module(custom_widget.findtext("header")))

miniconda3/envs/qt_test/lib/python3.8/site-packages/PyQt6/uic/Compiler/qobjectcreator.py

addCustomWidget对应着上面的addCustomWidget

widgetClass指的是promoted widgets里的promoted class name
module指promoted widgets里的Headfile

最后会调用_writeImportCode,
得到from module import widgetClass

class _CustomWidgetLoader(object):
    def __init__(self):
        self._widgets = {}
        self._usedWidgets = set()
        
    def addCustomWidget(self, widgetClass, baseClass, module):
        assert widgetClass not in self._widgets 
        self._widgets[widgetClass] = (baseClass, module)

    def _writeImportCode(self):
        imports = {}
        for widget in self._usedWidgets:
            _, module = self._widgets[widget]
            imports.setdefault(module, []).append(widget)

        for module, classes in sorted(imports.items()):
            write_code("from %s import %s" % (module, ", ".join(sorted(classes))))

QUiLoader()

ui的写法与uic里一样

然后用QUiLoader()的load加载ui
如果你是pyside,一定要写registerCustomWidget将对应的类加载进来

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

from PySide6 import QtCore
from PySide6.QtUiTools import QUiLoader
from PySide6.QtWidgets import QApplication
from pyqtgraph import PlotWidget

os.environ["PYSIDE_DESIGNER_PLUGINS"] = "."


class Stock:
    def __init__(self):
        loader = QUiLoader()
        loader.registerCustomWidget(PlotWidget)
        self.ui = loader.load('my_mainwindow.ui')
        hour = list(range(1, 11))
        temperature = [30, 32, 34, 32, 33, 31, 29, 32, 35, 45]
        self.ui.graphWidget.plot(hour, temperature)


if __name__ == '__main__':
    QtCore.QCoreApplication.setAttribute(QtCore.Qt.AA_ShareOpenGLContexts)
    app = QApplication([])
    stock = Stock()
    stock.ui.show()
    # window = MainWindow()
    # window.show()
    app.exec()

参考:

https://www.pythonguis.com/tutorials/pyqt6-embed-pyqtgraph-custom-widgets-qt-app/
https://doc.qt.io/qtforpython/PySide6/QtUiTools/QUiLoader.html#PySide6.QtUiTools.PySide6.QtUiTools.QUiLoader.registerCustomWidget
https://stackoverflow.com/questions/68528717/environment-variable-pyside-designer-plugins-is-not-set-bailing-out
https://doc-snapshots.qt.io/qtforpython-dev/tutorials/basictutorial/uifiles.html#custom-widgets-in-qt-designer

https://blog.csdn.net/feiyangqingyun/article/details/123005373
https://blog.csdn.net/panchang199266/article/details/104249647

你可能感兴趣的:(pyqt,python,qt)