Как реализовать кнопки в делегате PyQt - PullRequest
0 голосов
/ 20 апреля 2020

Я делаю программу для перевода текста (см. Скриншот)

screenshot

У меня есть три класса

класс для отображения окна, которое редактирует элемент:

class StyleDelegate(QStyledItemDelegate):
        def __init__(self, parent=None):
            super(StyleDelegate, self).__init__()
        def createEditor(self, widget, style, index):
            self.mainWidget = QWidget(widget)
            self.line = QLineEdit() # line for input text 
            self.delButton= QPushButton('❌')  # button for delete current item
            self.trnButton = QPushButton('➕')  # button for make translation text in another QListView
            self.qhbLayout = QHBoxLayout()
            self.qhbLayout.addWidget(self.line)
            self.qhbLayout.addWidget(self.delButton)
            self.qhbLayout.addWidget(self.trnButton)
            self.mainWidget.setLayout(self.qhbLayout)
            return self.mainWidget
        # there is still a lot of code in this place

класс для хранения, добавления, удаления и редактирования данных:

    class TranslateListModel(QAbstractListModel):
        def __init__(self, parent=None):
            super(TranslateListModel, self).__init__()
            self.words = ['1', '2', '3', '4']

        def removeItem(self, index):
            self.beginRemoveRows(index, index.row(), index.row())
            del self.words[index.row()]
            self.endRemoveRows()
            return True
        # there is still a lot of code in this place

основной класс программы:

class QTranslate(QtWidgets.QDialog, log.Ui_Dialog):
     def __init__(self):
        super().__init__()
        self.originalModel = TranslateListModel() 
        self.translateModel = TranslateListModel() 

        self.styleDelegate = StyleDelegate()

        self.originalLV.setModel(self.originalModel) 
        #QListView from Ui_Dialog

        self.translateLV.setModel(self.translateModel)
        #QListView from Ui_Dialog

        self.originalLV.setItemDelegate(self.styleDelegate)
        self.translateLV.setItemDelegate(self.styleDelegate)
    # there is still a lot of code in this place

Как реализовать кнопки для удаления текущий элемент и изменить перевод в другом QListView, используя QStyledItemDelegate? Я не могу получить доступ к этим кнопкам вне класса StyleDelegate, чтобы связать их с методами класса TranslateListModel.

1 Ответ

1 голос
/ 20 апреля 2020

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

class StyleDelegate(QStyledItemDelegate):
    deleteRequested = QtCore.pyqtSignal(int)
    translateRequested = QtCore.pyqtSignal(int)

    def __init__(self, parent=None):
        super(StyleDelegate, self).__init__()
    def createEditor(self, widget, style, index):
        # note: I removed the "self" references as they're unnecessary
        mainWidget = QWidget(widget)
        line = QLineEdit()
        delButton= QPushButton('❌')
        trnButton = QPushButton('➕')
        qhbLayout = QHBoxLayout()
        qhbLayout.addWidget(line)
        qhbLayout.addWidget(delButton)
        qhbLayout.addWidget(trnButton)
        mainWidget.setLayout(qhbLayout)
        delButton.clicked.connect(
            lambda _, row=index.row(): self.deleteRequested.emit(row))
        trnButton.clicked.connect(
            lambda _, row=index.row(): self.translateRequested.emit(row))
        return mainWidget


class QTranslate(QtWidgets.QDialog, log.Ui_Dialog):
    def __init__(self):
        # ...
        self.originalLV.setItemDelegate(self.styleDelegate)
        self.styleDelegate.deleteRequested.connect(self.deleteRow)
        self.styleDelegate.translateRequested.connect(self.translateRow)

    def deleteRow(self, row):
        # ...

    def translateRow(self, row):
        # ...

Обратите внимание, что вам следует всегда используйте уникальный экземпляр делегата для каждого представления, как объяснено в документации :

Предупреждение : Вы не должны совместно использовать один и тот же экземпляр делегата между представлениями. Это может привести к некорректному или неинтуитивному поведению редактирования, поскольку каждое представление, подключенное к данному делегату, может получить сигнал closeEditor () и попытаться получить доступ, изменить или закрыть редактор, который уже был закрыт.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...