[solved]QAbstractListModel - update data in table view [linux]



  • How to update/refresh a data when my app is running. Data in ‘file.txt’ is changing, how to display this changes ?
    I don’t want to shutdown and restart my app.

    @ class StockListModel(QtCore.QAbstractListModel):

        def __init__(self, stockdata = [], parent = None):
            QtCore.QAbstractListModel.__init__(self, parent)            
            self.__stockdata = stockdata            
     
        def rowCount(self, parent):
            return len(self.__stockdata)
     
        def data(self, index, role):        
            if role == QtCore.Qt.DisplayRole:
                row = index.row()
                value = self.__stockdata[row]
     
                return value
     
    if __name__ == '__main__':
        app = QtGui.QApplication(sys.argv)
        app.setStyle("plastique")
     
        tableView = QtGui.QTableView()      
        tableView.show()
     
        a = os.popen("cat /home/user/file.txt")
        a = a.read()
        time_variable = QtCore.QString("%s"%a)       # how to refresh when app is running ?
     
        model = StockListModel([time_variable])
     
        tableView.setModel(model)
        sys.exit(app.exec_())
    

    @



  • Reset Model and add repopulate data?



  • Should reset looks like that?, if yes how can I repopulate data?
    Code below begins in the line 16.

    @def resetItems(self,model):
    self.beginResetModel()
    self.model = model
    self.endResetModel()
    @



  • Have you made yourself acquaint with Signals and Slots?

    When is your "resetItems" being called? I am not familiar with the Python Implementation of Qt -- maybe you should use "setModel"?



  • I am just a beginner in Qt.
    Perhaps instead of "model" I shoud reset "stockdata" (add to the line 6):

    @
    def resetItems(self,stockdata):
    self.beginResetModel()
    self.__stockdata = stockdata
    self.endResetModel()
    @

    I took the example from this website:
    http://www.nullege.com/codes/show/src@o@m@omg-0.3.1@omg@models@simplelistmodel.py/42/PyQt4.QtCore.QAbstractListModel.beginResetModel/python



  • There is something like " self.dataChanged.emit(index, index, ())" but I haven't found how to use reset and signal together to refresh my view yet.



  • somebody? any idea how?
    Is it possible to refresh QAbstractListModel getting data from file at all?


  • Lifetime Qt Champion

    Hi,

    You could use a QFileSystemWatcher so you get the information that the file has been modified and re-read it.

    Hope it helps



  • I use QFileSystemWatcher like that:
    @
    file_check = QtCore.QFileSystemWatcher(['/home/user/file.txt'])
    file_check.fileChanged.connect(resetItems)@

    "resetItems" looks like that:

    @def resetItems(self,stockdata):
    self.beginResetModel()
    self.stockdata = stockdata
    self.endResetModel()@

    it looks fine but when I run script I got the error:

    TypeError: resetItems() takes exactly 2 arguments (1 given)

    Could it be mistake in QFileSystemWatcher syntax?

    thx for reply!



  • Or problem is related how I reset model:

    @ def resetItems(self):
    self.beginResetModel()
    self.__stockdata = stockdata
    self.endResetModel()@

    Error:
    AttributeError: 'QString' object has no attribute 'beginResetModel'


  • Lifetime Qt Champion

    It looks like you are mixing several things here. Why did you change your class base type ?



  • @SGaist what do you mean by changing my class base type?, are you talking about 'stockdata' vs '__stockdata' ?
    What I understand, my app is running, 'QWatcher' checks if the source file hasn't been changed if yes it runs 'resetItems'.



  • I checked and QWatcher works fine. Problem is related to function resetItems but I haven't found solution.. any idea?


  • Lifetime Qt Champion

    @AttributeError: ‘QString’ object has no attribute ‘beginResetModel’@

    means that you are trying to call beginResetModel on a QString class, which is wrong.

    stockdata and __stockdata don't seem to represent the same thing, you should use more meaningful names for your variables to make your code easier to understand



  • how then resetItems has to look like? in this particular case. thx


  • Lifetime Qt Champion

    It should be part of your subclass of QAbstractItemModel



  • what you have written means that this is wrong ?

    @class StockListModel(QtCore.QAbstractListModel):
    def init(self, stockdata = [], parent = None):
    QtCore.QAbstractListModel.init(self, parent)
    self.stockdata = stockdata

        def getItems(self):
           return stockdata
    

    #resetItems:
    def resetItems(self,stockdata):
    self.beginResetModel()
    self.stockdata = stockdata
    self.endResetModel()

        def rowCount(self, parent):
            return len(self.stockdata)
            
        def data(self, index, role):        
            if role == QtCore.Qt.DisplayRole:
                row = index.row()
                value = self.stockdata[row]
                return value
                
        file_check = QtCore.QFileSystemWatcher(['/home/user/Desktop/plik.txt'])
        file_check.fileChanged.connect(resetItems)
    

    if name == 'main':
    app = QtGui.QApplication(sys.argv)
    app.setStyle("plastique")

        tableView = QtGui.QTableView()      
        tableView.show()
     
        a = os.popen("cat /home/user/Desktop/plik.txt")
        a = a.read()
        time_variable = QtCore.QString("%s"%a)
     
        model = StockListModel([time_variable])
     
        tableView.setModel(model)
        sys.exit(app.exec_())@
    

    and instead of QtCore.QAbstractListModel i should use QtCore.QAbstractItemModel ? or add aditional subclass?


  • Lifetime Qt Champion

    Shouldn't stockdata be a list ? If so, your connection doesn't make sense



  • Yes it is a list but I didn't paste the whole code. There is only one cell in this code. What do you mean "connection doesn't make sense", which part?


  • Lifetime Qt Champion

    fileChanged gives you the path of the file that changed, not it's content, so basically you are replacing your list by a string.

    Also, why are you using the model/view approach if you only have one entry ?



  • Model view approach is needed for let's say full version of the script.

    I think I get your point about string. Let me check that.


  • Lifetime Qt Champion

    The signal will just tell you that the file has changed, it will not reload the content for you. You'll have to parse the file again and update stockdata with what you just read from it



  • One more thing.
    file_check = QtCore.QFileSystemWatcher(['/home/user/Desktop/plik.txt'])
    file_check only checks if file was changed if was:

    file_check.fileChanged.connect(resetItems)
    it sends signal to 'resetItems' and 'resetItems' should reload data, true?
    and I have to find a way how accept the string parameter emitted by fileChanged..



  • Is it better ? but I have got error like that:
    AttributeError: 'StockListModel' object has no attribute 'beginResetModel'

    @def init(self, stockdata = [], parent = None):
    QtCore.QAbstractListModel.init(self, parent)
    self.stockdata = stockdata
    self.file_check = QtCore.QFileSystemWatcher(['/home/user/Desktop/file.txt'])
    self.file_check.fileChanged.connect(self.resetItems)

        def getItems(self):
           return stockdata
    
        @QtCore.pyqtSlot(str)
        def resetItems(self, path):
           self.beginResetModel()
           ....
    

    @


  • Lifetime Qt Champion

    You have to the data reloading yourself. Like in your main function.

    As for beginResetModel I don't know why it's saying that



  • I cannot find a solution for this error.
    @SGaist, writing "reloading data" do you mean file with data?


  • Lifetime Qt Champion

    Yes, that's what I mean. On you program startup you are reading that file and put it's content in the stockdata variable. When the QFileSystemWatcher triggers, you must do that parsing again.



  • Finally solved. 'beginResetModel', 'end...' and 'self.stockdata' in 'resetItems' are not needed. It can be done without it. Thank you for support.


  • Lifetime Qt Champion

    You're welcome !

    Since you have it working now, please update the thread title prepending [solved] so that other forum users may know a solution has been found :)


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.