转载: 问题:如何实现在一个列表中点击右键,如果在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上。上面的代码菜单是没有功能的。 |
|