Create database in QT - qt

Newbie having trouble creating a database here.
Following code compiles ok, but no database is created and I can't find any sqlite file.
#include "makeDB.h"
#include <iostream>
#include <QString>
#include <QtSql>
void makeDB(QString dbName) {
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
db.setHostName("localHost");
db.setDatabaseName(dbName);
db.setUserName("logger");
db.setPassword("logger");
}
#include <QtGui/QApplication>
#include <QString>
#include <QtSql>
#include "mainwindow.h"
#include "makeDB.h"
#include "createTable.h"
#include "ui_mainwindow.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
makeDB("log1");
createTable();
return a.exec();
}
What am I doing wrong here? Thanks!
Waynew
Edit/Delete Message

We can't see what you createTable() does, the code that you have never calls db.open() most of the QT database and SQL calls return bool for success and there is a lastError() function for both the QSqlDatabase and the QSqlQuery calls. Check those if appropriate calls, i.e. db.open() and query.exec() return false.
e.g.
bool makeDB(QString dbName) {
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
db.setHostName("localHost");
db.setDatabaseName(dbName);
bool result = db.open();
if (result)
{
//do more processing
}
else
{
qDebug() << db.lastError().text()
}
return result;
}
Also I don't think that SqlLite supports any kind of authentication this seems to indicate that you can secure your db by licensing an extension from the creators of SqlLite.
As to the actual table creation there should be some SQL that is executed that looks like this:
CREATE TABLE (x int, y varchar);
depending on the columns that you actually want.
This is the respective documentation.

Related

Doctest and qapplication

I must integrate doctest lib to a QT core project (Qt5 exactly).
At a point, I need a qcoreapplication to run event loop.
But when I try implement my doctest main with a qcoreapplication it looks doctest context and qcoreapplication parasite themself.
Do there are some workarounds? like qeventloop without qcoreapplication? other ways?
Did someone have already encountered this kind of case with other test libs?
Thanks for answers ;)
Edit 1:
For confidentiality reason i can't share actual base code. But i have same issue with basic code.
At my actual point i fall in an infinite loop at the end of execution.
I may just miss something on QCoreApplication execution end.
#define DOCTEST_CONFIG_IMPLEMENT
#include <QDebug>
#include <QObject>
#include <QSignalSpy>
#include <QApplication>
#include <QEventLoop>
#include "../../Core/external/doctest/doctest.h"
TEST_CASE("Basic class") {
SUBCASE("2*2") {
qDebug()<<"2*2";
CHECK_EQ(2*2, 4);
}
SUBCASE("1+1") {
qDebug()<<"1+1";
CHECK_EQ(1+1, 2);
}
SUBCASE("Termination") {
qDebug()<<"End!!";
QCoreApplication::instance()->quit();
}
}
int main(int argc, char** argv) {
doctest::Context context;
// defaults
context.setOption("abort-after", 5);
context.setOption("order-by", "name");
QCoreApplication app (argc, argv);
context.applyCommandLine(argc, argv);
context.setOption("no-breaks", true);
int res = context.run();
if(context.shouldExit())
return res;
int client_stuff_return_code = 0;
return res + client_stuff_return_code + app.exec(); // the result from doctest is propagated here as well
}

How to implement reactive programming rx in Qt creator?

I'm new to QT please help me with how to implement reactive programming in Qt
If you want to use QML, then reactive programming will be very easy. Item properties in QML are naturally of reactive nature (just write a "java script" expression which uses other properties and the reactive connection will be established). Since Qt6, property bindings are available also in C++, see https://www.youtube.com/watch?v=pN0pRBUqrrc
Moreover, you can use property bindings by KDAB https://www.kdab.com/signals-slots-properties-bindings/
There is a project called rqxt that you may want to look into. Check out the samples folder.
For example, this is a sample for signals and slots:
#include <QApplication>
#include <QDebug>
#include <QKeyEvent>
#include <QLineEdit>
#include <QPushButton>
#include <QVBoxLayout>
#include <QWidget>
#include <rxqt.hpp>
int main(int argc, char* argv[])
{
QApplication a(argc, argv);
auto widget = std::unique_ptr<QWidget>(new QWidget());
auto layout = new QVBoxLayout;
widget->setLayout(layout);
{
auto e0 = new QLineEdit("Edit here");
auto e1 = new QLineEdit;
e1->setEnabled(false);
layout->addWidget(e0);
layout->addWidget(e1);
rxqt::from_signal(e0, &QLineEdit::textChanged)
.map([](const QString& s) { return "[[[" + s + "]]]"; })
.subscribe([e1](const QString& s) { e1->setText(s); });
rxqt::from_event(e0, QEvent::KeyPress)
.subscribe([](const QEvent* e) {
auto ke = static_cast<const QKeyEvent*>(e);
qDebug() << ke->key();
});
}
widget->show();
return a.exec();
}

Qt - Compile-time check if qRegisterMetaType<T>() was called

‎
Question: Is there a way to check at compile-time if qRegisterMetaType<T>() was called for a custom type T?
The custom type T needs to be registered in Qt meta-type system in order to be used in e.g. queued connections.
If such a connection is made, and a signal triggered, the runtime warning will be shown:
QObject::connect: Cannot queue arguments of type 'T'
(Make sure 'T' is registered using qRegisterMetaType().)
This is hard to track, so I would prefer to check this at compile-time. Is that in any way possible?
(I understand that if it was possible, it would probably already be a part of Qt Framework itself, but maybe...?)
Note: I know I can check if a type was declared as metatype (Check if type is declared as a meta type system (for SFINAE)), but this doesn't solve my problem.
The code example would be:
#include <QCoreApplication>
#include <QDebug>
#include <QMetaMethod>
#include <QObject>
#include <QThread>
#include <QTimer>
struct Payload {
Payload() = default;
};
// Type is declared as metatype
Q_DECLARE_METATYPE(Payload)
class ObjectOne : public QObject {
Q_OBJECT
public:
using QObject::QObject;
void emitPayloadChanged() { Payload p; emit payloadChanged(p); }
signals:
void payloadChanged(const Payload& p);
};
class ObjectTwo : public QObject {
Q_OBJECT
public:
using QObject::QObject;
void handlePayload(const Payload& p) { qDebug() << "handling payload"; }
};
int main(int argc, char* argv[]) {
QCoreApplication app(argc, argv);
// Uncommenting the following line fixes the runtime warning
// qRegisterMetaType<Payload>();
QThread t1, t2;
ObjectOne o1;
o1.moveToThread(&t1);
ObjectTwo o2;
o2.moveToThread(&t2);
t1.start();
t2.start();
QObject::connect(&o1, &ObjectOne::payloadChanged, &o2, &ObjectTwo::handlePayload);
QTimer::singleShot(0, &o1, [&] { QMetaObject::invokeMethod(&o1, &ObjectOne::emitPayloadChanged); });
return app.exec();
}
#include "main.moc"

Problems with function QTimer::singleShot

I am trying to record sound by QAudioInput. According to the doc in this website QAudioInput. But when I ran, it exported an empty-raw file. After checking, It seems like the function QTimer::singleShot didn't working ( I added statement qWarning << "Done" in void stopRecording() and It didn't display "Done" so I thought it had some mistake in QTimer::singleShot function ).
This is my code used to check function QTimer::singleShot
----Check.pro----
QT += core
QT -= gui
TARGET = Check
CONFIG += console
CONFIG -= app_bundle
TEMPLATE = app
SOURCES += main.cpp
HEADERS += test.h
-----test.h------
#ifndef TEST_H
#define TEST_H
#include <QCoreApplication>
#include <QTimer>
#include <iostream>
#include <QObject>
#include <test.h>
#include <QDebug>
using namespace std;
class Object: public QObject {
Q_OBJECT
private slots:
void func() { cout << "Hello"; }
};
#endif // TEST_H
----main.cpp----
#include <QCoreApplication>
#include <QTimer>
#include <iostream>
#include <QObject>
#include <test.h>
#include <QDebug>
using namespace std;
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
Object *o = new Object;
QTimer::singleShot(10000, o, SLOT(func()));
return 0;
}
And this code doesn't working, too. Can anyone explain me? I am newbie at Qt-programming.
Your program exits right after it's set the timer - it has no time to fire.
For the timer to work, you need an event loop running. Without the event loop, no events get processed.
Change the last line of your main to
return a.exec();
Also change your test slot by adding << std::endl or flush std::cout otherwise you might see no output on the console.
Your program should then work as expected (except it won't ever finish since nothing will cause the event loop to stop - just interrupt it).

Declaring a signal in Qt script prototype

I tried declaring a signal in a prototype and then connecting it is script funcition for some reason it does not work as I hoped. My code is as follows. Could some one help me in this.
What I expected was, once I called p.setText('New String') in the script code, since setText emits the textChanged signal it should invoke the slot which is catchSignal(text) already connected in the script code.
Prototype header
#ifndef SCRIPTACTION_H
#define SCRIPTACTION_H
#include <QObject>
#include <QtScript>
class ScriptAction : public QObject , public QScriptable
{
Q_OBJECT
public:
ScriptAction(QObject *parent = 0);
signals:
void textChanged(const QString changedString);
};
#endif // SCRIPTACTION_H
Class
#include "scriptaction.h"
#include <QAction>
Q_DECLARE_METATYPE(QAction*)
ScriptAction::ScriptAction(QObject *parent) : QObject(parent)
{
}
Main Class
#include <QApplication>
#include <QDebug>
#include <QAction>
#include "scriptaction.h"
#include <QPushButton>
Q_DECLARE_METATYPE(QAction*)
QScriptValue qAction_Constructor(QScriptContext *ctx, QScriptEngine *eng)
{
qDebug() << "QAction is called";
if(ctx->isCalledAsConstructor())
{
QObject *parent = ctx->argument(0).toQObject();
QAction *action = new QAction("Test",parent);
return eng->newQObject(action, QScriptEngine::ScriptOwnership);
} else {
return QString("invalid call. Use new Constructor");
}
}
int main(int argc, char *argv[])
{
QApplication app(argc,argv);
QScriptEngine engine;
//Evaluating a simaple expresssion
qDebug() << engine.evaluate("1+2").toNumber();
QPushButton button;
QScriptValue buttonScript= engine.newQObject(&button);
engine.globalObject().setProperty("button", buttonScript);
engine.evaluate("button.text ='Hello Text'; button.show()");
//QAction Prototype
ScriptAction qsAction ;
QScriptValue script_proto = engine.newQObject(&qsAction);
engine.setDefaultPrototype(qMetaTypeId<QAction*>(), script_proto);
QScriptValue ctor = engine.newFunction(qAction_Constructor , script_proto);
QScriptValue metaObject = engine.newQMetaObject(&QObject::staticMetaObject, ctor);
engine.globalObject().setProperty("QSAction" , metaObject);
engine.evaluate("var p = new QSAction(button);p.textChanged.connect(catchSignal);");
engine.evaluate("function catchSignal(text) { print ('PROTOTYPE SIGNAL IS CALLED ',text); } p.setText('New String'); " );
return app.exec();
}
I got rid of the issue, and now I see the signal is being triggered and slot is called properly.
All I did was moving the code to a separate script file and start using the QScriptDebugger to see its output. Then I figured there was an error and the code is edited to work.
Anyone who wants an example prototype class, this will hopefully be a good guideline.

Resources