将小部件添加到从 .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_())
我正在使用 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_())