从 QObject 外部显示并获取 QMessageBox 的结果

发布于 2024-10-04 09:53:05 字数 2558 浏览 0 评论 0原文

我正在尝试从 QObject 类外部显示消息框并获取结果。我似乎能够生成这样的对话框:

#include <iostream>

#include <QApplication>
#include <QtConcurrentRun>
#include <QMessageBox>

class DialogHandler : public QObject
{
Q_OBJECT

signals:
  void MySignal();

public:
  DialogHandler()
  {
    connect( this, SIGNAL( MySignal() ), this, SLOT(MySlot()) );
  }

  void EmitSignal()
  {
    emit MySignal();
  }

public slots:
  void MySlot()
  {
    QMessageBox* dialog = new QMessageBox;
    dialog->setText("Test Text");
    dialog->exec();
    int result = dialog->result();
    if(result)
    {
      std::cout << "ok" << std::endl;
    }
    else
    {
      std::cout << "invalid" << std::endl;
    }
  }
};

#include "main.moc" // For CMake's automoc

void MyFunction(DialogHandler* dialogHandler)
{
  dialogHandler->EmitSignal();
}

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

  DialogHandler* dialogHandler = new DialogHandler;

  MyFunction(dialogHandler);

  return app.exec();
}

为了将结果返回到 MyFunction,似乎只需传递一个对象来填充结果,如下所示:

#include <iostream>

#include <QApplication>
#include <QtConcurrentRun>
#include <QMessageBox>

class DialogHandler : public QObject
{
Q_OBJECT

signals:
  void MySignal(int* returnValue);

public:
  DialogHandler()
  {
    connect( this, SIGNAL( MySignal(int*) ), this, SLOT(MySlot(int*)), Qt::BlockingQueuedConnection );
  }

  void EmitSignal(int* returnValue)
  {
    emit MySignal(returnValue);
  }

public slots:
  void MySlot(int* returnValue)
  {
    std::cout << "input: " << *returnValue << std::endl;
    QMessageBox* dialog = new QMessageBox;
    dialog->addButton(QMessageBox::Yes);
    dialog->addButton(QMessageBox::No);
    dialog->setText("Test Text");
    dialog->exec();
    int result = dialog->result();
    if(result == QMessageBox::Yes)
    {
      *returnValue = 1;
    }
    else
    {
      *returnValue = 0;
    }
  }
};

#include "main.moc" // For CMake's automoc

void MyFunction(DialogHandler* dialogHandler)
{
  int returnValue = -1;
  dialogHandler->EmitSignal(&returnValue);

  std::cout << "returnValue: " << returnValue << std::endl;
}

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

  DialogHandler* dialogHandler = new DialogHandler;

  QtConcurrent::run(MyFunction, dialogHandler);

  std::cout << "End" << std::endl;
  return app.exec();
}

这看起来合理吗?有更好的方法吗?

I am trying to display and get the result a message box from outside of a QObject class. I seem to be able to generate the dialog like this:

#include <iostream>

#include <QApplication>
#include <QtConcurrentRun>
#include <QMessageBox>

class DialogHandler : public QObject
{
Q_OBJECT

signals:
  void MySignal();

public:
  DialogHandler()
  {
    connect( this, SIGNAL( MySignal() ), this, SLOT(MySlot()) );
  }

  void EmitSignal()
  {
    emit MySignal();
  }

public slots:
  void MySlot()
  {
    QMessageBox* dialog = new QMessageBox;
    dialog->setText("Test Text");
    dialog->exec();
    int result = dialog->result();
    if(result)
    {
      std::cout << "ok" << std::endl;
    }
    else
    {
      std::cout << "invalid" << std::endl;
    }
  }
};

#include "main.moc" // For CMake's automoc

void MyFunction(DialogHandler* dialogHandler)
{
  dialogHandler->EmitSignal();
}

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

  DialogHandler* dialogHandler = new DialogHandler;

  MyFunction(dialogHandler);

  return app.exec();
}

To get the result back in MyFunction, it seems to work to do simply pass an object to fill with the result like this:

#include <iostream>

#include <QApplication>
#include <QtConcurrentRun>
#include <QMessageBox>

class DialogHandler : public QObject
{
Q_OBJECT

signals:
  void MySignal(int* returnValue);

public:
  DialogHandler()
  {
    connect( this, SIGNAL( MySignal(int*) ), this, SLOT(MySlot(int*)), Qt::BlockingQueuedConnection );
  }

  void EmitSignal(int* returnValue)
  {
    emit MySignal(returnValue);
  }

public slots:
  void MySlot(int* returnValue)
  {
    std::cout << "input: " << *returnValue << std::endl;
    QMessageBox* dialog = new QMessageBox;
    dialog->addButton(QMessageBox::Yes);
    dialog->addButton(QMessageBox::No);
    dialog->setText("Test Text");
    dialog->exec();
    int result = dialog->result();
    if(result == QMessageBox::Yes)
    {
      *returnValue = 1;
    }
    else
    {
      *returnValue = 0;
    }
  }
};

#include "main.moc" // For CMake's automoc

void MyFunction(DialogHandler* dialogHandler)
{
  int returnValue = -1;
  dialogHandler->EmitSignal(&returnValue);

  std::cout << "returnValue: " << returnValue << std::endl;
}

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

  DialogHandler* dialogHandler = new DialogHandler;

  QtConcurrent::run(MyFunction, dialogHandler);

  std::cout << "End" << std::endl;
  return app.exec();
}

Does that seem reasonable? Is there a better way to do it?

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

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

发布评论

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

评论(1

薆情海 2024-10-11 09:53:05

这不可能像你所拥有的那样,但只要做一些工作就可以完成。当然,一种选择是将您的类转换为 QObject,此时您可以发送信号。然而,它对执行期间的延迟没有帮助。如果有必要,您可以拥有一个位于主 UI 线程中但可以从其他线程调用的消息传递类。从其他线程调用的函数需要锁定、创建信号量,并向自身发送一个事件以及要显示的信号量和消息。然后,在 customEvent(位于 UI 线程中)中,您将创建消息框,执行它,并在消息框被清除后触发信号量。

当然,如果您还需要以其他方式发回信息,事情会变得更加复杂。然后,您的程序将需要一个完整的子系统,而不是像我在这里描述的那样只有一个基本类。

This isn't possible quite like you have it, but with a bit of work it could be done. One option, of course, would be to convert your class to a QObject, at which point you could send signals. It doesn't help for the delay during exec, however. If that is necessary, you could have a messaging class that lives in the main UI thread, but can be called from other threads. The function called from other threads would need to lock, make a semaphore, and send an event to itself with the semaphore and message to be displayed. Then, in customEvent (which would be in the UI thread), you would create the message box, exec it, and trigger the semaphore after the message box is cleared.

Of course, things get a bit more complicated if you need to send information back the other way as well. Then you'll need a complete subsystem for your program, instead of just one basic class like I describe here.

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