Qt:TableWidget的ItemAt()表现异常

4
我正在开发一个Windows应用程序,在对话框中从Postgres查询一些数据,然后手动在表格部件中显示输出。
m_ui->tableWidget->setRowCount(joinedData.count());
for(int i=0; i<joinedData.count(); i++) //for each row
{
        m_ui->tableWidget->setItem(i, 0, new QTableWidgetItem(joinedData[i].bobin.referenceNumber));
        m_ui->tableWidget->setItem(i, 1, new QTableWidgetItem(QString::number(joinedData[i].bobin.width)));
        m_ui->tableWidget->setItem(i, 2, new QTableWidgetItem(QString::number(joinedData[i].tolerance.getHole())));
        m_ui->tableWidget->setItem(i, 3, new QTableWidgetItem(QString::number(joinedData[i].tolerance.getLessThanZeroFive())));                      m_ui->tableWidget->setItem(i, 4, new QTableWidgetItem(QString::number(joinedData[i].tolerance.getZeroFive_to_zeroSeven())));
        m_ui->tableWidget->setItem(i, 5, new QTableWidgetItem(QString::number(joinedData[i].tolerance.getZeroFive_to_zeroSeven_repetitive())));
        m_ui->tableWidget->setItem(i, 6, new QTableWidgetItem(QString::number(joinedData[i].tolerance.getZeroSeven_to_Three())));
        m_ui->tableWidget->setItem(i, 7, new QTableWidgetItem(QString::number(joinedData[i].tolerance.getThree_to_five())));
        m_ui->tableWidget->setItem(i, 8, new QTableWidgetItem(QString::number(joinedData[i].tolerance.getMoreThanFive())));
 }

另外,根据行列信息,我会将一些tablewidgetitems涂上不同的颜色,但我认为这并不重要。

我重新实现了QDialog的contextMenuEvent函数,以获取右键单击的tableWidgetItem的行列坐标:

void BobinFlanView::contextMenuEvent(QContextMenuEvent *event)
{
    QMenu menu(m_ui->tableWidget);
    //standard actions
    menu.addAction(this->markInactiveAction);
    menu.addAction(this->markActiveAction);
    menu.addSeparator();
    menu.addAction(this->exportAction);
    menu.addAction(this->exportAllAction);

    //obtain the rightClickedItem
    QTableWidgetItem* clickedItem = m_ui->tableWidget->itemAt(m_ui->tableWidget->mapFromGlobal(event->globalPos()));



    // if it's a colored one, add some more actions
    if (clickedItem && clickedItem->column()>1 && clickedItem->row()>0)
    {
        //this is a property, i'm keeping this for a later use
        this->lastRightClickedItem = clickedItem; 
        //debug purpose:
        QMessageBox::information(this, "", QString("clickedItem = %1, %2").arg(clickedItem->row()).arg(clickedItem->column()));
        QMessageBox::information(this, "", QString("globalClick = %1, %2\ntransformedPos = %3, %4").arg(event->globalX()).arg(event->globalY())
                                 .arg(m_ui->tableWidget->mapFromGlobal(event->globalPos()).x()).arg(m_ui->tableWidget->mapFromGlobal(event->globalPos()).y()));

        menu.addSeparator();

        menu.addAction(this->changeSelectedToleranceToUygun);
        menu.addAction(this->changeSelectedToleranceToUyar);
        menu.addAction(this->changeSelectedToleranceToDurdurUyar);

        //... some other irrevelant 'enable/disable' activities

    menu.exec(event->globalPos());
}

问题是,当我右键单击同一项时,我得到相同的全局坐标,但行列信息随机不同。例如,全局位置确切为600,230,但行列对为(5,3)和(4,3)。我的意思是,这是什么鬼?
此外,如果我从最后两行(超过13行)中点击一个项目,它永远不会满足“if (clickedItem && clickedItem->column() > 1 && clickedItem->row() > 0)” 的条件,我认为主要是因为“clickedItem”为空。
我将非常乐意分享任何更多信息,甚至是完整的cpp-h-ui三合一以获得帮助。
非常感谢。
2个回答

5

试试这个:

QTableWidgetItem* clickedItem = m_ui->tableWidget->itemAt(event->pos());

问题在于您试图将全局位置映射到表格小部件位置,而没有考虑可滚动区域。要将全局位置映射为可以传递给itemAt的内容,请使用tableWidget->viewport()->mapFromGlobal

1
我来这里感谢Lukáš Lalinský,他的解释为我结束了半天的痛苦。
在我的情况下,当使用QDropEvent::pos()作为参数给itemAt()时,它会返回表格行中偏移1的项目。
原因是我有一个水平标题,它缩小了视口,垂直标题也一样,但由于很窄,我没有意识到它也会导致偏移。 修复方法是调用QTableWidget的viewport()->mapFromParent( [drop pos] ),因为位置已经在QTableWidget坐标系中了。
再次感谢!

感谢他人最好的方式就是接受答案并为有帮助的答案投票。 - sirandy
谢谢提醒,我已经点赞了,但由于我在这里还是新手,我的声音对官方答案评分没有贡献。至于接受答案——这是给原帖作者的,不是吗? - raverman
是的,这是给他的。 - sirandy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接