Home > Software engineering >  How do I show status tips in the main window for an undocked dock widget?
How do I show status tips in the main window for an undocked dock widget?

Time:11-25

I'd like to be able to use QWidget.setStatusTip(str) for widgets inside a docked widget, when the dock widget is undocked. This does not work by default.

Theoretically I could manually manage the status bar manually, but this seems like a very bad way of going about solving this issue.

Example of status tip working properly when QDockWidget is docked:

Example when docked

Example of status tip not working properly when QDockWidget is undocked (note that I am hovering over the same box, the only difference is that the widget is floating):

Example when floating)

I've tried setting the parent of the dock widget to be the QMainWindow.

CodePudding user response:

Status tip work by triggering the StatusTip event on the widget, if it does not handle it, it is propagated to its parents hierarchy until any of them does handle it (and its event() returns True).

The status tip is normally managed by the top level main window that contains the widget triggering the event. When the dock widget is floating, it is its own top level window, so the main window will not receive it.

A possible solution is to install an event filter on the dock widget, check if the event is of the correct type, verify if the dock is actually floating and then "reroute" the event to the event() of the main window and return its result.

from PyQt5.QtWidgets import *
from PyQt5.QtCore import *

class Window(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setCentralWidget(QTextEdit())
        self.dockWidget = QDockWidget()
        container = QWidget()
        self.dockWidget.setWidget(container)
        self.button = QPushButton(
            'I am a button', 
            toolTip='I am a tool tip', 
            statusTip='I am a status tip'
        )
        QVBoxLayout(container).addWidget(self.button)
        self.addDockWidget(Qt.LeftDockWidgetArea, self.dockWidget)

        self.statusBar()

        self.dockWidget.installEventFilter(self)

    def eventFilter(self, obj, event):
        if (
            event.type() == event.StatusTip
            and obj == self.dockWidget
            and self.dockWidget.isFloating()
        ):
            return self.event(event)
        return super().eventFilter(obj, event)

if __name__ == "__main__":
    import sys
    app = QApplication(sys.argv)
    window = Window()
    window.show()
    sys.exit(app.exec())

Note: setting the QDockWidget parent to the main window is pointless: when it's properly added using addDockWidget() (as it should), it's automatically reparented anyway (otherwise you wouldn't be able to see it embedded in the dock areas).

  • Related