【问题标题】:How to capture the new name after editing qlistwidget item如何在编辑 qlistwidget 项目后捕获新名称
【发布时间】:2019-10-20 11:17:25
【问题描述】:

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

要进行重命名,用户可以“双击”项目,其中将提供一个 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_())

【问题讨论】:

    标签: python pyqt pyqt4 qlistwidget


    【解决方案1】:

    我不完全确定您打算做什么。我的建议是改变激活方式,例如:

    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
    

    【讨论】:

    • 我累了...我正在研究 PyQt5...但是如果它有效,请告诉我 :)
    【解决方案2】:

    适用于这种情况的信号是 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_())
    

    【讨论】:

      猜你喜欢
      • 2014-08-17
      • 2018-06-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-04-22
      • 2018-01-14
      相关资源
      最近更新 更多