QSqlTableModel() empty on Ubuntu but works on Windows ?
-
@JonB said in QSqlTableModel() empty on Ubuntu but works on Windows ?:
@R-P-H
You sub-class fromQSqlDatabase. Personally I would always do that anyway, precisely for this reason --- you never know what you may find you need to add/alter from the suppliedQSqlDatabase. (I do this for allQWidgets too, but that's another matter.)Can you please provide an example ?
@R-P-H
Of how to sub-class in C++? It's just basic C++.I see @SGaist offered this 7 years ago: https://forum.qt.io/topic/30562/example-of-subclassing-qsqltablemodel/2. You'll want something like:
// mytablemodel.h class MyTableModel : public QSqlTableModel { public: explicit MyTableModel(QObject * parent = 0, QSqlDatabase db = QSqlDatabase() ); // the same arguments as QSqlTableModel protected: virtual QString selectStatement() const; }; // mytablemodel.cpp MyTableModel::MyTableModel(QObject * parent, QSqlDatabase db) : QSqlTableModel(parent, db) { // the rest of your code } QString MyTableModel::selectStatement() const { QString ss = QSqlTableModel::selectStatement(); qDebug() << ss; return ss; }I don't think
QSqlQuery QSqlQueryModel::query() constisvirtual, so you can't override it; nor is itprotected, it'spublic, so just call it if you need to access it. -
@R-P-H
Of how to sub-class in C++? It's just basic C++.I see @SGaist offered this 7 years ago: https://forum.qt.io/topic/30562/example-of-subclassing-qsqltablemodel/2. You'll want something like:
// mytablemodel.h class MyTableModel : public QSqlTableModel { public: explicit MyTableModel(QObject * parent = 0, QSqlDatabase db = QSqlDatabase() ); // the same arguments as QSqlTableModel protected: virtual QString selectStatement() const; }; // mytablemodel.cpp MyTableModel::MyTableModel(QObject * parent, QSqlDatabase db) : QSqlTableModel(parent, db) { // the rest of your code } QString MyTableModel::selectStatement() const { QString ss = QSqlTableModel::selectStatement(); qDebug() << ss; return ss; }I don't think
QSqlQuery QSqlQueryModel::query() constisvirtual, so you can't override it; nor is itprotected, it'spublic, so just call it if you need to access it.@JonB I'm not quite sure how to implement this correctly. I have a class that deals with all database related stuff. Inside that class I have a function that generates the
QSqlTableModelusing the code you've already seen.Now obviously if I create another class for
MyTableModel, include it and create model usingMyTableModel *model = new MyTableModel(nullptr, db);instead I still get a protected function error when calling itsselectStatement()member.What would be the correct way of testing this ? Thanks.
-
@JonB I'm not quite sure how to implement this correctly. I have a class that deals with all database related stuff. Inside that class I have a function that generates the
QSqlTableModelusing the code you've already seen.Now obviously if I create another class for
MyTableModel, include it and create model usingMyTableModel *model = new MyTableModel(nullptr, db);instead I still get a protected function error when calling itsselectStatement()member.What would be the correct way of testing this ? Thanks.
Inside that class I have a function that generates the
QSqlTableModelYou don't want to directly create a
QSqlTableModelanywhere, you want it now to create aMyTableModel. E.g if you currently have anew QSqlTableModelsomewhere it now goesnew MyTableModel. This is basic C++ sub-classing, I don't know whether you're confused over that.include it and create model using
MyTableModel *model = new MyTableModel(nullptr, db);instead I still get a protected function error when calling itsselectStatement()member.Assuming you've got the first bit right, you still cannot call a
protectedmethod on an instance from outside of theMyTableModelclass code, that's whatprotectedis all about. You will need something like the definition I showed you ofQString MyTableModel::selectStatement() const. You can either then write anotherpublicmethod inMyTableModelwhich calls it and the outside world can go via that public method, or (as I do) override all the methods inMyTableModelwhich do queries, updates etc. and have them print it out. It takes a few minutes to write these override functions, but once you have them from then on it's a lot easier to see what's going on, do logging, handle any errors etc. from theQSql...classes you use. -
Inside that class I have a function that generates the
QSqlTableModelYou don't want to directly create a
QSqlTableModelanywhere, you want it now to create aMyTableModel. E.g if you currently have anew QSqlTableModelsomewhere it now goesnew MyTableModel. This is basic C++ sub-classing, I don't know whether you're confused over that.include it and create model using
MyTableModel *model = new MyTableModel(nullptr, db);instead I still get a protected function error when calling itsselectStatement()member.Assuming you've got the first bit right, you still cannot call a
protectedmethod on an instance from outside of theMyTableModelclass code, that's whatprotectedis all about. You will need something like the definition I showed you ofQString MyTableModel::selectStatement() const. You can either then write anotherpublicmethod inMyTableModelwhich calls it and the outside world can go via that public method, or (as I do) override all the methods inMyTableModelwhich do queries, updates etc. and have them print it out. It takes a few minutes to write these override functions, but once you have them from then on it's a lot easier to see what's going on, do logging, handle any errors etc. from theQSql...classes you use. -
Would you be able to provide a small step by step guide to reproduce your test database ? Meaning the command you are currently using on your Linux machine to create the role and the database.
-
Would you be able to provide a small step by step guide to reproduce your test database ? Meaning the command you are currently using on your Linux machine to create the role and the database.
@SGaist Hi, I just use psql to create the database/table/user.
CREATE DATABASE my_db WITH OWNER = postgres ENCODING = 'UTF8' TABLESPACE = pg_default CONNECTION LIMIT = -1;CREATE ROLE my_user WITH LOGIN NOSUPERUSER INHERIT NOCREATEDB NOCREATEROLE NOREPLICATION ENCRYPTED PASSWORD 'md5hidden';CREATE TABLE public.my_table ( example_column character varying COLLATE pg_catalog."default", ) TABLESPACE pg_default; ALTER TABLE public.my_table OWNER to postgres; GRANT INSERT, SELECT, DELETE ON TABLE public.my_table TO my_user;So for example:
sudo -u postgres psql -c 'one of the above blocks of code'So here
my_dbis the database name,my_useris the role I'm using to access the table andmy_tableis the table name. -
Sorry I did not had time to test the database.
One thing that you could try (I don't think it would change anything but worth a try), reorder the database setup and add your custom role and it setup both at the end.
-
Sorry I did not had time to test the database.
One thing that you could try (I don't think it would change anything but worth a try), reorder the database setup and add your custom role and it setup both at the end.
@SGaist said in QSqlTableModel() empty on Ubuntu but works on Windows ?:
Sorry I did not had time to test the database.
One thing that you could try (I don't think it would change anything but worth a try), reorder the database setup and add your custom role and it setup both at the end.
I guess I could try that but why would the error be
QSqlError("", "Unable to find table logs", "")then ?
-
Gut feeling: PostgreSQL namespace.
-
Gut feeling: PostgreSQL namespace.
@SGaist said in QSqlTableModel() empty on Ubuntu but works on Windows ?:
Gut feeling: PostgreSQL namespace.
I had a look, but I don't quite understand how it applies to this...
-
The database role must have access to the namespace in order to access the relation it contains.
There might be a glitch there.
-
The database role must have access to the namespace in order to access the relation it contains.
There might be a glitch there.
@SGaist said in QSqlTableModel() empty on Ubuntu but works on Windows ?:
The database role must have access to the namespace in order to access the relation it contains.
There might be a glitch there.
Yet the same role (same exact application/code) works fine on Windows ?