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. Widgets are shrinked when added to scroll area
Qt 6.11 is out! See what's new in the release blog

Widgets are shrinked when added to scroll area

Scheduled Pinned Locked Moved Unsolved General and Desktop
16 Posts 3 Posters 3.4k 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.
  • K Offline
    K Offline
    kraken1564
    wrote on last edited by
    #7

    About 5-10. It's not too many I think. But I have quite old CPU - Athlon 64 x2 3800+. I do not have any fancy hardware with me right now to test it.

    But, indeed, the rarer the GUI needs to be updated, the less frequent these glitch are.

    1 Reply Last reply
    0
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by
      #8

      The number seems fine but is it per image ?
      It could also come from your graphics stack.

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      1 Reply Last reply
      0
      • K Offline
        K Offline
        kraken1564
        wrote on last edited by
        #9

        No, It's one signal per image.

        1 Reply Last reply
        0
        • SGaistS Offline
          SGaistS Offline
          SGaist
          Lifetime Qt Champion
          wrote on last edited by
          #10

          Can you provide a minimal buildable example that shows that behaviour ?

          Interested in AI ? www.idiap.ch
          Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

          1 Reply Last reply
          0
          • K Offline
            K Offline
            kraken1564
            wrote on last edited by
            #11

            I think the "too many signals" hypothesis is right. I added a label and update it hundreds times per second. The glitches gets way worse. If I do not do it, they almost disappear. Also I tested it on another hardware and got the same behaviour ( less signals - no glitches, more signals - glitches).

            Here is the code (but it is use PyQt, is it ok?):

            import sys
            from multiprocessing import Pool
            from pathlib import Path
            
            from PyQt5 import QtCore, QtGui, QtWidgets
            
            # !!! Change to your folder with images
            FOLDER = '/home/user/images'
            
            def find_images(folder):
                '''Return paths of the images in the folder'''
            
                images = []
                for filename in Path(folder).rglob('*.jpg'):
                    if filename.is_file():
                        images.append(str(filename))
                return images
            
            def scale_image_BA(image_path):
                '''To generate more signals, concurrent processing is
                used (via lib "multiprocessing"). QPixmap or QImage cannot
                be serialized so converting to QByteArray is used'''
            
                reader = QtGui.QImageReader(image_path)
                reader.setScaledSize(QtCore.QSize(200, 200))
                image = reader.read()
            
                ba = QtCore.QByteArray()
                buf = QtCore.QBuffer(ba)
                buf.open(QtCore.QIODevice.WriteOnly)
                image.save(buf, 'JPG', 100)
                buf.close()
                return ba
            
            def QByteArray_to_QPixmap(ba_image):
                '''Convert from QByteArray back to QPixmap'''
            
                pixmap = QtGui.QPixmap()
                pixmap.loadFromData(ba_image)
                return pixmap
            
            
            class Signals(QtCore.QObject):
                image = QtCore.pyqtSignal(QtCore.QByteArray)
                label = QtCore.pyqtSignal(str)
            
            
            class Worker(QtCore.QRunnable):
                def __init__(self, image_paths):
                    super().__init__()
                    self.image_paths = image_paths
                    self.signals = Signals()
            
                @QtCore.pyqtSlot()
                def run(self):
                    '''Run image scaling on all available cores to emit more signals'''
            
                    with Pool() as p:
                        for baimg in p.imap_unordered(scale_image_BA, self.image_paths):
                            # Glitches happen if emit many signals per second???
                            # Without updating 'label' many times, everything's fine
                            for i in range(1000):
                                self.signals.label.emit(str(i))
                            self.signals.image.emit(baimg)
            
            
            class MyMainWindow(QtWidgets.QMainWindow):
            
                def __init__(self):
                    super().__init__()
            
                    self.setMinimumSize(QtCore.QSize(800, 600))
            
                    centralWidget = QtWidgets.QWidget()
                    self.setCentralWidget(centralWidget)
            
                    scrollArea = QtWidgets.QScrollArea()
                    scrollArea.setWidgetResizable(True)
            
                    imagesWidget = QtWidgets.QWidget()
                    scrollArea.setWidget(imagesWidget)
            
                    self.label = QtWidgets.QLabel('Counter')
            
                    startButton = QtWidgets.QPushButton('Start')
                    startButton.clicked.connect(self.run_worker)
            
                    verticalLayout = QtWidgets.QVBoxLayout()
                    verticalLayout.addWidget(scrollArea)
                    verticalLayout.addWidget(self.label)
                    verticalLayout.addWidget(startButton)
                    centralWidget.setLayout(verticalLayout)
            
                    self.imagesLayout = QtWidgets.QVBoxLayout()
                    imagesWidget.setLayout(self.imagesLayout)
            
                def run_worker(self):
                    images = find_images(FOLDER)
                    threadpool = QtCore.QThreadPool.globalInstance()
                    w = Worker(images)
                    w.signals.image.connect(self.update_gui)
                    w.signals.label.connect(self.label.setText)
                    threadpool.start(w)
            
                def update_gui(self, image):
                    label = QtWidgets.QLabel()
                    pixmap = QByteArray_to_QPixmap(image)
                    label.setPixmap(pixmap)
                    self.imagesLayout.addWidget(label)
            
            
            if __name__ == '__main__':
            
                app = QtWidgets.QApplication(sys.argv)
                mw = MyMainWindow()
                mw.show()
                app.exec()
            
            1 Reply Last reply
            0
            • SGaistS Offline
              SGaistS Offline
              SGaist
              Lifetime Qt Champion
              wrote on last edited by
              #12

              What version of PyQt5 are you using ?

              Interested in AI ? www.idiap.ch
              Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

              1 Reply Last reply
              0
              • K Offline
                K Offline
                kraken1564
                wrote on last edited by
                #13

                5.12.2, but tested also on 5.14.2 and 5.9 - got the same behaviour.

                1 Reply Last reply
                0
                • SGaistS Offline
                  SGaistS Offline
                  SGaist
                  Lifetime Qt Champion
                  wrote on last edited by
                  #14

                  What graphics stack do you have on your machine ?

                  Interested in AI ? www.idiap.ch
                  Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                  1 Reply Last reply
                  0
                  • K Offline
                    K Offline
                    kraken1564
                    wrote on last edited by kraken1564
                    #15

                    One PC has Geforce GT 730, driver v. 435.21, Linux Mint with Cinnamon DE (last one);
                    the other one has Intel UHD 630, Manjaro with KDE (use Qt, right?) - again get the same thing,

                    1 Reply Last reply
                    0
                    • K Offline
                      K Offline
                      kraken1564
                      wrote on last edited by kraken1564
                      #16

                      I've made the peace of code showing this behaviour a little simpler:

                      import sys
                      from PyQt5 import QtCore, QtGui, QtWidgets
                      
                      # Maybe you need to play with these constants
                      PIXMAP_NUM = 1000
                      EVENTLOOP_RUN_NUM = 100
                      
                      
                      class Signals(QtCore.QObject):
                          pixmaps = QtCore.pyqtSignal(list)
                      
                      
                      class Worker(QtCore.QRunnable):
                          def __init__(self):
                              super().__init__()
                              self.signals = Signals()
                      
                          @QtCore.pyqtSlot()
                          def run(self):
                              '''Make QPixmap object with different colours, add them to a list
                              and emit the list'''
                      
                              c = QtGui.QColor
                              colors = [c('red'), c('green'), c('blue'), c('cyan'),
                                        c('magenta'), c('yellow')]
                              i = 0
                      
                              pms = []
                              for _ in range(PIXMAP_NUM):
                                  pixmap = QtGui.QPixmap(200, 200)
                                  pixmap.fill(colors[i])
                                  i += 1
                                  if i == len(colors):
                                      i = 0
                                  pms.append(pixmap)
                      
                              self.signals.pixmaps.emit(pms)
                      
                      
                      class MyMainWindow(QtWidgets.QMainWindow):
                      
                          def __init__(self):
                              super().__init__()
                      
                              self.setMinimumSize(QtCore.QSize(800, 600))
                      
                              centralWidget = QtWidgets.QWidget()
                              self.setCentralWidget(centralWidget)
                      
                              scrollArea = QtWidgets.QScrollArea()
                              scrollArea.setWidgetResizable(True)
                      
                              imagesWidget = QtWidgets.QWidget()
                              scrollArea.setWidget(imagesWidget)
                      
                              startButton = QtWidgets.QPushButton('Start')
                              startButton.clicked.connect(self.run_worker)
                      
                              verticalLayout = QtWidgets.QVBoxLayout()
                              verticalLayout.addWidget(scrollArea)
                              verticalLayout.addWidget(startButton)
                              centralWidget.setLayout(verticalLayout)
                      
                              self.imagesLayout = QtWidgets.QVBoxLayout()
                              imagesWidget.setLayout(self.imagesLayout)
                      
                          def run_worker(self):
                              threadpool = QtCore.QThreadPool.globalInstance()
                              w = Worker()
                              w.signals.pixmaps.connect(self.update_gui)
                              threadpool.start(w)
                      
                          def update_gui(self, pixmaps):
                              for i, img in enumerate(pixmaps):
                                  label = QtWidgets.QLabel()
                                  # The next line doesn't change the behaviour
                                  label.setMinimumSize(QtCore.QSize(200, 200))
                                  label.setPixmap(img)
                                  self.imagesLayout.addWidget(label)
                                  # The next line doesn't change the behaviour
                                  self.updateGeometry()
                      
                                  if i % EVENTLOOP_RUN_NUM == 0:
                                      QtCore.QCoreApplication.processEvents()
                      
                      
                      if __name__ == '__main__':
                      
                          app = QtWidgets.QApplication(sys.argv)
                          mw = MyMainWindow()
                          mw.show()
                          app.exec()
                      

                      This code reproduce the glitches on both the machines.

                      I've noticed one thing. If we do not set the minimum size,

                      label.setMinimumSize(QtCore.QSize(200, 200))
                      

                      labels shrink. But if we do, they overlap (so, indeed, the minimum size is respected but imagesWidget is not big enough - cannot change its own size fast enough??? - to set the labels without overlapping???)

                      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