将小部件添加到从 .ui 文件创建的布局

Adding a widget to a layout created from .ui file

我正在使用 PySide2 在 Python 中创建一个 GUI,这是我的 .ui 文件:

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>main_window</class>
 <widget class="QWidget" name="main_window">
  <property name="windowModality">
   <enum>Qt::NonModal</enum>
  </property>
  <property name="enabled">
   <bool>true</bool>
  </property>
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>1000</width>
    <height>640</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>Testing App</string>
  </property>
  <layout class="QVBoxLayout" name="layout">
   <item>
    <layout class="QVBoxLayout" name="other_layout">
     <item>
      <widget class="QWidget" name="panel" native="true">
       <layout class="QHBoxLayout" name="layout3">
        <item>
         <layout class="QVBoxLayout" name="layout4">
          <item>
           <layout class="QHBoxLayout" name="layout5">
            <item>
             <widget class="QLabel" name="lo">
              <property name="text">
               <string>X</string>
              </property>
              <property name="alignment">
               <set>Qt::AlignCenter</set>
              </property>
             </widget>
            </item>
            <item>
             <widget class="QLineEdit" name="resolution_x">
              <property name="sizePolicy">
               <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
                <horstretch>0</horstretch>
                <verstretch>0</verstretch>
               </sizepolicy>
              </property>
              <property name="inputMethodHints">
               <set>Qt::ImhDigitsOnly</set>
              </property>
              <property name="text">
               <string>175</string>
              </property>
             </widget>
            </item>
           </layout>
          </item>
          <item>
           <layout class="QHBoxLayout" name="layout6">
            <item>
             <widget class="QLabel" name="lo2">
              <property name="text">
               <string>Y</string>
              </property>
              <property name="alignment">
               <set>Qt::AlignCenter</set>
              </property>
             </widget>
            </item>
            <item>
             <widget class="QLineEdit" name="res2">
              <property name="sizePolicy">
               <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
                <horstretch>0</horstretch>
                <verstretch>0</verstretch>
               </sizepolicy>
              </property>
              <property name="inputMethodHints">
               <set>Qt::ImhDigitsOnly</set>
              </property>
              <property name="text">
               <string>150</string>
              </property>
             </widget>
            </item>
           </layout>
          </item>
         </layout>
        </item>
        <item>
         <layout class="QVBoxLayout" name="layout7">
          <item>
           <layout class="QHBoxLayout" name="iterations_layout">
            <item>
             <widget class="QLabel" name="iterLab">
              <property name="text">
               <string>Num Passes</string>
              </property>
              <property name="alignment">
               <set>Qt::AlignCenter</set>
              </property>
             </widget>
            </item>
            <item>
             <widget class="QLineEdit" name="itr">
              <property name="sizePolicy">
               <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
                <horstretch>0</horstretch>
                <verstretch>0</verstretch>
               </sizepolicy>
              </property>
              <property name="inputMethodHints">
               <set>Qt::ImhDigitsOnly</set>
              </property>
              <property name="text">
               <string>20</string>
              </property>
             </widget>
            </item>
           </layout>
          </item>
          <item>
           <layout class="QHBoxLayout" name="layout8">
            <item>
             <widget class="QPushButton" name="reset_button">
              <property name="sizePolicy">
               <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
                <horstretch>0</horstretch>
                <verstretch>0</verstretch>
               </sizepolicy>
              </property>
              <property name="minimumSize">
               <size>
                <width>50</width>
                <height>0</height>
               </size>
              </property>
              <property name="layoutDirection">
               <enum>Qt::LeftToRight</enum>
              </property>
              <property name="text">
               <string>Zoom</string>
              </property>
             </widget>
            </item>
           </layout>
          </item>
         </layout>
        </item>
       </layout>
      </widget>
     </item>
     <item>
      <layout class="QHBoxLayout" name="process_layout">
       <item alignment="Qt::AlignLeft">
        <widget class="QLabel" name="status">
         <property name="sizePolicy">
          <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
           <horstretch>0</horstretch>
           <verstretch>0</verstretch>
          </sizepolicy>
         </property>
         <property name="minimumSize">
          <size>
           <width>120</width>
           <height>20</height>
          </size>
         </property>
         <property name="maximumSize">
          <size>
           <width>120</width>
           <height>20</height>
          </size>
         </property>
         <property name="text">
          <string/>
         </property>
         <property name="alignment">
          <set>Qt::AlignCenter</set>
         </property>
        </widget>
       </item>
       <item alignment="Qt::AlignRight">
        <widget class="QLabel" name="procLab">
         <property name="minimumSize">
          <size>
           <width>77</width>
           <height>20</height>
          </size>
         </property>
         <property name="maximumSize">
          <size>
           <width>77</width>
           <height>20</height>
          </size>
         </property>
         <property name="text">
          <string>#</string>
         </property>
        </widget>
       </item>
       <item alignment="Qt::AlignRight">
        <widget class="QLineEdit" name="processes">
         <property name="sizePolicy">
          <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
           <horstretch>0</horstretch>
           <verstretch>0</verstretch>
          </sizepolicy>
         </property>
         <property name="minimumSize">
          <size>
           <width>50</width>
           <height>0</height>
          </size>
         </property>
         <property name="maximumSize">
          <size>
           <width>50</width>
           <height>2000</height>
          </size>
         </property>
         <property name="inputMethodHints">
          <set>Qt::ImhDigitsOnly</set>
         </property>
         <property name="text">
          <string>8</string>
         </property>
        </widget>
       </item>
      </layout>
     </item>
    </layout>
   </item>
  </layout>
 </widget>
 <resources/>
 <connections/>
</ui>

我想从我的 Python 脚本动态添加一个小部件到主布局 ('layout'):

app = QApplication(sys.argv)
f = MyWindow()
sys.exit(app.exec_())

class MyWindow(QWidget):
    def __init__(self):
        super(MyWindow, self).__init__(None)
        ui_file = QtCore.QFile("./myui.ui")
        ui_file.open(QtCore.QFile.ReadOnly)
        loader = QtUiTools.QUiLoader()
        self.window = loader.load(ui_file)
        ui_file.close()

        self.layout.addWidget(QLabel('Stuff'))

        self.window.show()

但是,我收到以下错误

    self.layout.addWidget(QLabel('Stuff'))
AttributeError: 'builtin_function_or_method' object has no attribute 'addWidget'

我不明白为什么 self.layout 没有 属性 addWidget。我以为 self.layout 会引用 QVBoxLayout 对象?

您有几个错误:

  • 从 .ui 加载的小部件不是 MyWindow,另一方面,在 PySide2 中不可能将 .ui 加载到小部件 class 由 python 实现(在 PyQt5 中,如果可能,通过 uic.loadUi())所以 class 应该处理小部件。

  • 另一方面,不要使用可能与方法名冲突的变量名,例如QWidget class有一个布局方法,所以不建议你有一个具有该名称的属性,一个可能的解决方案是使用 findChild 来获取布局:

import sys

from PySide2.QtCore import QObject, QFile
from PySide2.QtWidgets import QApplication, QLabel, QVBoxLayout, QWidget
from PySide2.QtUiTools import QUiLoader


class Manager(QObject):
    def __init__(self):
        super(Manager, self).__init__(None)
        ui_file = QFile("./myui.ui")
        ui_file.open(QFile.ReadOnly)
        loader = QUiLoader()
        self.window = loader.load(ui_file)
        ui_file.close()
        lay = self.window.findChild(QVBoxLayout, "layout")
        lay.addWidget(QLabel("Stuff"))

        self.window.show()


if __name__ == "__main__":

    app = QApplication(sys.argv)
    f = Manager()
    sys.exit(app.exec_())
  • 另一种可能的解决方案是将布局的名称更改为例如 vlayout:<layout class="QVBoxLayout" name="vlayout">
import sys

from PySide2.QtCore import QObject, QFile
from PySide2.QtWidgets import QApplication, QLabel, QWidget
from PySide2.QtUiTools import QUiLoader


class Manager(QObject):
    def __init__(self):
        super(Manager, self).__init__(None)
        ui_file = QFile("./myui.ui")
        ui_file.open(QFile.ReadOnly)
        loader = QUiLoader()
        self.window = loader.load(ui_file)
        ui_file.close()
        self.window.vlayout.addWidget(QLabel("Stuff"))

        self.window.show()


if __name__ == "__main__":

    app = QApplication(sys.argv)
    f = Manager()
    sys.exit(app.exec_())