Ich habe zwei Widgets ParentWidget
und ChildWidget
beide abgeleitet von QWidget
und beide überschreiben void dragEnterEvent(QDragEnterEvent *event)
.Wie verwerfen Sie ein QEvent, anstatt es nur zu ignorieren
Jetzt ist ChildWidget
im ParentWidget
enthalten. Angenommen, ein bestimmter QDragEvent*
namens event
könnte für ParentWidget
gültig sein, aber nicht für ChildWidget
und angenommen, dass dragEnterEvent
für ChildWidget
aufgerufen wird.
Jetzt kann ich einfach event->ignore()
anrufen, um das Ereignis für ChildWidget
zu ignorieren, aber dann dragEnterEvent
für ParentWidget
heißt.
Und das ist mein Problem. Ich will nicht, dass dragEnterEvent
für ParentWidget
aufgerufen wird, wenn das Ereignis bereits in ChildWidget
verworfen wurde.
Einfach gesagt möchte ich nicht nur das Ereignis ignoriert werden, aber darüber hinaus muss das Ereignis vollständig innerhalb der dragEnterEvent
von ChildWidget
verworfen werden.
Wie kann ein solches Verhalten unter der Annahme erreicht werden, dass ParentWidget
und ChildWidget
lose gekoppelte Komponenten sind?
Minimal Beispiel
Das folgende Beispiel zeigt, was ich versuche zu erreichen ist und auch ein brauchbarer Ansatz in einem gewissen Sinne. Im Fall von komplizierteren Szenarien würde dies zu kompliziertem Code führen.
Die ChildWidget
akzeptiert Tropfen Dateinamen mit txt
enden, während die ParentWidget
alle Tropfen akzeptiert, außer den bereits von ChildWidget
ignoriert.
main.cpp
#include <QApplication>
#include "ParentWidget.h"
int main(int argc, char** args) {
QApplication app(argc, args);
auto widget=new ParentWidget;
widget->show();
app.exec();
}
ParentWidget.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();
}
}
};
Können Sie Ihre Implementierung zeigen? Sie können '' 'dragEnterEvent''' für' '' ChildWidget''' reimplementieren, weil es ein virtuelles –
@ThibautB ist. Ich habe 'dragEnterEvent' für beide Widgets,' ChildWidget' und 'ParentWidget' implementiert. Es ist nur so, dass sich 'dragEnterEvent' für' ParentWidget' anders verhalten sollte, wenn das Ereignis in 'dragEnterEvent' von' ChildWidget' ignoriert wurde. – Aleph0
@ThibautB. Kann 'QDragEnterEvent' diesen Boolean transportieren? – Aleph0