简体   繁体   中英

QTreeWidget childAt(int x, int y) returns NULL

I am trying to get the QTreeWidgetItem (node) at the position where the mouse pointer is. The QTreeWidget class has a method called childAt(int x, int y) which does not seem to be documented here: http://qt-project.org/doc/qt-5.1/qtwidgets/qtreewidget.html and I have no idea why. May be there is a reason behind it. The method always returns NULL for me.

I have extended the QTreeWidget class so I can capture the mouseMoveEvent.

class CustomTreeWidget : public QTreeWidget 
{
  Q_OBJECT

  public:
      explicit CustomTreeWidget(QWidget *parent = 0);

  signals:
      void OnMouseMove(int x, int y);

  public slots:

  private:
      void mouseMoveEvent(QMouseEvent *event);

 };

Then in my main cpp file:

void CustomTreeWidget::mouseMoveEvent(QMouseEvent *event)
{
    QTreeWidget::mouseMoveEvent(event);

    POINT p;
    if (GetCursorPos(&p))
    {
       qDebug(QString("GetCursorPos() OK: X=" + QString::number(p.x) + " Y=" + QString::number(p.y)).toLocal8Bit().data());

       QTreeWidgetItem *item = dynamic_cast<QTreeWidgetItem *> (this->childAt(p.x, p.y));

       if (item == NULL) return;

       qDebug(item->text(0).toLocal8Bit().data());
    }

    emit OnMouseMove(p.x, p.y);
}

Then in my MainWindow file:

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)

{
   ui->setupUi(this);

   XTreeWidget *treeWidget = new XTreeWidget(this);

   QTreeWidgetItem *rootItem = new QTreeWidgetItem(treeWidget, QTreeWidgetItem::UserType);
   rootItem->setText(0, "Item 1");
   treeWidget->addTopLevelItem(rootItem);

   rootItem = new QTreeWidgetItem(treeWidget, QTreeWidgetItem::UserType);
   rootItem->setText(0, "Item 2");
   treeWidget->addTopLevelItem(rootItem);

   this->setCentralWidget(treeWidget);
}

I run the code and the following statement never runs:

qDebug(item->text(0).toLocal8Bit().data());

So in the mouseMoveEvent in the CustomTreeWidget class, the following statement returns true and the method returns:

if (item == NULL) return;

What I am I doing wrong? dynamic_cast fails.

I also tried ScreenToClient((HWND)this->winId(), &p)) and passing px and py to childAt() as well as event.pos.x() and event.pos.y(). I am really confused.

I checked my px and py in the log and they always valid.

I even show a tooltip at the x and y and they are valid, yet, childAt() fails.

The problem is that you use "the position of the mouse cursor, in screen coordinates.", but it requires coordinates in QTreeWidget's coordinates system. Thus I would suggest to drop using WinAPI and use QMouseEvent::pos() function instead. Your mouseMoveEvent will look like:

void CustomTreeWidget::mouseMoveEvent(QMouseEvent *event)
{
    QTreeWidget::mouseMoveEvent(event);    
    QTreeWidgetItem *item = itemAt(event->pos();    
    if (item != NULL)
        qDebug(item->text(0).toLocal8Bit().data());
}

Please note the usage of QTableWidget::itemAt() function instead of childAt() .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM