我有两个小部件ParentWidget
,它们都是ChildWidget
从.QWidget
void dragEnterEvent(QDragEnterEvent *event)
现在ChildWidget
包含在ParentWidget
. 现在假设某个QDragEvent*
被调用event
可能对 有效ParentWidget
,但对 无效,ChildWidget
并假设dragEnterEvent
forChildWidget
被调用。
现在我可以调用event->ignore()
以忽略事件 for ChildWidget
,但随后调用dragEnterEvent
for ParentWidget
。
这是我的问题。我不希望,dragEnterEvent
如果ParentWidget
事件已经在ChildWidget
.
简单地说,我只是不希望事件被忽略,而且事件需要在dragEnterEvent
of中完全丢弃ChildWidget
。
假设ParentWidget
和ChildWidget
是松散耦合的组件,如何实现这样的行为?
最小的例子
以下示例显示了我想要实现的目标,并且在某种意义上也是一种可行的方法。在更复杂的情况下,它会导致代码过于复杂。
ChildWidget
接受以 结尾的文件名txt
,而接受ParentWidget
所有丢弃,除了已经被 忽略的那些ChildWidget
。
主文件
#include <QApplication>
#include "ParentWidget.h"
int main(int argc, char** args) {
QApplication app(argc, args);
auto widget=new ParentWidget;
widget->show();
app.exec();
}
父小部件.h
#pragma once
#include <QWidget>
#include <QDebug>
#include <QDragEnterEvent>
#include <QHBoxLayout>
#include <QLabel>
#include "ChildWidget.h"
class ParentWidget : public QWidget {
Q_OBJECT
public:
ParentWidget(QWidget* parent = nullptr) : QWidget(parent) {
setLayout(new QHBoxLayout);
setAcceptDrops(true);
layout()->addWidget(new QLabel("ParentLabel"));
layout()->addWidget(new ChildWidget);
}
void dragEnterEvent(QDragEnterEvent *event) override {
qDebug() << "Parent";
// Check if event was already ignored in ChildWidget?
if (auto childWidget = qobject_cast<ChildWidget*>(childAt(event->pos()))) {
event->ignore();
}
else {
event->acceptProposedAction();
}
}
};
ChildWidget.h
#pragma once
#include <QWidget>
#include <QUrl>
#include <QMimeData>
#include <QDragEnterEvent>
#include <QLabel>
#include <QDebug>
#include <QByteArray>
#include <QHBoxLayout>
class ChildWidget : public QWidget {
Q_OBJECT
public:
ChildWidget(QWidget* parent = nullptr) : QWidget(parent) {
setAcceptDrops(true);
setLayout(new QHBoxLayout);
layout()->addWidget(new QLabel("ChildLabel"));
}
void dragEnterEvent(QDragEnterEvent *event) override {
qDebug() << "Child";
if (auto mimeData=event->mimeData()) {
auto url = QUrl(mimeData->text());
if (!url.isValid()) { event->ignore(); return; }
if (!url.isLocalFile()) { event->ignore(); return; }
auto filename = url.fileName();
if (!filename.endsWith(".txt")) { event->ignore(); return; }
// ChildWidget can only process txt files.
qDebug() << url.fileName();
event->acceptProposedAction();
}
else {
event->ignore();
}
}
};