将自定义 QWidget 添加到 QListWidget

Posted

技术标签:

【中文标题】将自定义 QWidget 添加到 QListWidget【英文标题】:Adding Custom QWidget to QListWidget 【发布时间】:2018-02-08 04:03:13 【问题描述】:

如何将自定义 qwidget 添加到 QListWidget 以获得列表小部件功能,例如选择、滚动、改进的内存管理等。

我的目标是创建一个图层管理器​​,类似于许多人在 Photoshop 或 Affinity Photo 等程序中看到的。我最终将扩展我的 LayerWidget,使其拥有更多控件,而不仅仅是一个简单的标签和复选框。

关于 SO 的上一个问题 (https://***.com/a/30802784/3156300) 用户提到使用 QListWidget 和 QListWidgetItem 来创建我正在尝试做的事情。然而,经过进一步的研究,我想不出如何将我的自定义小部件添加到 listWidget 中,就像他提到的那样。

Photoshop/Affinity 照片

import sys
from PySide import QtGui, QtCore


class LayerObject(object):

    def __init__(self, **kwargs):
        self.name = kwargs.get('name', '')
        self.enabled = kwargs.get('enabled', False)


class LayerWidget(QtGui.QWidget):

    def __init__(self, layer):
        super(LayerWidget, self).__init__()
        self.resize(400, 50)

        # controls
        self.ui_enabled = QtGui.QCheckBox()
        self.ui_layername = QtGui.QLabel()
        self.ui_items = QtGui.QComboBox()
        self.ui_items.addItems(['Color','Saturation','Blend'])

        main_layout = QtGui.QHBoxLayout()
        main_layout.addWidget(self.ui_layername)
        main_layout.addWidget(self.ui_items)
        main_layout.addStretch()
        main_layout.addWidget(self.ui_enabled)
        self.setLayout(main_layout)

        # construct
        self._layer = None
        self.layer = layer


    # properties
    @property
    def layer(self):
        return self._layer

    @layer.setter
    def layer(self, value):
        self._layer== value
        self.ui_layername.setText(value.name)
        self.ui_enabled.setChecked(value.enabled)


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

        # controls
        self.ui_scroll = QtGui.QWidget()
        self.ui_scroll_layout = QtGui.QVBoxLayout()
        self.ui_scroll.setLayout(self.ui_scroll_layout)

        self.ui_scroll_area = QtGui.QScrollArea()
        self.ui_scroll_area.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn)
        self.ui_scroll_area.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
        self.ui_scroll_area.setWidgetResizable(True)
        self.ui_scroll_area.setWidget(self.ui_scroll)

        main_layout = QtGui.QHBoxLayout()
        main_layout.addWidget(self.ui_scroll_area)
        self.setLayout(main_layout)


        self.add_layers()

    def add_layers(self):
        layers = [
            LayerObject(name='Layer001', enabled=False),
            LayerObject(name='Layer002', enabled=False),
            LayerObject(name='Layer003', enabled=True),
            LayerObject(name='Layer004', enabled=False),
            LayerObject(name='Layer005', enabled=True),
            LayerObject(name='Layer006', enabled=False),
            LayerObject(name='Layer007', enabled=False),
            LayerObject(name='Layer008', enabled=True),
            LayerObject(name='Layer009', enabled=False),
            LayerObject(name='Layer010', enabled=True)
        ]

        for x in layers:
            widget = LayerWidget(layer=x)
            self.ui_scroll_layout.addWidget(widget)


def main():
    app = QtGui.QApplication(sys.argv)
    ex = LayerManager()
    ex.show()
    sys.exit(app.exec_())


if __name__ == '__main__':
    main()

【问题讨论】:

【参考方案1】:

要添加一个小部件,您必须使用方法setItemWidget(),您必须将该方法传递给QListWidgetItem,为此您可以通过insertItem() 方法添加它。观察到的问题之一是项目的大小与小部件的大小不对应,为此您必须使用sizeHint()

class LayerManager(QtGui.QWidget):
    def __init__(self):
        super(LayerManager, self).__init__()
        self.resize(400, 300)
        self.list_widget = QtGui.QListWidget()
        main_layout = QtGui.QHBoxLayout(self)
        main_layout.addWidget(self.list_widget)
        self.add_layers()

    def add_layers(self):
        layers = [
            LayerObject(name='Layer001', enabled=False),
            LayerObject(name='Layer002', enabled=False),
            LayerObject(name='Layer003', enabled=True),
            LayerObject(name='Layer004', enabled=False),
            LayerObject(name='Layer005', enabled=True),
            LayerObject(name='Layer006', enabled=False),
            LayerObject(name='Layer007', enabled=False),
            LayerObject(name='Layer008', enabled=True),
            LayerObject(name='Layer009', enabled=False),
            LayerObject(name='Layer010', enabled=True)
        ]

        for x in layers:
            widget = LayerWidget(layer=x)
            item =  QtGui.QListWidgetItem()
            self.list_widget.insertItem(self.list_widget.count(), item)
            self.list_widget.setItemWidget(item, widget)
            item.setSizeHint(widget.sizeHint())

【讨论】:

以上是关于将自定义 QWidget 添加到 QListWidget的主要内容,如果未能解决你的问题,请参考以下文章

将自定义常量添加到系统常量[重复]

将自定义标头添加到 AFNetworking,我做错了啥?

将自定义标记 (HTMLMarkers) 添加到聚类

如何将自定义挂钩添加到 Woocommerce 的自定义插件

AWS Elastic Beanstalk:将自定义日志添加到 CloudWatch?

将自定义 UIView 添加到 iCarousel