2016-08-31 17 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を持つことができます:あなたが呼び出されているそれらのスロットの順序を心配している場合は、this


あるいはすべきを参照してください

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

私はメニューの同じインスタンスを再利用するか、同じ ポインタに保存しますか?

さて、あなたは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); 
    .... 
} 

ような何かを行うことができ、それはsがクリーンアップmenu」の世話をします。 (QObject派生クラスである)MainWindowautomatically deletesすべての子供たち


最後に、あなたは単にMainWindowのメンバーとしてmenuを持つことができ、あなたがmenu新鮮な作用を有することが必要なとき、あなたがするQMenu::clearを使用することができますので、既存のアクションをすべて削除します。

+0

あなたの提案が問題を解決しないことがわかりました。これは、ユーザーがメニュー内の特定の項目をクリックする必要がないためです。 –

+0

@TomášZato、そう、あなたは '&QMenu :: triggered'が必ずしも発生していないと言っていますか? ....その場合、2番目と3番目のオプションはどうですか? – WhiZTiM

+0

私はいくつかの変数のメニューを最後の手段としてのみ使うことを考えました。特に、そのメニューだけが常に1回だけ表示されます。しかし、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 

これは他のオブジェクトにも使用できます。

関連する問題