Search code examples
pythonpyqtqtabwidgetmouse-cursor

How to set the mouse cursor on QTabWidget tabs


I am dealing with a simple problem I don't succeed to solve. I am working with Python-3.6 and PyQt5.

What I wish is to change the mouse cursor when the user has the mouse above the inactive tab (to understand he can click on it to change the active tab). And this only on the inactive tab, not on its content (because changing the cursor parameter in Qt Designer permits me to do this). I looked for this answer on internet during a few hours but I didn't find what I want. I think I have to deal with the stylesheet property, but I don't know how to do (it seems to be something with QTabWidget::pane maybe). Can someone help me please?

Here is a sample code in which the mouse-cursor is changed over the whole the tab, not only the tab title:

from PyQt5 import QtCore, QtGui, QtWidgets
import sys

class Ui_Form(QtWidgets.QWidget):
    def __init__(self, nb_courbes=1, nom_courbes='', parent=None):
        super(Ui_Form, self).__init__(parent)
        self.setupUi(self)

    def setupUi(self, Form):
        Form.setObjectName("Form")
        Form.resize(249, 169)
        self.tabWidget = QtWidgets.QTabWidget(Form)
        self.tabWidget.setGeometry(QtCore.QRect(40, 40, 127, 80))
        self.tabWidget.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor))
        self.tabWidget.setObjectName("tabWidget")
        self.tab = QtWidgets.QWidget()
        self.tab.setObjectName("tab")
        self.tabWidget.addTab(self.tab, "")
        self.tab_2 = QtWidgets.QWidget()
        self.tab_2.setObjectName("tab_2")
        self.tabWidget.addTab(self.tab_2, "")

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

I want the normal cursor (the arrow) on the blue zone, but change the mouse cursor on the inactive tab title in the red zone.

tabtab2


Solution

  • You can change the cursor for all the tabs by setting it on the tab-bar:

        self.tabWidget.tabBar().setCursor(QtCore.Qt.PointingHandCursor)
    

    However, to change it for only the inactive tabs, you must use an event filter to change the cursor dynamically, like this:

    def setupUi(self, Form):
        ...
        self.tabWidget.tabBar().installEventFilter(self)
        self.tabWidget.tabBar().setMouseTracking(True)
        ...
    
    def eventFilter(self, source, event):
        if (event.type() == QtCore.QEvent.MouseMove and
            source is self.tabWidget.tabBar()):
            index = source.tabAt(event.pos())
            if index >= 0 and index != source.currentIndex():
                source.setCursor(QtCore.Qt.PointingHandCursor)
            else:
                source.setCursor(QtCore.Qt.ArrowCursor)
        return super(Ui_Form, self).eventFilter(source, event)
    

    (PS: Qt does not support changing the cursor via stylesheets).