• 12817阅读
  • 3回复

[讨论]关于QTableView右键的一个问题及解决办法 [复制链接]

上一主题 下一主题
离线justwake
 

只看楼主 倒序阅读 楼主  发表于: 2013-10-12
要实现的功能是QTableview中Item项上右键弹出菜单
这就必然要判断点击右键时鼠标指针是否在QTableView的Item上


如果是QTableWidget可以用itemAt来判断
QTableView通过查看文档  发现有个indexAt函数  返回QModelIndex


  1. QModelIndex QTableView::indexAt(const QPoint & pos) const [virtual]
  2. Reimplemented from QAbstractItemView::indexAt().
  3. Returns the index position of the model item corresponding to the table item at position pos in contents coordinates.

于是通过如下代码判断鼠标右键单击的时候,鼠标指针是否在item上
  1. qDebug()<<ui->tableview->indexAt(ui->tableview->mapFromGlobal(QCursor::pos())).row();

可是发现一些问题:
当鼠标右键点击第一行的上边缘附近  返回0


点击第一行中间  返回1  


点击最后一行中间就返回  -1

也就是说 点击行A的上边缘附近 返回的是A的上一行
只有点击行A的中间返回的才是A行
并不是  indexAt函数所描述的那样返回的是当前行


最后发现问题出在:
indexAt函数根据QPoint判断行的时候 是没有把 QTableView的表头去掉的  (HoriziotalHeader和VerticalHeader)
所以   隐藏表头后  就一切正常了
如果不愿意隐藏表头  我是用如下代码 解决的:
  1. QPoint pt = ui->tableview->mapFromGlobal(QCursor::pos());
  2. int height = ui->tableview->horizontalHeader()->height();
  3. QPoint pt2(0,height);
  4. pt+=pt2;
  5. qDebug()<<ui->tableview->indexAt(pt).row();

现在debug输出就一切正常了(上面只是针对QtableView上面的horizontal表头不隐藏,如果竖直方向的也没隐藏,那么也要加上其宽度)。


以上就是我解决问题的过程。本来上图的 ,可是例子在家里面的电脑上,店里的电脑上没有Qt环境






离线liangwenkuai

只看该作者 1楼 发表于: 2014-05-29
你好,能不能把完整的代码贴出来,我也想实现这样一个。
离线donglaile

只看该作者 2楼 发表于: 2015-10-21
这样用没有问题耶
void contextMenuEvent(QContextMenuEvent *event)
{
    pop_menu->clear(); //清除原有菜单
    QPoint point = event->pos(); //得到窗口坐标
    QModelIndex curIndex =  this->indexAt(point);
    if(curIndex.row() == 0){//只要第一列数据弹出菜单
        pop_menu->addAction(action_insert);
        pop_menu->addAction(action_delete);
        pop_menu->addSeparator();
        pop_menu->addAction(action_copy);
        pop_menu->addAction(action_pause);
        pop_menu->addSeparator();

        //菜单出现的位置为当前鼠标的位置
        pop_menu->exec(QCursor::pos());
        event->accept();
    }
}
离线smooth_zyn

只看该作者 3楼 发表于: 2015-10-22
支持楼主,懂的分享。
快速回复
限100 字节
 
上一个 下一个