QSqlDatabase:无法使用QThread的连接

时间:2016-06-02 15:11:14

标签: qt qthread qsqldatabase

我有两个QSqlDatabase数据库连接," local"和"远程"。我有一个使用两个连接的函数(从本地数据库获取数据并发送到远程数据库)。当我从QThread类运行此函数时,本地连接工作(我得到了预期的数据),但远程连接失败。但是,如果我在QThread类之外运行此函数(在main()中),则两个连接都可以正常工作。

当我尝试使用错误消息打开连接时远程连接失败:" QSqlDatabasePrivate :: database:无法打开数据库:QMYSQL:无法连接"。在此之前,我测试了连接是否有效(isValid())并且它是okey。我还检查连接是否已经打开,但它不是。

我也发现了这个信息,但是因为" local"连接可以从线程中工作,这可能不是问题:

主题和SQL模块 只能在创建连接的线程中使用连接。不支持在线程之间移动连接或从其他线程创建查询。 http://doc.qt.io/qt-5/threads-modules.html#threads-and-the-sql-module

错误发现在Qt 5.5.1,32bit,Ubuntu 14.04中。还在Raspberry Pi,Qt 5.6上进行了测试,但是使用了" Segmentation fault"结果。

有什么问题?

的main.c

main()
{
  DataHandler dh();
  DataHandlerThread dht(&dh); //pointer to dh to get access to dh functions from the thread

  //here I run dh.foo() or dht.run(), never both functions
  dh.foo();
  dht.run();
  ...
}

datahandler.cpp

DataHandler::DataHandler()
{
  m_dbLocal = QSqlDatabase::addDatabase("QMYSQL", "local");
  m_dbLocal.setHostName("localhost");
  ...

  m_dbRemote = QSqlDatabase::addDatabase("QMYSQL", "remote");
  m_dbRemote.setHostName(...);
  ...
}

DataHandler::foo()
{
  qDebug() << QSqlDatabase::connectionNames(); //always ("remote", "local")
  m_dbLocal.isValid(); //always true
  m_dbLocal.open(); //always true

  m_dbRemote.isValid(); //always true

  //true if foo() is called from main using dm.foo()
  //QSqlDatabasePrivate::database: unable to open database: " QMYSQL: Unable to connect" if called from main using dmt.run()
  m_dbRemote.open(); 
}

datahandlerthread.h

class DataHandlerThread : public QThread
{
    Q_OBJECT
public:
    explicit DataHandlerThread(DataHandler* dh);

private:
    void run() Q_DECL_OVERRIDE;

    DataHandler* m_dh;

};

datahandlerthread.cpp

DataHandlerThread::DataHandlerThread(DataHandler* dh)
{
    m_dh = dh;
}

void DataHandlerThread::run()
{
    m_dh->foo();
}

1 个答案:

答案 0 :(得分:0)

我找到了问题的解决方案。解决方案是在DataHandlerThread构造函数中创建本地和远程连接的新实例:

<强> datahandlerthread.cpp

DataHandlerThread::DataHandlerThread(DataHandler* dh)
{
  m_dh = dh;
  m_dbLocal = QSqlDatabase::addDatabase("QMYSQL", "local_thread");
  m_dbLocal.setHostName("localhost");
  ...

  m_dbRemote = QSqlDatabase::addDatabase("QMYSQL", "remote_thread");
  m_dbRemote.setHostName(...);
  ...
}

据我了解,这些新实例也可以通过使用QSqlDatabase :: cloneDatabase()创建,并将这些新实例传递给DataHandlerThread构造函数(未测试)。

因此,它似乎是&#34;线程和SQL模块中的信息&#34;链接有些正确。由于某种原因,&#34;本地&#34;连接仍然在线程中工作。