2016-06-02 7 views
0

Ich habe zwei QSqlDatabase-Datenbankverbindungen, "local" und "remote". Ich habe eine Funktion, die beide Verbindungen verwendet (Daten von der lokalen Datenbank holen und an die entfernte Datenbank senden). Wenn ich diese Funktion aus meiner QThread-Klasse ausführen, funktioniert die lokale Verbindung (ich habe erwartete Daten), aber die Remoteverbindung schlägt fehl. Aber wenn ich diese Funktion außerhalb der Klasse QThread (in main()) ausführen, funktionieren beide Verbindungen.QSqlDatabase: Verbindung von QThread kann nicht verwendet werden

Die Remoteverbindung schlägt fehl, wenn ich versuche, die Verbindung mit der Fehlermeldung zu öffnen: "QSqlDatabasePrivate :: Datenbank: Datenbank kann nicht geöffnet werden: QMYSQL: Verbindung nicht möglich". Vorher habe ich getestet, ob die Verbindung gültig ist (isValid()) und es war okey. Ich überprüfe auch, ob die Verbindung bereits offen war, aber es war nicht.

Ich fand diese Informationen auch, aber da die „lokale“ Verbindung aus dem Thread arbeitet könnte dies das Problem nicht:

Themen und die SQL-Modul Eine Verbindung kann nur von innen die verwendet werden, Thread, der es erstellt hat. Das Verschieben von Verbindungen zwischen Threads oder das Erstellen von Abfragen aus einem anderen Thread wird nicht unterstützt. http://doc.qt.io/qt-5/threads-modules.html#threads-and-the-sql-module

Der Fehler wird in Qt 5.5.1, 32bit, Ubuntu 14.04 gefunden. Auch getestet auf Raspberry Pi, Qt 5.6, aber mit "Segmentierungsfehler" als Ergebnis.

Was ist los?

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(); 
} 
+0

Vielleicht könnte das Posten des Codes helfen, das Problem zu sehen? – Silicomancer

+0

Beitrag mit Code aktualisiert – Peder

Antwort

0

fand ich eine Lösung für das Problem. Die Lösung bestand darin, neue Instanzen sowohl den lokalen zu schaffen und die Remote-Verbindung im DataHandlerThread Konstruktor:

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(...); 
    ... 
} 

Wie ich es verstehe, könnten diese neuen Instanzen auch unter Verwendung erstellt QSqlDatabase :: cloneDatabase() und übergab diese neuen Instanzen an den DataHandlerThread-Konstruktor (nicht getestet).

So scheint es, als ob die Informationen im Link "Threads und das SQL-Modul" etwas korrekt waren. Aus irgendeinem Grund funktionierte die "lokale" Verbindung noch aus dem Thread.