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

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 3 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.
  • K koahnig

    @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.

    JonBJ Offline
    JonBJ Offline
    JonB
    wrote on 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 kshegunovK 2 Replies Last reply
    0
    • JonBJ JonB

      @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 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
      • JonBJ JonB

        @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?

        kshegunovK Offline
        kshegunovK Offline
        kshegunov
        Moderators
        wrote on last edited by kshegunov
        #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 last edited by David Jacobson
          #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 kshegunovK 2 Replies Last reply
          0
          • D David Jacobson

            @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 last edited by koahnig
            #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

              @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)
              
              kshegunovK Offline
              kshegunovK Offline
              kshegunov
              Moderators
              wrote on 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 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. :)

                kshegunovK 1 Reply Last reply
                0
                • D David Jacobson

                  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. :)

                  kshegunovK Offline
                  kshegunovK Offline
                  kshegunov
                  Moderators
                  wrote on last edited by kshegunov
                  #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
                  2
                  • kshegunovK kshegunov

                    @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 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.

                    kshegunovK 1 Reply Last reply
                    0
                    • D David Jacobson

                      @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.

                      kshegunovK Offline
                      kshegunovK Offline
                      kshegunov
                      Moderators
                      wrote on 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 last edited by David Jacobson
                        #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 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

                          • Login

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