如何检测pyqt4中tablewidget中单元格中文本的编辑?
how to detect editing of text in a cell in a tablewidget in pyqt4?
我有一个 tablewidget,其中的行是动态添加的,我必须在第一列中输入一个特定的名称,所以我在 tablewidget 旁边有一个 listwidget,其中显示的名称来自数据库,那么现在如何检测单元格中的变化,以便我可以过滤掉 listwidget 中的名称。
我已经尝试了 tablewidget 发出的所有信号,但没有成功,所有信号都是在单击鼠标或键盘按钮后发出的,我想检测输入或删除的每个字母在单个单元格中的变化。
我也尝试过 ItemDelegate,但它只检测到编辑的开始,这是我的代码
class ItemDelegate(QtGui.QStyledItemDelegate):
cellEditingStarted = QtCore.pyqtSignal(int, int)
def createEditor(self, parent, option, index):
result = super(ItemDelegate, self).createEditor(parent, option, index)
if result:
self.cellEditingStarted.emit(index.row(), index.column())
return result
.
.
.
self.delegate = ItemDelegate()
self.delegate.cellEditingStarted.connect(self.showlistwidget)
self.tableWidget.setItemDelegate(self.delegate)
您应该使用编辑器的 textChanged 信号 (QLineEdit),而不是检测编辑器何时显示:
from PyQt4 import QtCore, QtGui
class StyledItemDelegate(QtGui.QStyledItemDelegate):
textChanged = QtCore.pyqtSignal(str)
editingFinished = QtCore.pyqtSignal()
def createEditor(self, parent, option, index):
editor = super(StyledItemDelegate, self).createEditor(
parent, option, index
)
if isinstance(editor, QtGui.QLineEdit):
editor.textChanged.connect(self.textChanged)
editor.editingFinished.connect(self.editingFinished)
return editor
class Widget(QtGui.QWidget):
def __init__(self, parent=None):
super(Widget, self).__init__(parent)
self.table_widget = QtGui.QTableWidget(4, 4)
self.table_widget.setHorizontalHeaderLabels(("Name", "1", "2", "3"))
delegate = StyledItemDelegate(self.table_widget)
delegate.textChanged.connect(self.filter)
delegate.editingFinished.connect(self.clear_filter)
self.table_widget.setItemDelegateForColumn(0, delegate)
self.list_widget = QtGui.QListWidget()
hlay = QtGui.QHBoxLayout(self)
hlay.addWidget(self.table_widget)
hlay.addWidget(self.list_widget)
for letter1 in "ABCDEFGHIJKLMNOPQRSTUVWXYZ":
for letter2 in "ABCDEFGHIJKLMNOPQRSTUVWXYZ":
text = letter1 + letter2
it = QtGui.QListWidgetItem(text)
self.list_widget.addItem(it)
@QtCore.pyqtSlot(str)
def filter(self, text):
self.clear_filter()
for r in range(self.list_widget.count()):
it = self.list_widget.item(r)
# filter algorithm
is_showing = text in it.text()
# Hide the row if necessary
it.setHidden(not is_showing)
@QtCore.pyqtSlot()
def clear_filter(self):
for r in range(self.list_widget.count()):
it = self.list_widget.item(r)
it.setHidden(False)
if __name__ == "__main__":
import sys
app = QtGui.QApplication(sys.argv)
w = Widget()
w.show()
sys.exit(app.exec_())
更新:
from functools import partial
from PyQt4 import QtCore, QtGui
class StyledItemDelegate(QtGui.QStyledItemDelegate):
textChanged = QtCore.pyqtSignal(int, int, str)
editingFinished = QtCore.pyqtSignal()
def createEditor(self, parent, option, index):
editor = super(StyledItemDelegate, self).createEditor(
parent, option, index
)
if isinstance(editor, QtGui.QLineEdit):
editor.textChanged.connect(
partial(self.textChanged.emit, index.row(), index.column())
)
editor.editingFinished.connect(self.editingFinished)
return editor
class Widget(QtGui.QWidget):
def __init__(self, parent=None):
super(Widget, self).__init__(parent)
self.table_widget = QtGui.QTableWidget(4, 4)
self.table_widget.setHorizontalHeaderLabels(("Name", "1", "2", "3"))
delegate = StyledItemDelegate(self.table_widget)
delegate.textChanged.connect(self.filter)
delegate.editingFinished.connect(self.clear_filter)
self.table_widget.setItemDelegate(delegate)
self.list_widget = QtGui.QListWidget()
hlay = QtGui.QHBoxLayout(self)
hlay.addWidget(self.table_widget)
hlay.addWidget(self.list_widget)
for letter1 in "ABCDEFGHIJKLMNOPQRSTUVWXYZ":
for letter2 in "ABCDEFGHIJKLMNOPQRSTUVWXYZ":
text = letter1 + letter2
it = QtGui.QListWidgetItem(text)
self.list_widget.addItem(it)
@QtCore.pyqtSlot(int, int, str)
def filter(self, row, column, text):
print(row, column)
self.clear_filter()
for r in range(self.list_widget.count()):
it = self.list_widget.item(r)
# filter algorithm
is_showing = text in it.text()
# Hide the row if necessary
it.setHidden(not is_showing)
@QtCore.pyqtSlot()
def clear_filter(self):
for r in range(self.list_widget.count()):
it = self.list_widget.item(r)
it.setHidden(False)
if __name__ == "__main__":
import sys
app = QtGui.QApplication(sys.argv)
w = Widget()
w.show()
sys.exit(app.exec_())
我有一个 tablewidget,其中的行是动态添加的,我必须在第一列中输入一个特定的名称,所以我在 tablewidget 旁边有一个 listwidget,其中显示的名称来自数据库,那么现在如何检测单元格中的变化,以便我可以过滤掉 listwidget 中的名称。
我已经尝试了 tablewidget 发出的所有信号,但没有成功,所有信号都是在单击鼠标或键盘按钮后发出的,我想检测输入或删除的每个字母在单个单元格中的变化。
我也尝试过 ItemDelegate,但它只检测到编辑的开始,这是我的代码
class ItemDelegate(QtGui.QStyledItemDelegate):
cellEditingStarted = QtCore.pyqtSignal(int, int)
def createEditor(self, parent, option, index):
result = super(ItemDelegate, self).createEditor(parent, option, index)
if result:
self.cellEditingStarted.emit(index.row(), index.column())
return result
.
.
.
self.delegate = ItemDelegate()
self.delegate.cellEditingStarted.connect(self.showlistwidget)
self.tableWidget.setItemDelegate(self.delegate)
您应该使用编辑器的 textChanged 信号 (QLineEdit),而不是检测编辑器何时显示:
from PyQt4 import QtCore, QtGui
class StyledItemDelegate(QtGui.QStyledItemDelegate):
textChanged = QtCore.pyqtSignal(str)
editingFinished = QtCore.pyqtSignal()
def createEditor(self, parent, option, index):
editor = super(StyledItemDelegate, self).createEditor(
parent, option, index
)
if isinstance(editor, QtGui.QLineEdit):
editor.textChanged.connect(self.textChanged)
editor.editingFinished.connect(self.editingFinished)
return editor
class Widget(QtGui.QWidget):
def __init__(self, parent=None):
super(Widget, self).__init__(parent)
self.table_widget = QtGui.QTableWidget(4, 4)
self.table_widget.setHorizontalHeaderLabels(("Name", "1", "2", "3"))
delegate = StyledItemDelegate(self.table_widget)
delegate.textChanged.connect(self.filter)
delegate.editingFinished.connect(self.clear_filter)
self.table_widget.setItemDelegateForColumn(0, delegate)
self.list_widget = QtGui.QListWidget()
hlay = QtGui.QHBoxLayout(self)
hlay.addWidget(self.table_widget)
hlay.addWidget(self.list_widget)
for letter1 in "ABCDEFGHIJKLMNOPQRSTUVWXYZ":
for letter2 in "ABCDEFGHIJKLMNOPQRSTUVWXYZ":
text = letter1 + letter2
it = QtGui.QListWidgetItem(text)
self.list_widget.addItem(it)
@QtCore.pyqtSlot(str)
def filter(self, text):
self.clear_filter()
for r in range(self.list_widget.count()):
it = self.list_widget.item(r)
# filter algorithm
is_showing = text in it.text()
# Hide the row if necessary
it.setHidden(not is_showing)
@QtCore.pyqtSlot()
def clear_filter(self):
for r in range(self.list_widget.count()):
it = self.list_widget.item(r)
it.setHidden(False)
if __name__ == "__main__":
import sys
app = QtGui.QApplication(sys.argv)
w = Widget()
w.show()
sys.exit(app.exec_())
更新:
from functools import partial
from PyQt4 import QtCore, QtGui
class StyledItemDelegate(QtGui.QStyledItemDelegate):
textChanged = QtCore.pyqtSignal(int, int, str)
editingFinished = QtCore.pyqtSignal()
def createEditor(self, parent, option, index):
editor = super(StyledItemDelegate, self).createEditor(
parent, option, index
)
if isinstance(editor, QtGui.QLineEdit):
editor.textChanged.connect(
partial(self.textChanged.emit, index.row(), index.column())
)
editor.editingFinished.connect(self.editingFinished)
return editor
class Widget(QtGui.QWidget):
def __init__(self, parent=None):
super(Widget, self).__init__(parent)
self.table_widget = QtGui.QTableWidget(4, 4)
self.table_widget.setHorizontalHeaderLabels(("Name", "1", "2", "3"))
delegate = StyledItemDelegate(self.table_widget)
delegate.textChanged.connect(self.filter)
delegate.editingFinished.connect(self.clear_filter)
self.table_widget.setItemDelegate(delegate)
self.list_widget = QtGui.QListWidget()
hlay = QtGui.QHBoxLayout(self)
hlay.addWidget(self.table_widget)
hlay.addWidget(self.list_widget)
for letter1 in "ABCDEFGHIJKLMNOPQRSTUVWXYZ":
for letter2 in "ABCDEFGHIJKLMNOPQRSTUVWXYZ":
text = letter1 + letter2
it = QtGui.QListWidgetItem(text)
self.list_widget.addItem(it)
@QtCore.pyqtSlot(int, int, str)
def filter(self, row, column, text):
print(row, column)
self.clear_filter()
for r in range(self.list_widget.count()):
it = self.list_widget.item(r)
# filter algorithm
is_showing = text in it.text()
# Hide the row if necessary
it.setHidden(not is_showing)
@QtCore.pyqtSlot()
def clear_filter(self):
for r in range(self.list_widget.count()):
it = self.list_widget.item(r)
it.setHidden(False)
if __name__ == "__main__":
import sys
app = QtGui.QApplication(sys.argv)
w = Widget()
w.show()
sys.exit(app.exec_())