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. QAbstractListModel not updating row count in QML when rows are added outside of my MainWindow's constructor.

QAbstractListModel not updating row count in QML when rows are added outside of my MainWindow's constructor.

Scheduled Pinned Locked Moved Solved Qt for Python
11 Posts 2 Posters 1.6k 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.
  • C Offline
    C Offline
    cray12399
    wrote on last edited by cray12399
    #1

    Hello all,

    To start off, while I have a bit of experience with QtWidgets, I am a newb when it comes to QML and Qt Quick. I am developing an app using PySide2 + QML and have been dealing with an issue with the QAbstractListModel for 2 days so far. When I append rows to my model anywhere outside of the constructor of my MainWindow class (which is a QObject), while the rows are added, the rowCount() remains zero on the QML side of my code. If I append rows within the constructor, the model works perfectly as expected. Here is the code for my model:

    class PhoneDataModel(QAbstractListModel):
        NameRole = Qt.UserRole + 1000
        AddressRole = Qt.UserRole + 1001
        BtSocketConnectedRole = Qt.UserRole + 1002
    
        def __init__(self, phone_data=None, parent=None):
            super(PhoneDataModel, self).__init__(parent)
            if phone_data is None:
                self.__phone_data = []
            else:
                self.__phone_data = phone_data
    
        def rowCount(self, parent=QModelIndex()):
            return len(self.__phone_data)
    
        def data(self, index, role=Qt.DisplayRole):
            if 0 <= index.row() < self.rowCount() and index.isValid():
                if role == PhoneDataModel.NameRole:
                    return self.__phone_data[index.row()]["name"]
                elif role == PhoneDataModel.AddressRole:
                    return self.__phone_data[index.row()]["address"]
                elif role == PhoneDataModel.BtSocketConnectedRole:
                    return self.__phone_data[index.row()]["btSocketConnected"]
    
        @Slot(int, result='QVariant')
        def get(self, row):
            if 0 <= row < self.rowCount():
                return self.__phone_data[row]
    
        def roleNames(self):
            roles = super().roleNames()
            roles[PhoneDataModel.NameRole] = b"name"
            roles[PhoneDataModel.AddressRole] = b"address"
            roles[PhoneDataModel.BtSocketConnectedRole] = b"btSocketConnected"
            return roles
    
        def appendRow(self, name, address, bt_socket_connected):
            self.beginInsertRows(QModelIndex(), self.rowCount(), self.rowCount())
            self.__phone_data.append({'name': name, 'address': address, 'btSocketConnected': bt_socket_connected})
            print(self.__phone_data)
            self.endInsertRows()
    
        def removeRow(self, row, parent=None, *args, **kwargs):
            self.beginRemoveRows(QModelIndex(), row, row)
            self.__phone_data.pop(row)
            self.endRemoveRows()
    
        def setData(self, index, value, role=Qt.EditRole):
            if not index.isValid():
                return False
            if role == Qt.EditRole:
                item = index.internalPointer()
                item.set_name(value)
            return True
    

    And here all of the code from my MainWindow that interacts with the model:

    class MainWindow(QObject):
        def __init__(self, backend_socket):
            super().__init__(None)
    
            self.__phone_connection_data = {}
            self.__phone_data_model = PhoneDataModel([])
            self.__phone_data_model.appendRow('phone 1', '1001', True)  # This works perfectly.
            self.__backend_socket = backend_socket
            self.__thread_pool = QThreadPool(self)
    
            self.__initialize_gui()
            self.__initialize_looper_thread(backend_socket)
    
            self.log = lambda level, message, exception=False: \
                log(self.__backend_socket, level, message, exception)
    
            self.log('i', "GUI started successfully!")
    
    ...
    
        def __initialize_looper_thread(self, backend_socket):
            self.__looper_thread = LooperThread(backend_socket, self)
            self.__looper_thread.set_phone_data_signal.connect(
                lambda phone_connection_data: self.set_phone_data(phone_connection_data)) # Signal that connects to method that adds row to model
            self.__looper_thread.start()
    
    @Property(QObject)
        def phoneDataModel(self):
            return self.__phone_data_model
    
    ...
    
        def set_phone_data(self, phone_connection_data):
            self.__phone_connection_data = phone_connection_data
    
            for phone_address in phone_connection_data.keys():
                name = phone_connection_data[phone_address]['name']
                bt_socket_connected = phone_connection_data[phone_address]['socket_connected']
                # self.__phone_data_model_provider.add_phone(name, phone_address, bt_socket_connected) # Original code, commented out for testing purposes.
            self.__phone_data_model.appendRow('phone 3', '1001', True)  # This doesnt work.
    

    The main window receives a signal from my looper thread with the data of a new phone, which triggers the set_phone_data() method. The signal is working perfectly fine and the method gets called every time my looper thread emits the signal.

    Since my QML isn't formatting right, here are the pastebins:
    MainWindow:
    https://pastebin.com/gPNRk2wc

    PhoneSelector (Essentially my own custom ComboBox because the stock combobox wasn't doin' it for me):
    https://pastebin.com/AAqtq4Hj

    Here are things I have tried so far:

    • Putting the count into a separate property using the Property class from QtCore.

    • Providing the model via a separate QObject

    • Making the main window the parent of the model

    • Modifying the model using a QThread (in case it was a problem with the MainWindow QObject)

    Expected behavior:

    • Once a new phone is added, rowCount() is greater than one and the label goes from "No phones connected..." to the name of the current phone in the model. The MouseArea becomes enabled so the user can interact with the PhoneSelecter

    Actual behavior:

    • PhoneSelector behaves as if the rowCount() is 0. Mouse area is disabled and the label says "No Phones Connected..." If I make the MouseArea always enabled, the ListView shows the phones in my model, but the count is still zero. UNLESS, I add the phones within my main window's constructor. If I add a phone in the constructor and add a phone in my set_phone_data method, both phones are shown in my list, but the count on the QML side is just 1 rather than 2.
    eyllanescE 1 Reply Last reply
    0
    • C cray12399

      @eyllanesc Alright, I implemented the code. Here is the output I got:

      file:///home/chris/Documents/Programming/Synchrony/Desktop/GUI/MainWindow.qml:26:5: QML Settings: Failed to initialize QSettings instance. Status code is: 1
      file:///home/chris/Documents/Programming/Synchrony/Desktop/GUI/MainWindow.qml:26:5: QML Settings: The following application identifiers have not been set: QVector("organizationName", "organizationDomain")
      Icon theme "elementary" not found.
      Icon theme "gnome" not found.
      <_MainThread(MainThread, started 139841449985856)>
      The row count is 1
      This print statement is in set_phone_data right before the line appending a row to the model.
      This statement is in set_phone_data right after the line appending a row to the model: The row count is 2
      

      I kept the same code as above where a phone was added in the constructor, and the the set_phone_data statement. I dont know if I mentioned it in the original post, but I actually tried this same test and the row count increments on the Python side fine. However, on the QML side, it doesn't increment when a phone is added via the set_phone_data method. The way I know this is in my PhoneSelector QML, I set the QLabel to show the rowCount() of the model with the following code:

          Label {
              id: currentItemText
              anchors.verticalCenter: parent.verticalCenter
              anchors.left: parent.left
              anchors.right: downArrow.left
              anchors.rightMargin: 15
              anchors.leftMargin: 15
              color: "black"
             // text: count > 0 ? phoneSelector.currentText : "No Phones Connected..."
              text: "Row count is " + phoneSelector.model.rowCount()
              elide: Text.ElideRight
          }
      

      Using the code from my example, where two phones are added, while the rowCount() returns 2 in the python code, it is 1 in the actual GUI, despite two phones being listed in my list model. Here is a picture:

      https://imgur.com/a/SplNJZc

      This picture was taken after the set_phone_data method was run. Using the same QML code to output the row count, if I don't add the phone in the constructor, it shows 0 instead of 1, but it will still show the phone in the list if I enable the mouse area so that the listview can be expanded. So it seems that the row count is not updating when a phone is added outside the constructor.

      eyllanescE Offline
      eyllanescE Offline
      eyllanesc
      wrote on last edited by eyllanesc
      #10

      @cray12399 I can't tell you where the error is since I can't analyze it completely since they are just pieces of code but I can point out some observations:

      • rowCount is not a property but a method, so they are not used to make a binding, that means that if the number of rows is changed then the property will not be reevaluated. There are 2 options: Use the rowsInserted, rowsRemoved, etc tokens to update the qml property, or create a qproperty called count associated with a signal so that it can be used in bindings.

      first option:

      Connections{
          target: <FOO>.phoneDataModel
          function onRowsInserted(){
              currentItemText.text = "Row count is " + <FOO>.phoneDataModel.rowCount()
          }
          // function onRowsRemoved(){}
      }

      If you want me to help you develop some work then you can write to my email: e.yllanescucho@gmal.com.

      C 1 Reply Last reply
      0
      • C cray12399

        Hello all,

        To start off, while I have a bit of experience with QtWidgets, I am a newb when it comes to QML and Qt Quick. I am developing an app using PySide2 + QML and have been dealing with an issue with the QAbstractListModel for 2 days so far. When I append rows to my model anywhere outside of the constructor of my MainWindow class (which is a QObject), while the rows are added, the rowCount() remains zero on the QML side of my code. If I append rows within the constructor, the model works perfectly as expected. Here is the code for my model:

        class PhoneDataModel(QAbstractListModel):
            NameRole = Qt.UserRole + 1000
            AddressRole = Qt.UserRole + 1001
            BtSocketConnectedRole = Qt.UserRole + 1002
        
            def __init__(self, phone_data=None, parent=None):
                super(PhoneDataModel, self).__init__(parent)
                if phone_data is None:
                    self.__phone_data = []
                else:
                    self.__phone_data = phone_data
        
            def rowCount(self, parent=QModelIndex()):
                return len(self.__phone_data)
        
            def data(self, index, role=Qt.DisplayRole):
                if 0 <= index.row() < self.rowCount() and index.isValid():
                    if role == PhoneDataModel.NameRole:
                        return self.__phone_data[index.row()]["name"]
                    elif role == PhoneDataModel.AddressRole:
                        return self.__phone_data[index.row()]["address"]
                    elif role == PhoneDataModel.BtSocketConnectedRole:
                        return self.__phone_data[index.row()]["btSocketConnected"]
        
            @Slot(int, result='QVariant')
            def get(self, row):
                if 0 <= row < self.rowCount():
                    return self.__phone_data[row]
        
            def roleNames(self):
                roles = super().roleNames()
                roles[PhoneDataModel.NameRole] = b"name"
                roles[PhoneDataModel.AddressRole] = b"address"
                roles[PhoneDataModel.BtSocketConnectedRole] = b"btSocketConnected"
                return roles
        
            def appendRow(self, name, address, bt_socket_connected):
                self.beginInsertRows(QModelIndex(), self.rowCount(), self.rowCount())
                self.__phone_data.append({'name': name, 'address': address, 'btSocketConnected': bt_socket_connected})
                print(self.__phone_data)
                self.endInsertRows()
        
            def removeRow(self, row, parent=None, *args, **kwargs):
                self.beginRemoveRows(QModelIndex(), row, row)
                self.__phone_data.pop(row)
                self.endRemoveRows()
        
            def setData(self, index, value, role=Qt.EditRole):
                if not index.isValid():
                    return False
                if role == Qt.EditRole:
                    item = index.internalPointer()
                    item.set_name(value)
                return True
        

        And here all of the code from my MainWindow that interacts with the model:

        class MainWindow(QObject):
            def __init__(self, backend_socket):
                super().__init__(None)
        
                self.__phone_connection_data = {}
                self.__phone_data_model = PhoneDataModel([])
                self.__phone_data_model.appendRow('phone 1', '1001', True)  # This works perfectly.
                self.__backend_socket = backend_socket
                self.__thread_pool = QThreadPool(self)
        
                self.__initialize_gui()
                self.__initialize_looper_thread(backend_socket)
        
                self.log = lambda level, message, exception=False: \
                    log(self.__backend_socket, level, message, exception)
        
                self.log('i', "GUI started successfully!")
        
        ...
        
            def __initialize_looper_thread(self, backend_socket):
                self.__looper_thread = LooperThread(backend_socket, self)
                self.__looper_thread.set_phone_data_signal.connect(
                    lambda phone_connection_data: self.set_phone_data(phone_connection_data)) # Signal that connects to method that adds row to model
                self.__looper_thread.start()
        
        @Property(QObject)
            def phoneDataModel(self):
                return self.__phone_data_model
        
        ...
        
            def set_phone_data(self, phone_connection_data):
                self.__phone_connection_data = phone_connection_data
        
                for phone_address in phone_connection_data.keys():
                    name = phone_connection_data[phone_address]['name']
                    bt_socket_connected = phone_connection_data[phone_address]['socket_connected']
                    # self.__phone_data_model_provider.add_phone(name, phone_address, bt_socket_connected) # Original code, commented out for testing purposes.
                self.__phone_data_model.appendRow('phone 3', '1001', True)  # This doesnt work.
        

        The main window receives a signal from my looper thread with the data of a new phone, which triggers the set_phone_data() method. The signal is working perfectly fine and the method gets called every time my looper thread emits the signal.

        Since my QML isn't formatting right, here are the pastebins:
        MainWindow:
        https://pastebin.com/gPNRk2wc

        PhoneSelector (Essentially my own custom ComboBox because the stock combobox wasn't doin' it for me):
        https://pastebin.com/AAqtq4Hj

        Here are things I have tried so far:

        • Putting the count into a separate property using the Property class from QtCore.

        • Providing the model via a separate QObject

        • Making the main window the parent of the model

        • Modifying the model using a QThread (in case it was a problem with the MainWindow QObject)

        Expected behavior:

        • Once a new phone is added, rowCount() is greater than one and the label goes from "No phones connected..." to the name of the current phone in the model. The MouseArea becomes enabled so the user can interact with the PhoneSelecter

        Actual behavior:

        • PhoneSelector behaves as if the rowCount() is 0. Mouse area is disabled and the label says "No Phones Connected..." If I make the MouseArea always enabled, the ListView shows the phones in my model, but the count is still zero. UNLESS, I add the phones within my main window's constructor. If I add a phone in the constructor and add a phone in my set_phone_data method, both phones are shown in my list, but the count on the QML side is just 1 rather than 2.
        eyllanescE Offline
        eyllanescE Offline
        eyllanesc
        wrote on last edited by eyllanesc
        #2

        @cray12399

        1. Change to self.__looper_thread.set_phone_data_signal.connect(self.set_phone_data), lambda is useless.

        2. Have you verified that the set_phone_data method is called?

        If you want me to help you develop some work then you can write to my email: e.yllanescucho@gmal.com.

        1 Reply Last reply
        0
        • C Offline
          C Offline
          cray12399
          wrote on last edited by
          #3
          1. Thank you for the advice on the lambda. I thought I needed it to get the data from the signal to go into the method, but it works perfectly fine without lambda.

          2. Yes, I verified that the set_phone_data method is called by putting print(phone_connection_data) in the method. The print statement shows in the output with the correct data, so I know it is working as intended (besides the updating the model part, of course.)

          eyllanescE 1 Reply Last reply
          0
          • C cray12399
            1. Thank you for the advice on the lambda. I thought I needed it to get the data from the signal to go into the method, but it works perfectly fine without lambda.

            2. Yes, I verified that the set_phone_data method is called by putting print(phone_connection_data) in the method. The print statement shows in the output with the correct data, so I know it is working as intended (besides the updating the model part, of course.)

            eyllanescE Offline
            eyllanescE Offline
            eyllanesc
            wrote on last edited by
            #4

            @cray12399 Then the error may be elsewhere. Run your script from the console and let me know if any error messages are shown, don't use an IDE as many don't know how to handle Qt errors and hide them.

            If you want me to help you develop some work then you can write to my email: e.yllanescucho@gmal.com.

            C 1 Reply Last reply
            0
            • eyllanescE eyllanesc

              @cray12399 Then the error may be elsewhere. Run your script from the console and let me know if any error messages are shown, don't use an IDE as many don't know how to handle Qt errors and hide them.

              C Offline
              C Offline
              cray12399
              wrote on last edited by cray12399
              #5

              @eyllanesc Thanks for the tip! I wish I would've known about the terminal thing earlier, it would've saved me some headache on other issues I have dealt with. I ran it in the terminal and here is what I got:

              QQmlExpression: Expression file:///home/chris/Documents/Programming/Synchrony/Desktop/GUI/MainWindow.qml:16:5 depends on non-NOTIFYable properties:
                  MainWindow::phoneDataModel
              file:///home/chris/Documents/Programming/Synchrony/Desktop/GUI/MainWindow.qml:26:5: QML Settings: Failed to initialize QSettings instance. Status code is: 1
              file:///home/chris/Documents/Programming/Synchrony/Desktop/GUI/MainWindow.qml:26:5: QML Settings: The following application identifiers have not been set: QVector("organizationName", "organizationDomain")
              Icon theme "elementary" not found.
              Icon theme "gnome" not found.
              This print statement is in set_phone_data right before the line appending a row to the model.
              
              

              I added a print statement right before the appendRow() code in the set_phone_data method as you can see above, and no errors popped up after the print statement. However, I am assuming the problem has to do with this line:

              QQmlExpression: Expression file:///home/chris/Documents/Programming/Synchrony/Desktop/GUI/MainWindow.qml:16:5 depends on non-NOTIFYable properties:
                  MainWindow::phoneDataModel
              

              But I am not sure what the error means.

              eyllanescE 1 Reply Last reply
              0
              • C cray12399

                @eyllanesc Thanks for the tip! I wish I would've known about the terminal thing earlier, it would've saved me some headache on other issues I have dealt with. I ran it in the terminal and here is what I got:

                QQmlExpression: Expression file:///home/chris/Documents/Programming/Synchrony/Desktop/GUI/MainWindow.qml:16:5 depends on non-NOTIFYable properties:
                    MainWindow::phoneDataModel
                file:///home/chris/Documents/Programming/Synchrony/Desktop/GUI/MainWindow.qml:26:5: QML Settings: Failed to initialize QSettings instance. Status code is: 1
                file:///home/chris/Documents/Programming/Synchrony/Desktop/GUI/MainWindow.qml:26:5: QML Settings: The following application identifiers have not been set: QVector("organizationName", "organizationDomain")
                Icon theme "elementary" not found.
                Icon theme "gnome" not found.
                This print statement is in set_phone_data right before the line appending a row to the model.
                
                

                I added a print statement right before the appendRow() code in the set_phone_data method as you can see above, and no errors popped up after the print statement. However, I am assuming the problem has to do with this line:

                QQmlExpression: Expression file:///home/chris/Documents/Programming/Synchrony/Desktop/GUI/MainWindow.qml:16:5 depends on non-NOTIFYable properties:
                    MainWindow::phoneDataModel
                

                But I am not sure what the error means.

                eyllanescE Offline
                eyllanescE Offline
                eyllanesc
                wrote on last edited by
                #6

                @cray12399 Change:

                @Property(QObject)
                def phoneDataModel(self):
                    return self.__phone_data_model
                

                to

                def get_phoneDataModel(self):
                    return self.__phone_data_model
                
                phoneDataModel = Property(QObject, fget=get_phoneDataModel, constant=True)
                

                If you want me to help you develop some work then you can write to my email: e.yllanescucho@gmal.com.

                C 1 Reply Last reply
                1
                • eyllanescE eyllanesc

                  @cray12399 Change:

                  @Property(QObject)
                  def phoneDataModel(self):
                      return self.__phone_data_model
                  

                  to

                  def get_phoneDataModel(self):
                      return self.__phone_data_model
                  
                  phoneDataModel = Property(QObject, fget=get_phoneDataModel, constant=True)
                  
                  C Offline
                  C Offline
                  cray12399
                  wrote on last edited by
                  #7

                  @eyllanesc I changed the code you said and it fixed the error in the terminal, but I am still having the same problem, unfortunately. This is the terminal output now:

                  file:///home/chris/Documents/Programming/Synchrony/Desktop/GUI/MainWindow.qml:26:5: QML Settings: Failed to initialize QSettings instance. Status code is: 1
                  file:///home/chris/Documents/Programming/Synchrony/Desktop/GUI/MainWindow.qml:26:5: QML Settings: The following application identifiers have not been set: 
                  Icon theme "elementary" not found.
                  Icon theme "gnome" not found.
                  This print statement is in set_phone_data right before the line appending a row to the model.
                  
                  eyllanescE 1 Reply Last reply
                  0
                  • C cray12399

                    @eyllanesc I changed the code you said and it fixed the error in the terminal, but I am still having the same problem, unfortunately. This is the terminal output now:

                    file:///home/chris/Documents/Programming/Synchrony/Desktop/GUI/MainWindow.qml:26:5: QML Settings: Failed to initialize QSettings instance. Status code is: 1
                    file:///home/chris/Documents/Programming/Synchrony/Desktop/GUI/MainWindow.qml:26:5: QML Settings: The following application identifiers have not been set: 
                    Icon theme "elementary" not found.
                    Icon theme "gnome" not found.
                    This print statement is in set_phone_data right before the line appending a row to the model.
                    
                    eyllanescE Offline
                    eyllanescE Offline
                    eyllanesc
                    wrote on last edited by
                    #8

                    @cray12399

                    If you add:

                    import threading
                    
                    def set_phone_data(self, phone_connection_data):
                        print(threading.current_thread()) # <----
                        # ...
                        self.__phone_data_model.appendRow('phone 3', '1001', True)  # This doesnt work.
                        print(self.__phone_data_model.rowCount()) # <----
                    

                    What is printed on the console?

                    How to verify that the number of rows does not change?

                    If you want me to help you develop some work then you can write to my email: e.yllanescucho@gmal.com.

                    C 1 Reply Last reply
                    0
                    • eyllanescE eyllanesc

                      @cray12399

                      If you add:

                      import threading
                      
                      def set_phone_data(self, phone_connection_data):
                          print(threading.current_thread()) # <----
                          # ...
                          self.__phone_data_model.appendRow('phone 3', '1001', True)  # This doesnt work.
                          print(self.__phone_data_model.rowCount()) # <----
                      

                      What is printed on the console?

                      How to verify that the number of rows does not change?

                      C Offline
                      C Offline
                      cray12399
                      wrote on last edited by cray12399
                      #9

                      @eyllanesc Alright, I implemented the code. Here is the output I got:

                      file:///home/chris/Documents/Programming/Synchrony/Desktop/GUI/MainWindow.qml:26:5: QML Settings: Failed to initialize QSettings instance. Status code is: 1
                      file:///home/chris/Documents/Programming/Synchrony/Desktop/GUI/MainWindow.qml:26:5: QML Settings: The following application identifiers have not been set: QVector("organizationName", "organizationDomain")
                      Icon theme "elementary" not found.
                      Icon theme "gnome" not found.
                      <_MainThread(MainThread, started 139841449985856)>
                      The row count is 1
                      This print statement is in set_phone_data right before the line appending a row to the model.
                      This statement is in set_phone_data right after the line appending a row to the model: The row count is 2
                      

                      I kept the same code as above where a phone was added in the constructor, and the the set_phone_data statement. I dont know if I mentioned it in the original post, but I actually tried this same test and the row count increments on the Python side fine. However, on the QML side, it doesn't increment when a phone is added via the set_phone_data method. The way I know this is in my PhoneSelector QML, I set the QLabel to show the rowCount() of the model with the following code:

                          Label {
                              id: currentItemText
                              anchors.verticalCenter: parent.verticalCenter
                              anchors.left: parent.left
                              anchors.right: downArrow.left
                              anchors.rightMargin: 15
                              anchors.leftMargin: 15
                              color: "black"
                             // text: count > 0 ? phoneSelector.currentText : "No Phones Connected..."
                              text: "Row count is " + phoneSelector.model.rowCount()
                              elide: Text.ElideRight
                          }
                      

                      Using the code from my example, where two phones are added, while the rowCount() returns 2 in the python code, it is 1 in the actual GUI, despite two phones being listed in my list model. Here is a picture:

                      https://imgur.com/a/SplNJZc

                      This picture was taken after the set_phone_data method was run. Using the same QML code to output the row count, if I don't add the phone in the constructor, it shows 0 instead of 1, but it will still show the phone in the list if I enable the mouse area so that the listview can be expanded. So it seems that the row count is not updating when a phone is added outside the constructor.

                      eyllanescE 1 Reply Last reply
                      0
                      • C cray12399

                        @eyllanesc Alright, I implemented the code. Here is the output I got:

                        file:///home/chris/Documents/Programming/Synchrony/Desktop/GUI/MainWindow.qml:26:5: QML Settings: Failed to initialize QSettings instance. Status code is: 1
                        file:///home/chris/Documents/Programming/Synchrony/Desktop/GUI/MainWindow.qml:26:5: QML Settings: The following application identifiers have not been set: QVector("organizationName", "organizationDomain")
                        Icon theme "elementary" not found.
                        Icon theme "gnome" not found.
                        <_MainThread(MainThread, started 139841449985856)>
                        The row count is 1
                        This print statement is in set_phone_data right before the line appending a row to the model.
                        This statement is in set_phone_data right after the line appending a row to the model: The row count is 2
                        

                        I kept the same code as above where a phone was added in the constructor, and the the set_phone_data statement. I dont know if I mentioned it in the original post, but I actually tried this same test and the row count increments on the Python side fine. However, on the QML side, it doesn't increment when a phone is added via the set_phone_data method. The way I know this is in my PhoneSelector QML, I set the QLabel to show the rowCount() of the model with the following code:

                            Label {
                                id: currentItemText
                                anchors.verticalCenter: parent.verticalCenter
                                anchors.left: parent.left
                                anchors.right: downArrow.left
                                anchors.rightMargin: 15
                                anchors.leftMargin: 15
                                color: "black"
                               // text: count > 0 ? phoneSelector.currentText : "No Phones Connected..."
                                text: "Row count is " + phoneSelector.model.rowCount()
                                elide: Text.ElideRight
                            }
                        

                        Using the code from my example, where two phones are added, while the rowCount() returns 2 in the python code, it is 1 in the actual GUI, despite two phones being listed in my list model. Here is a picture:

                        https://imgur.com/a/SplNJZc

                        This picture was taken after the set_phone_data method was run. Using the same QML code to output the row count, if I don't add the phone in the constructor, it shows 0 instead of 1, but it will still show the phone in the list if I enable the mouse area so that the listview can be expanded. So it seems that the row count is not updating when a phone is added outside the constructor.

                        eyllanescE Offline
                        eyllanescE Offline
                        eyllanesc
                        wrote on last edited by eyllanesc
                        #10

                        @cray12399 I can't tell you where the error is since I can't analyze it completely since they are just pieces of code but I can point out some observations:

                        • rowCount is not a property but a method, so they are not used to make a binding, that means that if the number of rows is changed then the property will not be reevaluated. There are 2 options: Use the rowsInserted, rowsRemoved, etc tokens to update the qml property, or create a qproperty called count associated with a signal so that it can be used in bindings.

                        first option:

                        Connections{
                            target: <FOO>.phoneDataModel
                            function onRowsInserted(){
                                currentItemText.text = "Row count is " + <FOO>.phoneDataModel.rowCount()
                            }
                            // function onRowsRemoved(){}
                        }

                        If you want me to help you develop some work then you can write to my email: e.yllanescucho@gmal.com.

                        C 1 Reply Last reply
                        0
                        • eyllanescE eyllanesc

                          @cray12399 I can't tell you where the error is since I can't analyze it completely since they are just pieces of code but I can point out some observations:

                          • rowCount is not a property but a method, so they are not used to make a binding, that means that if the number of rows is changed then the property will not be reevaluated. There are 2 options: Use the rowsInserted, rowsRemoved, etc tokens to update the qml property, or create a qproperty called count associated with a signal so that it can be used in bindings.

                          first option:

                          Connections{
                              target: <FOO>.phoneDataModel
                              function onRowsInserted(){
                                  currentItemText.text = "Row count is " + <FOO>.phoneDataModel.rowCount()
                              }
                              // function onRowsRemoved(){}
                          }
                          C Offline
                          C Offline
                          cray12399
                          wrote on last edited by
                          #11

                          @eyllanesc Thank you my friend! Your method works and I learned a new thing about using QML. :)

                          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