PyQt QItemDelegate устанавливаетFocus в QTableWidget после нажатия «Enter» - PullRequest
0 голосов
/ 18 сентября 2018

Я использую QTableWidget для создания чего-то вроде excel. Один из столбцов QTableWidget может позволить пользователю обновлять заметку несколькими строками. Перед использованием QTextEdit пользователю необходимо вручную добавить «\ n» для получения нескольких строк, но это не дружественный пользователь. Я узнал, что могу установить QTextEdit в QTableWidget. Используя QTextEdit, я могу набрать несколько строк, нажав «Enter» или «Shift + Enter». Однако я хочу, чтобы при нажатии «Shift + Enter» он переходил на следующую строку, но при нажатии «Enter» он запускает функцию self.update_MySQL.

Ниже приведен пример кода

import sys, itertools, sip
sip.setapi('QVariant',2)
from PyQt4 import QtCore, QtGui

class CustomTextEditDelegate(QtGui.QItemDelegate):
    def createEditor(self, parent, option, index):
        editor = QtGui.QTextEdit(parent)
        return editor

    def setEditorData(self, editor, index):
        editor.setText(index.data())

    def setModelData(self, editor, model, index):
        model.setData(index, editor.toPlainText())

class PIX_DATABASE_UI(QtGui.QTableWidget):
    def __init__(self, parent=None):
        super(PIX_DATABASE_UI, self).__init__(parent)

        ### signal
        self.update_tableWidget()
        self.itemEntered.connect(self.update_MySQL)

    # -----------------------------------------------------------------------------------------------------------------#
    def update_MySQL(self):
        print "MySQL Updated"

    def update_tableWidget(self):
        self.filter_columns = [u'remark']
        self.setColumnCount(len(self.filter_columns))
        self.setHorizontalHeaderLabels(self.filter_columns)
        self.setRowCount(5)

        for row, col in itertools.product(range(5), range(len(self.filter_columns))):
            if self.filter_columns[col] == "remark":
                width = self.sizeHint().width()
                self.setColumnWidth(col, width * 0.75)
                self.setItem(row, col, QtGui.QTableWidgetItem(str("ABC")))
                self.setItemDelegateForColumn(col, CustomTextEditDelegate(self))
                self.verticalHeader().setResizeMode(row, QtGui.QHeaderView.ResizeToContents)

# -----------------------------------------------------------------------------------------------------------------#
# -----------------------------------------------------------------------------------------------------------------#

if __name__ == '__main__':
    global ui
    try:
        ui.close()
    except:
        pass

    app = QtGui.QApplication(sys.argv)
    app.setStyle(QtGui.QStyleFactory.create("Plastique"))
    # print QtGui.QStyleFactory.keys()

    ui = PIX_DATABASE_UI()
    ui.show()
    sys.exit(app.exec_()) 

Вывод:

Спасибо eyllanesc, код помогает мне достичь того, чего я хочу достичь, слегка изменив keyPressEvent. Исходный код все еще излучается, даже когда я нажимаю «Shift + Enter». Ниже приведен код, который я изменил.

def keyPressEvent(self, event):
    modifiers = QtGui.QApplication.keyboardModifiers()
    if modifiers != QtCore.Qt.ShiftModifier and event.key() == QtCore.Qt.Key_Return:
        self.enter.emit()
        # If you do not want a new line uncomment the following
        # return
    super(TextEdit, self).keyPressEvent(event)

Так что теперь, после редактирования в textEdit и нажатия «Enter», он запустит self.update_MySQL, а когда нажмете «Shift + Enter», он перейдет к следующей строке.

1 Ответ

0 голосов
/ 18 сентября 2018

Что вы можете сделать, это то, что данные модели обновлены, и для этого должен быть выдан сигнал commitData, вызывающий метод setModelData().

При этом вы можете использовать сигнал itemChanged() потому что данные предмета изменены.

import sys, itertools, sip
sip.setapi('QVariant',2)
from PyQt4 import QtCore, QtGui

class TextEdit(QtGui.QTextEdit):
    pressed = QtCore.pyqtSignal()
    def keyPressEvent(self, event):
        if event.key() == QtCore.Qt.Key_Return:
            self.pressed.emit()
            # If you do not want a new line uncomment the following
            # return
        super(TextEdit, self).keyPressEvent(event)


class CustomTextEditDelegate(QtGui.QItemDelegate):
    def createEditor(self, parent, option, index):
        editor = TextEdit(parent)
        editor.pressed.connect(self.commitAndCloseEditor)
        return editor

    def setEditorData(self, editor, index):
        editor.setText(index.data())

    def setModelData(self, editor, model, index):
        model.setData(index, editor.toPlainText())

    def commitAndCloseEditor(self):
        editor = self.sender()
        self.commitData.emit(editor)
        # if you want to close the editor uncomment the following
        # self.closeEditor.emit(editor, QtGui.QAbstractItemDelegate.NoHint)

class PIX_DATABASE_UI(QtGui.QTableWidget):
    def __init__(self, parent=None):
        super(PIX_DATABASE_UI, self).__init__(parent)

        ### signal
        self.update_tableWidget()
        self.itemEntered.connect(self.update_MySQL)
        self.itemChanged.connect(self.update_MySQL)

    # -----------------------------------------------------------------------------------------------------------------#
    def update_MySQL(self, it):
        print("MySQL Updated", it.text())

    def update_tableWidget(self):
        self.filter_columns = [u'remark']
        self.setColumnCount(len(self.filter_columns))
        self.setHorizontalHeaderLabels(self.filter_columns)
        self.setRowCount(5)

        for row, col in itertools.product(range(5), range(len(self.filter_columns))):
            if self.filter_columns[col] == "remark":
                width = self.sizeHint().width()
                self.setColumnWidth(col, width * 0.75)
                self.setItem(row, col, QtGui.QTableWidgetItem(str("ABC")))
                self.setItemDelegateForColumn(col, CustomTextEditDelegate(self))
                self.verticalHeader().setResizeMode(row, QtGui.QHeaderView.ResizeToContents)

# -----------------------------------------------------------------------------------------------------------------#
# -----------------------------------------------------------------------------------------------------------------#

if __name__ == '__main__':
    global ui
    try:
        ui.close()
    except:
        pass

    app = QtGui.QApplication(sys.argv)
    app.setStyle(QtGui.QStyleFactory.create("Plastique"))
    # print QtGui.QStyleFactory.keys()

    ui = PIX_DATABASE_UI()
    ui.show()
    sys.exit(app.exec_())  
...