如何在pyqt中捕获鼠标在QTableWidget项的事件?

时间:2013-11-19 06:47:40

标签: python pyqt qtablewidget mousehover qtablewidgetitem

当我将鼠标悬停在我的QTableWidget项目上时,我想要做的是更改QTableWidget项目的颜色。

4 个答案:

答案 0 :(得分:8)

首先,表格小部件需要启用mouse-tracking才能获得悬停事件。

其次,我们需要找到一些信号告诉我们什么时候鼠标进入和离开表格单元格,以便可以在正确的时间更改背景颜色。

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_())

答案 1 :(得分:3)

您可以使用正确的信号轻松实现您的目标,如以下简单代码所证明的那样:

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方法)。

<强>更新

抱歉,我忘记了问题的第二部分,即鼠标离开牢房时会发生什么。即使这样,问题也可以在不使用事件的情况下轻松解决请查看更新的代码。

答案 2 :(得分:1)

没有基于QTableWidgetItem的事件,但您可以这样做:

  • 重新实现QTableWidget的mouseMoveEvent(),你可以获得鼠标位置;
  • 使用itemAt()方法获取鼠标光标下的项目;
  • 自定义您的项目;

这可能会让你想要什么。

答案 3 :(得分:0)

我知道这已经很老了,但是当我遇到这个页面寻找类似的解决方案时,我想对其进行一些更新。它有两个部分,一个与上面相似,但是如果单元格为空,则避免了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]