Reputation: 473
I'm having a problem with tracking mouse movements in a QMainWindow
. I have a toggle button buttonGenerate
. Here is the code for the MainWindow
class MainWindow : public QMainWindow, private Ui::MainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
protected:
void mouseMoveEvent(QMouseEvent *);
private slots:
void on_buttonGenerate_toggled(bool checked);
};
void MainWindow::mouseMoveEvent(QMouseEvent *event)
{
label_5->setText(tr("%1 %2 %3")
.arg(event->x())
.arg(event->y())
.arg(hasMouseTracking()));
event->ignore();
}
void MainWindow::on_buttonGenerate_toggled(bool checked)
{
buttonGenerate->setText(checked
? tr("Stop")
: tr("Start"));
setMouseTracking(checked);
}
When the button is toggled on, the mouse should be tracked and its X & Y coordinates along with whether tracking is enabled or not should be shown in label_5
. When the button is toggled off, mouse tracking should be off and label_5 not-updated. This is not the case.
Regardless of whether the button is pressed, the mouse is not being tracked. Only when I hold down a mouse button will label_5
be updated, and this is irregardless of whether setMouseTracking(bool)
is active.
Any insight would be greatly appreciated.
Upvotes: 7
Views: 12807
Reputation: 4266
It happens because Qt designer creates a "hidden" widget in QMainWindow
, as can be seen in the generated ui_MainWindow.h
:
[...]
centralWidget = new QWidget(MainWindow);
[...]
MainWindow->setCentralWidget(centralWidget);
Thus it is this widget who receives the mouse events and on which the child widgets are placed, not the QMainWindow.
if you place:
centralWidget()->setAttribute(Qt::WA_TransparentForMouseEvents);
setMouseTracking(true);
in the constructor of your mainwindow, you'll see the mouse events but you cannot press the button because this central widget do not receive any mouse event at all.
Solution:
Design a widget in the Designer (with button & label), override its mouseMoveEvent
and do a QMainWindow::setCentralWidget
with it.
Upvotes: 22
Reputation: 229
It's a really old topic, I'm sorry but I've just found an other solution.
When you want to catch events over all the MainWindow, you can use QApplication::notify(QObject* obj, QEvent* ev)
just by checking if obj is your window and the needed event, it is called for each event on every widget. You just need to inherit from QApplication and put your work in the overrode notify method. I think it can be useful for anyone with the same issue.
Upvotes: 2