QListWidget的item上實現右鍵選單
阿新 • • 發佈:2019-01-25
。
問題:如何實現在一個列表中點選右鍵,如果在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上。上面的程式碼選單是沒有功能的。
問題:如何實現在一個列表中點選右鍵,如果在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上。上面的程式碼選單是沒有功能的。