Qt: TableWidget's ItemAt() acting weirdly
i'm working on a windows application, where in a dialog i query some data from Postgres, and manually show the output in a table widget.
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())));
}
Also, based on row and column information, i paint some of these tablewidgetitems to some colors, but i don't think it's relevant.
I reimplemented the QDialog's contextMenuEvent, to obtain the right clicked tableWidgetItem's row and column coordinates:
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->changeSelectedToleranc开发者_如何学CeToUygun);
menu.addAction(this->changeSelectedToleranceToUyar);
menu.addAction(this->changeSelectedToleranceToDurdurUyar);
//... some other irrevelant 'enable/disable' activities
menu.exec(event->globalPos());
}
The problem is, when i right click on the same item i get the same global coordinates, but randomly different row-column information. For instance, the global pos is exactly 600,230 but row-column pair is randomly (5,3) and (4,3). I mean, what?!
Also, when i click to an item from the last to rows (later than 13, i guess) will never go into condition "if (clickedItem && clickedItem->column()>1 && clickedItem->row()>0)", i think it's mainly because 'clickedItem' is null.
I'll be more than glad to share any more information, or even the full cpp-h-ui trio in order to get help.
Thanks a lot.
Try this:
QTableWidgetItem* clickedItem = m_ui->tableWidget->itemAt(event->pos());
The problem is that you are trying to map the global position to the table widget position, without considering the scrollable area. To map the global position into something you can pass to itemAt
, use tableWidget->viewport()->mapFromGlobal
.
Came here to thank Lukáš Lalinský, as his explanation put an end to half a day of misery for me.
In my case, itemAt() when fed with QDropEvent::pos(), was returning items from a table row, offset by 1.
The reason was that I had a horizontal header, which shrunk the viewport, same with the vertical header, but since it was very narrow, I did not realize it caused an offset too. The fix was to call QTableWidget's viewport()->mapFromParent( [drop pos] ), as the position was in QTableWidget coordinates already.
Again, thanks A LOT!
精彩评论