Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Qt for Python
  4. Trying to customize the 4th column (Data Modified) of QFileSystemModel as my own data.
Forum Updated to NodeBB v4.3 + New Features

Trying to customize the 4th column (Data Modified) of QFileSystemModel as my own data.

Scheduled Pinned Locked Moved Solved Qt for Python
5 Posts 2 Posters 546 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.
  • K Offline
    K Offline
    K_17_M
    wrote on last edited by
    #1

    Using Qt5 - Trying to use the 4th column (Data Modified) of QFileSystemModel as my own content (since I don't need the Date Modified field, I am so close... So far I can update the header and set the data correctly to my custom text, but as soon as I try and type in the column it won't save it, it just reverts to the text I have set using data. My functions looks like this:

    class MyFileSystemModel(QtWidgets.QFileSystemModel):
        def __init__(self, parent = None):
            super(MyFileSystemModel, self).__init__(parent)
            self.role_dictionary = {
                1: QtCore.Qt.UserRole,      # Project
                2: QtCore.Qt.UserRole + 1}  # Path
    
    .....
    def data(self, index, role=QtCore.Qt.DisplayRole):
            if not index.isValid():
                return self.nullVariant()
            if index.column() == 3: # Department, overriding Data Modified
                    file_path = self.data(index, self.role_dictionary[2])
    
                    if os.path.isdir(file_path):
                        return " " # if you don't return empty, you will get the default file time stamp
                    else:
                        a, b = file_path.rsplit('.', 1) # Account for files that have more then one dot in it.
                        department = self.file_extension_lookup('.' + b)
                        return department
              return super(MyFileSystemModel, self).data(index, role)
    
        def setData(self, index, value, role=QtCore.Qt.EditRole):
            if not index.isValid():
                return False
    if role == QtCore.Qt.EditRole:
                if index.column() == 3:
                    print(value)
                    self.dataChanged.emit(index, index)
                   return True
                 return True
    
        def flags(self, index):
            if not index.isValid():
                return None
            if index.column() == 3: # Department
                return QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEditable
            else:
                return QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable
    

    I have tried EVERYTHING, originally I was just creating a QSortFilterProxyModel, with all the setData and override functions on this, and using sourceModel to set and access the data, but I have since split it out like I shown above into a QFileSystemModel and a QSortFilterProxyModel (incase I was using QSortFilterProxyModel wrong), but I still cannot get it to take the data when I type it the 4th column, it just goes back to showing the data I have set in data for the 4th column. Do I need to send the 'value' somewhere in setData? I do not have parent or index implemented, I don't think that's the issue. I tried creating a 5th column of QSortFilterProxyModel, but I could only get the header to change and data would not write anything text there at all... I tried using user roles but to be honest I don't really understand User Roles, but that's not really my question, and I don't believe they are really needed here. This feels like it should be straightforward.

    I have read Advanced Qt Programming by Mark Summerfield, and have looked on the internet for days :S

    I would really appreciate some help, this is sort of niche topic,
    Thankyou,

    JonBJ 1 Reply Last reply
    0
    • K K_17_M

      Using Qt5 - Trying to use the 4th column (Data Modified) of QFileSystemModel as my own content (since I don't need the Date Modified field, I am so close... So far I can update the header and set the data correctly to my custom text, but as soon as I try and type in the column it won't save it, it just reverts to the text I have set using data. My functions looks like this:

      class MyFileSystemModel(QtWidgets.QFileSystemModel):
          def __init__(self, parent = None):
              super(MyFileSystemModel, self).__init__(parent)
              self.role_dictionary = {
                  1: QtCore.Qt.UserRole,      # Project
                  2: QtCore.Qt.UserRole + 1}  # Path
      
      .....
      def data(self, index, role=QtCore.Qt.DisplayRole):
              if not index.isValid():
                  return self.nullVariant()
              if index.column() == 3: # Department, overriding Data Modified
                      file_path = self.data(index, self.role_dictionary[2])
      
                      if os.path.isdir(file_path):
                          return " " # if you don't return empty, you will get the default file time stamp
                      else:
                          a, b = file_path.rsplit('.', 1) # Account for files that have more then one dot in it.
                          department = self.file_extension_lookup('.' + b)
                          return department
                return super(MyFileSystemModel, self).data(index, role)
      
          def setData(self, index, value, role=QtCore.Qt.EditRole):
              if not index.isValid():
                  return False
      if role == QtCore.Qt.EditRole:
                  if index.column() == 3:
                      print(value)
                      self.dataChanged.emit(index, index)
                     return True
                   return True
      
          def flags(self, index):
              if not index.isValid():
                  return None
              if index.column() == 3: # Department
                  return QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEditable
              else:
                  return QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable
      

      I have tried EVERYTHING, originally I was just creating a QSortFilterProxyModel, with all the setData and override functions on this, and using sourceModel to set and access the data, but I have since split it out like I shown above into a QFileSystemModel and a QSortFilterProxyModel (incase I was using QSortFilterProxyModel wrong), but I still cannot get it to take the data when I type it the 4th column, it just goes back to showing the data I have set in data for the 4th column. Do I need to send the 'value' somewhere in setData? I do not have parent or index implemented, I don't think that's the issue. I tried creating a 5th column of QSortFilterProxyModel, but I could only get the header to change and data would not write anything text there at all... I tried using user roles but to be honest I don't really understand User Roles, but that's not really my question, and I don't believe they are really needed here. This feels like it should be straightforward.

      I have read Advanced Qt Programming by Mark Summerfield, and have looked on the internet for days :S

      I would really appreciate some help, this is sort of niche topic,
      Thankyou,

      JonBJ Offline
      JonBJ Offline
      JonB
      wrote on last edited by JonB
      #2

      @K_17_M
      In your data() case you do your if index.column() == 3: return ... without looking at the role parameter. That's not right.

      In your setData() case for if index.column() == 3: I see you emitting a dataChanged() but I don't see you actually storing the value passed in anywhere.

      Quite why you are "overriding" the existing Date Modified column for some other purpose I don't know, I would have thought you might add a new column.

      1 Reply Last reply
      2
      • K Offline
        K Offline
        K_17_M
        wrote on last edited by
        #3

        Oh shoot, copy and paste error, I do have this in my data, I am sorry.

        def data(self, index, role=QtCore.Qt.DisplayRole):
                if not index.isValid():
                    return self.nullVariant()
                if role == QtCore.Qt.DisplayRole or role == QtCore.Qt.EditRole:
                    if index.column() == 3: # Department, overriding Data Modified
                        file_path = self.data(index, self.role_dictionary[2])
        
                        if os.path.isdir(file_path):
                            return " " # if you don't return empty, you will get the default file time stamp
                        else:
                            a, b = file_path.rsplit('.', 1) # Account for files that have more then one dot in it.
                            department = self.file_extension_lookup('.' + b)
                            return department
                  return super(MyFileSystemModel, self).data(index, role)
        

        Thanks for responding, so originally I was only creating a custom QSortFilterProxyModel (with all the overrides there)and using the out of the box QFileSystemModel, so when I tried to create a 5th column it didn't work, and since I was so far down the coding rabbit hold I was trying to shoe horn in the only columns I could get working with my own data. After a big research session last night I realized I need to create a custom QFileSystemModel and a QSortFilterProxyModel and move over all my custom functions to the QFileSystemModel (minus filterAcceptsRow). This since has allowed me to add a 5th column and display my data in 'data' there, but the setData still doesn't work.

        I think you are onto something with your point on "I don't see you actually storing the value passed in anywhere.", Do I have to store the value in my own data set? Like maybe a dictionary? and just the act of saving and then reading from there allows it to be editable? I went down this road with the checkbox in column 0, I just thought it was different for some reason...

        JonBJ 1 Reply Last reply
        0
        • K K_17_M

          Oh shoot, copy and paste error, I do have this in my data, I am sorry.

          def data(self, index, role=QtCore.Qt.DisplayRole):
                  if not index.isValid():
                      return self.nullVariant()
                  if role == QtCore.Qt.DisplayRole or role == QtCore.Qt.EditRole:
                      if index.column() == 3: # Department, overriding Data Modified
                          file_path = self.data(index, self.role_dictionary[2])
          
                          if os.path.isdir(file_path):
                              return " " # if you don't return empty, you will get the default file time stamp
                          else:
                              a, b = file_path.rsplit('.', 1) # Account for files that have more then one dot in it.
                              department = self.file_extension_lookup('.' + b)
                              return department
                    return super(MyFileSystemModel, self).data(index, role)
          

          Thanks for responding, so originally I was only creating a custom QSortFilterProxyModel (with all the overrides there)and using the out of the box QFileSystemModel, so when I tried to create a 5th column it didn't work, and since I was so far down the coding rabbit hold I was trying to shoe horn in the only columns I could get working with my own data. After a big research session last night I realized I need to create a custom QFileSystemModel and a QSortFilterProxyModel and move over all my custom functions to the QFileSystemModel (minus filterAcceptsRow). This since has allowed me to add a 5th column and display my data in 'data' there, but the setData still doesn't work.

          I think you are onto something with your point on "I don't see you actually storing the value passed in anywhere.", Do I have to store the value in my own data set? Like maybe a dictionary? and just the act of saving and then reading from there allows it to be editable? I went down this road with the checkbox in column 0, I just thought it was different for some reason...

          JonBJ Offline
          JonBJ Offline
          JonB
          wrote on last edited by JonB
          #4

          @K_17_M said in Trying to customize the 4th column (Data Modified) of QFileSystemModel as my own data.:

          I think you are onto something with your point on "I don't see you actually storing the value passed in anywhere.", Do I have to store the value in my own data set?

          Yes :)

          In your data() method you get your index.column() == 3 value ultimately from your file_path = self.data(index, self.role_dictionary[2]). (Probably not right, you're trying to store it in a role here, I would add my own datastore. But in any case...).

          However, in your setData() case you do nothing with the passed in value (other than print it). You have store that value somewhere, in such a way that when you are asked to return it in the data() case you return that value. Else, as you said, you'll "revert" after editing. You need to pair this with your current file_path = self.data(index, self.role_dictionary[2]), or whatever you have there in data().

          1 Reply Last reply
          2
          • K Offline
            K Offline
            K_17_M
            wrote on last edited by
            #5

            Thanks so much, you made me look at the issue differently and I FINALLY have it working, it's a miracle! I think I thought because originally I was using the Date Modified 4th column in the QFileSystemModel, I thought it would just store my data since it stores the date modified data, but that is not the case, so once I created the 5th column and hid the 4th column it was obvious no one was storing my data, I don't know why it took me so long to come to this realization, I did it for the checkbox in column 0 last week! The role_dictionary[2] was just one of the millions trys and because it was returning the path correctly I just left it, I removed it and am using ```
            folder_path = self.filePath(index)

            AGAIN I really appreciate your time on this Monday morning!
            1 Reply Last reply
            1

            • Login

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