Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. How to get the position of widgets in QTablewidget

How to get the position of widgets in QTablewidget

Scheduled Pinned Locked Moved Solved General and Desktop
19 Posts 2 Posters 3.8k Views 1 Watching
  • 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.
  • M Offline
    M Offline
    MasterBlade
    wrote on last edited by MasterBlade
    #1

    Hello I have a QTableWidget, and I set some widgets in it.

    When I right-click that widget, I want to know which row it is in.

    I used the following code, but during my debugging, row is always 0. What's the matter?

    QComboBox* cb = new QComboBox(this);
    connect(cb, &QComboBox::customContextMenuRequested, [=](QPoint pos){ContextMenu(pos);});
    
    void EffectTable::ContextMenu(QPoint &pos)
    {
        QModelIndex index = ui->table->indexAt(pos);
        qint32 row = index.row();
    }
    
    B 1 Reply Last reply
    0
    • M MasterBlade

      Hello I have a QTableWidget, and I set some widgets in it.

      When I right-click that widget, I want to know which row it is in.

      I used the following code, but during my debugging, row is always 0. What's the matter?

      QComboBox* cb = new QComboBox(this);
      connect(cb, &QComboBox::customContextMenuRequested, [=](QPoint pos){ContextMenu(pos);});
      
      void EffectTable::ContextMenu(QPoint &pos)
      {
          QModelIndex index = ui->table->indexAt(pos);
          qint32 row = index.row();
      }
      
      B Offline
      B Offline
      Bonnie
      wrote on last edited by Bonnie
      #2

      @MasterBlade You need to map pos from comboBox to the tableWidget (maybe it's better to map to the viewport) using

      QPoint QWidget::mapTo(const QWidget *parent, const QPoint &pos) const
      

      or mapToGlobal and then mapFromGlobal.

      M 1 Reply Last reply
      0
      • B Bonnie

        @MasterBlade You need to map pos from comboBox to the tableWidget (maybe it's better to map to the viewport) using

        QPoint QWidget::mapTo(const QWidget *parent, const QPoint &pos) const
        

        or mapToGlobal and then mapFromGlobal.

        M Offline
        M Offline
        MasterBlade
        wrote on last edited by MasterBlade
        #3

        @Bonnie said in How to get the position of widgets in QTablewidget:

        @MasterBlade You need to map pos from comboBox to the tableWidget (maybe it's better to map to the viewport) using

        QPoint QWidget::mapTo(const QWidget *parent, const QPoint &pos) const
        

        or mapToGlobal and then mapFromGlobal.

        Thank you for the reply.

        I tried this

        QWidget* w = qobject_cast<QWidget*>(sender());
            QPoint p = mapTo(w, pos);
            QModelIndex index = ui->table->indexAt(p);
            qint32 row = index.row();
        

        But row is still 0. I replaced mapTo() with mapFrom(), same result.

        B 1 Reply Last reply
        0
        • M MasterBlade

          @Bonnie said in How to get the position of widgets in QTablewidget:

          @MasterBlade You need to map pos from comboBox to the tableWidget (maybe it's better to map to the viewport) using

          QPoint QWidget::mapTo(const QWidget *parent, const QPoint &pos) const
          

          or mapToGlobal and then mapFromGlobal.

          Thank you for the reply.

          I tried this

          QWidget* w = qobject_cast<QWidget*>(sender());
              QPoint p = mapTo(w, pos);
              QModelIndex index = ui->table->indexAt(p);
              qint32 row = index.row();
          

          But row is still 0. I replaced mapTo() with mapFrom(), same result.

          B Offline
          B Offline
          Bonnie
          wrote on last edited by Bonnie
          #4

          @MasterBlade No, the mapTo should be called by the comboBox.
          Did you see the doc?
          The parent should be a parent of the calling widget.
          I think it should be

              QPoint p = w->mapTo(ui->table->viewport(), pos);
          

          If you are confused with that, you can try

          QPoint global = w->mapToGlobal(pos);
          QPoint p = ui->table->viewport()->mapFromGlobal(global);
          
          M 1 Reply Last reply
          0
          • B Bonnie

            @MasterBlade No, the mapTo should be called by the comboBox.
            Did you see the doc?
            The parent should be a parent of the calling widget.
            I think it should be

                QPoint p = w->mapTo(ui->table->viewport(), pos);
            

            If you are confused with that, you can try

            QPoint global = w->mapToGlobal(pos);
            QPoint p = ui->table->viewport()->mapFromGlobal(global);
            
            M Offline
            M Offline
            MasterBlade
            wrote on last edited by
            #5

            @Bonnie The program crashed at QModelIndex index = ui->table->indexAt(p);

            QWidget* w = qobject_cast<QWidget*>(sender());
                QPoint p = w->mapTo(ui->table->viewport(), pos);
                QModelIndex index = ui->table->indexAt(p);
                qint32 row = index.row();
            

            Annotation 2020-05-09 235907.png

            B 1 Reply Last reply
            0
            • M MasterBlade

              @Bonnie The program crashed at QModelIndex index = ui->table->indexAt(p);

              QWidget* w = qobject_cast<QWidget*>(sender());
                  QPoint p = w->mapTo(ui->table->viewport(), pos);
                  QModelIndex index = ui->table->indexAt(p);
                  qint32 row = index.row();
              

              Annotation 2020-05-09 235907.png

              B Offline
              B Offline
              Bonnie
              wrote on last edited by Bonnie
              #6

              @MasterBlade Wow, I thought the viewport should be a parent of the cell widget. It's not?
              Then you should try the "global" ones.

              [EDITED]
              Is the sender widget set by setCellWidget?
              If it is, can you try that if you don't use viewport, will it crash? If not crash, what's the result?

              QPoint p = w->mapTo(ui->table, pos);
              
              M 1 Reply Last reply
              0
              • B Bonnie

                @MasterBlade Wow, I thought the viewport should be a parent of the cell widget. It's not?
                Then you should try the "global" ones.

                [EDITED]
                Is the sender widget set by setCellWidget?
                If it is, can you try that if you don't use viewport, will it crash? If not crash, what's the result?

                QPoint p = w->mapTo(ui->table, pos);
                
                M Offline
                M Offline
                MasterBlade
                wrote on last edited by MasterBlade
                #7

                @Bonnie
                I used ui->table->setCellWidget(j, 2, cb); to setup the widget.

                After changing to QPoint p = w->mapTo(ui->table, pos);
                it still crashed with exactly the same error message.

                [EDIT]
                I tried

                QPoint global = w->mapToGlobal(pos);
                QPoint p = ui->table->mapFromGlobal(global);
                

                It didn't crash. But I'm having issues with QtCreator. It's not showing watchlist.
                But I'm sure row is a negative value because the program went into

                if (row < 0){
                //
                }
                
                B 1 Reply Last reply
                0
                • M MasterBlade

                  @Bonnie
                  I used ui->table->setCellWidget(j, 2, cb); to setup the widget.

                  After changing to QPoint p = w->mapTo(ui->table, pos);
                  it still crashed with exactly the same error message.

                  [EDIT]
                  I tried

                  QPoint global = w->mapToGlobal(pos);
                  QPoint p = ui->table->mapFromGlobal(global);
                  

                  It didn't crash. But I'm having issues with QtCreator. It's not showing watchlist.
                  But I'm sure row is a negative value because the program went into

                  if (row < 0){
                  //
                  }
                  
                  B Offline
                  B Offline
                  Bonnie
                  wrote on last edited by
                  #8

                  @MasterBlade Wait! I found that in your code the ContextMenu is not called as a slot.
                  So the sender() should not be the comboBox...

                  M 2 Replies Last reply
                  0
                  • B Bonnie

                    @MasterBlade Wait! I found that in your code the ContextMenu is not called as a slot.
                    So the sender() should not be the comboBox...

                    M Offline
                    M Offline
                    MasterBlade
                    wrote on last edited by
                    #9

                    @Bonnie It's a lambda function and should work.

                    Actually I also connected the table with this function.

                    connect(ui->table, &QTableWidget::customContextMenuRequested, [=](QPoint pos){ContextMenu(pos);});
                    

                    This is working alright. I can get the correct row number.

                    B 1 Reply Last reply
                    0
                    • M MasterBlade

                      @Bonnie It's a lambda function and should work.

                      Actually I also connected the table with this function.

                      connect(ui->table, &QTableWidget::customContextMenuRequested, [=](QPoint pos){ContextMenu(pos);});
                      

                      This is working alright. I can get the correct row number.

                      B Offline
                      B Offline
                      Bonnie
                      wrote on last edited by Bonnie
                      #10

                      @MasterBlade But that's not the correct way to use sender()

                      1. If EffectTable::ContextMenu is declared as a slot, use
                      connect(cb, &QComboBox::customContextMenuRequested, this, &EffectTable::ContextMenu);
                      
                      1. If not , try this and don't do any mapping in EffectTable::ContextMenu, leave it same as in the top post
                          connect(cb, &QComboBox::customContextMenuRequested, [=](QPoint pos){
                              QWidget* w = qobject_cast<QWidget*>(sender());
                              ContextMenu(w->mapTo(ui->table->viewport(), pos));
                          });
                      
                      M 3 Replies Last reply
                      0
                      • B Bonnie

                        @MasterBlade But that's not the correct way to use sender()

                        1. If EffectTable::ContextMenu is declared as a slot, use
                        connect(cb, &QComboBox::customContextMenuRequested, this, &EffectTable::ContextMenu);
                        
                        1. If not , try this and don't do any mapping in EffectTable::ContextMenu, leave it same as in the top post
                            connect(cb, &QComboBox::customContextMenuRequested, [=](QPoint pos){
                                QWidget* w = qobject_cast<QWidget*>(sender());
                                ContextMenu(w->mapTo(ui->table->viewport(), pos));
                            });
                        
                        M Offline
                        M Offline
                        MasterBlade
                        wrote on last edited by
                        #11

                        @Bonnie

                        You are correct. I output sender with

                        QObject* obj = sender();
                        qDebug() << obj;
                        

                        and got

                        QObject(0x0)
                        

                        sender is not working in this case.

                        1 Reply Last reply
                        0
                        • B Bonnie

                          @MasterBlade But that's not the correct way to use sender()

                          1. If EffectTable::ContextMenu is declared as a slot, use
                          connect(cb, &QComboBox::customContextMenuRequested, this, &EffectTable::ContextMenu);
                          
                          1. If not , try this and don't do any mapping in EffectTable::ContextMenu, leave it same as in the top post
                              connect(cb, &QComboBox::customContextMenuRequested, [=](QPoint pos){
                                  QWidget* w = qobject_cast<QWidget*>(sender());
                                  ContextMenu(w->mapTo(ui->table->viewport(), pos));
                              });
                          
                          M Offline
                          M Offline
                          MasterBlade
                          wrote on last edited by MasterBlade
                          #12

                          @Bonnie There is a compile error with ContextMenu(w->mapTo(ui->table->viewport(), pos));

                          C:\Users\<...>\effecttable.cpp:132: error: non-const lvalue reference to type 'QPoint' cannot bind to a temporary of type 'QPoint'

                          I changed it to

                          QPoint p = w->mapTo(ui->table->viewport(), pos);
                          ContextMenu(p);
                          

                          and it's running.

                          But it again crashed with the same error message.

                          B 1 Reply Last reply
                          0
                          • B Bonnie

                            @MasterBlade But that's not the correct way to use sender()

                            1. If EffectTable::ContextMenu is declared as a slot, use
                            connect(cb, &QComboBox::customContextMenuRequested, this, &EffectTable::ContextMenu);
                            
                            1. If not , try this and don't do any mapping in EffectTable::ContextMenu, leave it same as in the top post
                                connect(cb, &QComboBox::customContextMenuRequested, [=](QPoint pos){
                                    QWidget* w = qobject_cast<QWidget*>(sender());
                                    ContextMenu(w->mapTo(ui->table->viewport(), pos));
                                });
                            
                            M Offline
                            M Offline
                            MasterBlade
                            wrote on last edited by
                            #13

                            @Bonnie said in How to get the position of widgets in QTablewidget:

                            connect(cb, &QComboBox::customContextMenuRequested, this, &EffectTable::ContextMenu);

                            connect(cb, &QComboBox::customContextMenuRequested, this, &EffectTable::ContextMenu);

                            has a link error.
                            C:\Qt\5.15.0\msvc2019_64\include\QtCore\qobject.h:255: error: C2338: Signal and slot arguments are not compatible.

                            1 Reply Last reply
                            0
                            • B Bonnie

                              @MasterBlade Wait! I found that in your code the ContextMenu is not called as a slot.
                              So the sender() should not be the comboBox...

                              M Offline
                              M Offline
                              MasterBlade
                              wrote on last edited by
                              #14

                              @Bonnie It's late at night in China and I need to take some sleep.
                              Thank you so much for the help.
                              I will answer your further responses tomorrow.

                              1 Reply Last reply
                              0
                              • M MasterBlade

                                @Bonnie There is a compile error with ContextMenu(w->mapTo(ui->table->viewport(), pos));

                                C:\Users\<...>\effecttable.cpp:132: error: non-const lvalue reference to type 'QPoint' cannot bind to a temporary of type 'QPoint'

                                I changed it to

                                QPoint p = w->mapTo(ui->table->viewport(), pos);
                                ContextMenu(p);
                                

                                and it's running.

                                But it again crashed with the same error message.

                                B Offline
                                B Offline
                                Bonnie
                                wrote on last edited by Bonnie
                                #15

                                @MasterBlade I've tried myself. sender() is still 0x0.
                                Seems not a good idea to use it in the lambda. We should use cb instead.
                                Still in the lambda:

                                QPoint p = cb->mapTo(ui->table, pos);
                                ContextMenu(p);
                                

                                And no mapping in ContextMenu.
                                I've tried, this works. ;)

                                M 2 Replies Last reply
                                1
                                • B Bonnie

                                  @MasterBlade I've tried myself. sender() is still 0x0.
                                  Seems not a good idea to use it in the lambda. We should use cb instead.
                                  Still in the lambda:

                                  QPoint p = cb->mapTo(ui->table, pos);
                                  ContextMenu(p);
                                  

                                  And no mapping in ContextMenu.
                                  I've tried, this works. ;)

                                  M Offline
                                  M Offline
                                  MasterBlade
                                  wrote on last edited by
                                  #16

                                  @Bonnie Oh god this is working!
                                  Thank you so much!

                                  1 Reply Last reply
                                  0
                                  • B Bonnie

                                    @MasterBlade I've tried myself. sender() is still 0x0.
                                    Seems not a good idea to use it in the lambda. We should use cb instead.
                                    Still in the lambda:

                                    QPoint p = cb->mapTo(ui->table, pos);
                                    ContextMenu(p);
                                    

                                    And no mapping in ContextMenu.
                                    I've tried, this works. ;)

                                    M Offline
                                    M Offline
                                    MasterBlade
                                    wrote on last edited by MasterBlade
                                    #17

                                    @Bonnie Well there are still some minor problems.

                                    I have QComboBox and QPushbutton on the same row.

                                    Let's say the first row. Right-clicking the QPushbutton gives row# 0, but QComboBox gives 1.

                                    Also for the last row both give -1.

                                    They are linked the the same ContextMenu() function.

                                    B 1 Reply Last reply
                                    0
                                    • M MasterBlade

                                      @Bonnie Well there are still some minor problems.

                                      I have QComboBox and QPushbutton on the same row.

                                      Let's say the first row. Right-clicking the QPushbutton gives row# 0, but QComboBox gives 1.

                                      Also for the last row both give -1.

                                      They are linked the the same ContextMenu() function.

                                      B Offline
                                      B Offline
                                      Bonnie
                                      wrote on last edited by Bonnie
                                      #18

                                      @MasterBlade I've tried again, to get the correct row, we need to map to the viewport, as I expected.
                                      So in the lambda

                                      QPoint p = cb->mapTo(ui->table->viewport(), pos);
                                      ContextMenu(p);
                                      

                                      I also tried to add a QPushButton, it works fine, too.
                                      How did you connect the button?
                                      Did you change cb to the button's pointer?

                                      M 1 Reply Last reply
                                      2
                                      • B Bonnie

                                        @MasterBlade I've tried again, to get the correct row, we need to map to the viewport, as I expected.
                                        So in the lambda

                                        QPoint p = cb->mapTo(ui->table->viewport(), pos);
                                        ContextMenu(p);
                                        

                                        I also tried to add a QPushButton, it works fine, too.
                                        How did you connect the button?
                                        Did you change cb to the button's pointer?

                                        M Offline
                                        M Offline
                                        MasterBlade
                                        wrote on last edited by
                                        #19

                                        @Bonnie
                                        After adding viewport everything works perfect!
                                        I wish I could give you 100 thumbs up!!!

                                        1 Reply Last reply
                                        0

                                        • Login

                                        • Login or register to search.
                                        • First post
                                          Last post
                                        0
                                        • Categories
                                        • Recent
                                        • Tags
                                        • Popular
                                        • Users
                                        • Groups
                                        • Search
                                        • Get Qt Extensions
                                        • Unsolved