当我将鼠标悬停在 QTableWidget 的项目上时,我想要做的是更改 QTableWidget 项目的颜色。
4 回答
首先,表格小部件需要打开鼠标跟踪才能获取悬停事件。
其次,我们需要找到一些信号,告诉我们鼠标何时进入和离开表格单元格,以便可以在正确的时间更改背景颜色。
QTableWidget 类有cellEntered / itemEntered信号,但是当鼠标离开单元格时没有任何东西。因此,我们需要创建一些自定义信号来做到这一点。
下面TableWidget
演示脚本中的类设置了必要的cellExited
/itemExited
信号,然后显示了如何在鼠标悬停时连接所有内容以更改项目背景:
from PyQt4 import QtGui, QtCore
class TableWidget(QtGui.QTableWidget):
cellExited = QtCore.pyqtSignal(int, int)
itemExited = QtCore.pyqtSignal(QtGui.QTableWidgetItem)
def __init__(self, rows, columns, parent=None):
QtGui.QTableWidget.__init__(self, rows, columns, parent)
self._last_index = QtCore.QPersistentModelIndex()
self.viewport().installEventFilter(self)
def eventFilter(self, widget, event):
if widget is self.viewport():
index = self._last_index
if event.type() == QtCore.QEvent.MouseMove:
index = self.indexAt(event.pos())
elif event.type() == QtCore.QEvent.Leave:
index = QtCore.QModelIndex()
if index != self._last_index:
row = self._last_index.row()
column = self._last_index.column()
item = self.item(row, column)
if item is not None:
self.itemExited.emit(item)
self.cellExited.emit(row, column)
self._last_index = QtCore.QPersistentModelIndex(index)
return QtGui.QTableWidget.eventFilter(self, widget, event)
class Window(QtGui.QWidget):
def __init__(self, rows, columns):
QtGui.QWidget.__init__(self)
self.table = TableWidget(rows, columns, self)
for column in range(columns):
for row in range(rows):
item = QtGui.QTableWidgetItem('Text%d' % row)
self.table.setItem(row, column, item)
layout = QtGui.QVBoxLayout(self)
layout.addWidget(self.table)
self.table.setMouseTracking(True)
self.table.itemEntered.connect(self.handleItemEntered)
self.table.itemExited.connect(self.handleItemExited)
def handleItemEntered(self, item):
item.setBackground(QtGui.QColor('moccasin'))
def handleItemExited(self, item):
item.setBackground(QtGui.QTableWidgetItem().background())
if __name__ == '__main__':
import sys
app = QtGui.QApplication(sys.argv)
window = Window(6, 3)
window.setGeometry(500, 300, 350, 250)
window.show()
sys.exit(app.exec_())
您可以使用以下简单代码证明的正确信号轻松实现目标:
from PyQt4.QtGui import *
from PyQt4.QtCore import *
class TableViewer(QMainWindow):
def __init__(self, parent=None):
super(TableViewer, self).__init__(parent)
self.table = QTableWidget(3, 3)
for row in range (0,3):
for column in range(0,3):
item = QTableWidgetItem("This is cell {} {}".format(row+1, column+1))
self.table.setItem(row, column, item)
self.setCentralWidget(self.table)
self.table.setMouseTracking(True)
self.current_hover = [0, 0]
self.table.cellEntered.connect(self.cellHover)
def cellHover(self, row, column):
item = self.table.item(row, column)
old_item = self.table.item(self.current_hover[0], self.current_hover[1])
if self.current_hover != [row,column]:
old_item.setBackground(QBrush(QColor('white')))
item.setBackground(QBrush(QColor('yellow')))
self.current_hover = [row, column]
if __name__ == '__main__':
import sys
app = QApplication(sys.argv)
tv = TableViewer()
tv.show()
sys.exit(app.exec_())
您可能也对其他信号感兴趣,尤其是itemEntered
. 但是,如果您想完全控制项目的编辑和显示,那么QTableWidget.setItemDelegate
强烈建议使用委托(通过方法)。
更新:
抱歉,我忘记了问题的第二部分,即鼠标退出单元格时会发生什么。即使这样,问题也可以在不使用事件的情况下轻松解决。请查看更新的代码。
没有基于 QTableWidgetItem 的事件,但您可以这样做:
- 重新实现
mouseMoveEvent()
QTableWidget的,可以得到鼠标位置; - 使用
itemAt()
方法获取鼠标光标下的项目; - 定制您的物品;
这可能会满足您的需求。
我知道这是旧的,但是当我遇到这个页面寻找类似的解决方案时,我想更新它的几个部分。这有几个部分,一个与上面类似,但NoneType
如果单元格为空,则会避免错误。此外,它会更改突出显示的单元格的颜色,还会更新单元格的工具提示,以在工具提示中显示单元格的内容。很好,如果你有径流 123 的细胞......
当然可以稍微清理一下,但适用于 PyQt5。干杯!
def cellHover(self, row, column):
item = self.My_Table1.item(row, column)
old_item = self.My_Table1.item(self.current_hover[0], self.current_hover[1])
if item is not None:
if self.current_hover != [row,column]:
text = item.text()
if text is not None:
self.My_Table1.setToolTip(text)
item.setBackground(QBrush(QColor('#bbd9f7')))
old_item.setBackground(QBrush(QColor('white')))
self.current_hover = [row, column]