2012-03-09 109 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繼承,並將您的工作置於重寫通知方法。我認爲這對任何有同樣問題的人都有用。