Как защитить ячейки, изменяющиеся в tablewidget, при использовании itemdelegate и сигнала от liswidget? - PullRequest
0 голосов
/ 21 июня 2019

У меня есть код, с которого я могу начать редактировать ячейку в табличном виджете и дважды щелкнуть по имени в виджете списка, чтобы добавить его в ячейку. Но когда я делаю это во второй ячейке, обе ячейки меняются. Как защитить ячейку от изменения, код выглядит следующим образом

from functools import partial
from PyQt4 import QtCore, QtGui


class StyledItemDelegate(QtGui.QStyledItemDelegate):
    textChanged = QtCore.pyqtSignal(int, int, str)
    #editingFinished = QtCore.pyqtSignal()

    def createEditor(self, parent, option, index):
        editor = super(StyledItemDelegate, self).createEditor(
            parent, option, index
        )
        if isinstance(editor, QtGui.QLineEdit):
            editor.textChanged.connect(
               partial(self.textChanged.emit, index.row(), index.column())
            )
            #editor.editingFinished.connect(self.editingFinished)
        return editor


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

        self.table_widget = QtGui.QTableWidget(4, 4)
        self.table_widget.setHorizontalHeaderLabels(("Name", "1", "2", 
                      "3"))
        delegate = StyledItemDelegate(self.table_widget)
        delegate.textChanged.connect(self.filter)
        #delegate.editingFinished.connect(self.clear_filter)
        self.table_widget.setItemDelegate(delegate)

        self.list_widget = QtGui.QListWidget()



        hlay = QtGui.QHBoxLayout(self)
        hlay.addWidget(self.table_widget)
        hlay.addWidget(self.list_widget)

        for letter1 in "ABCDEFGHIJKLMNOPQRSTUVWXYZ":
            for letter2 in "ABCDEFGHIJKLMNOPQRSTUVWXYZ":
                text = letter1 + letter2
                it = QtGui.QListWidgetItem(text)
                self.list_widget.addItem(it)

    @QtCore.pyqtSlot(int, int, str)
    def filter(self, row, column, text):
        print(row, column)
        self.clear_filter()
        for r in range(self.list_widget.count()):
            it = self.list_widget.item(r)
            # filter algorithm
            is_showing = text in it.text()
            # Hide the row if necessary
            it.setHidden(not is_showing)      
        self.list_widget.itemDoubleClicked.connect(
                           lambda:self.nameselected(row,column))

    @QtCore.pyqtSlot()
    def clear_filter(self):
        for r in range(self.list_widget.count()):
            it = self.list_widget.item(r)
            it.setHidden(False)

    def nameselected(self,row,column):
        name=self.list_widget.currentItem().text()
        print(name,row,column)
        #self.table_Widget.blockSignals(True)
        self.table_widget.setItem(row,column, 
                      QtGui.QTableWidgetItem(name))
        #self.table_Widget.blockSignals(False)

if __name__ == "__main__":
    import sys

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

давайте предположим, что я ввел 'A' в первой ячейке, у списка есть все имена, начинающиеся с 'A', когда я дважды щелкаю по 'AA' в списке, у первой ячейки есть текст 'AA'. когда я набираю 'B' во второй ячейке, listwidget содержит все имена, начинающиеся с 'B', когда я дважды щелкаю на 'BA' в listwidget, вторая ячейка должна иметь текст'BA '. Но здесь обе ячейки установлены на «BA». Как защитить другие ячейки от изменения.

1 Ответ

0 голосов
/ 22 июня 2019

Проблема связана с тем, что вы подключаетесь к слоту self.nameselected каждый раз, когда применяется новый фильтр. Это легко увидеть, если вы измените фильтр более одного раза: каждый раз, когда вы дважды щелкаете элемент в представлении списка, он печатает вывод слота nameselected более одного раза.

Вы можете использовать try и отключать сигнал itemDoubleClicked при каждом применении фильтра, но даже это не является хорошим решением (вам может потребоваться какое-то другое соединение с этим сигналом).

Просто подключите сигнал itemDoubleClicked к nameselected в __init__, а затем измените эту функцию следующим образом:

def nameselected(self):
    name=self.list_widget.currentItem().text()
    tableIndex = self.table_widget.currentIndex()
    self.table_widget.setItem(tableIndex(), tableIndex(), 
                  QtGui.QTableWidgetItem(name))

Если вы не хотите этого делать (например, чтобы избежать неправильного индекса, если пользователь по ошибке щелкнул другой элемент в таблице), просто сохраните внутреннюю ссылку на последний «отредактированный» индекс элемента и используйте что в имени выбранной функции.

...