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. QTableWidget... Does changing a header value trigger the cellChanged signal?
Forum Update on Monday, May 27th 2025

QTableWidget... Does changing a header value trigger the cellChanged signal?

Scheduled Pinned Locked Moved Solved General and Desktop
14 Posts 4 Posters 2.3k Views
  • 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.
  • D Offline
    D Offline
    David Jacobson
    wrote on 11 Aug 2018, 00:02 last edited by David Jacobson 8 Nov 2018, 00:04
    #1

    I have a QTableWidget where I do some processing when the user changes some data in a cell using the cellChanged signal, i.e.:

    table.cellChanged.connect(self.shiftTagsCellChanged)
    

    But, I also conditionally change my vertical header (row header) to a different image based on some logic, using the following code in my :

    # row header
    hitem = QTableWidgetItem()
    hitem.setData(Qt.UserRole, '+')
    hitem.setData(Qt.DecorationRole, QPixmap(self._sesTagShiftAddRowImg))
    table.setVerticalHeaderItem(row, hitem)
    

    I store custom data on the image item (Qt.UserRole) as a key.

    Ever since I took this approach, I was surprised to see my cellChanged slot callback getting called twice?! Does changing the header item count as a row cell change? It didn't seem to when I was just changing its text label. If so, is there a way I can turn this off? My current hack is to check the change against the previous (row, col) cellChanged call... which, you know, seems like a hack to me. :/

    Thanks for any insight.

    K 1 Reply Last reply 11 Aug 2018, 10:02
    0
    • D Offline
      D Offline
      David Jacobson
      wrote on 12 Aug 2018, 18:52 last edited by David Jacobson 8 Dec 2018, 19:15
      #13

      Ok, I have some crow to eat after further debugging and totally commenting out sections of my code, process of elimination, etc. ... my cellChanged slot function was not getting called redundantly on the same cell because of ANY of the multiple setData's I was doing on anything, header or otherwise. It was simply because I was trying to dynamically right justify the user's cell input with the following call in the cellChanged slot function!:

      changedItem = table.item(row, col)
      changedItem.setTextAlignment(Qt.AlignVCenter | Qt.AlignRight)
      

      I apologize for the wild goose chase. :)

      But, that's kind of interesting... setData does not cause a cellChanged signal, but setTextAlignment does?

      Related, I found this possible interesting approach to setting the default justification of my table items:

      https://stackoverflow.com/questions/15827886/set-default-alignment-for-cells-in-qtablewidget

      So, I basically have learned to use setItemPrototype during my table init, rather than changing that cell stuff during the cellChanged event, with the following simple code:

      rowitem = QTableWidgetItem()
      rowitem.setTextAlignment(Qt.AlignVCenter | Qt.AlignRight)
      table.setItemPrototype(rowitem)
      

      This is pretty much solved for me. Thank you all for your wise advice! :)

      1 Reply Last reply
      2
      • D David Jacobson
        11 Aug 2018, 00:02

        I have a QTableWidget where I do some processing when the user changes some data in a cell using the cellChanged signal, i.e.:

        table.cellChanged.connect(self.shiftTagsCellChanged)
        

        But, I also conditionally change my vertical header (row header) to a different image based on some logic, using the following code in my :

        # row header
        hitem = QTableWidgetItem()
        hitem.setData(Qt.UserRole, '+')
        hitem.setData(Qt.DecorationRole, QPixmap(self._sesTagShiftAddRowImg))
        table.setVerticalHeaderItem(row, hitem)
        

        I store custom data on the image item (Qt.UserRole) as a key.

        Ever since I took this approach, I was surprised to see my cellChanged slot callback getting called twice?! Does changing the header item count as a row cell change? It didn't seem to when I was just changing its text label. If so, is there a way I can turn this off? My current hack is to check the change against the previous (row, col) cellChanged call... which, you know, seems like a hack to me. :/

        Thanks for any insight.

        K Offline
        K Offline
        koahnig
        wrote on 11 Aug 2018, 10:02 last edited by
        #2

        @David-Jacobson

        Most likely is that you have accidently connect twice the same signal or that you have connected two signals to the same slot and the signals are triggered both with your action.

        You should inspect carefully the signals you are connecting. You can use also dumpObjectInfo to check for connected signals of an item.

        Vote the answer(s) that helped you to solve your issue(s)

        J 1 Reply Last reply 11 Aug 2018, 11:20
        3
        • K koahnig
          11 Aug 2018, 10:02

          @David-Jacobson

          Most likely is that you have accidently connect twice the same signal or that you have connected two signals to the same slot and the signals are triggered both with your action.

          You should inspect carefully the signals you are connecting. You can use also dumpObjectInfo to check for connected signals of an item.

          J Offline
          J Offline
          JonB
          wrote on 11 Aug 2018, 11:20 last edited by
          #3

          @koahnig
          Wow, I didn't know of https://doc.qt.io/qt-5/qobject.html#dumpObjectInfo, that could be really useful!

          While on that subject, is there something which will walk all QObjects and dump them/some of them? For debugging I use http://doc.qt.io/qt-5/qapplication.html#allWidgets to see what widgets there are, is there similar-ish for all QObjects?

          K K 2 Replies Last reply 11 Aug 2018, 11:37
          0
          • J JonB
            11 Aug 2018, 11:20

            @koahnig
            Wow, I didn't know of https://doc.qt.io/qt-5/qobject.html#dumpObjectInfo, that could be really useful!

            While on that subject, is there something which will walk all QObjects and dump them/some of them? For debugging I use http://doc.qt.io/qt-5/qapplication.html#allWidgets to see what widgets there are, is there similar-ish for all QObjects?

            K Offline
            K Offline
            koahnig
            wrote on 11 Aug 2018, 11:37 last edited by
            #4

            @JonB

            Frankly, I do not know.

            I came across the dumpObject routines a while ago here in the forum and use them occasionally.

            Vote the answer(s) that helped you to solve your issue(s)

            1 Reply Last reply
            1
            • J JonB
              11 Aug 2018, 11:20

              @koahnig
              Wow, I didn't know of https://doc.qt.io/qt-5/qobject.html#dumpObjectInfo, that could be really useful!

              While on that subject, is there something which will walk all QObjects and dump them/some of them? For debugging I use http://doc.qt.io/qt-5/qapplication.html#allWidgets to see what widgets there are, is there similar-ish for all QObjects?

              K Offline
              K Offline
              kshegunov
              Moderators
              wrote on 11 Aug 2018, 12:01 last edited by kshegunov 8 Nov 2018, 12:04
              #5

              @David-Jacobson said in QTableWidget... Does changing a header value trigger the cellChanged signal?:

              If so, is there a way I can turn this off?

              Expected behaviour (I think) as you're calling setData twice.

              @JonB said in QTableWidget... Does changing a header value trigger the cellChanged signal?:

              is there similar-ish for all QObjects?

              You can use findChildren<QObject *>() if you have a common root object, but not in the general case, no.

              Read and abide by the Qt Code of Conduct

              1 Reply Last reply
              4
              • D Offline
                D Offline
                David Jacobson
                wrote on 12 Aug 2018, 04:55 last edited by David Jacobson 8 Dec 2018, 05:07
                #6

                @koahnig Thanks for the dumpObject suggestion. Do you need to be using a debug compiled version of the Qt libs for that to work? And, for your other excellent suggestion... in my case, there is only one connect for the cellChanged signal in my code, but, I'll keep debugging.

                @kshegunov I'm suspicious of the setData's being the culprit as well. But, these are setData's on a stand-alone QTableWidgetItem object, that hasn't been associated with any QTableWidget (yet), until the table.setVerticalHeaderItem(...) function is called. ? Or are you referring to the setVerticalHeaderItem() call itself and the user changing the cell data (the original cellChanged trigger), as both being implied setData's? That's the premise of my question... whether setVerticalHeaderItem causes a cellChanged signal.

                Well, just for general interest, below is the code that I was describing as a "hack" that I put at the beginning of my cellChanged slot function, which actually works in my use case. :)

                # Redundancy safety check:
                # Header changes currently trigger cellChanged signal? :(
                if self._sesPrevChangedTagShiftCell:
                	(prevchrow, prevchcol) = self._sesPrevChangedTagShiftCell
                	if row == prevchrow and col == prevchcol:
                		# Can not change self cell twice
                		return
                self._sesPrevChangedTagShiftCell = (row, col)
                
                K K 2 Replies Last reply 12 Aug 2018, 06:54
                0
                • D David Jacobson
                  12 Aug 2018, 04:55

                  @koahnig Thanks for the dumpObject suggestion. Do you need to be using a debug compiled version of the Qt libs for that to work? And, for your other excellent suggestion... in my case, there is only one connect for the cellChanged signal in my code, but, I'll keep debugging.

                  @kshegunov I'm suspicious of the setData's being the culprit as well. But, these are setData's on a stand-alone QTableWidgetItem object, that hasn't been associated with any QTableWidget (yet), until the table.setVerticalHeaderItem(...) function is called. ? Or are you referring to the setVerticalHeaderItem() call itself and the user changing the cell data (the original cellChanged trigger), as both being implied setData's? That's the premise of my question... whether setVerticalHeaderItem causes a cellChanged signal.

                  Well, just for general interest, below is the code that I was describing as a "hack" that I put at the beginning of my cellChanged slot function, which actually works in my use case. :)

                  # Redundancy safety check:
                  # Header changes currently trigger cellChanged signal? :(
                  if self._sesPrevChangedTagShiftCell:
                  	(prevchrow, prevchcol) = self._sesPrevChangedTagShiftCell
                  	if row == prevchrow and col == prevchcol:
                  		# Can not change self cell twice
                  		return
                  self._sesPrevChangedTagShiftCell = (row, col)
                  
                  K Offline
                  K Offline
                  koahnig
                  wrote on 12 Aug 2018, 06:54 last edited by koahnig 8 Dec 2018, 06:54
                  #7

                  @David-Jacobson said in QTableWidget... Does changing a header value trigger the cellChanged signal?:

                  @koahnig Thanks for the dumpObject suggestion. Do you need to be using a debug compiled version of the Qt libs for that to work? And, for your other excellent suggestion... in my case, there is only one connect for the cellChanged signal in my code, but, I'll keep debugging.

                  Yes, it shows only when my application is in debug mode compiled.
                  Glad you consider it as useful

                  Vote the answer(s) that helped you to solve your issue(s)

                  1 Reply Last reply
                  1
                  • D David Jacobson
                    12 Aug 2018, 04:55

                    @koahnig Thanks for the dumpObject suggestion. Do you need to be using a debug compiled version of the Qt libs for that to work? And, for your other excellent suggestion... in my case, there is only one connect for the cellChanged signal in my code, but, I'll keep debugging.

                    @kshegunov I'm suspicious of the setData's being the culprit as well. But, these are setData's on a stand-alone QTableWidgetItem object, that hasn't been associated with any QTableWidget (yet), until the table.setVerticalHeaderItem(...) function is called. ? Or are you referring to the setVerticalHeaderItem() call itself and the user changing the cell data (the original cellChanged trigger), as both being implied setData's? That's the premise of my question... whether setVerticalHeaderItem causes a cellChanged signal.

                    Well, just for general interest, below is the code that I was describing as a "hack" that I put at the beginning of my cellChanged slot function, which actually works in my use case. :)

                    # Redundancy safety check:
                    # Header changes currently trigger cellChanged signal? :(
                    if self._sesPrevChangedTagShiftCell:
                    	(prevchrow, prevchcol) = self._sesPrevChangedTagShiftCell
                    	if row == prevchrow and col == prevchcol:
                    		# Can not change self cell twice
                    		return
                    self._sesPrevChangedTagShiftCell = (row, col)
                    
                    K Offline
                    K Offline
                    kshegunov
                    Moderators
                    wrote on 12 Aug 2018, 09:04 last edited by
                    #8

                    @David-Jacobson said in QTableWidget... Does changing a header value trigger the cellChanged signal?:

                    But, these are setData's on a stand-alone QTableWidgetItem object, that hasn't been associated with any QTableWidget (yet), until the table.setVerticalHeaderItem(...) function is called. ?

                    Well, yes, but I imagine setData is called onto the model whenever you associate it.

                    Note: I haven't looked at the source, but seems like a reasonable assumption.

                    That's the premise of my question... whether setVerticalHeaderItem causes a cellChanged signal.

                    I would say so, yes. You can probably check that though, by breaking at your signal handler and inspecting the stack trace.

                    Read and abide by the Qt Code of Conduct

                    1 Reply Last reply
                    1
                    • D Offline
                      D Offline
                      David Jacobson
                      wrote on 12 Aug 2018, 12:31 last edited by
                      #9

                      If this is the case, where setVerticalHeaderItem causes a cellChanged signal, then I would complain that the (row, col) params passed to the slot function are misleading. It would seem that if cell (0, 0) changed, and then I changed it's header cell, Qt signals (0, 0) changed again. I would prefer something indicating the header cell; like (0, -1) perhaps. :)

                      K 1 Reply Last reply 12 Aug 2018, 13:31
                      0
                      • D David Jacobson
                        12 Aug 2018, 12:31

                        If this is the case, where setVerticalHeaderItem causes a cellChanged signal, then I would complain that the (row, col) params passed to the slot function are misleading. It would seem that if cell (0, 0) changed, and then I changed it's header cell, Qt signals (0, 0) changed again. I would prefer something indicating the header cell; like (0, -1) perhaps. :)

                        K Offline
                        K Offline
                        kshegunov
                        Moderators
                        wrote on 12 Aug 2018, 13:31 last edited by kshegunov 8 Dec 2018, 13:32
                        #10

                        @David-Jacobson said in QTableWidget... Does changing a header value trigger the cellChanged signal?:

                        If this is the case, where setVerticalHeaderItem causes a cellChanged signal, then I would complain that the (row, col) params passed to the slot function are misleading.

                        I had a quick glance of the source. It comes through dataChanged and headerDataChanged. Long story short, you should choose one of the two to handle the use case properly. cellChanged loses from which data structure (header or table contents) the signal originated.

                        Or subscribe directly to the header view ...

                        Read and abide by the Qt Code of Conduct

                        D 1 Reply Last reply 12 Aug 2018, 16:29
                        2
                        • K kshegunov
                          12 Aug 2018, 13:31

                          @David-Jacobson said in QTableWidget... Does changing a header value trigger the cellChanged signal?:

                          If this is the case, where setVerticalHeaderItem causes a cellChanged signal, then I would complain that the (row, col) params passed to the slot function are misleading.

                          I had a quick glance of the source. It comes through dataChanged and headerDataChanged. Long story short, you should choose one of the two to handle the use case properly. cellChanged loses from which data structure (header or table contents) the signal originated.

                          Or subscribe directly to the header view ...

                          D Offline
                          D Offline
                          David Jacobson
                          wrote on 12 Aug 2018, 16:29 last edited by
                          #11

                          @kshegunov said in QTableWidget... Does changing a header value trigger the cellChanged signal?:

                          dataChanged

                          Thank you! I am definitely learning from the insight in this thread.

                          I believe this is the a more appropriate approach. But, I think there may still be a trade-off, i.e.: using the dataChanged slot on specific table items... it seems you gain visibility of the exact item emitting the signal, but lose visibility of the table (row, col) where the item is. Hmm.

                          K 1 Reply Last reply 12 Aug 2018, 17:39
                          0
                          • D David Jacobson
                            12 Aug 2018, 16:29

                            @kshegunov said in QTableWidget... Does changing a header value trigger the cellChanged signal?:

                            dataChanged

                            Thank you! I am definitely learning from the insight in this thread.

                            I believe this is the a more appropriate approach. But, I think there may still be a trade-off, i.e.: using the dataChanged slot on specific table items... it seems you gain visibility of the exact item emitting the signal, but lose visibility of the table (row, col) where the item is. Hmm.

                            K Offline
                            K Offline
                            kshegunov
                            Moderators
                            wrote on 12 Aug 2018, 17:39 last edited by
                            #12

                            @David-Jacobson said in QTableWidget... Does changing a header value trigger the cellChanged signal?:

                            but lose visibility of the table (row, col) where the item is.

                            I don't follow. You can get the row and column from the model index that's given to you as an argument.

                            Read and abide by the Qt Code of Conduct

                            1 Reply Last reply
                            0
                            • D Offline
                              D Offline
                              David Jacobson
                              wrote on 12 Aug 2018, 18:52 last edited by David Jacobson 8 Dec 2018, 19:15
                              #13

                              Ok, I have some crow to eat after further debugging and totally commenting out sections of my code, process of elimination, etc. ... my cellChanged slot function was not getting called redundantly on the same cell because of ANY of the multiple setData's I was doing on anything, header or otherwise. It was simply because I was trying to dynamically right justify the user's cell input with the following call in the cellChanged slot function!:

                              changedItem = table.item(row, col)
                              changedItem.setTextAlignment(Qt.AlignVCenter | Qt.AlignRight)
                              

                              I apologize for the wild goose chase. :)

                              But, that's kind of interesting... setData does not cause a cellChanged signal, but setTextAlignment does?

                              Related, I found this possible interesting approach to setting the default justification of my table items:

                              https://stackoverflow.com/questions/15827886/set-default-alignment-for-cells-in-qtablewidget

                              So, I basically have learned to use setItemPrototype during my table init, rather than changing that cell stuff during the cellChanged event, with the following simple code:

                              rowitem = QTableWidgetItem()
                              rowitem.setTextAlignment(Qt.AlignVCenter | Qt.AlignRight)
                              table.setItemPrototype(rowitem)
                              

                              This is pretty much solved for me. Thank you all for your wise advice! :)

                              1 Reply Last reply
                              2
                              • D Offline
                                D Offline
                                David Jacobson
                                wrote on 13 Aug 2018, 14:02 last edited by David Jacobson
                                #14

                                I would like to note another solution that should have been obvious to me once I figured out all the potential API calls that count as changes to table items. If, in the middle of your itemsChanged or cellChanged slot function, you'd like to make all kinds of cosmetic changes to your table without those changes retriggering calls to the *changed functions, you could simply turn off signals for the table at the beginning of it, and turn them back on at the end of it:

                                @pyqtSlot(QTableWidgetItem)
                                def mytableItemChanged(self, changedItem):
                                	table = self.tblMyTable
                                	table.itemChanged.disconnect()
                                	#
                                	# ...do all kinds of changes to the table (i.e.: validation colors, etc.)
                                	#
                                	table.itemChanged.connect(self.mytableItemChanged)
                                

                                Is this a fairly common practice?

                                1 Reply Last reply
                                0

                                1/14

                                11 Aug 2018, 00:02

                                • Login

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