[Re] Qlistwidget move up and down?
-
Re: Qlistwidget move up and down?
Hey, so I came accross this thread, but unfortunately, It didn't seem to have a clear answer
So:
Try to call https://doc.qt.io/qt-5/qtreewidget.html#itemWidget on currentItem and see if it still has it widget when you take it out.
Indeed, the custom widget disappear once takeItem() has been called (itemWidget() returns None). If I try to call setItemWidget() again with the same custom widget, my program segfaults, so I assume Qt deleted the object entirely. Is it a normal behavior or a bug ?
REPENT!!!
Why are you using this?Could you clarify ? I would like to display more than text in the list, so I have using a widget to display that custom data. It seems like the most straightforward solution to me. Why shouldn't I do that ?
More specifically, here is the visual of what I would like to do (with drag & drop as another option to move items) :
The custom widget holds the text and the two buttons
If you have an idea of a better way to do it, please tell me
(I am using PyQt 5.15.9 btw)
-
Hi and welcome to devnet,
Why not ? Because you are going to generate lots of widgets. As the documentation says: it's for showing some static data.
If you want to do things properly, write a custom QStyledItemDelegate that draws the text and the controls the way you want it. You will then have automatic handling of row movements, etc. already provided by QListWidget.
-
Sorry for the late answer, I thought I had notifications enabled
Thanks for your answer ! Looking at QStyledItemDelegate online, it seems to be quite low level: I would have to manage myself drawing the button and hovering over it (and probably some other things since I didn't quite understand how QStyledItemDelegate works).
Is it really necessary for what seems such a simple thing ?
If so, do you have a tutorial/example that could help me implement it ? -
Sorry for the late answer, I thought I had notifications enabled
Thanks for your answer ! Looking at QStyledItemDelegate online, it seems to be quite low level: I would have to manage myself drawing the button and hovering over it (and probably some other things since I didn't quite understand how QStyledItemDelegate works).
Is it really necessary for what seems such a simple thing ?
If so, do you have a tutorial/example that could help me implement it ?Here a small example showing the painting of a button in the delegate.
You can adapt it to your needs (i.e. draw two buttons instead one and detect which button should be down when pressed)
import sys from PySide6.QtCore import QAbstractItemModel from PySide6.QtCore import QEvent from PySide6.QtCore import QModelIndex from PySide6.QtCore import Signal from PySide6.QtGui import QMouseEvent from PySide6.QtGui import QStandardItem from PySide6.QtGui import QStandardItemModel from PySide6.QtWidgets import QApplication from PySide6.QtWidgets import QStyle from PySide6.QtWidgets import QStyledItemDelegate from PySide6.QtWidgets import QStyleOptionButton from PySide6.QtWidgets import QStyleOptionViewItem from PySide6.QtWidgets import QTableView class Delegate(QStyledItemDelegate): clicked = Signal(QModelIndex) def __init__(self, parent=None) -> None: super().__init__(parent) self._is_down = False def _build_option(self, option, index: QModelIndex) -> QStyleOptionButton: pb_style = QStyleOptionButton() pb_style.state = option.state pb_style.state |= QStyle.State_Sunken if self._is_down else QStyle.State_Raised pb_style.fontMetrics = option.fontMetrics pb_style.rect = option.rect pb_style.text = index.data() return pb_style def editorEvent( self, event: QEvent, model: QAbstractItemModel, option: QStyleOptionViewItem, index: QModelIndex, ) -> bool: if isinstance(event, QMouseEvent): if event.type() == QEvent.MouseButtonPress: self._is_down = True elif event.type() == QEvent.MouseButtonRelease: self._is_down = False self.clicked.emit(index) return True return False def paint(self, painter, option, index) -> None: button_option = self._build_option(option, index) qApp.style().drawControl( QStyle.CE_PushButton, button_option, painter, self.parent() ) def show_text(index: QModelIndex) -> None: print(index.data()) if __name__ == "__main__": app = QApplication(sys.argv) view = QTableView() model = QStandardItemModel(3, 2) for row in range(model.rowCount()): for column in range(model.columnCount()): item = QStandardItem(f"row {row}, column {column}") model.setItem(row, column, item) view.setModel(model) delegate = Delegate(view) view.setItemDelegateForColumn(1, delegate) view.show() delegate.clicked.connect(show_text) sys.exit(app.exec())