2016-08-31 4 views
1

사용자 정의 컨텍스트 메뉴를 표 위에 표시 할 수 있습니다. 이 메뉴는 대상 위젯을 허용하고 조정하는 일반적인 기능을 사용하여 생성되는 방법입니다QMenu 컨텍스트 메뉴를 적절히 삭제하는시기와 방법은 무엇입니까?

#include <QMenu> 
void MainWindow::makeContextMenu(const QPoint& pos, QWidget* target) 
{ 
    QMenu *menu = new QMenu(this); 
    menu->addAction(new QAction("Action 1", menu)); 
    menu->addAction(new QAction("Action 2", menu)); 
    menu->addAction(new QAction("Action 3", menu)); 
    // Notify window about clicking 
    QObject::connect(menu, &QMenu::triggered, this, &MainWindow::menuClicked); 
    // If this is a scroll area, map coordinates to real app coordinates 
    if(QAbstractScrollArea* area = dynamic_cast<QAbstractScrollArea*>(target)) 
     menu->popup(area->viewport()->mapToGlobal(pos)); 
    else 
     menu->popup(pos); 
} 

문제는 QMenu* menu 파괴하지 않고 메모리에서 제거됩니다 않을 것입니다. 숨겨진 후에도 MainWindow의 자식으로 지속됩니다.

어떻게해야합니까? 나 자신을 지울 수있는 메뉴를 설정할 수 있습니까? 또는 메뉴의 동일한 인스턴스를 다시 사용해야합니까 아니면 같은 포인터에 저장할 수 있습니까?

답변

3

코드에서이 이벤트가 발생한 후 menu을 삭제해야합니다.

// Notify window about clicking 
QObject::connect(menu, &QMenu::triggered, this, &MainWindow::menuClicked); 

나는 자체를 삭제 메뉴를 설정할 수 있습니까?

예,이 같은 객체 delete itself을 가질 수

당신이 호출되고 그 슬롯의 순서에 대해 고민하는 경우에
// Notify window about clicking 
QObject::connect(menu, &QMenu::triggered, this, &MainWindow::menuClicked); 
QObject::connect(menu, &QMenu::triggered, menu, &QMenu::deleteLater); 

this


를 참조하거나해야 메뉴의 동일한 인스턴스를 다시 사용하거나 동일한 포인터에 저장할 수 있습니까? 의 정리

글쎄, 당신은 MainWindow::~MainWindow() 소멸자에 관해서는

//Your constructor 
MainWindow::MainWindow(....) 
{ 
    menu = nullptr; 
    .... 
} 

//Make context Menu 
void MainWindow::makeContextMenu(const QPoint& pos, QWidget* target) 
{ 
    if(menu) 
     delete menu; 
    menu = new QMenu(this); 
    .... 
} 

과 같은 작업을 수행 할 수 있습니다, 그것은 '는 menu의 처리됩니다. (A QObject 파생 클래스가) MainWindowautomatically deletes 모든 어린이


마지막으로, 당신은 단순히 MainWindow의 구성원으로 menu을 가질 수 있습니다, 당신은 menu 신선한 행동을해야 할 때마다, 당신은에 QMenu::clear를 사용할 수 있기 때문에 기존의 모든 작업을 삭제하십시오.

//Your constructor 
MainWindow::MainWindow(....) 
{ 
    menu = new QMenu(this); 
    .... 
} 

void MainWindow::makeContextMenu(const QPoint& pos, QWidget* target) 
{ 
    menu->clear(); 
    //QMenu *menu = new QMenu(this); 
    menu->addAction(new QAction("Action 1", menu)); 
    menu->addAction(new QAction("Action 2", menu)); 
    menu->addAction(new QAction("Action 3", menu)); 
    // Notify window about clicking 
    QObject::connect(menu, &QMenu::triggered, this, &MainWindow::menuClicked); 
    // If this is a scroll area, map coordinates to real app coordinates 
    if(QAbstractScrollArea* area = dynamic_cast<QAbstractScrollArea*>(target)) 
     menu->popup(area->viewport()->mapToGlobal(pos)); 
    else 
     menu->popup(pos); 
} 
+0

귀하의 제안을 발견해도 문제가 해결되지 않았습니다. 이것은 사용자가 메뉴의 특정 항목을 클릭 할 필요가 없기 때문입니다 ... –

+0

@ TomášZato, 그래서, 당신은'& QMenu :: triggered'가 항상 발생하지 않는다고 말하고 있습니까? .... 그 경우 두 번째 및 세 번째 옵션은 무엇입니까? – WhiZTiM

+0

마지막 변수 옵션으로 만 일부 변수에 메뉴를 유지하는 것을 고려했습니다. 특히 그 메뉴는 항상 한 번만 표시됩니다. QMessageBox와 같이 사라지면 삭제 된 것이 더 좋을 것입니다. –

0

이 숨겨진 경우 QMenu을 삭제할 수 있습니다. 그 목적을 위해 이벤트 필터 클래스를 디자인했습니다 :

#ifndef DELETEONHIDEFILTER_H 
#define DELETEONHIDEFILTER_H 

#include <QObject> 
#include <QEvent> 

class DeleteOnHideFilter : public QObject 
{ 
     Q_OBJECT 
    public: 
     explicit DeleteOnHideFilter(QObject *parent = 0) : QObject(parent) {} 

    protected slots: 
     bool eventFilter(QObject *obj, QEvent *event) override { 
      if(event->type() == QEvent::Hide) { 
       obj->deleteLater(); 
      } 
      return false; 
     } 
}; 

#endif // DELETEONHIDEFILTER_H 

다른 개체에도 사용할 수 있습니다.

관련 문제