I am creating a GUI in Python using PySide2, this is my .ui file:
<?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>
I want to add a widget dynamically from my Python script to the main layout ('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()
However, I get the following error
self.layout.addWidget(QLabel('Stuff'))
AttributeError: 'builtin_function_or_method' object has no attribute 'addWidget'
I don't understand why self.layout doesn't have the property addWidget. I thought self.layout would have a reference to a QVBoxLayout object?
-
added more of the .ui filePablo– Pablo2020年11月29日 15:54:23 +00:00Commented Nov 29, 2020 at 15:54
-
@eyllanesc added itPablo– Pablo2020年11月29日 16:04:02 +00:00Commented Nov 29, 2020 at 16:04
1 Answer 1
You have several errors:
The widget loaded from the .ui is not the MyWindow, on the other hand in PySide2 it is not possible to load a .ui to a widget class implemented by python (in PyQt5 if possible via
uic.loadUi()
) so the class should handle the widget.On the other hand, do not use variable names that may conflict with the names of the methods, for example the QWidget class has a layout method so it is not recommended that you have an attribute with that name, a possible solution is to use findChild to get the layout:
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_())
- Another possible solution is to change the name of the layout to for example 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_())