0

My goal is next: I added in qlistwidget items containing button for removing themselves from the list.

But when I connect button clicked signal with removing function in the loop in which I create list items then it always try remove my last item.

That's the code:

import sys
from PyQt5.QtWidgets import QApplication, QWidget, QListWidget, QVBoxLayout, QLabel, QPushButton, QListWidgetItem, \
    QHBoxLayout

def remove_item_from_list(listbox, item):
    print('was', listbox.count())
    print(item)
    row = listbox.row(item)
    print('row is', row)
    listbox.takeItem(row)
    print('now is', listbox.count())

class CustomQWidget(QWidget):
    def __init__(self, label_text, parent=None):
        super(CustomQWidget, self).__init__(parent)

        label = QLabel(label_text)

        self.button = QPushButton("A useless button")
        #self.button.clicked.connect(lambda : )
        layout = QHBoxLayout()
        layout.addWidget(label)
        layout.addWidget(self.button)

        self.setLayout(layout)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = QWidget()

    title = QLabel("Demo for widgets in a QListWidget")
    labels = ['Cat', 'Dog', 'Person']
    list = QListWidget()

    for label in labels:
        item = QListWidgetItem(list)
        print(item)
        item_widget = CustomQWidget(label)
        item.setSizeHint(item_widget.sizeHint())
        #list.addItem(item)
        item_widget.button.clicked.connect(lambda: remove_item_from_list(list, item))
        list.setItemWidget(item, item_widget)

    window_layout = QVBoxLayout(window)
    window_layout.addWidget(title)
    window_layout.addWidget(list)
    window.setLayout(window_layout)

    window.show()

    sys.exit(app.exec_())

But if I move my signals connecting into each of my item widget class then I get a needed result. That's changes:

class CustomQWidget(QWidget):
    def __init__(self, label_text, parent_item, parent_widget=None):
        super(CustomQWidget, self).__init__(parent_widget)

        label = QLabel(label_text)

        self.button = QPushButton("A useless button")
        self.button.clicked.connect(lambda: remove_item_from_list(parent_widget, parent_item))
        layout = QHBoxLayout()
        layout.addWidget(label)
        layout.addWidget(self.button)

        self.setLayout(layout)

and removed connecting of signals from the loop of items creating:

for label in labels:
    item = QListWidgetItem(list)
    item_widget = CustomQWidget(label, item, list)
    item.setSizeHint(item_widget.sizeHint())
    list.setItemWidget(item, item_widget)

So the question is why does the first way not work?

eyllanesc
  • 235,170
  • 19
  • 170
  • 241
AlmostAI
  • 327
  • 4
  • 14
  • You're playing with fire by naming your QListWidget instance `list` because it will clobber the built in Python list data structure. I ran your first code by replacing with `listw` and it works better. – bfris Aug 26 '19 at 22:36
  • 1
    1) change all `list` variable to `listw` 2) change `item_widget.button.clicked.connect(lambda checked, l=listw, it=item2: remove_item_from_list(l, it))` – eyllanesc Aug 27 '19 at 04:35

0 Answers0