首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >PySide QlistView拖放

PySide QlistView拖放
EN

Stack Overflow用户
提问于 2022-08-30 15:02:38
回答 1查看 43关注 0票数 0

我试图通过使用QListView实现一个简单的从一个QListView到另一个QListView的拖放功能。

下面是ui:

代码语言:javascript
复制
import sys

import qdarktheme
from PySide6.QtWidgets import QApplication, QWidget, QMainWindow, QVBoxLayout, QListView

from models.pipeline_model import PipelineListModel
from models.toolbox_model import ToolboxListModel, MyModel


class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()

        toolbox_list_model = ToolboxListModel()
        pipeline_list_model = PipelineListModel()

        for i in range(10):
            toolbox_list_model.toolbox_items.append(MyModel(x=i))

        toolbox_list_view = QListView()
        toolbox_list_view.setDragEnabled(True)
        toolbox_list_view.setModel(toolbox_list_model)

        pipeline_list_view = QListView()
        pipeline_list_view.setAcceptDrops(True)
        pipeline_list_view.setModel(pipeline_list_model)

        vbox = QVBoxLayout()
        vbox.addWidget(toolbox_list_view)
        vbox.addWidget(pipeline_list_view)

        main_widget = QWidget()
        main_widget.setLayout(vbox)
        self.setCentralWidget(main_widget)


if __name__ == '__main__':
    app = QApplication()
    app.setStyleSheet(qdarktheme.load_stylesheet())
    main_window = MainWindow()

    main_window.show()

    # Start the event loop.
    sys.exit(app.exec())

工具箱列表模型(其中应从其中拖动项目):

代码语言:javascript
复制
from typing import Union, Any

import PySide6
from PySide6 import QtCore
from PySide6.QtCore import Qt

from models.model_data import MyModel


class ToolboxListModel(QtCore.QAbstractListModel):
    def __init__(self):
        super().__init__()
        self.toolbox_items: list[MyModel] = []

    def data(self, index: Union[PySide6.QtCore.QModelIndex, PySide6.QtCore.QPersistentModelIndex],
             role: int = ...) -> Any:
        if role == Qt.DisplayRole:
            model = self.toolbox_items[index.row()]
            return model.x

    def rowCount(self, parent: Union[PySide6.QtCore.QModelIndex, PySide6.QtCore.QPersistentModelIndex] = ...) -> int:
        return len(self.toolbox_items)

目标列表模型(其中应删除工具箱项):

代码语言:javascript
复制
from typing import Union, Any

import PySide6
from PySide6 import QtCore
from PySide6.QtCore import Qt

from models.model_data import MyModel


class PipelineListModel(QtCore.QAbstractListModel):
    def __init__(self):
        super().__init__()
        self.toolbox_items: list[MyModel] = []

    def data(self, index: Union[PySide6.QtCore.QModelIndex, PySide6.QtCore.QPersistentModelIndex],
             role: int = ...) -> Any:
        if role == Qt.DisplayRole:
            model = self.toolbox_items[index.row()]
            return model.x

    def rowCount(self, parent: Union[PySide6.QtCore.QModelIndex, PySide6.QtCore.QPersistentModelIndex] = ...) -> int:
        return len(self.toolbox_items)

最后,共享数据模型:

代码语言:javascript
复制
import dataclasses


@dataclasses.dataclass
class MyModel:
    x: int

尽管如此,dragEnabled被设置为True,接收器QListView被设置为接受拖放,拖动操作甚至没有启动。

我在这里做错什么了?怎么做正确的手术?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-08-30 15:45:26

正如在模型视图文档中所解释的(我强烈建议阅读它的全部内容),您必须重写flags()函数,因为默认行为只使项启用和可选。

在视图上设置Drag标志只允许拖动操作,但只有模型才能判断可以拖动哪些项。

如果要允许索引可拖放,还必须提供ItemIsDragEnabled标志:

代码语言:javascript
复制
class ToolboxListModel(QtCore.QAbstractListModel):
    def flags(self, index):
        flags = super().flags(index)
        if index.isValid():
            flags |= QtCore.Qt.ItemFlags.ItemIsDragEnabled
        return flags

然后,根据您希望在目标模型上的行为,您可能需要覆盖标志来接受拖放到现有项上(以覆盖项),或者实现其他函数,如关于子类QAbstractListModel的文档所示,因为默认情况下它不支持可调整大小的列表。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73544611

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档