2011-02-28 62 views
2

在我的MainWindow中,我有一個按鈕和一個菜單欄項目,它們的信號都連接到同一個插槽。在插槽功能中,我寫了:無法在菜單動作中更改Qt主窗口中的光標

mainWindow->setCursor(QCursor(Qt::WaitCursor)); 

這可以按預期的方式通過按鈕調用槽功能;但是,當從菜單調用相同的函數時,等待光標不會出現。任何想法爲什麼?

我也考慮過使用QApplication :: setOverrideCursor;但是,這會導致其他問題。

有什麼建議嗎?謝謝!

(我使用Qt 4.7和Qt Creator要使用默認MinGW的編譯器做我的開發在Windows 7上。)

這裏的更多細節。

在主窗口構造

this->setCursor(Qt::CrossCursor);

信號/槽連接:

QObject::connect(button, SIGNAL(clicked()), MainWindow, SLOT(showMessageBox())); 
QObject::connect(action, SIGNAL(triggered()), MainWindow, SLOT(showMessageBox())); 

showMessageBox功能:

void MainWindow::showMessageBox() 
{ 
    this->setCursor(Qt::WaitCursor); 
    // display wait cursor briefly before showing message box 
    for (int i = 0; i < 1<<30;) {++i;} 
    QMessageBox msgBox; 
    msgBox.setText("Hello!"); 
    msgBox.setStandardButtons(QMessageBox::Ok); 
    msgBox.setCursor(Qt::PointingHandCursor); 
    msgBox.exec(); 
    this->setCursor(Qt::CrossCursor); 
} 

showMessageBox被調用, '按鈕',等待光標被顯示爲預期。

當通過'action'調用showMessageBox時,等待光標不會出現;相反,只要用戶選擇'action'菜單項,光標就會從Qt :: CrossCursor變爲Qt :: ArrowCursor,然後在消息框打開後更改爲Qt :: PointingHandCursor。等待光標從不出現。

+0

什麼是使用setOverrideCursor的問題? – Exa

+0

哦,你可以發佈一些更多的代碼?也許問題已經在連接宏中發生了。 – Exa

+0

我擴展了我的帖子以包含一些重現行爲的示例代碼。使用setOverrideCursor發現的不便之處在於,如果您需要在顯示等待光標的函數的某個位置顯示消息框,則必須臨時刪除等待光標(使用restoreOverrideCursor);否則等待光標也會出現在對話框中。另外,我發現在顯示Qt生成的對話框(QFileDialog :: getOpenFileName)時也應該做同樣的事情以避免閃爍。 –

回答

0

您的代碼是同步的,並使用延遲循環。當你在延遲循環中時,任何Qt代碼都無法執行。光標變化需要事件循環旋轉 - 所以它出現你給出的症狀。

下面是如何正確地做到這一點 - 記住,如果您在GUI代碼中使用延遲/睡眠和其他阻止調用,那麼您的用戶會討厭你,這是正確的。在消息/對話框中使用exec()也是不好的樣式。你的應用程序是異步的,編碼如此。確保你的插槽是這樣聲明的(在MainWindow聲明的保護槽:部分)。

void MainWindow::showMessageBox() 
{ 
    this->setCursor(Qt::WaitCursor); 
    QTimer::singleSlot(200, this, SLOT(slot1()); // fire slot1 after 200ms 
} 

void MainWindow::slot1() 
{ 
    QMessageBox * msgBox = new QMessageBox(this); 
    msgBox->setText("Hello!"); 
    msgBox->setStandardButtons(QMessageBox::Ok); 
    msgBox->setCursor(Qt::PointingHandCursor); 
    msgBox->show(); 
    connect(msgBox, buttonClicked(QAbstractButton*), SLOT(slot2(QAbstractButton*))); 
} 

void MainWindow::slot2(QAbstractButton* button) 
{ 
    // a button was clicked on the message box 
    this->setCursor(Qt::CrossCursor); 
}