Как применить post-преобразование в QItemDelegate?

#python #pyqt5

#python #pyqt5

Вопрос:

Рассмотрим приведенный ниже фрагмент:

 import sys

from PyQt5.Qt import *  # noqa


class MyCell(QItemDelegate):
    def createEditor(self, parent, option, index):
        w = QLineEdit(parent)
        validator = QRegExpValidator(QRegExp("^$|[0-9A-Fa-f]{1}|[0-9A-Fa-f]{2}|[-]"))
        w.setValidator(validator)

        def convert():
            w.setText(w.text().upper().zfill(2))

        w.returnPressed.connect(convert)

        return w


class MyTable(QTableWidget):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setItemDelegate(MyCell())


if __name__ == "__main__":
    app = QApplication(sys.argv)
    w = MyTable()
    w.setColumnCount(1)
    w.setRowCount(16)
    w.show()
    sys.exit(app.exec_())
 

Как бы вы применили функцию convert не только при отправке сигнала returnPressed, но и при редактировании, и внезапно вы переключаете фокус на другой элемент с помощью мыши?

Комментарии:

1. @musicamante Нет, это другой вопрос, который уже был рассмотрен в этом посте, пожалуйста, посмотрите это видео , как вы можете видеть… Я редактирую элемент там, и когда я переключаюсь на другой элемент convert , функция вызываться не будет… итак, идея заключается в том, чтобы выяснить, как этого добиться :/

2. Да, извините, я только что видел редактирование на другом. В любом случае, вы не ответили на то, что я там спросил: функция convert предназначена только для демонстрации, или вам просто нужно изменить содержимое на верхний регистр? Короче говоря, вам действительно нужно, чтобы пользователь мог вводить только две шестнадцатеричные цифры (или «-«, что, я полагаю, означает отсутствие ввода)?

3. @musicamante Да, хе-хе, у меня еще не было времени ответить на ваш предыдущий вопрос… короче говоря, элемент должен содержать либо «-» (пустая ячейка), либо (0-255) числа в шестнадцатеричном формате, другой тип вывода не должен быть разрешен в таблице, а также они должны быть в верхнем регистре… Я пишу какой-то музыкальный трекер, чтобы эти ячейки содержали «шаблоны» нот 🙂

Ответ №1:

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

 class MyCell(QItemDelegate):
    def createEditor(self, parent, option, index):
        w = QLineEdit(parent)
        validator = QRegExpValidator(QRegExp("[0-9A-Fa-f]{1}|[0-9A-Fa-f]{2}|[-]"))
        w.setValidator(validator)
        return w

    def setModelData(self, editor, model, index):
        text = editor.text().upper().zfill(2)
        model.setData(index, text)
 

Комментарии:

1. Супер круто! Мне нравится ваше решение. Кстати… когда вы выбираете несколько ячеек, нажимаете enter и редактируете свой элемент … есть ли какой-нибудь способ применить вывод ко всем ячейкам? Может ли это быть достигнуто на QItemDelegate или это нужно сделать на уровне QTableWidget?

2. @BTL Из того, что я понимаю, вы выбираете, скажем, 3 элемента, затем нажимаете enter, и он открывается из одного из его редакторов, затем вы хотите, чтобы при нажатии enter (или изменении фокуса) этот текст копировался в другие выбранные элементы, я прав? Правильно? Это было бы в обоих случаях, поскольку вы должны определить, что редактор был закрыт, а затем отправить сигнал в представление, где он копирует содержимое отредактированной ячейки в другие выбранные ячейки.

3. @BTL Я не собираюсь расширять обсуждение других функций, поскольку это не является целью комментариев, поэтому я рекомендую вам попробовать то, что я указываю, и если это не сработает для вас, вы должны опубликовать новое сообщение с указанием вашего намерения

4. Да, конечно, я попробую, и если я застряну, я опубликую новый пост об этом позже… Надеюсь, я выясню, как избежать уведомления родителя от делегата, поскольку это был бы плохой код. В любом случае, спасибо за вашу помощь.

5. @BTL Создайте сигнал в делегате, что-то вроде closed = pyqtSignal(QModelIndex) , а затем вы соединяете сигнал делегата с методом представления, чтобы все было разделено (это магия сигналов Qt)