2012-03-09 247 views
5

我在跟踪QMainWindow中的鼠标移动时遇到问题。我有一个切换按钮buttonGenerate。这里是当按钮处于启用状态为MainWindowQMainWindow无法跟踪鼠标与setMouseTracking()

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); 
} 

代码,鼠标应该被跟踪,并跟踪是否启用不应label_5显示其X & Y坐标一起。当按钮关闭时,鼠标跟踪应该关闭并且label_5未更新。不是这种情况。

无论按钮是否被按下,鼠标都没有被跟踪。只有当我按住鼠标按钮时,label_5才会更新,这无关于setMouseTracking(bool)是否处于活动状态。

任何有识之士将不胜感激。

+0

你是否确认'on_buttonGenerate_toggled'中的'checked'在你期望的时候是'true'? – 2012-03-09 17:57:39

+0

是的,切换时'%3'参数为1。 – nerozehl 2012-03-09 17:58:44

+0

但是你只能看到,当你按下鼠标按钮时 - 它触发我作为一个可能性,鼠标按下临时设置“hasMouseTracking”为1。所以我会验证它在'on_buttonGenerate_toggled'。 – 2012-03-09 18:01:24

回答

12

这是因为Qt的设计师创造了QMainWindow“隐藏”的小部件,如中可以看到生成的ui_MainWindow.h

[...] 
centralWidget = new QWidget(MainWindow); 
[...] 
MainWindow->setCentralWidget(centralWidget); 

因此,它是这个小部件谁接收鼠标事件,并在其子控件被放置,而不是QMainWindow。

如果你把:

centralWidget()->setAttribute(Qt::WA_TransparentForMouseEvents); 
setMouseTracking(true); 
在主窗口的构造

,你会看到鼠标事件,但你不能按下按钮,因为这中央物件不接收任何鼠标事件都没有。

解决方案:

设计在设计器(带按钮&标签)的窗口小部件,覆盖其mouseMoveEvent并做QMainWindow::setCentralWidget它。

+0

但文档说应该传播鼠标移动事件? – nerozehl 2012-03-09 18:21:01

+1

它被传播,直到它被接受,这是一个小部件的情况下,除非你让它“事件透明”。 – Koying 2012-03-09 18:24:06

+1

因此,为了能够追踪QMainWindow中的子窗口小部件,您需要为每个窗口小部件调用'setMouseTracking(true)'! – phyatt 2014-05-28 22:27:11

1

这是一个非常古老的话题,我很抱歉,但我刚刚找到了其他解决方案。 当您想要捕捉所有MainWindow上的事件时,只需检查obj是否为您的窗口和所需事件即可使用QApplication::notify(QObject* obj, QEvent* ev),它将针对每个窗口小部件上的每个事件调用。您只需要从QApplication继承,并将您的工作置于重写通知方法。我认为这对任何有同样问题的人都有用。