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

Qt 从QObject外部显示并获取QMessageBox的结果,qt,qt4,Qt,Qt4,我试图在QObject类外部的消息框中显示并获取结果。我似乎能够生成如下对话框: #include <iostream> #include <QApplication> #include <QtConcurrentRun> #include <QMessageBox> class DialogHandler : public QObject { Q_OBJECT signals: void MySignal(); public: D

我试图在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();
}
#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();
}
#包括
#包括
#包括
#包括
类DialogHandler:公共QObject
{
Q_对象
信号:
void MySignal();
公众:
DialogHandler()
{
连接(这个,信号(MySignal()),这个,插槽(MySlot());
}
无效信号()
{
发出我的信号();
}
公众时段:
void MySlot()
{
QMessageBox*对话框=新建QMessageBox;
对话框->设置文本(“测试文本”);
对话框->exec();
int result=对话框->结果();
如果(结果)
{
std::cout EmitSignal(&returnValue);

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


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

那么您使用多线程?您可以在MyClass中创建一个QObject派生类,只需显示msgbo即可x在一个插槽中,或者你可以将另一个线程中的对象连接到你的小部件,并在那里显示messagebox。啊,没错,我将其归因于不在QObject类中,但你显然是正确的,这是因为该类不在同一个线程中。我仍然不知道如何连接信号和插槽,因为我在这里:Form::My类::MyFunction(){…执行函数…发生错误…ProduceMessageBox()}由于MyClass不是QObject,它无法发出信号,因此如何使其调用形式函数?我想我得到了“单向”情况(请参见问题中的编辑)。这就是你的意思吗?它不执行任何显式锁定,但似乎可以工作?你有没有关于如何发送信息的示例?我没有完全验证你的代码,但该方法可以工作。你需要确保你的DialogHandler在UI线程中实例化(就像你在主示例中所做的那样)。可以通过自定义事件将信息发送回原始对象,尽管我手头上没有任何特定的示例。我认为这是可行的,但它似乎只在第一次循环中起作用,然后程序似乎停止运行(处理器为0%,但它从未运行第二次迭代)?-在这里,我希望消息框会连续显示3次。但是,它只显示一次,然后它就会出现我提到的“暂停”。有没有想过为什么会出现这种情况?没关系,这是一件不相关的事情-我必须将QApplication::quitOnLastWindowClosed()设置为false,以便在窗口关闭后应用程序不会退出(虽然它似乎并没有一路退出…,但这解决了它)。