无法从菜单操作中更改Qt主窗口的光标

3

在我的MainWindow中,我有一个按钮和一个菜单栏项,它们的信号都连接到同一个槽。在槽函数中,我已经编写了以下内容:

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

当通过按钮调用插槽函数时,这个功能按预期工作;然而,当从菜单中调用相同的函数时,等待光标不会出现。有任何想法为什么会这样?
我也考虑过使用QApplication::setOverrideCursor,但那会引起其他问题。
有什么建议吗?谢谢!
(我正在使用Qt 4.7,在Windows 7上使用Qt Creator和默认的MinGW编译器进行开发。)
以下是更详细的信息。
在MainWindow构造函数中: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);
}

当使用'button'调用showMessageBox时,等待光标会按预期显示。
当通过'action'调用showMessageBox时,等待光标不会出现;相反,光标从Qt :: CrossCursor更改为Qt :: ArrowCursor,一旦用户选择“操作”菜单项,然后在消息框打开时更改为Qt :: PointingHandCursor。等待光标从未出现。

使用setOverrideCursor会遇到哪些问题? - Exa
哦,你能发一些更多的代码吗?也许问题已经出现在连接宏中了。 - Exa
我扩展了我的帖子,包括一些重现该行为的示例代码。使用setOverrideCursor的不便之处在于,如果您需要在函数的某个点显示一个显示等待光标的消息框,则必须暂时删除等待光标(使用restoreOverrideCursor);否则,等待光标也将出现在对话框中。此外,我发现在显示Qt生成的对话框(QFileDialog :: getOpenFileName)时也应执行相同的操作以避免一些闪烁。 - Jan Hettich
我在我的 Ubuntu 10.10 上尝试了你的代码,它正常工作:在两种情况下都显示等待光标。 - serge_gubenko
2
在更改光标后,尝试使用qApp->processEvents();。 - Dmitriy
1个回答

0

你的代码是同步的,并使用延迟循环。当你在延迟循环中时,任何Qt代码都无法执行。光标更改需要事件循环旋转--所以从你提供的症状来看,似乎是这样。

以下是正确的做法--记住,如果在GUI代码中使用延迟/睡眠和其他阻塞调用,你的用户会讨厌你,这是理所当然的。在消息/对话框中使用exec()也是不好的风格。你的应用程序是异步的,因此要编写相应的代码。确保你的槽被声明为这样(在MainWindow声明的protected slots:部分)。

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接