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

时间:2010-11-24 17:38:40

标签: qt qt4

我正在尝试显示并从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();
}

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

1 个答案:

答案 0 :(得分:1)

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

当然,如果您还需要以其他方式发送信息,事情会变得复杂一些。那么你需要一个完整的子程序来代替你的程序,而不仅仅是我在这里描述的一个基本类。