Solved Unable to add a widget to a QScrollArea object dynamically
-
@jsulm Hi, sorry I was not clear. When I comment that out, nothing happens if I click the "Add" button. But I print the number of the widget in
main_window._my_list._layout.count()
, the number increases correctly. -
@sunshk1227 Try to call show() on new buttons:
def _add(self): b = QPushButton('test') self._list._layout.addWidget(b) b.show()
-
@jsulm Hi, thank you for your help! But it seems that it does not work.
(By the way, if I do NOT comment it out, a new button will be displayed on the screen when I click the "Add" button...)
-
@sunshk1227 Strange.
Not a solution for the problem, but an improvement idea: instead of exposing internals of the MyList class (_layout) to the outside world you should make it private and add a method to add new widgets (like buttons).class MyList(QScrollArea): ... def addWidget(self, widget): self.__layoutaddWidget(widget)
This way MyButton does not have to know where to add new buttons to the list:
def _add(self): self._list.addWidget(QPushButton('test'))
You could improve your design even more if you remove self._list from MyButton completely and instead emit a signal in MyButton and connect it to a slot in MyList. This way MyButton and MyList do not have to know anything about each other.
-
@jsulm Thank you very much for your suggestions! Got it. But I still have a question... should I further improve my design like this? (In this case, could you please tell me how to connect a function with an additional argument, where I marked by '?' in my code?)
Thank you again for your advice!class MyList(QScrollArea): ... def _addWidget(self, widget): self._layout.addWidget(widget) class MyButton(QPushButton): def __init__(self, text): super().__init__(text=text) class MainWindow(QWidget): def __init__(self): ... self._my_list = MyList() self._my_button = MyButton(text='Add') self._my_button.clicked.connect(self._my_list._addWidget(?)) ... ... ...
-
@sunshk1227 said in Unable to add a widget to a QScrollArea object dynamically:
self._my_button.clicked.connect(self._my_list._addWidget(?))
This is wrong, should be:
self._my_button.clicked.connect(self._my_list._addWidget)
In this line you only connect the signal to the slot, you do not call the slot. Slot will be called as soon as signal is emitted.
class MyButton(QPushButton): newWidget = pyqtSignal() def __init__(self, text): super().__init__(text=text) self.clicked.connect(self._add) def _add(self): newWidget.emit(QPushButton('test')) self._my_button.newWidget.connect(self._my_list._addWidget)
Not sure this 100% correct as I don't use PyQt/PiSide :-)
-
I figure out the reason with the help of @T.sagiv.
The solution is that I have to adjust the scrollarea. Just replaceself.setMinimumSize(1024, 540)
withself.setWidgetResizable(True)
. -
@jsulm said in Unable to add a widget to a QScrollArea object dynamically:
Not sure this 100% correct as I don't use PyQt/PiSide :-)
newWidget.emit(QPushButton('test'))
Whazzis? :)
-
@JonB You're the Python guy here :-) It was meant to emit a signal with a parameter.
-
@jsulm
Yeah but I was suprised at your parameter! Yours isemit newWidget(new QPushButton("test"))
, is that what you intended? I didn't really read what OP wanted :-; So you want to emit a signal which accepts an unplacednew
widget, presumably the slot does something with it? Interesting! -
@JonB Yes, the emitter sends new widget to add via signal. The receiver adds it to its UI.