[英]Why drag&drop does not called dropEvent?
我想沒有人知道這件事。 同一個問題問了兩天,沒人回答。
我找到了一個關於拖放的 toDoList 項目。 我想知道我能得到拖放的項目嗎? 我正在閱讀文檔 2 天。 我實施這些方法。
protected:
void dragEnterEvent( QDragEnterEvent *anEvent ) override;
void dragMoveEvent( QDragMoveEvent *anEvent ) override;
void dragLeaveEvent( QDragLeaveEvent *anEvent ) override;
void dropEvent( QDropEvent *anEvent ) override;
有 2 個列表視圖和工具欄。 我將添加和刪除添加到工具欄。
我可以拖放,但我無法獲取拖動項目的文本。 這是主要代碼。 我真的很想知道,我們是否正確地覆蓋了方法。 但是我們沒有將方法與某事聯系起來。 該方法如何工作?
todolist::todolist(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::todolist)
{
QWidget* pWidget = new QWidget(this);
pWidget->setStyleSheet("background-color: #ECF0F1");
setCentralWidget(pWidget);
QVBoxLayout* pMainLayout = new QVBoxLayout();
pWidget->setLayout(pMainLayout);
QLabel* pwTitle = new QLabel("To Do List", this);
pMainLayout->addWidget(pwTitle);
pwTitle->setAlignment(Qt::AlignCenter);
pwTitle->setStyleSheet("font-size: 30pt; margin: 10%;");
QHBoxLayout* pHLayoutLabels = new QHBoxLayout();
pMainLayout->addLayout(pHLayoutLabels);
QLabel* plblPending = new QLabel("Pending", this);
plblPending->setStyleSheet("font-size: 15pt;");
pHLayoutLabels->addWidget(plblPending);
QLabel* plblCompleted = new QLabel("Completed", this);
plblCompleted->setStyleSheet("font-size: 15pt;");
pHLayoutLabels->addWidget(plblCompleted);
QHBoxLayout* pHLayout = new QHBoxLayout();
pMainLayout->addLayout(pHLayout);
m_pwPending = new QListView(this);
m_pwPending->setDragEnabled(true);
m_pwPending->setAcceptDrops(true);
m_pwPending->setDropIndicatorShown(true);
m_pwPending->setDefaultDropAction(Qt::MoveAction);
pHLayout->addWidget(m_pwPending);
m_pwCompleted = new QListView(this);
m_pwCompleted->setDragEnabled(true);
m_pwCompleted->setAcceptDrops(true);
m_pwCompleted->setDropIndicatorShown(true);
m_pwCompleted->setDefaultDropAction(Qt::MoveAction);
pHLayout->addWidget(m_pwCompleted);
m_pwPending->setModel(new QStringListModel());
m_pwCompleted->setModel(new QStringListModel());
m_pwPending->setStyleSheet
("QListView { font-size: 20pt; font-weight: bold; }"
"QListView::item { background-color: #E74C3C; padding: 10%;"
"border: 1px solid #C0392B; }"
"QListView::item::hover { background-color: #C0392B }");
m_pwCompleted->setStyleSheet
("QListView { font-size: 20pt; font-weight: bold; }"
"QListView::item { background-color: #2ECC71; padding: 10%;"
"border: 1px solid #27AE60; }"
"QListView::item::hover { background-color: #27AE60 }");
QToolBar* pToolBar = new QToolBar(this);
addToolBar(pToolBar);
m_pActAdd = new QAction(this);
m_pActAdd->setIcon(QIcon(":/resources/add.png"));
connect(m_pActAdd, &QAction::triggered, this, &todolist::onAdd);
m_pActRemove = new QAction(this);
m_pActRemove->setIcon(QIcon(":/resources/remove.png"));
connect(m_pActRemove, &QAction::triggered, this, &todolist::onRemove);
pToolBar->addAction(m_pActAdd);
pToolBar->addAction(m_pActRemove);
setAcceptDrops(true);
}
void todolist::onAdd()
{
m_pwPending->model()->insertRow(m_pwPending->model()->rowCount());
QModelIndex oIndex = m_pwPending->model()->index(
m_pwPending->model()->rowCount() - 1, 0);
m_pwPending->edit(oIndex);
}
void todolist::onRemove()
{
QModelIndex oIndex = m_pwPending->currentIndex();
m_pwPending->model()->removeRow(oIndex.row());
}
void todolist::dropEvent(QDropEvent* event) {
const QMimeData* mimeData = event->mimeData();
QString temp;
if(mimeData->hasText()) {
temp = mimeData->text();
}
QMessageBox::information(this,"x",temp);
}
void todolist::dragEnterEvent(QDragEnterEvent *anEvent)
{
anEvent->setAccepted(true);
}
void todolist::dragMoveEvent(QDragMoveEvent *anEvent)
{
}
void todolist::dragLeaveEvent(QDragLeaveEvent *anEvent)
{
}
todolist::~todolist()
{
delete ui;
}
QMimeData* ListModel::mimeData(const QModelIndexList& qMIndices) const {
QMimeData* const pQMimeData = new QMimeData;
QString qText;
for (const QModelIndex& qMIndex : qMIndices) {
qText += data(qMIndex, Qt::DisplayRole).toString() + "\n";
}
pQMimeData->setText(qText);
std::cout << "1" << std::endl;
draggedData = qText;
return pQMimeData;
}
draggedData = qText; 此行會引發錯誤。
我使用了推薦的網站Qt Doc。 - 模型/視圖編程 - 使用拖放和項目視圖來編織一個小的示例應用程序,以滿足 OP 的要求。
我的 MCVE testQListViewDragNDrop.cc
:
#include <QtWidgets>
class ListModel: public QStringListModel {
public:
using QStringListModel::QStringListModel;
protected:
// for drag site
// encodes dragged items (different from default).
virtual QMimeData* mimeData(const QModelIndexList& qMIndices) const override;
// for drop site
// returns which kind of drop actions are supported.
virtual Qt::DropActions supportedDropActions() const override
{
return Qt::MoveAction;
}
// checks whether certain dragged MIME data is droppable.
virtual bool canDropMimeData(
const QMimeData* pQMimeData, // dragged data
Qt::DropAction action, // not evaluated
int row, // not evaluated
int column, // uninteresting for lists (but relevant for tables and trees)
const QModelIndex& qMIndex) // uninteresting for lists (but relevant for trees)
const override
{
return pQMimeData->hasText();
}
// drops dragged MIME data into model.
virtual bool dropMimeData(
const QMimeData* pQMimeData, // dropped data
Qt::DropAction action, // not evaluated
int row, // where to insert
int column, // uninteresting for lists (but relevant for tables and trees)
const QModelIndex& qMIndex) // uninteresting for lists (but relevant for trees)
override;
};
QMimeData* ListModel::mimeData(const QModelIndexList& qMIndices) const
{
QMimeData* const pQMimeData = new QMimeData;
QString qText;
for (const QModelIndex& qMIndex : qMIndices) {
qText += data(qMIndex, Qt::DisplayRole).toString() + "\n";
}
pQMimeData->setText(qText);
return pQMimeData;
}
bool ListModel::dropMimeData(
const QMimeData* pQMimeData, Qt::DropAction action,
int row, int, const QModelIndex& qMIndex)
{
// get text from mime data
const QString qText = pQMimeData->text().trimmed();
if (qText.isEmpty()) return true;
// split text into lines
const QStringList qLines = qText.split(QChar('\n'));
const int n = qLines.size();
// fix row
if (qMIndex.isValid()) row = qMIndex.row(); // dropped on row
if (row < 0 || row > rowCount()) row = rowCount();
// insert list into list model
if (insertRows(row, n)) {
for (const QString& qLine : qLines) {
setData(index(row, 0), qLine);
}
}
// done
return true;
}
QStringList makeSampleData()
{
QStringList qList;
qList
<< "Read the Qt doc."
<< "Write CMakeLists.txt"
<< "Write testQListViewDragNDrop.cc"
<< "Test and Debug"
<< "Fix bugs"
<< "Test and Debug"
<< "Fix bugs"
<< "Test and Debug"
<< "Fix bugs"
<< "Test and Debug"
<< "Fix bugs"
<< "Test and Debug"
<< "Fix bugs"
<< "Write SO answer";
return qList;
}
int main(int argc, char** argv)
{
QApplication app(argc, argv);
// setup GUI
QWidget qWinMain;
qWinMain.setWindowTitle("Test QListView Drag & Drop");
qWinMain.resize(640, 480);
QGridLayout qGrid;
qGrid.addWidget(new QLabel("<b>To Do</b>"), 0, 0);
qGrid.addWidget(new QLabel("<b>Done</b>"), 0, 1);
qGrid.setRowStretch(1, 1);
QListView qListToDo; // drag site
ListModel qListModelToDo;
qListModelToDo.setStringList(makeSampleData());
qListToDo.setModel(&qListModelToDo);
qListToDo.setDragEnabled(true); // allow drag in ToDo list
qGrid.addWidget(&qListToDo, 1, 0);
QListView qListDone; // drop site
ListModel qListModelDone;
qListDone.setModel(&qListModelDone);
qListDone.viewport()->setAcceptDrops(true); // allow drops
qListDone.setDropIndicatorShown(true); // adjust drop indicator
qGrid.addWidget(&qListDone, 1, 1);
qWinMain.setLayout(&qGrid);
qWinMain.show();
// run-time loop
return app.exec();
}
演示 Session:
筆記:
QListView
,但必須配置 Drag 和 Drop。 因此,與我的示例代碼相比,可以將QListView
配置為拖放。dragEnterEvent()
(或公司)。 這些事件已經在QListView
中被覆蓋,並咨詢相應的 model 以獲得拖放支持。QStringListModel
一起使用。 我派生QStringListModel
來演示如何自定義拖放。mimeData()
、 canDropMimeData()
和dropMimeData()
也不是必需的。 即使沒有它們,拖放也可以工作。 (我在添加它們之前對此進行了測試。)我不知道使用什么 MIME 數據來傳達拖動的內容。 由於在我的示例中拖放站點和拖放站點是相同的小部件 class,因此可以拖放拖動的數據(但它存儲在內部)也就不足為奇了。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.