QPushButton与QTextBrowser的mouseMoveEvent行为差异及解决方法
I noticed a difference in mouseMoveEvent behavior when implementing it on QTextBrowser and QPushButton:
- When hovering over
QTextBrowser,mouseMoveEventis triggered continuously as the mouse moves. - But for
QPushButton,mouseMoveEventonly fires when the mouse is pressed and moved; hovering without pressing doesn't trigger it.QListWidgetbehaves the same asQPushButton.
Why does this difference exist? And how can I make QPushButton trigger mouseMoveEvent without needing to press the mouse?
Here's my test code:
import sys from PyQt5 import QtWidgets class window35(QtWidgets.QMainWindow): def __init__(self): super(window35, self).__init__() myWidget=QtWidgets.QWidget() self.Hbox=QtWidgets.QHBoxLayout() self.btn=QtWidgets.QPushButton("HAA BHYI\nBUTTON") self.textBrowser=QtWidgets.QTextBrowser() self.Hbox.addWidget(self.btn) self.Hbox.addWidget(self.textBrowser) myWidget.setLayout(self.Hbox) self.setCentralWidget(myWidget) self.btn.mouseMoveEvent=self.mouse_move self.textBrowser.mouseMoveEvent=self.text_browser_move self.show() def mouse_move(self,event): print("hello btn") try: QtWidgets.QPushButton.mouseMoveEvent(self.btn,event) except Exception as E: print(E) def text_browser_move(self,event): print("hello list") try: QtWidgets.QTextBrowser.mouseMoveEvent(self.textBrowser,event) except Exception as E: print(E) app=QtWidgets.QApplication([]) ex=window35() sys.exit(app.exec_())
Why the Difference?
The core reason boils down to mouse tracking—a Qt widget property that controls whether the widget receives mouse move events when no mouse buttons are pressed.
QTextBrowser(and related widgets likeQTextEditorQScrollArea) have mouse tracking enabled by default. This means they automatically pick upmouseMoveEventwhenever the cursor hovers and moves over them, no button presses required. This makes sense for text-focused widgets where hover interactions (like link previews) are common.QPushButtonandQListWidgethave mouse tracking disabled by default. For these widgets, Qt only sendsmouseMoveEventwhen a mouse button is held down during movement. This is the standard behavior for most interactive buttons and item views, since they don't need to react to hover movements unless explicitly designed to.
How to Make QPushButton Trigger MouseMoveEvent on Hover
To get QPushButton to fire mouseMoveEvent without pressing the mouse, you just need to enable mouse tracking for the button. Here are two straightforward ways to do this:
1. Enable Mouse Tracking Directly in Initialization
Add a single line right after creating your button:
self.btn=QtWidgets.QPushButton("HAA BHYI\nBUTTON") self.btn.setMouseTracking(True) # This enables hover move events
2. Subclass QPushButton (for Reusable Behavior)
If you need this hover behavior across multiple buttons, subclassing is a cleaner approach:
class HoverAwarePushButton(QtWidgets.QPushButton): def __init__(self, text="", parent=None): super().__init__(text, parent) self.setMouseTracking(True) # Enable tracking in the subclass def mouseMoveEvent(self, event): print("hello hover btn") super().mouseMoveEvent(event) # Don't forget to call the base class method!
Then use this subclass instead of the default QPushButton:
self.btn=HoverAwarePushButton("HAA BHYI\nBUTTON")
Once mouse tracking is enabled, your mouse_move function will print "hello btn" every time the mouse moves over the button—just like the QTextBrowser does.
Quick Reminder
Always make sure to call the base class's mouseMoveEvent (like you're already doing in your code). Skipping this can break the button's native functionality, like correctly handling press/release states or visual hover effects.
内容的提问来源于stack exchange,提问作者Nimish Bansal




