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
Forum Updated to NodeBB v4.3 + New Features

How to get the position of widgets in QTablewidget

Scheduled Pinned Locked Moved Solved General and Desktop
19 Posts 2 Posters 3.7k 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 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