小能豆

在内部拖放 Pyside PyQt 后,放置的自定义 QWidget 项目在 QListWidget 中消失

javascript

如果 QListWidget 中的项目拖放到同一个 QListWidget 对象中的另一个项目上,则这些项目会开始消失在彼此后面或堆叠在一起,有时甚至显示为空白项目。如下所示

1.png

我不确定导致该问题的实现代码存在什么错误或缺失。

此外,我想禁用拖放时的复制功能,如果用户在内部拖放时按住 CTRL 按钮,闪光符号将更改为 + 符号,并且项目将添加到列表中。

该功能应该被禁用,但我不知道该怎么做,如果无法在放置时禁用复制功能,我想知道是否有可用的解决方法,因为在 QWidgetList 对象 [listWidgetA 和 listWidgetB] 中每个项目都不应存在超过一个,两个列表中都不允许有任何项目的重复。

总而言之,我希望解决以下问题。

  1. 在同一列表中拖放项目时项目消失或堆叠的缺陷或问题。
  2. 可以在拖放时按住 CTRL 键来禁用复制项目的功能,或者建议采取一种解决方法来防止在同一列表或其他列表中复制项目。

下面我附上了错误的代码。

from PySide6 import QtGui, QtCore, QtWidgets
import sys, os, pathlib


class ThumbListWidget(QtWidgets.QListWidget):
    def __init__(self, type, parent=None):
        super(ThumbListWidget, self).__init__(parent)
        self.setIconSize(QtCore.QSize(124, 124))
        self.setDragDropMode(QtWidgets.QAbstractItemView.DragDrop)
        self.setDefaultDropAction(QtCore.Qt.MoveAction)
        self.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection)
        self.setAcceptDrops(True)
        self.model().rowsInserted.connect(
            self.handleRowsInserted, QtCore.Qt.QueuedConnection)

    def handleRowsInserted(self, parent, first, last):
        print(f"first:{first} last:{last} parent:{parent}")
        for index in range(first, last + 1):
            item = self.item(index)
            if item is not None and self.itemWidget(item) is None:
                index, name, icon = item.data(QtCore.Qt.UserRole)
                widget = QCustomQWidget()
                widget.setTextUp(index)
                widget.setTextDown(name)
                widget.setIcon(icon)
                item.setSizeHint(widget.sizeHint())
                self.setItemWidget(item, widget)


class Dialog_01(QtWidgets.QMainWindow):
    def __init__(self):
        super().__init__()
        self.listItems = {}

阅读 81

收藏
2025-01-27

共1个答案

小能豆

自动使用DragDrop标志允许复制内部项目的可能性,因为这是由Ctrl修饰符启用的,您只需要在dragMoveEvent和中检查它dropEvent,并最终忽略它:

class ThumbListWidget(QtWidgets.QListWidget):
    # ...
    def dragMoveEvent(self, event):
        if event.keyboardModifiers():
            event.ignore()
        else:
            super().dragMoveEvent(event)

    def dropEvent(self, event):
        if event.keyboardModifiers():
            event.ignore()
        else:
            super().dropEvent(event)

关于另一点,我能够重现“空”单元格问题,但只是随机重现。这可能是列表小部件和项目小部件的几何图形之间的交互导致的错误(特别是考虑到 QLabel 带有像素图,这可能会导致一些布局和抛光问题),但很难找到实际原因,因此几乎不可能找到适当的解决方案或解决方法。
如果您能够找到一种一致地重现该问题的方法,我建议您相应地更新您的问题(但请注意,这并不意味着我们也可以重现它)。

考虑一下,虽然在许多简单情况下使用项目小部件似乎是合理的,但更好的解决方案是使用自定义委托并覆盖其paint函数来绘制内容。

2025-01-27