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. QComboBox::showPopup() override timing problem
Forum Updated to NodeBB v4.3 + New Features

QComboBox::showPopup() override timing problem

Scheduled Pinned Locked Moved Unsolved General and Desktop
6 Posts 2 Posters 2.7k Views 2 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.
  • J Offline
    J Offline
    JonB
    wrote on 26 Jul 2018, 09:00 last edited by JonB
    #1

    I override http://doc.qt.io/qt-5/qcombobox.html#showPopup (called when user clicks the combo's dropdown button) to execute some code to populate the list of items shown dynamically, prior to displaying the list.

    It seems this works well if the population code executed is "quick" but misbehaves if the code is "slow" by failing to actually show the popup after population.

    Following code tested with Qt 5.7 under Linux. I cannot test under Windows, so I don't know if the issue is Qt widget or native combobox.

    class JComboBox(QComboBox):
        # class variable for a new "popupAboutToBeShown" signal
        # Qt does not emit a signal when the dropdwon/popup of a combobox is about to be shown
        # we add this signal, which can be used for e.g. dynamically populating the items
        popupAboutToBeShown = QtCore.pyqtSignal(name='popupAboutToBeShown')
    
        # override of virtual function
        def showPopup(self):
            # emit the new signal
            self.popupAboutToBeShown.emit()
            # call the base method now to display the popup
            super().showPopup()
    

    I do not believe the issue is to do with the use of signal/slot here, but that is how I do it. All single-threaded here, the emit() is indeed a direct, blocking function call to slot. [EDIT I just tried code below in direct override of showPopup() instead of going via signal/slot to eliminate that, same behaviour.]

    self.combo = JCombBox()
    self.combo.setEditable(True)
    self.combo.popupAboutToBeShown.connect(populateCombo)
    
    def populateCombo(self)
        # In real life `items` would be populated by call to synchronous, non-Qt library function
        # which takes a little time to complete
        # Here we emulate this with a "sleep" and a fixed list
        # QThread.msleep(100)    # this works
        QThread.msleep(500)    # this misbehaves
        items = ["Item 1", "Item 2", "Item 3"]
        self.combo.clear()
        self.combo.addItems(items)
    

    In my tests, after a delay of 100 millis the popup is shown with its new items. However, with a delay of 500 millis the popup does not get shown (the items are correctly populated, e.g. can be seen by using the down arrow key on the combo to move through them). Obviously your mileage may vary on the numbers for the delay.

    Any comment on how long my showPopup() is allowed to take before something decides it's not going to show the popup/dropdown list?

    At this rate I'm thinking I won't be able to override showPopup to dynamically populate list (something which I have done successfully in native Windows code in the past) and will have to rewrite so that I have something like a ... button with an attached popup dialog instead to execute the code because I can't do it right via a QComboBox, which is doable but would be a shame....

    1 Reply Last reply
    0
    • M Offline
      M Offline
      mrjj
      Lifetime Qt Champion
      wrote on 26 Jul 2018, 10:24 last edited by
      #2

      Hi
      Tested on windows.
      Seems to work as expected.
      alt text

      class ComboTest : public QComboBox {
        Q_OBJECT
       public:
        explicit ComboTest(QWidget* parent = nullptr);
       public slots:
       public:
        virtual void showPopup() override {
          clear();
          for (int var = 0; var < 10000; ++var) {
            addItem("TEST" + QString::number(var));
          }
          QComboBox::showPopup();
        }
      };
      

      Takes quite some time for it to open. but seems to do it every time.

      J 1 Reply Last reply 26 Jul 2018, 10:33
      4
      • M mrjj
        26 Jul 2018, 10:24

        Hi
        Tested on windows.
        Seems to work as expected.
        alt text

        class ComboTest : public QComboBox {
          Q_OBJECT
         public:
          explicit ComboTest(QWidget* parent = nullptr);
         public slots:
         public:
          virtual void showPopup() override {
            clear();
            for (int var = 0; var < 10000; ++var) {
              addItem("TEST" + QString::number(var));
            }
            QComboBox::showPopup();
          }
        };
        

        Takes quite some time for it to open. but seems to do it every time.

        J Offline
        J Offline
        JonB
        wrote on 26 Jul 2018, 10:33 last edited by
        #3

        @mrjj
        Thank you for testing. But to test same as me, please replace with something like

          virtual void showPopup() override {
            QThread::msleep(2000);
            clear();
            for (int var = 0; var < 3; ++var) {
              addItem("TEST" + QString::number(var));
            }
            QComboBox::showPopup();
          }
        

        If that still works for you, I guess it's something like Ubuntu desktop (Unity)/X11 which is interfering (or my Qt 5.7 if you're on later).

        M 1 Reply Last reply 26 Jul 2018, 10:37
        0
        • J JonB
          26 Jul 2018, 10:33

          @mrjj
          Thank you for testing. But to test same as me, please replace with something like

            virtual void showPopup() override {
              QThread::msleep(2000);
              clear();
              for (int var = 0; var < 3; ++var) {
                addItem("TEST" + QString::number(var));
              }
              QComboBox::showPopup();
            }
          

          If that still works for you, I guess it's something like Ubuntu desktop (Unity)/X11 which is interfering (or my Qt 5.7 if you're on later).

          M Offline
          M Offline
          mrjj
          Lifetime Qt Champion
          wrote on 26 Jul 2018, 10:37 last edited by mrjj
          #4

          @JonB
          Hi still works with msleep.
          Im on Qt.5.11.1
          update: installing 5.7 just to see.
          will report back when its finished.

          J 1 Reply Last reply 26 Jul 2018, 10:44
          3
          • M mrjj
            26 Jul 2018, 10:37

            @JonB
            Hi still works with msleep.
            Im on Qt.5.11.1
            update: installing 5.7 just to see.
            will report back when its finished.

            J Offline
            J Offline
            JonB
            wrote on 26 Jul 2018, 10:44 last edited by
            #5

            @mrjj
            Hmm, thank you for testing. I guess it must be either my Linux or my Qt 5.7 then....

            I'll leave this open for a while, in case e.g. someone wishes to test your code under Linux/Qt 5.7.

            Meanwhile since I need to support my configuration I'm already doing it via a separate button to refresh combo list instead. I'll have to stick with that if I cannot resolve showPopup()....

            M 1 Reply Last reply 26 Jul 2018, 10:49
            0
            • J JonB
              26 Jul 2018, 10:44

              @mrjj
              Hmm, thank you for testing. I guess it must be either my Linux or my Qt 5.7 then....

              I'll leave this open for a while, in case e.g. someone wishes to test your code under Linux/Qt 5.7.

              Meanwhile since I need to support my configuration I'm already doing it via a separate button to refresh combo list instead. I'll have to stick with that if I cannot resolve showPopup()....

              M Offline
              M Offline
              mrjj
              Lifetime Qt Champion
              wrote on 26 Jul 2018, 10:49 last edited by
              #6

              @JonB
              Works the same in Qt5.7
              ill try on linux a later.

              1 Reply Last reply
              4

              2/6

              26 Jul 2018, 10:24

              topic:navigator.unread, 4
              • Login

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