更新QListWidgetItem的DisplayRole

时间:2018-09-25 21:09:02

标签: python qt pyside

在提交对项目所做的更改后,更新ListWidgetItem的正确方法是什么?可以在弹出的“编辑”对话框中进行更改,当用户双击列表中的项目时,该对话框将打开。我是否需要更改框架以利用AbstractModel设置?如果可以的话,有人可以帮助演示这种更正确的方法吗?

在图像中,当用户单击“确定”时,应更新UI中的显示文本。 enter image description here

代码:

import os, sys, json
from PySide import QtGui, QtCore

class Preset(object):
    '''
    Description:
        Simple class object which represents a submission preset
    '''
    def __init__(self, *args, **kwargs):
        self.name = kwargs.get('name', '')
        self.maxprescript = kwargs.get('maxprescript', '')
        self.maxsubmissionscript = kwargs.get('maxsubmissionscript', '')
        self.maxpostscript = kwargs.get('maxpostscript', '')


    def toDict(self):
        '''
        Description:
            Used when saving to json file
        '''
        data = {
            'name': self.name,
            'maxprescript': self.maxprescript,
            'maxsubmissionscript': self.maxsubmissionscript,
            'maxpostscript': self.maxpostscript
        }
        return data


class AddEditPresetDialog(QtGui.QDialog):

    def __init__(self, presetItem, parent=None):
        super(AddEditPresetDialog, self).__init__(parent)
        self.resize(400,200)
        self._presetItem = presetItem

        self.uiName = QtGui.QLineEdit()
        self.uiMaxprescript = QtGui.QLineEdit()
        self.uiMaxsubmissionscript = QtGui.QLineEdit()
        self.uiMaxpostscript = QtGui.QLineEdit()

        self.uiButtons = QtGui.QDialogButtonBox()
        self.uiButtons.addButton(QtGui.QDialogButtonBox.Ok)
        self.uiButtons.addButton(QtGui.QDialogButtonBox.Cancel)

        # form layout
        self.form = QtGui.QFormLayout()
        self.form.addRow('Name', self.uiName)
        self.form.addRow('Max Prescript', self.uiMaxprescript)
        self.form.addRow('Max Submission Script', self.uiMaxsubmissionscript)
        self.form.addRow('Max Postscript', self.uiMaxpostscript)

        # main layout
        self.layout = QtGui.QVBoxLayout()
        self.layout.setContentsMargins(10,10,10,10)
        self.layout.addLayout(self.form)
        self.layout.addWidget(self.uiButtons)
        self.setLayout(self.layout)

        self.uiButtons.accepted.connect(self.accept)
        self.uiButtons.rejected.connect(self.reject)

        # populate the ui controls
        self.uiName.setText(getattr(presetItem, 'name', ''))
        self.uiMaxprescript.setText(getattr(presetItem, 'maxprescript', ''))
        self.uiMaxsubmissionscript.setText(getattr(presetItem, 'maxsubmissionscript', ''))
        self.uiMaxpostscript.setText(getattr(presetItem, 'maxpostscript', ''))

    # override events
    def accept(self):
        setattr(self._presetItem, 'name', self.uiName.text())
        setattr(self._presetItem, 'maxprescript', self.uiMaxprescript.text())
        setattr(self._presetItem, 'maxsubmissionscript', self.uiMaxsubmissionscript.text())
        setattr(self._presetItem, 'maxpostscript', self.uiMaxpostscript.text())
        super(AddEditPresetDialog, self).accept()


class SubmissionWindow(QtGui.QDialog):

    def __init__(self, filepath, parent=None):
        super(SubmissionWindow, self).__init__(parent)
        self.setWindowTitle('Submission Presets')
        self.resize(400, 400)

        # privates
        self._filepath = filepath # path used to load/save default preset

        # controls
        self.uiSearch = QtGui.QLineEdit('')
        self.uiSearch.setPlaceholderText('Search...')
        self.uiAvailableList = QtGui.QListWidget()
        self.uiAvailableList.setSelectionMode(QtGui.QAbstractItemView.SingleSelection)
        self.uiAvailableList.setSortingEnabled(True)

        self.uiOk = QtGui.QPushButton('OK')
        self.uiCancel = QtGui.QPushButton('Cancel')

        self.uiButtons = QtGui.QDialogButtonBox()
        self.uiButtons.addButton(self.uiOk, QtGui.QDialogButtonBox.ActionRole)
        self.uiButtons.addButton(self.uiCancel, QtGui.QDialogButtonBox.ActionRole)

        # actions
        addNewPresetAct = QtGui.QAction("Add New...", self)
        addNewPresetAct.triggered.connect(self.showAddNewPresetDialog)

        fileMenu = QtGui.QMenu('File', self)
        fileMenu.addAction(addNewPresetAct)
        menuBar = QtGui.QMenuBar(self)
        menuBar.addMenu(fileMenu)

        # main layout
        self.layout = QtGui.QVBoxLayout()
        self.layout.setContentsMargins(10,10,10,10)
        self.layout.addWidget(self.uiSearch)
        self.layout.addWidget(self.uiAvailableList)
        self.layout.addWidget(self.uiButtons)
        self.layout.setMenuBar(menuBar)

        self.setLayout(self.layout)

        # Signals
        # self.uiAvailableList.itemSelectionChanged.connect(self.selectionChanged)
        self.uiAvailableList.itemDoubleClicked.connect(self.itemDoubleClicked)
        self.uiSearch.textChanged.connect(self.filterAvailableList)
        self.uiOk.clicked.connect(self.accept)
        self.uiCancel.clicked.connect(self.reject)

        # init
        self.load(self._filepath)
        self.updateControls()


    # Methods    
    def appendPreset(self, obj):
        item = QtGui.QListWidgetItem()
        item.setText(obj.name)
        item.setData(QtCore.Qt.UserRole, obj)
        self.uiAvailableList.addItem(item)


    def setAvailableItems(self, items):
        self.uiAvailableList.clear()
        for x in items:
            self.uiAvailableList.addItem(x)


    def filterAvailableList(self, text):
        if not text:
            for x in range(self.uiAvailableList.count()):
                self.uiAvailableList.item(x).setHidden(False)
        else:
            for x in range(self.uiAvailableList.count()):
                row = self.uiAvailableList.item(x)
                if text.lower() in row.text().lower():
                    row.setHidden(False)
                    row.setSelected(True)
                else:
                    row.setHidden(True)
                    row.setSelected(False)


    def updateControls(self):
        items = self.uiAvailableList.selectedItems()
        # if len(items) == 1:
        #     self.uiOk.setEnabled(True)
        # else:
        #     self.uiOk.setEnabled(False)


    def showAddNewPresetDialog(self):
        obj = Preset()
        dlg = AddEditPresetDialog(obj, parent=self)
        if dlg.exec_():
            self.appendPreset(obj)


    def showEditPresetDialog(self, obj):
        dlg = AddEditPresetDialog(obj, parent=self)
        if dlg.exec_():
            print 'saved'


    def save(self, filepath):
        '''
        Saves items to json file
        '''
        if not filepath:
            filepath, ext = QtGui.QFileDialog.getSaveFileName(self, 'Open', '', 'Hotkey Files (*.vsp)')

        if not filepath or not filepath.lower().endswith('.vsp'):
            return

        # collect the data
        data = []
        for x in range(self.uiAvailableList.count()):
            row = self.uiAvailableList.item(x)
            data.append(row.data(QtCore.Qt.UserRole).toDict())

        with open(filepath, 'w') as f:
            json.dump(data, f, indent=4)


    def load(self, filepath=''):
        '''
        Description:
            Will load the specified preset filepath overriding any valid hotkeys
        '''
        if not filepath:
            filepath, ext = QtGui.QFileDialog.getOpenFileName(self, 'Open', '', 'Submission Files (*.vps)')

        if not os.path.isfile(filepath):
            return

        data = []
        with open(filepath) as f:
            data = json.load(f)

        for d in data:
            # unpack the dictionary and pass it as args to the constructor of the Preset Object
            new = Preset(**d)
            self.appendPreset(new)


    # override events
    def accept(self):
        self.save(filepath=self._filepath)
        super(SubmissionWindow, self).accept()

    # Slots
    def itemDoubleClicked(self, item):
        self.showEditPresetDialog(item.data(QtCore.Qt.UserRole))


    def selectionChanged(self):
        self.updateControls()


def main():
    app = QtGui.QApplication(sys.argv)
    ex = SubmissionWindow(filepath=os.path.expanduser('~/documents/presets/submission_presets.vsp'))
    ex.show()
    sys.exit(app.exec_())


if __name__ == '__main__':
    main()

0 个答案:

没有答案