實現右鍵菜單

來源:互聯網
上載者:User

 

 

一直潛水,現在貼點東東,希望能協助大家。http://blog.chinaunix.net/u3/103355/showart_2101288.html

作者:wangxinus, <wangxinus@gmail.com>
來源:http://wangxinus.cublog.cn
說明:原創文章歡迎轉載,交流請Email給作者

關於右鍵菜單的實現,可以參考另一篇我轉載的文章,在QT中添加右鍵菜單。

問題:如何?在一個列表中點擊右鍵,如果在Item上面,則有“修改”選項,在其餘空白處,則只有“添加”,"刪除"選項。

實現右鍵菜單, 從QListWidget中派生出ListWidget,重寫
void QWidget::contextMenuEvent ( QContextMenuEvent * event )   [virtual protected]
當滑鼠在ListWidget中右擊時,就會調用這個事件。
void ListWidget::contextMenuEvent ( QContextMenuEvent * event )
{
    QMenu* popMenu = new QMenu(this);
    popMenu->addAction(new QAction("添加", this));
    popMenu->addAction(new QAction("刪除", this));
    popMenu->addAction(new QAction("修改", this));
  
    popMenu->exec(QCursor::pos()); // 菜單出現的位置為當前滑鼠的位置
}

在程式中使用ListWidget,當滑鼠在之上右擊時, 就會出現如上代碼中的菜單,但是無論右擊何處,都會相出現相同的選項。顯然,在空白處的右鍵菜單上面不應該出現"修改"選項,不然修改的是那一個???

問題的關鍵就是判定調用右鍵菜單時,滑鼠右擊的位置處是不是一個Item。那麼實現的代碼應該是這樣的:
void ListWidget::contextMenuEvent ( QContextMenuEvent * event )
{
    QMenu* popMenu = new QMenu(this);
    popMenu->addAction(new QAction("添加", this));
    popMenu->addAction(new QAction("刪除", this));
    if(currentMousePosHasAItem())
    {
        popMenu->addAction(new QAction("修改", this));
    }
  
    popMenu->exec(QCursor::pos()); // 菜單出現的位置為當前滑鼠的位置
}
如何才能判定滑鼠右擊時,是否是在一個Item上面呢?可愛的Qt很容易實現。

QListWidgetItem * QListWidget::itemAt ( const QPoint & p ) const
Returns a pointer to the item at the coordinates p.

QListWidgetItem * QListWidget::itemAt ( int x, int y ) const
This is an overloaded member function, provided for convenience.
Returns a pointer to the item at the coordinates (x, y).

以上兩個重載的函數,就是如何利用座標位置擷取item,如何返回的 NULL, 那麼就沒有Item。
void ListWidget::contextMenuEvent ( QContextMenuEvent * event )
{
    QMenu* popMenu = new QMenu(this);
    popMenu->addAction(new QAction("添加", this));
    popMenu->addAction(new QAction("刪除", this));
    if(this->itemAt(QCursor::pos()) != NULL) //如果有item則添加"修改"菜單 [1]*
    {
        popMenu->addAction(new QAction("修改", this));
    }
  
    popMenu->exec(QCursor::pos()); // 菜單出現的位置為當前滑鼠的位置
}

寫好上面的代碼,咦?還是不行?呵呵,我這裡也不行。因為itemAt()中接受的座標是ListWidget座標系的。而通過QCursor::pos()獲得座標是全域座標。需要映射到ListWidget上才可以,Qt Assist中是這樣描述的。
QPoint QCursor::pos ()   [static]
Returns the position of the cursor (hot spot) in global screen coordinates.
You can call QWidget::mapFromGlobal() to translate it to widget coordinates.
See also setPos(), QWidget::mapFromGlobal(), and QWidget::mapToGlobal().

所以最終的代碼是:
void ListWidget::contextMenuEvent ( QContextMenuEvent * event )
{
    QMenu* popMenu = new QMenu(this);
    popMenu->addAction(new QAction("添加", this));
    popMenu->addAction(new QAction("刪除", this));
    if(this->itemAt(mapFromGlobal(QCursor::pos())) != NULL) //如果有item則添加"修改"菜單 [1]*
    {
        popMenu->addAction(new QAction("修改", this));
    }
  
    popMenu->exec(QCursor::pos()); // 菜單出現的位置為當前滑鼠的位置
}

OK, 功能實現。記得在自己的代碼總要把QAction串連到處理的slot上。上面的代碼菜單是沒有功能的

本文來自CSDN部落格,轉載請標明出處:http://blog.csdn.net/nowgoant/archive/2011/05/06/6398993.aspx

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.