Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Language Bindings
  4. PyQt4 - How can I store the value of a QTableWidget cell before cellChanged signal is emitted
Forum Updated to NodeBB v4.3 + New Features

PyQt4 - How can I store the value of a QTableWidget cell before cellChanged signal is emitted

Scheduled Pinned Locked Moved Unsolved Language Bindings
7 Posts 2 Posters 5.3k 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.
  • A Offline
    A Offline
    AbdelrahmanSaid
    wrote on last edited by
    #1

    I am writing a program that uses QTableWidget as a front-end for an sqlite database.

    When any cell of the table is changed, it emits a cellChanged signal that updates the database.

    However, I now need to check the new value of the cell against a variable that is stored in the program, and if it goes through, the new value is approved, but if it doesn't, the old value of the cell is restored.

    Here is an example code of what I want to do:

    #!/usr/bin/python3
    import sys
    from PyQt4 import QtCore, QtGui
    
    app = QtGui.QApplication(sys.argv)
    
    table = QtGui.QTableWidget()
    
    def update_db(row, col):
        old_value = SOME_WAY_TO_STORE_THE_OLD_VALUE_OF_THE_CELL
    
        new_value = table.item(row, col).text()
    
        if new_value == VARIABLE:
            pass
        else:
            table.item(row, col).setText(old_value)
    
    table.cellChanged.connect(update_db)
    
    table.show()
    
    sys.exit(app.exec_())
    

    I have found this solution, which relies on subclassing the QStandardItemModel to store the old value of an item in a QTreeView. This would work with the QTableView as well.

    But this solution doesn't work with the QTableWidget, because its setModel() function is a private method, not public.

    The problem is, going back to use the QTableView is going to waste a lot of time for me, as I have already used QTableWidget in a lot of parts of the program.

    One workaround that solves the problem for me in all but one case is using the currentCellChanged signal to call a function that stores the cell's value. This relies on the fact that the user will need to navigate to the cell to be able to change its value.

    However, this won't work if the user decides to change the cell that is already selected.

    Is there a way for me to achieve what I want without going back and replacing all instances of QTableWidget with QTableView.

    1 Reply Last reply
    0
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Hi and welcome to devnet,

      So basically, your user can only change to that variable value or keep the current, correct ?

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

      A 1 Reply Last reply
      0
      • SGaistS SGaist

        Hi and welcome to devnet,

        So basically, your user can only change to that variable value or keep the current, correct ?

        A Offline
        A Offline
        AbdelrahmanSaid
        wrote on last edited by AbdelrahmanSaid
        #3

        Hi @SGaist.. Thank you very much.

        The user isn't even changing to the variable value. I used this bit if new_value == VARIABLE: in the original post just as an example, because I didn't think it will make much difference.

        Seeing that it might do, let me explain more explicitly what I need to do. Initially, when the user inputs the very first data into the cell, as I said, the database is updated, and a file is created named exactly as the text that the user entered.

        Therefore, when the user wants to change that cell again, I would like to show a QMessageBox that confirms if the user actually wants that change or not.

        The variable I mentioned in the original post is basically the user's response to the message box.

        If the user confirms the change, then the original file will be deleted, the new value will be kept, and a new file will be created.

        But if the user doesn't actually want the change to happen, then the old value will be restored.

        So, a more accurate example code would be something like that:

        if user_input == 'yes':
                pass
        else:
                table.item(row, col).setText(old_value)
        

        I hope this clarifies my intent and sorry for any confusion I might have caused.

        1 Reply Last reply
        0
        • SGaistS Offline
          SGaistS Offline
          SGaist
          Lifetime Qt Champion
          wrote on last edited by
          #4

          Then it sounds like you should implement a custom QStyledItemDelegate, do your validation in the setModelData.

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

          A 1 Reply Last reply
          0
          • SGaistS SGaist

            Then it sounds like you should implement a custom QStyledItemDelegate, do your validation in the setModelData.

            A Offline
            A Offline
            AbdelrahmanSaid
            wrote on last edited by
            #5

            Thanks for the help @SGaist.. any ideas where I can find good examples of how to use the QStyledItemDelegate with the QTableWidget, as I can't seem to find any.

            Also, someone on StackOverflow suggested implementing an Undo/Redo framework and using it to restore the original value. However, I am not sure if that would work well with what I want to do.

            What do you think?

            1 Reply Last reply
            0
            • A Offline
              A Offline
              AbdelrahmanSaid
              wrote on last edited by AbdelrahmanSaid
              #6

              I keep finding examples of how to customize the QStyledItemDelegate, but they are all in c++, and frankly, I know nothing about c++.

              This example, for instance, goes into creating a custom delegate and overriding the setModelData(), but I am not able to translate it into PyQt.

              All I can find is the PyQt class references which, of course, do not explain how to use the delegates in a real scenario.

              1 Reply Last reply
              0
              • SGaistS Offline
                SGaistS Offline
                SGaist
                Lifetime Qt Champion
                wrote on last edited by
                #7

                It's essentially the same, most of the time you have some translation to do from one language to the other, but the logic is exactly the same.

                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
                0

                • Login

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