Отобразите и получите результат QMessageBox извне QObject - PullRequest
3 голосов
/ 24 ноября 2010

Я пытаюсь отобразить и получить результат окно сообщения из-за пределов класса 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 Ответ

1 голос
/ 01 декабря 2010

Это невозможно, как у вас, но с небольшой работой это можно сделать. Конечно, одним из вариантов будет преобразование вашего класса в объект QObject, после чего вы сможете отправлять сигналы. Это не помогает для задержки во время исполнения, однако. Если это необходимо, у вас может быть класс сообщений, который находится в основном потоке пользовательского интерфейса, но может вызываться из других потоков. Функция, вызываемая из других потоков, должна блокировать, создавать семафор и отправлять событие себе с семафором и сообщением, которое будет отображаться. Затем в customEvent (который будет в потоке пользовательского интерфейса) вы должны создать окно сообщения, выполнить его и запустить семафор после очистки окна сообщения.

Конечно, все становится немного сложнее, если вам нужно отправить информацию и в обратном направлении. Тогда вам понадобится полная подсистема для вашей программы, а не один базовый класс, как я описал здесь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...