Прежде всего, название вашего проекта является ошибкой. Пространство имен с префиксом Q
занято. Вы не должны иметь никаких классов с префиксом Q
ни в одном проекте, использующем Qt. Вы должны переименовать проект, например, в DataflowCanvas
.
Существует три решения:
Держите всех детей по значению, упорядочите детей в соответствии с их зависимостями. QWidgetPrivate::deleteChildren
, вызываемый с QDataFlowCanvas
, будет неактивным, или, по крайней мере, он не будет касаться объектов, которые вас интересуют.
Используйте старый синтаксис connect
при подключении к слоту MainWindow::onSelectionChanged
. Обратите внимание, что когда ваш слот был вызван, объект главного окна имел динамический тип QWidget
, а не тип MainWindow
. Соединения, сделанные с использованием старого синтаксиса соединения , соответствуют динамическому типу объекта , а подключение к слоту данного класса гарантирует, что объект этого класса динамически , т.е. во время выполнения.
Очистить выделение в деструкторе - тогда дальнейшие изменения выделения не будут обрабатываться.
Первое решение делает все явным и это то, что я бы использовал:
class DataFlowCanvas : public QGraphicsView {
...
private:
QDataflowModel *model_;
QDataflowTextCompletion *completion_;
QSet<QDataflowNode*> ownedNodes_;
QSet<QDataflowConnection*> ownedConnections_;
QMap<QDataflowModelNode*, QDataflowNode*> nodes_;
QMap<QDataflowModelConnection*, QDataflowConnection*> connections_;
bool showIOletsTooltips_;
bool showObjectHoverFeedback_;
bool showConnectionHoverFeedback_;
qreal gridSize_;
bool drawGrid_;
QGraphicsSecene scene_;
};
Сцена разрушена перед любыми другими полями. Задача решена. Вы должны также хранить все остальное по значению. Например. completion_
и т. Д. Указатели на указатели бесполезны.
Второе решение подчеркивает неудачную ошибку Qt. В приведенном ниже коде старый синтаксис подключения никогда не будет вызывать Derived2::aSlot2
, поскольку во время вызова слота объект больше не относится к типу Derived2
:
#include <QtCore>
int ctr1, ctr2;
struct Derived1 : QObject {
Q_SLOT void aSlot1() { ctr1++; qDebug() << __FUNCTION__; }
Q_SIGNAL void aSignal();
~Derived1() { Q_EMIT aSignal(); }
Q_OBJECT
};
struct Derived2 : Derived1 {
Q_SLOT void aSlot2() { ctr2++; qDebug() << __FUNCTION__ << qobject_cast<Derived2*>(this); }
Q_OBJECT
};
int main() {
{
Derived2 d;
QObject::connect(&d, &Derived2::aSignal, &d, &Derived2::aSlot2);
QObject::connect(&d, SIGNAL(aSignal()), &d, SLOT(aSlot2()));
QObject::connect(&d, SIGNAL(aSignal()), &d, SLOT(aSlot1()));
}
Q_ASSERT(ctr1 == 1);
Q_ASSERT(ctr2 == 1);
}
#include "main.moc"
Вывод ясно демонстрирует проблему:
aSlot2 QObject(0x0) <-- aSlot2 called but `this` is of `Derived1*` type!
aSlot1