0

Why do my listwidget items disappear sometimes when i resize the dialog?

Before:

enter image description here

After:

enter image description here

import os, sys, json
sys.path.append('Z:\\pipeline\\site-packages')
from PySide import QtGui, QtCore, QtSvg

################################################################################
# Custom Widgets
################################################################################
class LayerWidget(QtGui.QWidget):

    def __init__(self):
        super(LayerWidget, self).__init__()

        # controls
        self.ui_thumbnail = QtGui.QToolButton()
        self.ui_thumbnail.setToolButtonStyle(QtCore.Qt.ToolButtonTextUnderIcon)
        self.ui_thumbnail.setFixedSize(128,128)
        self.ui_thumbnail.setIconSize(QtCore.QSize(80,80))
        self.ui_thumbnail.setText('TITLE HERE')

        self.ui_profiles = QtGui.QComboBox()
        self.ui_profiles.addItems(['Item 1','Item 2','Item 3'])

        # layout
        main_layout = QtGui.QVBoxLayout()
        main_layout.setContentsMargins(0,0,0,0)
        main_layout.setSpacing(0)
        main_layout.addWidget(self.ui_thumbnail)
        main_layout.addWidget(self.ui_profiles)
        main_layout.addStretch()
        self.setLayout(main_layout)


class LayerManager(QtGui.QWidget):
    def __init__(self):
        super(LayerManager, self).__init__()
        self.resize(400, 500)

        self.ui_layers = QtGui.QListWidget()
        self.ui_layers.setViewMode(QtGui.QListWidget.IconMode)
        self.ui_layers.setResizeMode(QtGui.QListWidget.Adjust)
        self.ui_layers.setEditTriggers(QtGui.QAbstractItemView.NoEditTriggers)
        self.ui_layers.setMovement(QtGui.QListView.Static)
        self.ui_layers.setIconSize(QtCore.QSize(96,96))
        self.ui_layers.setSpacing(10)

        main_layout = QtGui.QVBoxLayout(self)
        main_layout.addWidget(self.ui_layers)


    def add_new_layers(self):
        for x in range(4):
            widget = LayerWidget()
            item = QtGui.QListWidgetItem()
            self.ui_layers.insertItem(self.ui_layers.count(), item)
            self.ui_layers.setItemWidget(item, widget)
            item.setSizeHint(widget.sizeHint())


################################################################################
# Main Window
################################################################################
class MainWindow(QtGui.QMainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()
        self.setWindowTitle('Hyv')
        self.resize(500, 500)

        self.ui_layerManager = LayerManager()
        self.setCentralWidget(self.ui_layerManager)
        self.ui_layerManager.add_new_layers()


################################################################################
# Launch Methods
################################################################################
def main():
    app = QtGui.QApplication(sys.argv)
    ex = MainWindow()
    ex.show()
    sys.exit(app.exec_())


if __name__ == '__main__':
    main()
ekhumoro
  • 115,249
  • 20
  • 229
  • 336
JokerMartini
  • 5,674
  • 9
  • 83
  • 193
  • In PySide 1.2.4 it works correctly as the following images show: https://imgur.com/a/7qKQ5 – eyllanesc Apr 17 '18 at 01:45
  • I was able to reproduce this in both Qt-4.8.7 and Qt-5.10.1, but the buggy behaviour comes and goes. It most often happens when resizing horizontally *larger* when the window is first shown. The algorithm seems to get confused about which row to show the last item in, and sometimes ends up not showing it at all. – ekhumoro Apr 17 '18 at 02:37
  • Yeah it happens enough that I'm not sure what the best solution is for this? It's a very annoying bug to have and makes the application not stable if it's hiding things which need to be visible. Any ideas on how to solve this? – JokerMartini Apr 17 '18 at 02:51
  • @ekhumoro I use Qt 4.8.7 and Qt 5.10.1 – eyllanesc Apr 17 '18 at 08:39
  • @eyllanesc. Well, you're out-numbered two to one at the moment :-) It's not easy to reproduce the problem. Sometimes I have to open and close the window several times before it starts. Try very slowly resizing the window horizontally larger until the last item moves to the top row. For me, there is a noticeable flicker back and forth between the rows, and then the last item disappears. It's somewhat easier to reproduce in Qt4 than Qt5. This is with an openbox wm on archlinux, with nvidia graphics driver. – ekhumoro Apr 17 '18 at 16:59
  • @ekhumoro You're absolutely right, I just tried it again and it's happening, that error occurs randomly, what madness. :-D – eyllanesc Apr 17 '18 at 18:24
  • It seems to be the use of item-widgets that is the cause. When using plain items with just icon/text, the problem goes away. – ekhumoro Apr 17 '18 at 18:34
  • @JokerMartini. [This answer of mine](https://stackoverflow.com/a/41643420/984421) has a FlowLayout class which could provide a replacement for an icon-view. I tried it with your `LayerWidget` class, and it works fine. – ekhumoro Apr 17 '18 at 18:50
  • well this is a bummer. I was hoping i would be able to stick with using the QListWidget. I wonder if this is a known bug. – JokerMartini Apr 17 '18 at 22:12
  • @ekhumoro you mention it doesn't break with the plain items. Is there a way i could reconfig my app to maybe work around the issue? – JokerMartini Apr 17 '18 at 22:15
  • @JokerMartini. I don't know - but I doubt it. If you posted a bug report, maybe someone who knows the code would be able to suggest something. Why do you need to use a `QListWidget`? Your example seems to use it as nothing more than a layout. – ekhumoro Apr 18 '18 at 00:01
  • @ekhumoro I use a QListWidget because it has the freebie of auto layout and positioning of items when the dialog is rescaled. I do not know of any other way of doing that without custom controls. Isn't that correct? – JokerMartini Apr 18 '18 at 12:40
  • @JokerMartini. Well, if you're not using any of the other features of a `QListWidget`, then at least you have a drop-in replacement in the form of the FlowLayout class I mentioned above. Otherwise, I don't really see what else you can do (except post a bug report, or wait for a "miracle" fix). – ekhumoro Apr 18 '18 at 17:32
  • @ekhumoro correct me if im wrong, but in order for me to get the QFlowLayout to work, would i need to subclass it like you did in your example in order to get it to mimic the current setup? – JokerMartini Apr 18 '18 at 18:08
  • @JokerMartini. No - in that example, you can simply replace the `Bubble` class with your `LayerWidget` class, and then in the `MainWindow` class replace the first three lines in the for-loop with `label = LayerWidget()` (and also change PyQt4 to PySide, if you like). With just those changes, the example will work. The `FlowLayout` class is a custom layout class based on [this example in the docs](https://doc.qt.io/archives/qt-4.8/qt-layouts-flowlayout-example.html). You use it exactly like one of the normal qt layout classes. It's basically a `QHBoxLayout` with wrapping. – ekhumoro Apr 18 '18 at 20:03
  • @ekhumoro how can i add additional padding/spacing to the items. For example id like to have 10 px padding around the items and 10px between each item – JokerMartini Apr 28 '18 at 12:18
  • @JokerMartini. The arguments to `FlowLayout` specify the margins and spacing. The padding around items can also be set via the contents-margins of your `LayerWidget` class. – ekhumoro Apr 28 '18 at 15:48

0 Answers0