【问题标题】:Is it possible to have PySide's QUIloader act like PyQt's uic.loadUi? [duplicate]是否可以让 PySide 的 QUIloader 像 PyQt 的 uic.loadUi 一样工作?
【发布时间】:2014-07-16 23:44:40
【问题描述】:

所以我有一个应用程序,我正在考虑从 PyQt4 迁移到 PySide。在这个应用程序中,我经常使用.ui 文件,使用模式如下:

class BaseGUIWidget(QWidget):
    def __init__(self, parent = None, ui_file = None):
        '''
        :param parent: parent widget of this widget
        :param ui_file: path to UI file to load (optional)
        '''
        super(BaseGUIWidget, self).__init__(parent)
        if ui_file is not None:
            uic.loadUi(ui_file, self)

假设我对QFrameQMainWindowQGroupBox 等有类似的课程。

这允许我创建使用 UI 文件中的数据的 python 类,以及我在代码中手动添加的任何附加功能。从本质上讲,我的BaseGUIWidget 类的行为就像是在扩展由 UI 文件生成的类。应用程序中的许多功能都非常依赖这种行为。

但是,据我所知,PySide 的QUIloader 没有类似的功能。它不是将 UI 文件的内容“填充”到您的类中,而是简单地在内部从 UI 文件构建一个小部件,然后返回它,然后您将它嵌入到您的小部件中 layout 就像任何其他小部件一样。,IE :

class BaseGUIWidget(QWidget):
    def __init__(self, parent = None, ui_file = None):
        '''
        :param parent: parent widget of this widget
        :param ui_file: path to UI file to load (optional)
        '''
        super(BaseGUIWidget, self).__init__(parent)
        self.setLayout(QVBoxLayout())
        if ui_file is not None:
            loader = QUILoader()
            uifile = QFile(ui_file)
            uifile.open(QFile.ReadOnly)                
            self.ui_widget = loader.load(ui_file, self)
            self.layout().addWidget(self.ui_widget)
            uifile.close()

这是一个相当大的差异。例如,如果您希望您的 UI 文件包含 QMainWindow 并且您的 python 类仍然是 QMainWindow 的扩展,因此它与其他类一样,您最终会在一个 QMainWindowQMainWindow,这不是你想要的。这也意味着您必须执行 widget.ui_widget.XXX 才能访问 UI 文件生成的小部件。

有什么方法可以让 PySide 的 uic 实现像 PyQt 的一样?

【问题讨论】:

    标签: python qt python-2.7 pyqt4 pyside


    【解决方案1】:

    使用 QtPy 包

    pip3 install QtPy
    

    它自动检测使用的绑定(pyqt5 或 pyside2)

    from QtPy import uic # and all other QT modules
    
    w = uic.loadUi("mywidget.ui")
    w.show()
    

    【讨论】:

      【解决方案2】:

      是的,这是可能的。 我知道这是个老问题,但突然有人会派上用场。 我在以下位置找到了这个解决方案:

      https://robonobodojo.wordpress.com/2017/10/03/loading-a-pyside-ui-via-a-class/

      ui_loader.py:

      #!/usr/bin/env python
      
      from PySide.QtUiTools import QUiLoader
      from PySide.QtCore import QMetaObject
      
      class UiLoader(QUiLoader):
          def __init__(self, base_instance):
              QUiLoader.__init__(self, base_instance)
              self.base_instance = base_instance
      
          def createWidget(self, class_name, parent=None, name=''):
              if parent is None and self.base_instance:
                  return self.base_instance
              else:
                  # create a new widget for child widgets
                  widget = QUiLoader.createWidget(self, class_name, parent, name)
                  if self.base_instance:
                      setattr(self.base_instance, name, widget)
                  return widget
      
      def load_ui(ui_file, base_instance=None):
          loader = UiLoader(base_instance)
          widget = loader.load(ui_file)
          QMetaObject.connectSlotsByName(widget)
          return widget
      

      示例:

      #!/usr/bin/env python
      
      from PySide import QtGui
      from ui_loader import load_ui
      import sys
      
      class MainWindow(QtGui.QMainWindow):
          def __init__(self, parent=None):
              QtGui.QMainWindow.__init__(self, parent)
              load_ui('my_interface.ui', self)
      
      def main():
          app = QtGui.QApplication(sys.argv)
          window = MainWindow()
          window.show()
          app.exec_()
      
      if __name__ == '__main__':
          main()
      

      【讨论】:

        【解决方案3】:

        其实我也想知道同样的事情,只是尝试了这个:

        1. 将 uic 包从 PyQt4 安装复制到 PySide 包(它所有的 python 模块,没有编译的库,所以不应该有任何不兼容性)

        2. 对 uic 包进行搜索和替换,将“PyQt4”替换为“PySide”

        3. 使用它:

          from PySide import uic
          
          w = uic.loadUi("mywidget.ui")
          w.show()
          

        它也适用于您描述的用例 (uic.loadUi(ui_file, self)) :) 当然,不能保证一切都会正常运行,但我很惊讶这个 hack 让它成功了。

        【讨论】:

        • 这对于家庭使用来说是可以的,但是对于在商业应用程序(免费或其他方式)中使用是超级、超级非法的,因为它基本上公然违反了几乎任何许可的条款。 PySide 存在的全部原因是(大致)用不同的许可方案替代 PyQt。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-08-15
        • 2017-06-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-10-07
        • 2023-03-14
        相关资源
        最近更新 更多