Sqlite3 network oddity - qt

I have a simple QT program to read an sqlite3 database. Annoyingly, my program failed when the actual database is on the network as a mapped drive (Windows 7) but works when the database is on the local drive. The code I'm using is below and just for experimental purposes.
QFileInfo fileInfo(m_lastDatabaseFile);
QString host = fileInfo.canonicalPath();
QString filename = fileInfo.fileName();
m_dataBase = QSqlDatabase::addDatabase("QSQLITE");
m_dataBase.setHostName(host);
m_dataBase.setDatabaseName(filename);
qDebug() << " valid: " << m_dataBase.isValid();
if (m_dataBase.open() )
{
QStringList tableList = m_dataBase.tables(QSql::Tables);
qDebug() << "Database open.";
QSqlQuery query = m_dataBase.exec("SELECT * FROM PallolBoards");
qDebug() << "Found: " << query.size();
if (query.size() <= 0)
{
QSqlError err = query.lastError();
qDebug() << "Last error: " << err.text();
}
while (query.next() )
{
QString title = query.value(0).toString();
qDebug() << "Query: " << title;
}
}
else
{
QMessageBox::critical(this,"Invalid database",m_dataBase.lastError().text());
}
Any clues anyone? So H: will fail but D: succeeds.

At least in windows vista there was a security setting controlling if an application was allowed to access network shares or not.
There is also a dependency between Internet security settings(accessible through e.g. internet explorer) and access to network shares.

Related

Qt: RFCOMM BluetoothSocket Connection Problems after switching Pages in QML

I'm developing an cross plattform Application in Qt Creator, which has the exercise to control a device via Classic Bluetooth. I have a communication protocol. FIRST: I can connect to device and write Data to it with BluetoothSocket. If I put the startMotor() function into the socketConnected SLOT after beepBuzzor() command then it works fine and I get state() connected.
My problem is if I switch the page in my Application on Android and click on the "start motor" button, I get the state() unconnected, but I am still connected to the device because the LED on the device shows connected. My app does not crash. I think the problem is in the line with socket->connectToService(...), but I'm unsure what to change. The beepBuzzor command works fine, startMotor command too. But if I call the function after successfully connectToService() it does not work because the state is unconnected.
BluetoothManager::BluetoothManager(QObject *parent) : QObject(parent)
{
socket = new QBluetoothSocket(QBluetoothServiceInfo::RfcommProtocol);
}
void BluetoothManager::startDiscovery()
{
// Check if Bluetooth is available on this device
if (localDevice.isValid()) {
qDebug() << "Bluetooth is available on this device";
//Turn BT on
localDevice.powerOn();
// Make it visible to others
localDevice.setHostMode(QBluetoothLocalDevice::HostDiscoverable);
//Read local device name & address
qDebug() << "Local Device:" << localDevice.name() << "(" << "Address:" << localDevice.address() << ")";
// Create a discovery agent and connect to its signals
discoveryAgent = new QBluetoothDeviceDiscoveryAgent(this);
connect(discoveryAgent, SIGNAL(finished()), this, SLOT(deviceDiscoverFinished()));
// Start a discovery
// Trick: da es kein DiscoveryTimer für Classic gibt, suchen wir nach LE devices, da BT121 BLE unterstützt.
// Die Verbindung erfolgt jedoch über RFCOMM sobald man sich mit dem Gerät verbindet.
discoveryAgent->setLowEnergyDiscoveryTimeout(5000);
discoveryAgent->start(QBluetoothDeviceDiscoveryAgent::LowEnergyMethod);
qDebug() << "Device discover started";
}
else
{
qDebug() << "Bluetooth is not available on this device";
}
}
//SLOT for the finish of device Discovery
void BluetoothManager::deviceDiscoverFinished()
{
qDebug() << "Device discover finished";
listOfDevices = discoveryAgent->discoveredDevices();
qDebug() << "Found new devices:";
for (int i = 0; i < listOfDevices.size(); i++)
{
//Q_OS_IOS / MAC do not need here cuz the run is on android device, delete later
//We do not find galileo device on MacBook
#if defined (Q_OS_IOS) || defined (Q_OS_MAC)
// On MacOS and iOS we get no access to device address,
// only unique UUIDs generated by Core Bluetooth.
qDebug() << "getting address from deviceUuid()" << listOfDevices.at(i).name().trimmed()
<< " ( " << listOfDevices.at(i).deviceUuid().toString().trimmed() << " ) ";
setDevice(listOfDevices.at(i).name().trimmed() + " (" + listOfDevices.at(i).deviceUuid().toString().trimmed() + ")");
#else
qDebug() << listOfDevices.at(i).name().trimmed()
<< " ("
<< listOfDevices.at(i).address().toString().trimmed()
<< ")";
setDevice(listOfDevices.at(i).name().trimmed() + " (" + listOfDevices.at(i).address().toString().trimmed() + ")");
#endif
}
}
/**
* In GUI (QML) user select a device with index i.
* Create a new socket, using Rfcomm protocol to communicate
*/
void BluetoothManager::deviceSelected(int i)
{
selectedDevice = listOfDevices.at(i);
#if defined (Q_OS_IOS) || defined (Q_OS_MAC)
qDebug() << "User select a device: " << selectedDevice.name() << " ("
<< selectedDevice.deviceUuid().toString().trimmed() << ")";
#else
qDebug() << "User select a device: " << selectedDevice.name() << " ("
<< selectedDevice.address().toString().trimmed() << ")";
#endif
if (localDevice.pairingStatus(selectedDevice.address())== QBluetoothLocalDevice::Paired)
{
qDebug() << "Pairing is allready done";
}
else
{
qDebug() << "Not paired. Please do pairing first for communication with device!";
}
selecDevAdress = selectedDevice.address();
connectToSvc();
//Connect SIGNALS with SLOTS
connect(socket, SIGNAL(error(QBluetoothSocket::SocketError)), this, SLOT(socketError(QBluetoothSocket::SocketError)));
connect(socket, SIGNAL(connected()), this, SLOT(socketConnected()));
connect(socket, SIGNAL(disconnected()), this, SLOT(socketDisconnected()));
connect(socket, SIGNAL(readyRead()), this, SLOT(socketRead()));
connect(socket, SIGNAL(stateChanged(QBluetoothSocket::SocketState)), this, SLOT(socketStateChanged()));
}
void BluetoothManager::connectToSvc()
{
qDebug() << "Create socket";
//socket->connectToService(selecDevAdress, QBluetoothUuid(QString("00001101-0000-1000-8000-00805F9B34FB")), QIODevice::ReadWrite);
//static const QString serviceUuid(QStringLiteral("00001101-0000-1000-8000-00805F9B34FB"));
socket->connectToService(selectedDevice.address(), QBluetoothUuid(QString("00001101-0000-1000-8000-00805F9B34FB")), QIODevice::ReadWrite);
//Also works with this line instead of the two above (with declaration of serviceUuid)
//socket->connectToService(QBluetoothAddress(selectedDevice.address()),QBluetoothUuid(QBluetoothUuid::SerialPort));
socket->open(QIODevice::ReadWrite);
socket->openMode();
}
//SLOT wenn Socket verbunden ist
void BluetoothManager::socketConnected()
{
//qDebug() << ("Connected to: "+socket->peerAddress().toString() +":"+socket->peerPort());
qDebug() << ("Connected to: "+socket->peerAddress().toString());
qDebug() << "Socket connected";
qDebug() << "Local: "
<< socket->localName()
<< socket->localAddress().toString()
<< socket->localPort();
qDebug() << "Peer: "
<< socket->peerName()
<< socket->peerAddress().toString()
<< socket->peerPort();
//Do "beep" sound commando after succesfull connection to Galileo device
beepBuzzor();
}
/**
* Socket disconnected.
* Delete socket, free the memory.
*/
//SLOT für Verbindungsabbruch von Socket
void BluetoothManager::socketDisconnected()
{
qDebug() << "Socket disconnected";
socket->deleteLater();
}
void BluetoothManager::socketError(QBluetoothSocket::SocketError error)
{
qDebug() << "Socket error: " << error;
}
void BluetoothManager::socketStateChanged()
{
int socketState = socket->state();
if(socketState == QAbstractSocket::UnconnectedState)
{
qDebug() << "unconnected";
}
else if(socketState == QAbstractSocket::HostLookupState)
{
qDebug() << "host lookup";
}
else if(socketState == QAbstractSocket::ConnectingState )
{
qDebug() << "connecting";
}
else if(socketState == QAbstractSocket::ConnectedState)
{
qDebug() << "connected";
}
else if(socketState == QAbstractSocket::BoundState)
{
qDebug() << "bound";
}
else if(socketState == QAbstractSocket::ClosingState)
{
qDebug() << "closing";
}
else if(socketState == QAbstractSocket::ListeningState)
{
qDebug() << "listening";
}
}
// SLOT when data ready on bluetooth socket
void BluetoothManager::socketRead()
{
qDebug() << "socketRead()";
QByteArray recievedData = socket->readAll();
emit dataRecieved(recievedData);
}
/**
* Get a string with device info
*/
const QString &BluetoothManager::device() const
{
return deviceInfo;
}
void BluetoothManager::setDevice(const QString &newDevice)
{
if (newDevice != deviceInfo) {
deviceInfo = newDevice;
emit deviceChanged();
}
}
void BluetoothManager::beepBuzzor()
{
QByteArray beep;
beep.append(QByteArray::fromRawData("\x04\x00\x09\xD0\x07\x32\x00", 7));
command(beep);
}
void BluetoothManager::startMotor()
{
qDebug() << "startMotor slot";
if(socket->state() == QBluetoothSocket::UnconnectedState){
qDebug() << "Socket Unconnected";
}
else{
qDebug() << "Socket Unonnected";
}
socketStateChanged();
//command(start);
}
void BluetoothManager::command(QByteArray &cmdBuf)
{
socket->write(cmdBuf);
}

Qmqtt QObject::connect: Cannot queue arguments of type 'ClientState' (Make sure 'ClientState' is registered using qRegisterMetaType().)

I am creating a thread and inside that thread :
m_client = new QMqttClient(this);
m_client->setHostname("ps01.xx.com");
m_client->setPort(1883);
m_client->setClientId("Sas-RASPi-001");
m_client->connectToHost();
connecting to the mqt broker.
any signal connecting attempt like :
QObject::connect(m_client, &QMqttClient::stateChanged, this, &Messenqt::updateLogStateChange);
produce an error like :
QObject::connect: Cannot queue arguments of type 'ClientState'
(Make sure 'ClientState' is registered using qRegisterMetaType().)
I added :
qRegisterMetaType<QMqttClient::ClientState>("QMqttClient::ClientState");
in the beginning of the code (above code)
still same problem.
What is the proper way to use mqt from different thread in QT signal/slot way ?
EDIT:
for (int i = 20 ; i < 20 ; i++){
QThread::sleep(1);
if(m_client->publish(topic_, QString("testing. . . ").toLocal8Bit() , 1 ,true) == -1;
qDebug() << " error" <<;
}
Hi,
I am using qmqtt in a for loop with sleep 1 second and then process waiting to send messages until all 20 messages published.
When the loop finishe all 20 messages send .
But . if we will not use QThread::sleep(1) . then each messages sending individually. why . ?
Is there any way to force send to each messages immediatelly when its published?
EDIT 2
Below example not sending the images to the broker. It is blocking some place somewhere. I need flush the messages :)
minimal example :
m_client = new QMqttClient(this);
m_client->setHostname("ps01.xxx.com");
m_client->setPort(1883);
m_client->setClientId("RASPBERRY-009");
m_client->setUsername("vv");
m_client->setPassword("vv");
m_client->setCleanSession(false);
m_client->connectToHost();
//yeni slot mekanizmasi. kendi icinde &Publisher örneği..
QObject::connect(m_client, &QMqttClient::stateChanged, this, &Publisher::updateStateChange);
QObject::connect(m_client, &QMqttClient::connected, this, &Publisher::sendMessages);
an the send message:
void Publisher::sendMessages()
{
QDir dir("/ram");
int count = 0;
QThread::sleep(5);
while (true){
QStringList images_metas = dir.entryList(QStringList() << "*.png" ,QDir::Files);
if (images_metas.size() > 0){
foreach(QString filename, images_metas) {
dataLoad *dl = new dataLoad;
QString img_path = "/ram/" + filename;
QImage img(img_path);
qDebug() << " : : : " << QImage("/ram/00-02-2018-04-05-2.png").size() << endl;
dl->image = img;
dl->text = "Deneme MEsajıdır . . ";
QByteArray byteArray_;
QDataStream stream(&byteArray_, QIODevice::WriteOnly);
stream.setVersion(QDataStream::Qt_5_10);
stream << dl->image << dl->text;
qDebug() << count++ << " sending : " << byteArray_.size() << " " << filename << endl;
qDebug() << testPublish(byteArray_)<< endl;
}
}
else {
qDebug() << " folder is empty waiting... " << endl;
}
//Check every 1 second
QThread::sleep(1);
}
}
and the publishing:
qint32 Publisher::testPublish(QByteArray &bytarray)
{
QMqttTopicName topic_ = QString("qtmqtt/topic1");
QString mesaj = ".x.x.x.x.x.x.x.";
auto id = m_client->publish(topic_, mesaj.toLocal8Bit() , 1 ,true);
return id;
}
Please try below code:
msg_timer = new QTimer(this);
//TODO big chip save timer.
connect(msg_timer, SIGNAL(timeout()) , this , SLOT(sendMessages()));
msg_timer->start(1000);
dont use while loop. It is blocking everything..
Best
I get a solution to the problem of "Qmqtt QObject::connect: Cannot queue arguments of type 'ClientState' (Make sure 'ClientState' is registered using qRegisterMetaType().)" caused by working in threads. Although I have not made clear the specific meaning, at least it can work well.
You can try it:
connect(m_client, &QMqttClient::stateChanged, [&](QMqttClient::ClientState state){
qDebug()<< state;
});

QSqlDatabase not opening

I am unable to understand what I am doing wrong here. I am using Qt 5.7.1 and the code is as follows:
QString filePath = QCoreApplication::applicationDirPath();
QString dbPath = QDir(filePath).absoluteFilePath("../../../Database");
m_db = QSqlDatabase::addDatabase("QSQLITE", "user_connection");
m_db.setDatabaseName(dbPath + "/Sensor_Objects.db");
qDebug() << filePath << " & " << dbPath;
if (!m_db.open())
qDebug() << "Database Error: " + m_db.lastError().text();
else
{
qDebug() << "Database: connection ok";
createDatabase("Sensor_Objects");
m_db.close();
}
qDebug() is printing the paths to the directories correctly and yet m_db.open() fails with the error "Database Error: out of memory Error opening database".
Probably the point is dbpath,try with
m_db.setDatabaseName(dbPath.toLatin1() + "/Sensor_Objects.db");

QSQLITE driver not loaded

I'm creating a light APP with QT that add entries into my SQLITE base from my website.
But I've this problem :
("QSQLITE")
QSqlError(-1, "", "")
DATABASE OPENED
QSqlQuery::prepare: database not open
QSqlError(-1, "Driver not loaded", "Driver not loaded")
I'm on a Bananapi (Debian 7) with QT installed and upgrade from Debian-APT.
This is my code :
// Load QSLite driver
qDebug() << bdd.drivers(); //Said : ("QSQLITE")
bdd = QSqlDatabase::addDatabase("QSQLITE");
qDebug() << bdd.lastError();
// Open the database
bdd.setDatabaseName("/var/www/config/database.sqlite");
// Connect to the database
if( ! bdd.open())
{
qDebug() << "ERROR " << EXIT_FAILURE_CANT_OPEN_DATABASE << " : Can't open database";
qDebug() << bdd.lastError();
exit(EXIT_FAILURE_CANT_OPEN_DATABASE);
}
else
qDebug() << "DATABASE OPENED";
query.prepare(....); //Said : QSqlQuery::prepare: database not open.
Any idea ?

Qt Serial Port Errors - Data not getting read

I'm trying to read a serial port with the Qt SerialPort library. I can read the data using HyperTerminal.
In Qt I used the following code to try and do the same thing. Qt says the the port has been opened correctly, but for some reason, the bytesAvailable from the serial port is always 0.
serial.setPortName("COM20");
if (serial.open(QIODevice::ReadOnly))
qDebug() << "Opened port " << endl;
else
qDebug() << "Unable to open port" << endl;
serial.setDataBits(QSerialPort::Data8);
serial.setParity(QSerialPort::EvenParity);
serial.setBaudRate(QSerialPort::Baud115200);
qDebug() << "Is open?? " << serial.isOpen();
// Wait unit serial port data is ready
while (!serial.bytesAvailable())
{
//qDebug() << serial.bytesAvailable()<<endl;
continue;
}
QByteArray data = serial.read(100);
qDebug() << "This is the data -" << data << endl;
serial.close();
In comparison, MATLAB code with the same structure as the above code, successfully manages to read the serial port data
%Serial Port Grapher - Shurjo Banerjee
s = serial('COM20');
s.BaudRate = 460800;
s.Parity = 'even';
try
input('Ready to begin?');
catch
end
fopen(s);
fh = figure();
hold on;
t = 1;
while (s.BytesAvailable <= 0)
continue
end
a = fread(s, 1)
old_t = 1;
old_a = a;
while true
if (s.BytesAvailable > 0)
a = fread(s, 1)
figure(fh)
t = t + 1;
plot([old_t t], [old_a a]);
old_t = t;
old_a = a;
end
end
fclose(s);
1) It's bug: https://codereview.qt-project.org/#change,47729
Recomended for solution:
I changed line 161 in qserialport_win.cpp from:
return error;
to
return !error;
and now my simplified example works.
2) Also i recomended:
One step: Open port:
if (this->open(QIODevice::ReadWrite)) {
} else {
qDebug() << "\n Can't open port | " << this->errorString();
}
Two step: I recommend checking the parameter setting:
if (
this->setBaudRate(this->baudRate)
&& this->setDataBits(this->dataBits)
&& this->setParity(this->parity)
&& this->setStopBits(this->stopBits)
&& this->setFlowControl(this->flowControl)) {
qDebug() << "\n[ info ] Port settings successfully";
} else {
qDebug() << "\n[ error ] Port settings failed";
}
If all is well, then recomended for using SIGNAL ReadyRead() and your SLOT for receiving data.

Resources