@Mercury13
Программист на «си с крестами» и не только

Qt: кто владеет createStandardContextMenu() и как его уничтожать?

Вот такой код падает, если вызвать то самое acAddNote (который, в свою очередь, вызывает модальный диалог).
QSharedPointer<QMenu> menu { tableDelegate.editor()->createStandardContextMenu() };
    menu->addSeparator();
    acAddNote->setText(STR_ADDNOTE);
    menu->addAction(acAddNote);
    menu->exec(tableDelegate.editor()->mapToGlobal(point));


Код вызывается из слота, привязанного к QLineEdit::customContextMenuRequested. А QLineEdit — редактор в таблице; вот такая у нас утка в зайце. Разумеется, где-то посреди exec’а редактор исчезает, возможно, унося с собой часть объектов.

Если вместо QSharedPointer поставить простой указатель QMenu*, полный порядок, но не «течёт» ли память?

Документация говорит, что «The popup menu's ownership is transferred to the caller». Ко мне вечно обращаются с толкованием правил настольных игр, но я этого не могу растолковать — по-моему, кто вызвал, тот и уничтожает.

Что делать? Кто владеет этим меню и как его уничтожать?
  • Вопрос задан
  • 243 просмотра
Решения вопроса 1
@Mercury13 Автор вопроса
Программист на «си с крестами» и не только
Исходники Qt говорят: владелец — редактор.
02405 #endif
02406     d->actions[QLineEditPrivate::ClearAct]->setEnabled(!d->readOnly && !d->text.isEmpty() && d->hasSelectedText());
02407     d->actions[QLineEditPrivate::SelectAllAct]->setEnabled(!d->text.isEmpty() && !d->allSelected());
02408 
02409     QMenu *popup = new QMenu(this);
02410     popup->setObjectName(QLatin1String("qt_edit_menu"));
02411     popup->addAction(d->actions[QLineEditPrivate::UndoAct]);
02412     popup->addAction(d->actions[QLineEditPrivate::RedoAct]);
02413     popup->addSeparator();

Ну разумеется. Хотя причиной оказался механизм signal-slot — во время обработки сигнала исчез его инициатор! Объясню вкратце, что пришлось сделать.
1. От греха подальше действие создавал каждый раз новое, владелец — меню.
2. Как только вызывается действие, владение меню переносится в другое место.
3. После exec() меню уничтожается без всяких условий.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы