Issue
I want to be able to move a layout to another layout based on a user input. I have the following code which does not appear to work for me. If I switch lines 31 and 34 so that they operate on the widget rather than the layout then I get the expected behaviour but I am hoping to operate on all widgets within a layout by just moving the layout.
import sys
from PyQt5.QtWidgets import QPushButton, QWidget, QHBoxLayout, QLabel, QApplication, QVBoxLayout
class b(QWidget):
def __init__(self, name):
super(b, self).__init__()
self.layout = QVBoxLayout(self)
lbl_1 = QLabel(name)
self.layout.addWidget(lbl_1)
class a(QWidget):
def __init__(self):
super(a, self).__init__()
self.layout = QHBoxLayout(self)
self.widget_1 = b('widget 1')
self.widget_2 = b('widget 2')
self.layout.addWidget(self.widget_1)
self.layout.addWidget(self.widget_2)
self.button_layout = QHBoxLayout()
self.move_layout = QPushButton('Move to other layout')
self.move_layout.clicked.connect(lambda: self.move_button())
self.button_layout.addWidget(self.move_layout)
self.widget = 'widget_2'
self.widget_2.layout.addLayout(self.button_layout)
def move_button(self):
if self.widget == 'widget_2':
self.widget_1.layout.addLayout(self.button_layout)
self.widget = 'widget_1'
else:
self.widget_2.layout.addLayout(self.button_layout)
self.widget = 'widget_2'
print('moved widget to {}'.format(self.widget))
if __name__ == '__main__':
app = QApplication(sys.argv)
window = a()
window.show()
sys.exit(app.exec_())
Edit: to clarify, In the example above, the layout I want to move (self.button_layout) is a child layout of self.widget_2.layout. When I click the pushbutton, I want the self.button_layout to be set as a child layout of self.widget_1.layout. Essentially it will do what the code below does but using addLayout instead of addWidget.
import sys
from PyQt5.QtWidgets import QPushButton, QWidget, QHBoxLayout, QLabel, QApplication, QVBoxLayout
class b(QWidget):
def __init__(self, name):
super(b, self).__init__()
self.layout = QVBoxLayout(self)
lbl_1 = QLabel(name)
self.layout.addWidget(lbl_1)
class a(QWidget):
def __init__(self):
super(a, self).__init__()
self.layout = QHBoxLayout(self)
self.widget_1 = b('widget 1')
self.widget_2 = b('widget 2')
self.layout.addWidget(self.widget_1)
self.layout.addWidget(self.widget_2)
self.button_layout = QHBoxLayout()
self.move_layout = QPushButton('Move to other layout')
self.move_layout.clicked.connect(lambda: self.move_button())
self.button_layout.addWidget(self.move_layout)
self.widget = 'widget_2'
self.widget_2.layout.addLayout(self.button_layout)
def move_button(self):
if self.widget == 'widget_2':
self.widget_1.layout.addWidget(self.move_layout)
self.widget = 'widget_1'
else:
self.widget_2.layout.addWidget(self.move_layout)
self.widget = 'widget_2'
print('moved widget to {}'.format(self.widget))
if __name__ == '__main__':
app = QApplication(sys.argv)
window = a()
window.show()
sys.exit(app.exec_())
Solution
The problem is that if a layout has a parent then it cannot be changed as the error message indicates:
QLayout::addChildLayout: layout "" already has a parent
One possible solution is to remove the parent:
def move_button(self):
self.button_layout.setParent(None)
if self.widget == "widget_2":
self.widget_1.layout.addLayout(self.button_layout)
self.widget = "widget_1"
else:
self.widget_2.layout.addLayout(self.button_layout)
self.widget = "widget_2"
print("moved widget to {}".format(self.widget))
Another alternative is to place the layout in a QWidget that is the container and that place it in the required layout:
class a(QWidget):
def __init__(self):
super(a, self).__init__()
layout = QHBoxLayout(self)
self.widget_1 = b("widget 1")
self.widget_2 = b("widget 2")
layout.addWidget(self.widget_1)
layout.addWidget(self.widget_2)
self.container = QWidget()
container_layout = QHBoxLayout(self.container)
button = QPushButton("Move to other layout")
button.clicked.connect(self.move_button)
container_layout.addWidget(button)
self.widget = "widget_1"
self.move_button()
def move_button(self):
if self.widget == "widget_2":
self.widget_1.layout.addWidget(self.container)
self.widget = "widget_1"
else:
self.widget_2.layout.addWidget(self.container)
self.widget = "widget_2"
print("moved widget to {}".format(self.widget))
Answered By - eyllanesc
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.