编辑qlistwidget项目后如何捕获新名称

时间:2019-06-04 22:30:35

标签: python pyqt pyqt4 qlistwidget

我已将QListWidget中的项目设置为可编辑,以便可以在需要时执行重命名。

要进行重命名,用户可以在该项目上双击以显示一个QLineEdit,该QLineEdit使您可以编辑文本,并且在QLineEdit之后捕获新名称时,我遇到了问题。

尝试使用itemDoubleClickedcurrentTextChanged信号,但似乎并没有给我重新命名。 例如,我试图将Trhee重命名为Three,但在rename_item()下,它返回我Trhee

class Dialog(QtGui.QDialog):
    def __init__(self, parent=None):
        super(Dialog, self).__init__()
        self.listWidget = QtGui.QListWidget()
        items = ['One', 'Two', 'Trhee']
        for item in items:
            self.listWidget.addItem(item)

        self.listWidget.currentTextChanged.connect(self.rename_item)
        # self.listWidget.itemDoubleClicked.connect(self.rename_item)

        for index in range(self.listWidget.count()):
            item = self.listWidget.item(index)
            item.setFlags(item.flags() | QtCore.Qt.ItemIsUserCheckable | QtCore.Qt.ItemIsEditable)
            item.setCheckState(QtCore.Qt.Checked)

        layout = QtGui.QVBoxLayout(self)
        layout.addWidget(self.listWidget)

    def rename_item(self):
        prev_item_name = self.listWidget.currentItem()
        print 'before rename: ', prev_item_name.text()

        # Returns me the same value as prev_item_name...
        new_item_name = self.listWidget.currentItem()
        print 'after rename: ', new_item_name.text()


if __name__ == '__main__':
    app = QtGui.QApplication(sys.argv)
    window = Dialog()
    window.setGeometry(600, 100, 300, 200)
    window.show()
    sys.exit(app.exec_())

2 个答案:

答案 0 :(得分:0)

我;我不确定您打算做什么。我的建议是更改激活方法,例如:

self.listWidget.itemDoubleClicked.connect(self.previous_name)
self.listWidget.itemChanged.connect(self.current_name)

def previous_name(self):
        prev_item_name = self.listWidget.currentItem()
        print ('before rename: ', prev_item_name.text())

def current_name(self):
        try:
            new_item_name = self.listWidget.currentItem()
            print ('after rename: ', new_item_name.text())
        except:
            pass

答案 1 :(得分:0)

在这种情况下,适当的信号是dataChanged,但不仅在修改文本时发出此信号,而且在修改其他属性(例如复选框状态)时也会发出此信号。在PyQt5 / Qt5中添加了一个信号,表明可以区分,但PyQt4并非如此。

获取修改后的角色是否对应于文本的一种方法是比较更改前后的文本,但是QListWidgetItem仅保存一个文本,因此必须使用另一个角色来保存旧文本。通过这种逻辑,我实现了以下解决方案:

from PyQt4 import QtCore, QtGui


class ListWidget(QtGui.QListWidget):
    textItemChanged = QtCore.pyqtSignal(QtGui.QListWidgetItem)

    OLDTEXTROLE = QtCore.Qt.UserRole + 1000

    def __init__(self, parent=None):
        super(ListWidget, self).__init__(parent)
        self.model().dataChanged.connect(self.on_data_changed)

    @QtCore.pyqtSlot(QtCore.QModelIndex, QtCore.QModelIndex)
    def on_data_changed(self, topLeft, bottomRight):
        if topLeft == bottomRight:
            it = self.itemFromIndex(topLeft)
            old_text = it.data(ListWidget.OLDTEXTROLE)
            if old_text is None:
                it.setData(ListWidget.OLDTEXTROLE, "")
            if old_text == it.text():
                return
            self.textItemChanged.emit(it)
            it.setData(ListWidget.OLDTEXTROLE, it.text())


class Dialog(QtGui.QDialog):
    def __init__(self, parent=None):
        super(Dialog, self).__init__()
        self.listWidget = ListWidget()
        items = ["One", "Two", "Trhee"]
        for item in items:
            self.listWidget.addItem(item)

        for index in range(self.listWidget.count()):
            item = self.listWidget.item(index)
            item.setFlags(
                item.flags()
                | QtCore.Qt.ItemIsUserCheckable
                | QtCore.Qt.ItemIsEditable
            )
            item.setCheckState(QtCore.Qt.Checked)

        self.listWidget.textItemChanged.connect(self.on_text_item_changed)

        layout = QtGui.QVBoxLayout(self)
        layout.addWidget(self.listWidget)

    @QtCore.pyqtSlot(QtGui.QListWidgetItem)
    def on_text_item_changed(self, it):
        current_text = it.text()
        old_text = it.data(ListWidget.OLDTEXTROLE)
        print("old_text: {}, current_text: {}".format(old_text, current_text))


if __name__ == "__main__":
    import sys

    app = QtGui.QApplication(sys.argv)
    window = Dialog()
    window.setGeometry(600, 100, 300, 200)
    window.show()
    sys.exit(app.exec_())