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. Populating a ListView with Python Objects
Forum Updated to NodeBB v4.3 + New Features

Populating a ListView with Python Objects

Scheduled Pinned Locked Moved Unsolved Qt for Python
10 Posts 5 Posters 2.3k 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
    christofer
    wrote on 14 Feb 2020, 00:15 last edited by
    #1

    I want to populate a ListView with objects from Python. I've been able to make a ListView work using ListModel+ ListElement in QML but not from Python. From what I've read, it seems I should use a QAbstractListModel but so far I haven't been able to get the values of the python objects to show up. It seems my QAbstractListModel's rowCount() and data() functions don't even get called.

    I posted a (hopefully) lean example in a GitLab project

    What am I missing?
    Thanks,
    -chris

    J 1 Reply Last reply 14 Feb 2020, 19:09
    0
    • C Offline
      C Offline
      christofer
      wrote on 14 Feb 2020, 18:53 last edited by
      #2

      @Denni-0 Thanks for the tips Denni!

      1 Reply Last reply
      0
      • C christofer
        14 Feb 2020, 00:15

        I want to populate a ListView with objects from Python. I've been able to make a ListView work using ListModel+ ListElement in QML but not from Python. From what I've read, it seems I should use a QAbstractListModel but so far I haven't been able to get the values of the python objects to show up. It seems my QAbstractListModel's rowCount() and data() functions don't even get called.

        I posted a (hopefully) lean example in a GitLab project

        What am I missing?
        Thanks,
        -chris

        J Offline
        J Offline
        JonB
        wrote on 14 Feb 2020, 19:09 last edited by JonB
        #3

        @christofer
        Having glanced at your code. I can't help you if you say rowCount() or data() are never called. I know nothing about QML so only you know if your code is being called. It looks fine as-is except that your data() method needs work.

            def data(self, index, role=Qt.DisplayRole):
                print("data: " + self.items)
                return self.items
        

        First it must return the correct indvidual element according to the index: QModelIndex parameter, and second it must only do so for the DisplayRole case on the role parameter, not for all cases as you have done. Until you have done those 2 it won't work right.

        If/when that's sorted out, you're trying to have data() return a class MyItem data item, say for the DisplayRole when it wants to show it. I can't imagine what a Qt view is going to make of that. If you're lucky it might use str(instanceMyItem), and I don't know what that looks like.

        C 1 Reply Last reply 15 Feb 2020, 05:26
        2
        • J JonB
          14 Feb 2020, 19:09

          @christofer
          Having glanced at your code. I can't help you if you say rowCount() or data() are never called. I know nothing about QML so only you know if your code is being called. It looks fine as-is except that your data() method needs work.

              def data(self, index, role=Qt.DisplayRole):
                  print("data: " + self.items)
                  return self.items
          

          First it must return the correct indvidual element according to the index: QModelIndex parameter, and second it must only do so for the DisplayRole case on the role parameter, not for all cases as you have done. Until you have done those 2 it won't work right.

          If/when that's sorted out, you're trying to have data() return a class MyItem data item, say for the DisplayRole when it wants to show it. I can't imagine what a Qt view is going to make of that. If you're lucky it might use str(instanceMyItem), and I don't know what that looks like.

          C Offline
          C Offline
          christofer
          wrote on 15 Feb 2020, 05:26 last edited by
          #4

          @JonB @Denni-0 I've made changes based on your feedback. Thanks. Still not sure the changes are correct because the functions do not get called. But at least it's closer to correct.

          C J 2 Replies Last reply 15 Feb 2020, 05:41
          0
          • C christofer
            15 Feb 2020, 05:26

            @JonB @Denni-0 I've made changes based on your feedback. Thanks. Still not sure the changes are correct because the functions do not get called. But at least it's closer to correct.

            C Offline
            C Offline
            christofer
            wrote on 15 Feb 2020, 05:41 last edited by
            #5

            @Denni-0 just a side note, but the PySide2 QCoreApplication, QGuiApplication, and QApplication have exec_() functions. The docs say things like "see exec()" but it doesn't exist. I get an AttributeError if I try to use it. I'm using PySide2 version 5.14.1

            1 Reply Last reply
            0
            • E Offline
              E Offline
              eyllanesc
              wrote on 15 Feb 2020, 06:16 last edited by
              #6

              @christofer You cannot expose a Python Object to QML, what you can do is export a QObject through the model as I have implemented in the PR to your repo.

              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
              • E Offline
                E Offline
                eyllanesc
                wrote on 15 Feb 2020, 06:24 last edited by
                #7

                @christofer You can also make the model expose each attribute of the items through the roles as I show in my second PR

                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 16 Feb 2020, 17:26
                0
                • C christofer
                  15 Feb 2020, 05:26

                  @JonB @Denni-0 I've made changes based on your feedback. Thanks. Still not sure the changes are correct because the functions do not get called. But at least it's closer to correct.

                  J Offline
                  J Offline
                  JonB
                  wrote on 15 Feb 2020, 09:31 last edited by
                  #8

                  @christofer said in Populating a ListView with Python Objects:

                  Still not sure the changes are correct because the functions do not get called

                  That sounds like a QML issue. You should heed what @eyllanesc has written, as he seems to know about Python to QML.

                  It really does not matter to try to change from exec_() to exec(). PyQt exposes an exec() (as well as exec_()), PySide does not. As I said, nothing in your existing code I saw needed changing, it was not PyQt4 syntax, it was all correct, except for the implementation of data().

                  1 Reply Last reply
                  0
                  • E eyllanesc
                    15 Feb 2020, 06:24

                    @christofer You can also make the model expose each attribute of the items through the roles as I show in my second PR

                    C Offline
                    C Offline
                    christofer
                    wrote on 16 Feb 2020, 17:26 last edited by christofer
                    #9

                    Thanks @eyllanesc for the MRs! They're very helpful.

                    On using roles for a and b (commit 1e5447) vs just using the display role (commit 83b42b) ... which do you recommend? I like the simple access in the QML model.a, model.b but it seems like making custom roles could conflict with Qt expecting the roles in PySide2.QtCore.Qt.ItemDataRole which makes me think model.display.a, model.display.b is a safer long-term solution.

                    1 Reply Last reply
                    0
                    • L Offline
                      L Offline
                      lbt_
                      wrote on 20 Jan 2021, 00:05 last edited by
                      #10

                      Old post but Google led me here so it seemed like a place to drop a super-simple solution.

                      One approach that works very easily if you have a python list of QObject derived objects is to pass a QVariantList of QObjects and access them via @Property

                      class MyItemModel(QObject):
                      ...
                          @Property(str)
                          def name(self):
                              return self.m_name
                      
                      class MyDataModel(QObject):
                      ...
                          @Property('QVariantList')
                          def names(self):
                              return list(self.m_item_objects_list) 
                      

                      QML:

                      LiistView {
                        id: lv
                          model: mydatamodelinstance.names // setContextProperty of a MyDataModel object
                          delegate: { Text { text: modelData.name } }  // This gets the name property of a MyItemModel
                      }
                      
                      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