Qt Forum

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Unsolved

    Unsolved QTreeWidget indexAt() doesn't work

    General and Desktop
    3
    14
    261
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • FluentCoding
      FluentCoding last edited by

      Hey!

      I wanna use the indexAt() method in the eventFilter method() of my application. The problem is that it is that the resulting ModelIndex isn't valid, even if I click on an item. Could someone help me? I have already tried setMouseTracking(true) but that didn't help either.

      Thanks!

      1 Reply Last reply Reply Quote 0
      • SGaist
        SGaist Lifetime Qt Champion last edited by

        Hi,

        Did you map properly the mouse position you got from the event to the widget you want to manipulate ?

        Interested in AI ? www.idiap.ch
        Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

        1 Reply Last reply Reply Quote 0
        • FluentCoding
          FluentCoding last edited by

          Yeah, I did. I casted the event to a mouseEvent and used the pos() method to get the coordinates. I already verified them by printing them out.

          1 Reply Last reply Reply Quote 0
          • SGaist
            SGaist Lifetime Qt Champion last edited by

            Did you map the coordinates ?

            Interested in AI ? www.idiap.ch
            Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

            1 Reply Last reply Reply Quote 1
            • B
              Bonnie last edited by

              Are you filtering the events from a itemWidget?
              The pos from the mouse events is in the coordinate system of that itemWidget, not the treeWidget.
              You can:

              1. map the pos from itemWidget to treeWidget's viewport
              QPoint pos = itemWidget->mapTo(treeWidget->viewport(), e->pos());
              
              1. map the global pos to treeWidget's viewport
              QPoint pos = treeWidget->viewport()->mapFromGlobal(e->globalPos());
              

              P.S.setMouseTracking(true) does not affect the pos value. It only makes you receiving mouse move events from the widget even no buttons are pressed.

              1 Reply Last reply Reply Quote 0
              • FluentCoding
                FluentCoding last edited by FluentCoding

                Ouch, I'm filtering them from the window because I want to check if I click away from a QTableWidget globally. I'll try it out :D Thanks, @Bonnie!

                B 1 Reply Last reply Reply Quote 0
                • B
                  Bonnie @FluentCoding last edited by

                  @FluentCoding Hmm..if you are not filtering from treeWidget's child widgets, then the first option need some change...

                  1 Reply Last reply Reply Quote 0
                  • FluentCoding
                    FluentCoding last edited by

                    Which? But I could use the second method as well?

                    B 1 Reply Last reply Reply Quote 0
                    • SGaist
                      SGaist Lifetime Qt Champion last edited by

                      What about the focusOutEvent ?

                      Interested in AI ? www.idiap.ch
                      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                      1 Reply Last reply Reply Quote 0
                      • B
                        Bonnie @FluentCoding last edited by

                        @FluentCoding Yes, the second is ok to use. It maps from global pos, so nothing to do with their child/parent relation.
                        The first one must map from child to a parent (recursively).
                        If you'are filtering the window, and the window is a parent of treeWidget, then it should be changed to

                        QPoint pos = treeWidget->viewport()->mapFrom(window, e->pos());
                        
                        1 Reply Last reply Reply Quote 0
                        • FluentCoding
                          FluentCoding last edited by

                          @Bonnie Thank you for the solution! Both work but have the same problem - when I'm scrolling a bit down in my QTableWidget, then I have the problem that the item gets shown as valid although I don't click on the widget.

                          My Code:

                          bool MainWindow::eventFilter(QObject* obj, QEvent* event) {
                              if (event->type() == QEvent::MouseButtonPress) {
                                  QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
                          
                                  QPoint pos = ui->treeWidget->viewport()->mapFromGlobal(mouseEvent->globalPos());
                                  QModelIndex index = ui->treeWidget->indexAt(pos);
                          
                                  if (!index.isValid() && ui->treeWidget->selectedItems().count() == 1) {
                                      ui->treeWidget->clearSelection();
                                  }
                              }
                          }
                          
                          B 1 Reply Last reply Reply Quote 0
                          • FluentCoding
                            FluentCoding last edited by FluentCoding

                            @SGaist Didn't try it out yet, but I don't think that it would be better than the eventFilter()-solution :/

                            1 Reply Last reply Reply Quote 0
                            • B
                              Bonnie @FluentCoding last edited by Bonnie

                              @FluentCoding Yes, the viewport is partly invisible, so the index got from indexAt may be not visible.
                              That's what you need to do when you map the pos not from treeWidget's child.
                              You need to see whether it is contained in treeWidget's rect, whether it is on the scrollbar or not...
                              I think it's a bit complicated, maybe you should try what @SGaist suggest, use the focusOutEvent.
                              This is what I think to solve the problem (but not usable when you have set any itemWidget)

                              QPoint pos = ui->treeWidget->mapFromGlobal(e->globalPos());  //map pos to treeWidget
                              if(ui->treeWidget->rect().contains(pos) &&  //pos is inside of treeWidget
                                  ui->treeWidget->childAt(pos) == ui->treeWidget->viewport() &&  //pos is not on scrollbars
                                  ui->treeWidget->indexAt(ui->treeWidget->viewport()->mapFromParent(pos)).isValid()) {  //get index from viewport, maybe you don't need this line
                                  //valid index
                              } else {
                                  //invalid index
                              }
                              
                              1 Reply Last reply Reply Quote 1
                              • FluentCoding
                                FluentCoding last edited by

                                @Bonnie Thank you so much, Bonnie! It worked!

                                1 Reply Last reply Reply Quote 0
                                • First post
                                  Last post