pythonpyqtpyqt5qtablewidgetqmouseevent

MouseMove event on cell in Qtablewidget to display or print a message


I have QTablewidget and I want to use a mousemoveevent on a particular cell B. When mouse moves over this cell B, a message would appear or be printed. I have created the constructor, but it really does not work. Every thing is allright expect from those lines of code.

def mouseMoveEvent(self, event):
    it = self.item(self.rowCount(),1) 
    it.QToolTip.showText('Insert')
    self.onHovered()

Keep in mind that Qtooltip is assigned when the cell is clicked and works. But I want to do this by MouseMoveevent. Maybe my constructor of MouseEvent code is not right.

Expecting to behave.

enter image description here

import sys
from PyQt5 import QtCore, QtGui, QtWidgets


def copy_widget(w):
    if isinstance(w, QtWidgets.QWidget):
        new_w = type(w)()
        if isinstance(w, QtWidgets.QComboBox):
            vals = [w.itemText(ix) for ix in range(w.count())]
            new_w.addItems(vals)
        return new_w

class LoadTable(QtWidgets.QTableWidget):
    def __init__(self, parent=None):
        super(LoadTable, self).__init__(1, 5, parent)
        self.setFont(QtGui.QFont("Helvetica", 10, QtGui.QFont.Normal, italic=False))   
        headertitle = ("A","B","C","D","E")
        self.setHorizontalHeaderLabels(headertitle)
        self.verticalHeader().hide()
        self.horizontalHeader().setHighlightSections(False)
        self.horizontalHeader().setSectionResizeMode(QtWidgets.QHeaderView.Fixed)

        self.setSelectionMode(QtWidgets.QAbstractItemView.NoSelection)
        self.setColumnWidth(0, 130)

        combox_lay = QtWidgets.QComboBox(self)
        combox_lay.addItems(["I","II"])
        self.setCellWidget(0, 4, combox_lay)

        self.cellChanged.connect(self._cellclicked)


    @QtCore.pyqtSlot(int, int)
    def _cellclicked(self, r, c):
        it = self.item(r, c)
        it.setTextAlignment(QtCore.Qt.AlignCenter)
        n_it = self.item(r,1)
        n_it.setToolTip('Test') 


    @QtCore.pyqtSlot()
    def _addrow(self):
        rowcount = self.rowCount()
        self.insertRow(rowcount)
        combox_add = QtWidgets.QComboBox(self)
        combox_add.addItems(["I","II"])
        self.setCellWidget(rowcount, 4, combox_add)

    @QtCore.pyqtSlot()
    def _removerow(self):
        if self.rowCount() > 0:
            self.removeRow(self.rowCount()-1)

    @QtCore.pyqtSlot()
    def _copyrow(self):
        r = self.currentRow()
        if 0 <= r < self.rowCount():
            cells = {"items": [], "widgets": []}
            for i in range(self.columnCount()):
                it = self.item(r, i)
                if it:
                    cells["items"].append((i, it.clone()))
                w = self.cellWidget(r, i)
                if w:
                    cells["widgets"].append((i, copy_widget(w)))
            self.copy(cells, r+1)

    def copy(self, cells, r):
        self.insertRow(r)
        for i, it in cells["items"]:
            self.setItem(r, i, it)
        for i, w in cells["widgets"]:
            self.setCellWidget(r, i, w)

    def mouseMoveEvent(self, event):
        it = self.item(self.rowCount(),1)
        it.QToolTip.showText('Insert')
        self.onHovered()

    def onHovered(self):
        print("Works")


class ThirdTabLoads(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super(ThirdTabLoads, self).__init__(parent)    

        table = LoadTable()

        add_button = QtWidgets.QPushButton("Add")
        add_button.clicked.connect(table._addrow)

        delete_button = QtWidgets.QPushButton("Delete")
        delete_button.clicked.connect(table._removerow)

        copy_button = QtWidgets.QPushButton("Copy")
        copy_button.clicked.connect(table._copyrow)

        button_layout = QtWidgets.QVBoxLayout()
        button_layout.addWidget(add_button, alignment=QtCore.Qt.AlignBottom)
        button_layout.addWidget(delete_button, alignment=QtCore.Qt.AlignTop)
        button_layout.addWidget(copy_button, alignment=QtCore.Qt.AlignTop)

        tablehbox = QtWidgets.QHBoxLayout()
        tablehbox.setContentsMargins(10, 10, 10, 10)
        tablehbox.addWidget(table)

        grid = QtWidgets.QGridLayout(self)
        grid.addLayout(button_layout, 0, 1)
        grid.addLayout(tablehbox, 0, 0)        


if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    w = ThirdTabLoads()
    w.show()
    sys.exit(app.exec_())

Solution

  • The itemEntered signal must be used, but to do this, the mouseTracking must be enabled in addition to the item. When a row is added it does not imply that the items for each box exist so I have modified it to create it.

    class LoadTable(QtWidgets.QTableWidget):
        def __init__(self, parent=None):
            super(LoadTable, self).__init__(0, 5, parent)
            self.setFont(QtGui.QFont("Helvetica", 10, QtGui.QFont.Normal, italic=False))   
            headertitle = ("A","B","C","D","E")
            self.setHorizontalHeaderLabels(headertitle)
            self.verticalHeader().hide()
            self.horizontalHeader().setHighlightSections(False)
            self.horizontalHeader().setSectionResizeMode(QtWidgets.QHeaderView.Fixed)
            self.setSelectionMode(QtWidgets.QAbstractItemView.NoSelection)
            self.setColumnWidth(0, 130)
    
            self.setMouseTracking(True)
            self.itemEntered.connect(self.on_itemEntered)
            self._addrow()
    
        def on_itemEntered(self, it):
            QtWidgets.QToolTip.hideText()
            if it.column() == 1:
                r = self.visualItemRect(it)
                p = self.viewport().mapToGlobal(QtCore.QPoint(r.center().x(), r.top()))
                QtWidgets.QToolTip.showText(p, "Insert")
    
        @QtCore.pyqtSlot()
        def _addrow(self):
            rowcount = self.rowCount()
            self.insertRow(rowcount)
            combox_add = QtWidgets.QComboBox(self)
            combox_add.addItems(["I","II"])
            self.setCellWidget(rowcount, 4, combox_add)
            for c in range(self.columnCount()):
                self.setItem(rowcount, c, QtWidgets.QTableWidgetItem())
        # ...