Reputation: 186
I am stuck into a PyQt5 Qlistwidget probelm. below is the current code I have:
from PyQt5 import QtWidgets, QtCore, QtGui
import sys
class FlatUIListWidget(QtWidgets.QListWidget):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.setStyleSheet("""
QScrollBar:vertical {
border: none;
background:white;
width:3px;
margin: 0px 0px 0px 0px;
}
QScrollBar::handle:vertical {
background: qlineargradient(x1:0, y1:0, x2:1, y2:0,
stop: 0 rgb(32, 47, 130), stop: 0.5 rgb(32, 47, 130), stop:1 rgb(32, 47, 130));
min-height: 0px;
}
QScrollBar::add-line:vertical {
background: qlineargradient(x1:0, y1:0, x2:1, y2:0,
stop: 0 rgb(32, 47, 130), stop: 0.5 rgb(32, 47, 130), stop:1 rgb(32, 47, 130));
height: 0px;
subcontrol-position: bottom;
subcontrol-origin: margin;
}
QScrollBar::sub-line:vertical {
background: qlineargradient(x1:0, y1:0, x2:1, y2:0,
stop: 0 rgb(32, 47, 130), stop: 0.5 rgb(32, 47, 130), stop:1 rgb(32, 47, 130));
height: 0 px;
subcontrol-position: top;
subcontrol-origin: margin;
}
""")
def add_custom_widget(self, widget):
myQListWidgetItem = QtWidgets.QListWidgetItem(self)
# Set size hint
myQListWidgetItem.setSizeHint(widget.sizeHint())
# Add QListWidgetItem into QListWidget
self.addItem(myQListWidgetItem)
self.setItemWidget(myQListWidgetItem, widget)
class DummyWidget(QtWidgets.QWidget):
delete_signal = QtCore.pyqtSignal(str)
def __init__(self, text):
super().__init__()
self.text = text
self.layout = QtWidgets.QVBoxLayout(self)
self.delete_button = QtWidgets.QPushButton(text)
self.delete_button.clicked.connect(self.on_delte_button_clicked)
self.layout.addWidget(self.delete_button)
def on_delte_button_clicked(self):
self.delete_signal.emit(self.text)
class Container(QtWidgets.QWidget):
def __init__(self):
super().__init__()
self.layout = QtWidgets.QVBoxLayout(self)
self.list_widget = FlatUIListWidget()
self.layout.addWidget(self.list_widget)
for i in range(10):
self.add_widget(str(i))
def add_widget(self, text):
item = DummyWidget(text)
item.delete_signal.connect(self.on_item_delete)
self.list_widget.add_custom_widget(item)
def on_item_delete(self, string):
try:
# cursor = QtGui.QCursor()
# print(cursor.pos())
# print(self.list_widget.itemAt(cursor.pos()))
# print(self.list_widget.selectedItems())
# print(self.sender().parent().parent())
# print(self.list_widget.currentRow())
# self.list_widget.setCurrentItem(self.sender().parent())
# self.list_widget.takeItem(self.sender().parent())
print(string)
self.list_widget.takeItem(self.list_widget.currentRow())
except Exception as e:
print(e)
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
mw = Container()
mw.show()
sys.exit(app.exec_())
basically, I want to create a QListWidget
with all customized items. In each of those item there is a button allowed for user to delete itself. I have tried the following:
connect button clicked signal to self.sender().deleteLater()
. This does not work since it only delete the widget inside the QListWidgetItem
and will leave a blank box in the QListWidget
.
after click the button, send out a signal to Container
widget and delete the current row. This is also not working because you actually need to select on the widget first and click delete, otherwise it will delete the very first row.
gave each item widget a name tag and after click button, looping through the listwidget and use takeItem()
to delete the one have the same tag. I just think this approach is not elegant...
I think it would make most of sense that if I can somehow get the row number for the widget which button have been clicked and use takeItem()
on self.list_widget.row(row_number)
to delete. I just couldn't figure out how.
I have read the official document of QListWidget
and QListWidgetItems
, which didn't give me an answer. I would be really appreciated it if somebody can provide some ideas.
Adding customized widget to QListWidget
is re-written from this post: PyQt QListWidget custom items
Upvotes: 0
Views: 630
Reputation: 243897
To eliminate the item using the QWidget
the procedure is as follows:
Obtain the position of the widget with respect to the viewport()
, in this case it is easy since the widget(DummyWidget
) is the children of the viewport()
, so we should only use self.sender().pos()
.
Using the position we obtain the item through itemAt()
.
Using the item we get the row through row()
.
And then we eliminate it with takeItem()
.
The implementation is as follows:
def on_item_delete(self, string):
it = self.list_widget.itemAt(self.sender().pos())
row = self.list_widget.row(it)
item = self.list_widget.takeItem(row)
del item
Upvotes: 1