如何将所选项目保存到QListWidget中的Qsettings

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (1)
  • 关注 (0)
  • 查看 (39)

我正在使用PyQt5和Py3.7,我试图遍历所有我的Qlistwidgets并保存他们的字符串数据,但也保存该小部件上的所有选定项目。我从这里略微修改了循环,但是使用listwidget数组循环获取所选项目进行保存和恢复时遇到了一些麻烦。我检查了文档,但似乎无法理解如何在数组中添加其他选项(例如保存所有选定的项目),来自此处的 SetArrayIndex的Qt文档。

我的listWidgets将selectionMode设置为MultiSelection。我目前正在使用此保存:

def save_list_data(self):
    self.settings = QSettings("data.ini", QSettings.IniFormat)
    for name, obj in inspect.getmembers(self):
        if isinstance(obj, QListWidget):
            name = obj.objectName()
            self.settings.beginWriteArray(name)
            for i in range(obj.count()):
                self.settings.setArrayIndex(i)
                self.settings.setValue(name, obj.item(i).text())
            self.settings.endArray()

然后使用以下命令恢复listWidget数据:

def open_list_data(self):
    self.settings = QSettings("data.ini", QSettings.IniFormat)
    for name, obj in inspect.getmembers(self):
        if isinstance(obj, QListWidget):
            name = obj.objectName()
            size = self.settings.beginReadArray(name)
            for i in range(size):
                self.settings.setArrayIndex(i)
                value = self.settings.value(name)
                if value != None:
                    obj.addItem(value)
            self.settings.endArray()

这适用于数据,但是如何从ListWidgets中获取selectedItems以进行保存和恢复?

提问于
用户回答回答于

对于我的解决方案,请考虑以下因素:

  • 使用inspect模块可能对其他库有益,但对于Qt,widget不一定是类的成员,所以最好使用findChildren使用Qt内省本身。
  • 在您使用的示例中,您只保存文本,但QListWidgetItem可以包含与角色相关的更多信息,例如背景颜色,前景色等。因此,我将使用QDataStream运算符,因为此获取和保存获取项目信息。
  • 我将使用“objectname / property”格式来保存信息,因为同一个窗口小部件可以包含您要保存的多个属性。
  • 要保存所选项目的信息,只需要保存行。

考虑到上述情况,解决方案是:

from PyQt5 import QtCore, QtGui, QtWidgets


class Widget(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)

        self.listwidget_1 = QtWidgets.QListWidget(
            objectName="listwidget_1", 
            selectionMode=QtWidgets.QAbstractItemView.MultiSelection
        )
        listwidget_2 = QtWidgets.QListWidget(
            objectName="listwidget_2", 
            selectionMode=QtWidgets.QAbstractItemView.MultiSelection
        )

        lay = QtWidgets.QVBoxLayout(self)
        lay.addWidget(self.listwidget_1)
        lay.addWidget(listwidget_2)

        self.read_settings()

    def closeEvent(self, event):
        self.write_settings()
        super().closeEvent(event)

    def read_settings(self):
        settings = QtCore.QSettings("data.ini", QtCore.QSettings.IniFormat)
        childrens = self.findChildren(QtWidgets.QWidget)
        for children in childrens:
            if isinstance(children, QtWidgets.QListWidget) and children.objectName():
                settings.beginGroup(children.objectName())
                items = settings.value("items")
                selecteditems = settings.value("selecteditems")
                # In the first reading the initial values must be established
                if items is None:
                    if children.objectName() == "listwidget_1":
                        for i in range(10):
                            children.addItem(QtWidgets.QListWidgetItem(str(i)))
                    elif children.objectName() == "listwidget_2":
                        for i in "abcdefghijklmnopqrstuvwxyz":
                            children.addItem(QtWidgets.QListWidgetItem(i))
                else:
                    stream = QtCore.QDataStream(items, QtCore.QIODevice.ReadOnly)
                    while not stream.atEnd():
                        it = QtWidgets.QListWidgetItem()
                        stream >> it
                        children.addItem(it)
                    stream = QtCore.QDataStream(selecteditems, QtCore.QIODevice.ReadOnly)
                    while not stream.atEnd():
                        row = stream.readInt()
                        it = children.item(row)
                        it.setSelected(True)
                settings.endGroup()

    def write_settings(self):
        settings = QtCore.QSettings("data.ini", QtCore.QSettings.IniFormat)
        childrens = self.findChildren(QtWidgets.QWidget)
        for children in childrens:
            if isinstance(children, QtWidgets.QListWidget) and children.objectName():
                settings.beginGroup(children.objectName())
                items = QtCore.QByteArray()
                stream = QtCore.QDataStream(items, QtCore.QIODevice.WriteOnly)
                for i in range(children.count()):
                    stream << children.item(i)
                selecteditems = QtCore.QByteArray()
                stream = QtCore.QDataStream(selecteditems, QtCore.QIODevice.WriteOnly)
                for it in children.selectedItems():
                    stream.writeInt(children.row(it))
                settings.setValue("items", items)
                settings.setValue("selecteditems", selecteditems)
                settings.endGroup()


if __name__ == "__main__":
    import sys

    app = QtWidgets.QApplication(sys.argv)
    w = Widget()
    w.show()
    sys.exit(app.exec_())

扫码关注云+社区

领取腾讯云代金券