Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Is QAbstractItemModel re-entrant
QtWS25 Last Chance

Is QAbstractItemModel re-entrant

Scheduled Pinned Locked Moved Solved General and Desktop
9 Posts 3 Posters 576 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.
  • ocgltdO Offline
    ocgltdO Offline
    ocgltd
    wrote on last edited by ocgltd
    #1

    I am implementing a QAbstractItemModel descendant that interacts with a potentially slow DB. My plan for methods like 'rowCount' is to signal the DB thread to get the info, and signal back the response. While waiting for the response, the rowCount methods starts a new eventloop until the answer arrives. This keeps the thread available to do other work.

    While this generally works, I'm encountering some strange behavior. (The first signal emitted does not reach the slot for 10 seconds, but other slots get their signals normally). I'm starting to wonder if the overlapping method calls in QAbstractItemModel are causing the problem? (While my eventloop waits, other QAIM methods are being called)

    If these overlapping function calls are in fact the problem, is there a better/right way to fetch data from another thread? I don't see any asynchronous methods in QAIM.

    1 Reply Last reply
    0
    • Christian EhrlicherC Christian Ehrlicher

      @ocgltd Sorry but I don't understand your problem. If there are no rows yet, return 0. If you received some rows from the database, return this number. What's so complicated about this?

      ocgltdO Offline
      ocgltdO Offline
      ocgltd
      wrote on last edited by
      #8

      @Christian-Ehrlicher The MVC is very straight forward with blocking code for data retrieval, but making it non blocking (asynchronous) is more challenging. QAbstractItemModel is not easily compatible with asynchronous use.

      I have it working now, but the view shows blank rows until the data arrives. If I hide rows without data then the view keeps asking for more rows until it has enough to fill the screen. So I have settled with showing blank rows. (Dummy data is essential blank column content).

      Christian EhrlicherC 1 Reply Last reply
      0
      • Christian EhrlicherC Offline
        Christian EhrlicherC Offline
        Christian Ehrlicher
        Lifetime Qt Champion
        wrote on last edited by
        #2

        No, QAbstractItemModel can not be used from different threads. It must be used in the main thread.
        Featch your data in a separate thread, emit a signal to transfer the data from this thread to the gui/main thread.

        Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
        Visit the Qt Academy at https://academy.qt.io/catalog

        ocgltdO 1 Reply Last reply
        2
        • Christian EhrlicherC Christian Ehrlicher

          No, QAbstractItemModel can not be used from different threads. It must be used in the main thread.
          Featch your data in a separate thread, emit a signal to transfer the data from this thread to the gui/main thread.

          ocgltdO Offline
          ocgltdO Offline
          ocgltd
          wrote on last edited by
          #3

          @Christian-Ehrlicher That's actually what I'm doing. I have a DB thread which gets requests via signal, and sends responses via signal. However, the QAbstractItemModel must wait for the response - and the only way to do this is with an event loop (to allow handling of incoming signals).

          However, when I do this my QAbstractItemModel allows another method (eg: rowCount) to run since these seem to be triggered by signals, so now I have 2 or more rowCounts in the same thread all waiting for answers via eventloops. A bit of a mess.

          Since QAbstractItemModel is not re-entrant, is there an asynchronous version of this class available? (Or some other way to implement this)

          (this is overlapping another post a bit - but still a bit different spin)

          Christian EhrlicherC 1 Reply Last reply
          0
          • ocgltdO ocgltd

            @Christian-Ehrlicher That's actually what I'm doing. I have a DB thread which gets requests via signal, and sends responses via signal. However, the QAbstractItemModel must wait for the response - and the only way to do this is with an event loop (to allow handling of incoming signals).

            However, when I do this my QAbstractItemModel allows another method (eg: rowCount) to run since these seem to be triggered by signals, so now I have 2 or more rowCounts in the same thread all waiting for answers via eventloops. A bit of a mess.

            Since QAbstractItemModel is not re-entrant, is there an asynchronous version of this class available? (Or some other way to implement this)

            (this is overlapping another post a bit - but still a bit different spin)

            Christian EhrlicherC Offline
            Christian EhrlicherC Offline
            Christian Ehrlicher
            Lifetime Qt Champion
            wrote on last edited by
            #4

            @ocgltd said in Is QAbstractItemModel re-entrant:

            However, the QAbstractItemModel must wait for the response - and the only way to do this is with an event loop (to allow handling of incoming signals).

            No, it must not. You return the row count which you've actually have. Once the db thread sends new data you add this to your model and properly call begin/endInsertRows().

            Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
            Visit the Qt Academy at https://academy.qt.io/catalog

            ocgltdO 1 Reply Last reply
            2
            • Christian EhrlicherC Christian Ehrlicher

              @ocgltd said in Is QAbstractItemModel re-entrant:

              However, the QAbstractItemModel must wait for the response - and the only way to do this is with an event loop (to allow handling of incoming signals).

              No, it must not. You return the row count which you've actually have. Once the db thread sends new data you add this to your model and properly call begin/endInsertRows().

              ocgltdO Offline
              ocgltdO Offline
              ocgltd
              wrote on last edited by ocgltd
              #5

              @Christian-Ehrlicher But as soon as rowCount returns a value > 0, the tableView starts calling the 'data' function for each row&col. So I have to return something in the subclassed 'data' method. I thought I would return fake data, and once the real data arrives from the DB I will issue a dataChanged signal for that row.

              Is there something I can return (not fake data) that tells the view that data is not available for this row/col? If I return an invalid QVariant for ALL columns, will the view hide the row? Because that's really what I want.

              As for your suggestion to begin/endInsertRows(), I understand how that would work the first time the view is populated, but when a row goes out of view and back in again, won't that cause the rowcount to keep increasing? (per this doc )

              jsulmJ Christian EhrlicherC 2 Replies Last reply
              0
              • ocgltdO ocgltd

                @Christian-Ehrlicher But as soon as rowCount returns a value > 0, the tableView starts calling the 'data' function for each row&col. So I have to return something in the subclassed 'data' method. I thought I would return fake data, and once the real data arrives from the DB I will issue a dataChanged signal for that row.

                Is there something I can return (not fake data) that tells the view that data is not available for this row/col? If I return an invalid QVariant for ALL columns, will the view hide the row? Because that's really what I want.

                As for your suggestion to begin/endInsertRows(), I understand how that would work the first time the view is populated, but when a row goes out of view and back in again, won't that cause the rowcount to keep increasing? (per this doc )

                jsulmJ Offline
                jsulmJ Offline
                jsulm
                Lifetime Qt Champion
                wrote on last edited by
                #6

                @ocgltd said in Is QAbstractItemModel re-entrant:

                rowCount

                Why would it be bigger than the number of rows you actually have?

                https://forum.qt.io/topic/113070/qt-code-of-conduct

                1 Reply Last reply
                1
                • ocgltdO ocgltd

                  @Christian-Ehrlicher But as soon as rowCount returns a value > 0, the tableView starts calling the 'data' function for each row&col. So I have to return something in the subclassed 'data' method. I thought I would return fake data, and once the real data arrives from the DB I will issue a dataChanged signal for that row.

                  Is there something I can return (not fake data) that tells the view that data is not available for this row/col? If I return an invalid QVariant for ALL columns, will the view hide the row? Because that's really what I want.

                  As for your suggestion to begin/endInsertRows(), I understand how that would work the first time the view is populated, but when a row goes out of view and back in again, won't that cause the rowcount to keep increasing? (per this doc )

                  Christian EhrlicherC Offline
                  Christian EhrlicherC Offline
                  Christian Ehrlicher
                  Lifetime Qt Champion
                  wrote on last edited by
                  #7

                  @ocgltd Sorry but I don't understand your problem. If there are no rows yet, return 0. If you received some rows from the database, return this number. What's so complicated about this?

                  Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                  Visit the Qt Academy at https://academy.qt.io/catalog

                  ocgltdO 1 Reply Last reply
                  0
                  • Christian EhrlicherC Christian Ehrlicher

                    @ocgltd Sorry but I don't understand your problem. If there are no rows yet, return 0. If you received some rows from the database, return this number. What's so complicated about this?

                    ocgltdO Offline
                    ocgltdO Offline
                    ocgltd
                    wrote on last edited by
                    #8

                    @Christian-Ehrlicher The MVC is very straight forward with blocking code for data retrieval, but making it non blocking (asynchronous) is more challenging. QAbstractItemModel is not easily compatible with asynchronous use.

                    I have it working now, but the view shows blank rows until the data arrives. If I hide rows without data then the view keeps asking for more rows until it has enough to fill the screen. So I have settled with showing blank rows. (Dummy data is essential blank column content).

                    Christian EhrlicherC 1 Reply Last reply
                    0
                    • ocgltdO ocgltd

                      @Christian-Ehrlicher The MVC is very straight forward with blocking code for data retrieval, but making it non blocking (asynchronous) is more challenging. QAbstractItemModel is not easily compatible with asynchronous use.

                      I have it working now, but the view shows blank rows until the data arrives. If I hide rows without data then the view keeps asking for more rows until it has enough to fill the screen. So I have settled with showing blank rows. (Dummy data is essential blank column content).

                      Christian EhrlicherC Offline
                      Christian EhrlicherC Offline
                      Christian Ehrlicher
                      Lifetime Qt Champion
                      wrote on last edited by
                      #9

                      @ocgltd said in Is QAbstractItemModel re-entrant:

                      I have it working now, but the view shows blank rows until the data arrives.

                      Then you're doing something wrong. When no data is available, you should return '0' as row count... (already said at least three times).

                      Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                      Visit the Qt Academy at https://academy.qt.io/catalog

                      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