|
轉(zhuǎn)載: 問題:如何實現(xiàn)在一個列表中點擊右鍵,如果在Item上面,則有“修改”選項,在其余空白處,則只有“添加”,"刪除"選項。 實現(xiàn)右鍵菜單, 從QListWidget中派生出ListWidget,重寫 void QWidget::contextMenuEvent ( QContextMenuEvent * event ) [virtual protected] 當鼠標在ListWidget中右擊時,就會調(diào)用這個事件。 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()); // 菜單出現(xiàn)的位置為當前鼠標的位置 } 在程序中使用ListWidget,當鼠標在之上右擊時, 就會出現(xiàn)如上代碼中的菜單,但是無論右擊何處,都會相出現(xiàn)相同的選項。顯然,在空白處的右鍵菜單上面不應(yīng)該出現(xiàn)"修改"選項,不然修改的是那一個??? 問題的關(guān)鍵就是判定調(diào)用右鍵菜單時,鼠標右擊的位置處是不是一個Item。那么實現(xiàn)的代碼應(yīng)該是這樣的: 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()); // 菜單出現(xiàn)的位置為當前鼠標的位置 } 如何才能判定鼠標右擊時,是否是在一個Item上面呢?可愛的Qt很容易實現(xiàn)。 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). 以上兩個重載的函數(shù),就是如何利用坐標位置獲取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()); // 菜單出現(xiàn)的位置為當前鼠標的位置 } 寫好上面的代碼,咦?還是不行?呵呵,我這里也不行。因為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()); // 菜單出現(xiàn)的位置為當前鼠標的位置 } OK, 功能實現(xiàn)。記得在自己的代碼總要把QAction連接到處理的slot上。上面的代碼菜單是沒有功能的。 |
|
|