[英]How to catch mouse over event of QTableWidget item in pyqt?
当我将鼠标悬停在QTableWidget的项目上时,我想做的就是更改QTableWidget项的颜色。
Firstly, the table widget needs to have mouse-tracking switched on to get the hover events. 首先,表格小部件需要打开鼠标跟踪才能获取悬停事件。
Secondly, we need to find some signals that tell us when the mouse enters and leaves the table cells, so that the background colours can be changed at the right times. 其次,我们需要找到一些信号来告诉我们鼠标何时进入和离开表格单元格,以便可以在正确的时间更改背景颜色。
The QTableWidget class has the cellEntered / itemEntered signals, but there is nothing for when the mouse leaves a cell. QTableWidget类具有cellEntered / itemEntered信号,但是当鼠标离开单元格时没有任何作用。 So, we will need to create some custom signals to do that.
因此,我们将需要创建一些自定义信号来做到这一点。
The TableWidget
class in the demo script below sets up the necessary cellExited
/ itemExited
signals, and then shows how everything can be hooked up to change the item background when hovering with the mouse: 下面的演示脚本中的
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_())
You can achieve your goal pretty easily using the proper signals as proved by the following simple code: 如下面的简单代码所示,您可以使用适当的信号轻松实现目标:
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_())
You may be interested in other signals too, especially itemEntered
. 您可能也对其他信号感兴趣,尤其是
itemEntered
。 However, if you want total control over the editing and display of items then using delegates (via the QTableWidget.setItemDelegate
method) is strongly recommended. 但是,如果要完全控制项目的编辑和显示,则强烈建议使用委托(通过
QTableWidget.setItemDelegate
方法)。
UPDATE : 更新 :
sorry, I had forgotten the second part of the problem ie what happens when the mouse exits a cell. 抱歉,我忘记了问题的第二部分,即当鼠标退出细胞时会发生什么。 Even then the problem can be solved easily without using events.
即使这样,也可以不使用事件就轻松解决问题。 See the updated code, please.
请查看更新的代码。
There are no events based on QTableWidgetItem, but you can do this: 没有基于QTableWidgetItem的事件,但是您可以执行以下操作:
mouseMoveEvent()
of QTableWidget, you can get the mouse position; mouseMoveEvent()
,可以获得鼠标的位置; itemAt()
method to get the item under your mouse cursor; itemAt()
方法获取鼠标光标下的项目; This may simalute what you want. 这可能会最小化您想要的内容。
I know this is old but wanted to update a couple of parts to it as I came across this page looking for a similar solution. 我知道这已经很老了,但是当我遇到此页面寻找类似的解决方案时,想对其进行更新。 This has a couple of parts to it, one is similar to the above but avoids the
NoneType
error if the cell is empty. 它有两个部分,一个与上面相似,但是如果单元格为空,则避免了
NoneType
错误。 Additionally, it will change the color of the highlighted cell, but also update a tooltip for the cell to display the contents of the cell in a tooltip. 此外,它将更改突出显示的单元格的颜色,但还会更新该单元格的工具提示,以在工具提示中显示该单元格的内容。 Nice if you have cells with runoffs 123...
如果您的单元格的径流量为123,则效果很好。
Sure it could be cleaned up a bit, but works for PyQt5. 当然可以清理一点,但是可以用于PyQt5。 Cheers!
干杯!
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]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.