【问题标题】:PyQt QItemDelegate setFocus to QTableWidget after "Enter" is pressed按下“Enter”后PyQt QItemDelegate setFocus to QTableWidget
【发布时间】:2019-02-22 06:19:21
【问题描述】:

我正在使用 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”时,它将转到下一行。

【问题讨论】:

  • 你为什么使用 QTextEdit?如果您想要 QTextEdit 中的更多行,就像输入的任务只是创建更多行一样。
  • 我正在使用 QTableWidget 来创建类似 excel 的东西。 QTableWidget 列之一能够让用户用多行更新注释。在使用 QTextEdit 之前,用户需要手动添加“\n”来实现多行,但这对用户不友好。然后,我发现我可以将 QTextEdit 设置为 QTableWidget。使用 QTextEdit 时,我可以通过按“Enter”或“Shift+Enter”来编写多行。但是,我只想在按下“Shift+Enter”时转到下一行,但是当按下“Enter”时,它会运行 self.update_MySQL 函数。
  • 你不认为把它放在你的问题中是正确的吗?
  • 好的,我会把它移到我的问题上,谢谢你的建议。
  • 我在询问之前显示了我的代码,你给了我澄清,所以想法是像你一样过滤 SHIFT 案例:-)。我认为您正确理解了我的解决方案真是太好了。

标签: python python-2.7 pyqt pyqt4 qtablewidget


【解决方案1】:

您可以做的是更新模型的数据,为此必须发出调用setModelData() 方法的commitData 信号。

通过这样做,您可以使用信号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_())  

【讨论】:

  • 嗨 eyllanesc,感谢您的回复。目前我的电脑不在我身边。我会在早上晚些时候试试你的代码。我会在这里更新,否则我会测试它。非常感谢!
  • 感谢eyllanesc,这是您第二次帮助我,再次感谢您的帮助!
猜你喜欢
  • 2018-08-05
  • 2013-07-08
  • 2015-08-07
  • 2016-12-29
  • 2018-08-02
  • 1970-01-01
  • 2018-02-13
  • 1970-01-01
  • 2019-05-14
相关资源
最近更新 更多