0

我正在开发一个针对 Windows 7 的 Qt 4.8.4 GUI 应用程序。我正在尝试实现“逐步解决问题”方法,以在长时间运行的计算期间保持 GUI 响应,这可以很好地分为许多小脚步。

这是该技术的一个最小工作示例:

计算.h

#pragma once

#include "QtCore/QCoreApplication"
#include "QtCore/QDebug"
#include "QtCore/QObject"
#include "QtCore/QTimer"

class Computation : public QObject {
  Q_OBJECT
 public:
  Computation() : amount_(0) {}

 public Q_SLOTS:
  void start() {
    amount_ = 100000;
    QTimer::singleShot(0, this, SLOT(calculate()));
  }

 private Q_SLOTS:
  void calculate() {
    if (--amount_ > 0) {
      qDebug() << "Calculating..." << amount_;
      //QCoreApplication::processEvents();
      QTimer::singleShot(0, this, SLOT(calculate()));
    } else {
      qDebug() << "Finished";
    }
  }

 private:
  int amount_;
};

主文件

#include "Computation.h"

#include "QtCore/QDebug"
#include "QtGui/QApplication"
#include "QtGui/QMainWindow"
#include "QtGui/QPushButton"

int main(int argc, char* argv[]) {
  QApplication app(argc, argv);

  Computation computation;

  QMainWindow window;
  QPushButton button(&window);
  button.setText("Test");
  QObject::connect(&button, SIGNAL(clicked()), &computation, SLOT(start()));

  window.show();
  return app.exec();
}

此示例还有一个CMakeLists.txt,以防有人想尝试。

现在,回到实际问题:当计算运行时,某些 GUI 交互会导致鼠标锁定。光标仍然可以移动,但在此状态下单击桌面的任何部分都没有任何效果。计算仍在继续。摆脱这种锁定的唯一方法是使用键盘切换到另一个应用程序(例如 Alt+Tab、按 Windows 键或 Ctrl+Alt+Del)或等到计算完成。

导致此状态的 GUI 操作包括尝试移动应用程序的主窗口或调整其大小。上面解释的鼠标锁定发生了,而不是改变窗口的几何形状。但是,一旦计算完成,窗口就会立即跳转到应该移动到的位置(并且您没有切换到中间的另一个窗口)。

打开系统菜单(通过单击标题栏中的应用程序符号)也会导致类似的行为,但这次只有应用程序(包括系统菜单)对鼠标单击无动于衷。

QCoreApplication::processEvents()我试图通过发出我的方法来解决这个问题calculate()(上例中的注释行)。这只是一点点帮助:不是每次尝试移动或调整窗口大小时都锁定鼠标,您现在必须执行大约 3-5 次才能触发该行为。QCoreApplication::sendPostedEvents()和的不同组合QCoreApplication::flush()也无济于事。

我怎么解决这个问题?这是一个已知的 Qt 错误和/或有解决方法吗?

4

2 回答 2

0

如果您需要使应用程序多线程,您可以使用 Qt 的插槽和信号架构。当事情发生变化时,只需从你的线程发出一个信号。然后在您的 UI 线程中,将一个插槽连接到来自您的线程的信号: Qt: Background thread refresh UI thread

于 2013-04-10T20:41:45.743 回答
0

使用 QThread 绝对是一种比分块计算并尝试在一个线程中完成所有事情更好的策略。

然后在计算线程中,每 1/15 秒(例如)使用一个计时器来调用一个已连接到主线程中插槽的信号,该信号通知 UI 更新您希望从计算中看到的任何数据。

于 2013-04-24T14:10:03.273 回答