I have a problem with Qt and sqlite. Until recently, I didn't have any problems creating tables, but now, whenever I try to create a table (using the exact same function) I get an error message:
QSqlError("1", "Unable to fetch row", "table selections already exists")
My query strings are as follows:
CREATE TABLE external_files (path VARCHAR (255) NOT NULL, used INTEGER (12) NOT NULL);
This is the same as before too.
The strange thing is though, all the tables are created without a problem, but I still get error messages.
If you have any ideas why this happens, I would appreciate it. :)
UPDATE: Minimal, complete, verifiable example:
#include <QCoreApplication>
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QSqlError>
#include <QFile>
#include <QTextStream>
#include <QDebug>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE", "CONN");
db.setDatabaseName("test.db");
if(!db.open()){
qDebug() << "Connection failed!";
}
QFile tableListFile(":/resources/sql/tables.sql");
if(tableListFile.open(QIODevice::ReadOnly))
{
QTextStream stream(&tableListFile);
while(!stream.atEnd())
{
QString queryString = stream.readLine();
qDebug() << "Query string: " << queryString;
QSqlQuery query(queryString, db);
if(!query.exec()){
qDebug() << "Query error: " << query.lastError();
}
}
}
db.close();
return a.exec();
}
Thanks in advance.
Ok, I managed to solve the problem.
The query was executed 2 times for each query string, and that caused the error messages.
To get to the solution, i edited my code like this:
QString queryString = stream.readLine();
qDebug() << "Query string: " << queryString;
QSqlQuery query;
if(!query.exec(queryString)){
qDebug() << "Query error: " << query.lastError();
}
Related
Would really appreciate your help. I'm new to Qt and C++.
I managed to get this working previously, but for some reason am no longer able to do so. I haven't touched anything to do with the writing of files, but all functions pertaining to file writing no longer seem to function. Here's an example of one of the simpler write functions:
#include <QStringList>
#include <QDir>
#include <QFile>
#include <QString>
#include <QTextStream>
void HandleCSV::writeToPIDCSV(UserAccount newUser)
{
// Storing in userPID db
QString filePath = returnCSVFilePath("dbPID");
qDebug() << "File path passsed to writeToPIDCSV is " << filePath;
// Open CSV filepath retrieved from associated dbName
QFile file(filePath);
if (!file.open(QIODevice::ReadWrite | QIODevice::Append))
{
qDebug() << file.isOpen() << "error " << file.errorString();
qDebug() << "File exists? " << file.exists();
qDebug() << "Error message: " << file.error();
qDebug() << "Permissions err: " << file.PermissionsError;
qDebug() << "Read error: " << file.ReadError;
qDebug() << "Permissions before: " << file.permissions();
// I tried setting permissions in case that was the issue, but there was no change
file.setPermissions(QFile::WriteOther);
qDebug() << "Permissions after: " << file.permissions();
}
// if (file.open(QIODevice::ReadWrite | QIODevice::Append))
else
{
qDebug() << "Is the file open?" << file.isOpen();
// Streaming info back into db
QTextStream stream(&file);
stream << newUser.getUID() << "," << newUser.getEmail() << "," << newUser.getPassword() << "\n";
}
file.close();
}
This gets me the following output when run:
File path passsed to writeToPIDCSV is ":/database/dummyPID.csv"
false error "Unknown error"
File exists? true
Error message: 5
Permissions err: 13
Read error: 1
Permissions before: QFlags(0x4|0x40|0x400|0x4000)
Permissions after: QFlags(0x4|0x40|0x400|0x4000)
The file clearly exists and is recognised when run, but for some reason file.isOpen() is false, and the permissions show that the user only has read (not write) permissions that are unaffected by permission settings.
Would someone have a clue as to why this is happening?
Many thanks in advance
Update
Thanks #chehrlic and #drescherjm - I didn't realise that I can only read but not write to my resource file!
Using QStandardPaths allows me to write to my AppDataLocation. I've included the code below for others who might encounter similar issues, adapted from https://stackoverflow.com/a/32535544/9312019
#include <QStringList>
#include <QDir>
#include <QFile>
#include <QString>
#include <QTextStream>
#include <QStandardPaths>
void HandleCSV::writeToPIDCSV(UserAccount newUser)
{
auto path = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);
if (path.isEmpty()) qFatal("Cannot determine settings storage location");
QDir d{path};
QString filepath = returnCSVFilePath("dbPID");
if (d.mkpath(d.absolutePath()) && QDir::setCurrent(d.absolutePath()))
{
qDebug() << "settings in" << QDir::currentPath();
QFile f{filepath};
if (f.open(QIODevice::ReadWrite | QIODevice::Append))
{
QTextStream stream(&f);
stream << newUser.getUserFirstName() << ","
<< newUser.getUserIDNumber() << "\n";
}
}
}
Am now testing to make this work with my Read functions.
If there's any way to be able to write to the Qt program's folder (or build folder), I'd really appreciate it!
You can not write to a Qt resource. If you want to update/write to a file you should put the file into a writeable filesystem. To e.g. place it in the appdata folder you can use QStandardPaths::writeableLocation(QStandardPaths::ApplicationsLocation)
I'm trying to learn how to share memory between Qt and Non-Qt application while having read-write access from both. For now I'm trying to create and then attach already created memory in Qt using native key. While the program can successfully create shared memory segment, it can't access it during the next launch. How can I fix this? Is there a way to attach shared memory segment using only native key?
#include <QCoreApplication>
#include <QDebug>
#include <QSharedMemory>
#include <sys/shm.h>
#include <errno.h>
#include <sys/types.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
qDebug() << "PID: " << getpid();
QSharedMemory *mem = new(QSharedMemory);
mem->setNativeKey("foobar");
if (!mem->create(3072, QSharedMemory::ReadWrite))
{
qDebug() << "Create fail:" << mem->errorString();
qDebug() << "trying to detach:" << mem->detach();
if (mem->attach())
{
qDebug() << "Attached succesfully";
}
else
{
qDebug() << "Attach fail:" << mem->errorString() << ", error:" << mem->error();
}
}
else
qDebug() << "Memory created successfully: ";
qDebug() << "nativeKey=" << mem->nativeKey() << ", key=" << mem->key();
qDebug() << "Waiting for input";
getchar();
// return a.exec();
return 0;
}
First launch: works as expected, the key is reset as nativeKey is set.
PID: 10989
Memory created successfully:
nativeKey= "foobar" , key= ""
Waiting for input
Second launch: trying to create throws an error as expected, trying to detach also throws an error as expected (as it's not attached) but when trying to attach the memory there's another unexpected error.
PID: 10992
Create fail: "QSharedMemory::create: already exists"
trying to detach: false
Attach fail: "QSharedMemoryPrivate::initKey: unable to set key on lock" , error: 3
nativeKey= "foobar" , key= ""
Error 3 (from Qt documentation):
The operation failed because of an invalid key.
I don't know what's wrong with my nativeKey.
I need some help in updating remote MySQL database using QT5.I am working on Linux Ubuntu 12.04.I want my app to connect to remote server and write some data to it.Any help will be greatly appreciated.
Here is an example:
#include <QCoreApplication>
#include <QtSql/QSqlDatabase>
#include <QtSql/QSqlQuery>
#include <QDebug>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
//use mysql driver
QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");
//set hostname
db.setHostName("localhost");
//set db name
db.setDatabaseName("test");
//set username and password
db.setUserName("user");
db.setPassword("pass");
//open db
bool ok = db.open();
qDebug() << "Db is open: " << ok;
//define a query
QSqlQuery query;
//set query
query.exec("SELECT * FROM `Persons`");
//get values from query
while (query.next()) {
QString LastName = query.value(1).toString();
QString FirstName = query.value(2).toString();
int age = query.value(3).toInt();
qDebug() << LastName << " " << FirstName << " " << age;
}
//close db
db.close();
return a.exec();
}
According to this, A JSON starting with bracket is valid, so i have encoded a list of item, in a test.json file:
[{"name": "a"},{"name": "b"}]
Heavily inspirated by this answer, i push this code in main.cpp:
#include <QApplication>
#include <QFile>
#include <QByteArray>
#include <QJsonObject>
#include <QJsonDocument>
#include <QVariant>
#include <QDebug>
#include <iostream>
int main(int argc, char *argv[]) {
// Reading the JSON, parse it, get data as QJsonObject
QString val;
QFile file;
file.setFileName("test.json");
file.open(QIODevice::ReadOnly | QIODevice::Text);
val = file.readAll();
file.close();
QJsonDocument d = QJsonDocument::fromJson(val.toUtf8());
QJsonObject sett2 = d.object();
// Printings
qWarning() << "File content: " << val;
qWarning() << "sett2: " << sett2 << " (empty: " << sett2.empty() << ')';
// try to access the data directly
QJsonValue value = sett2.value(QString("name"));
qWarning() << "name value: " << value;
QJsonObject item = value.toObject();
qWarning() << "QJsonObject of accessed value: " << item;
}
Here is the output:
File content: "[{\"name\": \"a\"},{\"name\": \"b\"}]\n"
sett2: QJsonObject() (empty: true )
name value: QJsonValue(undefined)
QJsonObject of accessed value: QJsonObject()
We see that the file is properly readed. However, no data seems to be accessed : sett2 is empty, as if holding no data.
After searching on the QJsonObject documentation, i can't found any routine that can give access to the data in the file, in this case: the only one that seems to allow an access to fields is the value(), method, but it needs a parameter.
Call it with 0, 1, NULL "name", "a", "b" and "knock knock" lead to compilation error or empty data.
Other methods, like keys(), returns also empty data.
How access data of objects ? (here, name: "a" and name: "b")
The answere is simple - you have to call QJsonDocument::array() instead of object:
QJsonArray sett2 = d.array();
I am trying to rig up some basic serial communications in QT
I am getting the port COM19 from QSerialPortInfo, and I speaking successfully to the port via Arduino. However, I cannot get anything back via QT.
#include "mainwindow.h"
#include <QApplication>
#include <QDebug>
#include <QTextStream>
#include <QFile>
#include <QtSerialPort/QSerialPort>
#include <QtSerialPort/QSerialPortInfo>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts()){
qDebug() << "Name :" << info.portName();
qDebug() << "Description :" << info.description();
qDebug() << "Manufactuer :" << info.manufacturer();
QSerialPort serial;
serial.setPort(info);
if(serial.open(QIODevice::ReadWrite))
qDebug() << serial.errorString();
serial.write("M114 \n");
qDebug() << serial.readAll();
serial.close();
// Now we need to send and receive commands
serial.setPortName("COM19");
serial.setBaudRate(QSerialPort::Baud57600);
serial.setDataBits(QSerialPort::Data8);
serial.setParity(QSerialPort::NoParity);
serial.setStopBits(QSerialPort::OneStop);
serial.setFlowControl(QSerialPort::NoFlowControl);
if(serial.open(QIODevice::ReadWrite)){
qDebug() << "opened";
}else{
qDebug() << "Not opened";
}
qDebug() << serial.errorString();
serial.write("M114 \n");
qDebug() << serial.readAll();
serial.close();
}
MainWindow w;
w.show();
return a.exec();
}
As you can see, I am trying a simple connection along the lines of the documentation, and one where I write out all the baud rate information. They throw two different errors.
Like I said, I am connecting via arduino to this same port and having success. Any ideas what's wrong?
Name : "COM19"
Description : "USB Serial (Communication Class, Abstract Control Model)"
Manufactuer : "PJRC.COM, LLC."
"Unknown error"
""
opened
"The handle is invalid."
""
Any ideas for what I am doing wrong?
My idea is to send commands to the device, and read them back to the console.
the code looks a bit confuse. You open all port available and then you try to do something wrong.
NOTE: You use a GUI application like a shell application. It is wrong.
Try:
#include "mainwindow.h"
#include <QApplication>
#include <QDebug>
#include <QTextStream>
#include <QFile>
#include <QtSerialPort/QSerialPort>
#include <QtSerialPort/QSerialPortInfo>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QSerialPort serial;
serial.setPortName("COM19");
if(serial.open(QIODevice::ReadWrite)){
//Now the serial port is open try to set configuration
if(!serial.setBaudRate(QSerialPort::Baud57600))
qDebug()<<serial.errorString();
if(!serial.setDataBits(QSerialPort::Data8))
qDebug()<<serial.errorString();
if(!serial.setParity(QSerialPort::NoParity))
qDebug()<<serial.errorString();
if(!serial.setStopBits(QSerialPort::OneStop))
qDebug()<<serial.errorString();
if(!serial.setFlowControl(QSerialPort::NoFlowControl))
qDebug()<<serial.errorString();
//If any error was returned the serial il corrctly configured
serial.write("M114 \n");
//the serial must remain opened
if(serial.waitForReadyRead(100)){
//Data was returned
qDebug()<<"Response: "<<serial.readAll();
}else{
//No data
qDebug()<<"Time out";
}
//I have finish alla operation
serial.close();
}else{
qDebug()<<"Serial COM19 not opened. Error: "<<serial.errorString();
}
MainWindow w;
w.show();
return a.exec();
}
Starting with the tenth port, his name will be \\.\COM10
You can reassign the port to a different number in Device Manager