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

发布于 2024-10-19 15:31:48 字数 1332 浏览 4 评论 0原文

在我的主窗口中,我有一个按钮和一个菜单栏项,它们的信号都连接到同一个插槽。在槽函数中,我写道:

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

当通过按钮调用槽函数时,这将按预期工作;但是,当从菜单调用相同的功能时,等待光标不会出现。知道为什么吗?

我还考虑过使用 QApplication::setOverrideCursor;然而,这会导致其他问题。

有什么建议吗?谢谢!

(我正在使用 Qt 4.7,并使用 Qt Creator 和默认的 MinGW 编译器在 Windows 7 上进行开发。)

这里有更多详细信息。

在 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。等待光标永远不会出现。

In my MainWindow, I have a push button and a menu bar item whose signals are both connected to the same slot. In the slot function, I have written:

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

This works as expected when the slot function is invoked via the button; however, when the same function is invoked from the menu, the wait cursor doesn't appear. Any idea why?

I also considered using QApplication::setOverrideCursor; however, that causes other problems.

Any recommendations? Thanks!

(I am using Qt 4.7 and doing my development on Windows 7 using Qt Creator with the default MinGW compiler.)

Here's more detail.

in MainWindow constructor: this->setCursor(Qt::CrossCursor);

signal/slot connections:

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

showMessageBox function:

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

When showMessageBox is invoked with 'button', the wait cursor is displayed as expected.

When showMessageBox is invoked through 'action', the wait cursor does not appear; instead the cursor changes from Qt::CrossCursor to a Qt::ArrowCursor as soon as the user selects the 'action' menu item, and then changes to Qt::PointingHandCursor once the message box opens. The wait cursor never appears.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

七度光 2024-10-26 15:31:48

您的代码是同步的并使用延迟循环。当您处于延迟循环中时,任何 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);
}

Your code is synchronous and uses a delay loop. When you're in the delay loop, there's no way for any Qt code to execute. A cursor change requires the event loop to be spinning -- so it appears from the symptoms you give.

Here's how to do it correctly -- remember, if you use delays/sleeps and other blocking calls in your GUI code, your users will hate you, and rightly so. Using exec() in message/dialog boxes is also bad style. Your application is asynchronous, code it so. Make sure your slots are declared as such (in the protected slots: section of MainWindow declaration).

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);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文