我试图通过使用QListView实现一个简单的从一个QListView到另一个QListView的拖放功能。
下面是ui:
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())工具箱列表模型(其中应从其中拖动项目):
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)目标列表模型(其中应删除工具箱项):
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)最后,共享数据模型:
import dataclasses
@dataclasses.dataclass
class MyModel:
x: int尽管如此,dragEnabled被设置为True,接收器QListView被设置为接受拖放,拖动操作甚至没有启动。
我在这里做错什么了?怎么做正确的手术?
发布于 2022-08-30 15:45:26
正如在模型视图文档中所解释的(我强烈建议阅读它的全部内容),您必须重写flags()函数,因为默认行为只使项启用和可选。
在视图上设置Drag标志只允许拖动操作,但只有模型才能判断可以拖动哪些项。
如果要允许索引可拖放,还必须提供ItemIsDragEnabled标志:
class ToolboxListModel(QtCore.QAbstractListModel):
def flags(self, index):
flags = super().flags(index)
if index.isValid():
flags |= QtCore.Qt.ItemFlags.ItemIsDragEnabled
return flags然后,根据您希望在目标模型上的行为,您可能需要覆盖标志来接受拖放到现有项上(以覆盖项),或者实现其他函数,如关于子类QAbstractListModel的文档所示,因为默认情况下它不支持可调整大小的列表。
https://stackoverflow.com/questions/73544611
复制相似问题