PyQt QItemDelegate setFocus to QTableWidget after "Enter" is pressed
PyQt QItemDelegate setFocus to QTableWidget after "Enter" is pressed
我正在使用 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" 时,它将转到下一行。
您可以做的是更新模型的数据,为此必须发出调用 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_())
我正在使用 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" 时,它将转到下一行。
您可以做的是更新模型的数据,为此必须发出调用 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_())