[英]PySide QlistView drag and drop
我正在嘗試使用 PySide6 實現從一個 QListView 到另一個 QListView 的簡單拖放功能。
這是用戶界面:
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 設置為接受放置,拖動操作甚至都不會開始。
我在這里做錯了什么? 如何正確進行 d'n'd 操作?
正如model 查看文檔(我強烈建議您完整閱讀)中解釋的那樣,您必須覆蓋flags()
function,因為默認行為只會啟用和選擇項目。
在視圖上設置Drag
標志只允許拖動操作,但只有 model 可以告訴哪些項目可以拖動。
如果要允許索引可拖動,還必須提供ItemIsDragEnabled
標志:
class ToolboxListModel(QtCore.QAbstractListModel):
def flags(self, index):
flags = super().flags(index)
if index.isValid():
flags |= QtCore.Qt.ItemFlags.ItemIsDragEnabled
return flags
然后,根據您希望在目標 model上的行為,您可能需要覆蓋標志以接受對現有項目的拖放(以覆蓋項目),或實現其他功能,如有關子類化 QAbstractListModel的文檔中所示,因為它不支持默認情況下可調整大小的列表。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.