从QFutureWatcher获取数据

时间:2017-04-17 18:15:52

标签: c++ qt qtconcurrent

我正在尝试将我的Qt应用程序连接到数据库。由于我有一个GUI,当然唯一的方法是在一个单独的线程中。我发现我可以通过QtConcurrent::run来完成。这是我的代码:

 
MainWindow::MainWindow(QWidget *parent) {
  // ...
  QFuture<bool> worker = QtConcurrent::run(this, &MainWindow::connectDatabase);
  QFutureWatcher<bool> *watcher = new QFutureWatcher<bool>;
  connect(watcher, &QFutureWatcher<bool>::finished, this, &MainWindow::databaseConnected);
  watcher->setFuture(worker);
}

bool MainWindow::connectDatabase() {
  QSqlDatabase db = QSqlDatabase::addDatabase("QPSQL");
  db.setHostName("127.0.0.1");
  db.setUserName("user");
  db.setPassword("pass");
  db.setDatabaseName("mydb");

  return db.open();
}

它有效,但我(显然)无法从过程中获取任何数据。例如,我想知道连接是否成功,如果我可以通过插槽,这将是理想的。

我可以将watcher添加为类的成员并从插槽中查询它,但这种方法对于我认为的许多异步任务来说都是乏味的。

我该怎么办?

1 个答案:

答案 0 :(得分:2)

你必须使worker成为一个类成员(因为在从构造函数退出时将删除局部变量):

MainWindow::MainWindow(QWidget *parent) {
  // ...
  m_worker = QtConcurrent::run(this, &MainWindow::connectDatabase);
  QFutureWatcher<bool> *watcher = new QFutureWatcher<bool>;
  connect(watcher, &QFutureWatcher<bool>::finished, this, &MainWindow::databaseConnected);
  watcher->setFuture(m_worker);
}

方式2:

MainWindow::MainWindow(QWidget *parent) { 
    connect(this, &MainWindow::mySignalAboutDBOpen, 
        this, &MainWindow::databaseConnected, Qt::QueuedConnection); 

        QtConcurrent::run(this, &MainWindow::connectDatabase);
    }

//and in the connectDatabase:
bool MainWindow::connectDatabase() {
    //...
    bool ret = db.open();
    emit mySignalAboutDBOpen(ret);
    return ret;
}

请注意,QSqlDatabase db变量也是本地变量,将在退出connectDatabase()时删除。

请参阅Qt::ConnectionType