Unsolved QSqlQueryModel to QStandardItemModel?
-
Hello thank for the response.
EDIT: i'm going to have to respond in parts. my post is flagged as spam. yay.
Part 1
The following code is my current setup:
mainwindow.hifndef MAINWINDOW_H define MAINWINDOW_H include <QMainWindow> namespace Ui { class MainWindow; } class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent = 0); ~MainWindow(); private slots: void on_pushButton_clicked(); private: Ui::MainWindow *ui; }; endif // MAINWINDOW_H
-
Part 2
main.cpp
include "mainwindow.h" include <QApplication> int main(int argc, char *argv[]) { QApplication a(argc, argv); MainWindow w; w.show(); return a.exec(); }
mainwindow.cpp
include "mainwindow.h" include "ui_mainwindow.h" include "animalsearch.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); } MainWindow::~MainWindow() { delete ui; } void MainWindow::on_pushButton_clicked() { AnimalSearch animalsearch; animalsearch.setModal(true); animalsearch.exec(); }
-
Part 3
animalsearch.h#ifndef ANIMALSEARCH_H #define ANIMALSEARCH_H #include <QDialog> #include <QtSql> #include <QStandardItemModel> namespace Ui { class AnimalSearch; } class AnimalSearch : public QDialog { Q_OBJECT public: explicit AnimalSearch(QWidget *parent = 0); ~AnimalSearch(); QSqlQueryModel *PreviousSearchModel; QSqlQueryModel *SearchModel; QStandardItemModel *TestModel; private slots: void on_OkButton_clicked(); void on_SearchButton_clicked(); void on_pushButton_clicked(); private: Ui::AnimalSearch *ui; }; #endif // ANIMALSEARCH_H
-
Part 4
Edit remove trailing " from sqlconnect.h
animalsearch.cpp
//trust me the syntax is correct in the actual file include animalsearch.h include ui_animalsearch.h include sqlconnect.h include QDebug include QStandardItemModel AnimalSearch::AnimalSearch(QWidget *parent) : QDialog(parent), ui(new Ui::AnimalSearch) { ui->setupUi(this); //Create an object named PreviousSearch sqlconnect PreviousSearch; qDebug() << "PreviousSearch Object:"; qDebug() << "Type of PreviousSearch: " << typeid(PreviousSearch).name(); QString uname = qgetenv("USER"); if (uname.isEmpty()) uname = qgetenv("USERNAME"); qDebug() << "Type of uname: " << typeid(uname).name(); qDebug() << "Address of uname: " << &uname; QString GetAutoComplete = "some query to return data"; qDebug() << "Output of PreviousSearchModel in Ui Setup: " << PreviousSearchModel; qDebug() << "Address of PreviousSearchModel in Ui Setup: " << &PreviousSearchModel; this->PreviousSearchModel = new QSqlQueryModel(); qDebug() << "Type of PreviousSearchModel: " << typeid(PreviousSearchModel).name(); PreviousSearchModel = PreviousSearch.QueryDB(GetAutoComplete); ui->PreviousSearchTableView->setModel(PreviousSearchModel); ui->SearchTableView->setModel(PreviousSearchModel); qDebug() << PreviousSearchModel; qDebug() << "\n"; } AnimalSearch::~AnimalSearch() { delete ui; } void AnimalSearch::on_OkButton_clicked() { close(); } void AnimalSearch::on_SearchButton_clicked() { sqlconnect CurrentSearch; qDebug() << "The Address of CurrentSearch Object: " << &CurrentSearch; QString SearchQuery = "somequery to return data'"; this->SearchModel = new QSqlQueryModel(); SearchModel = CurrentSearch.QueryDB(SearchQuery); ui->SearchTableView->setModel(SearchModel); qDebug() << "The Address of PreviousSearchModel Object after SearchButton_Clicked(): " << &PreviousSearchModel; } void AnimalSearch::on_pushButton_clicked() { //if this line wasn't here the code crashes, at some qsql_odbc.cpp line. ui->PreviousSearchTableView->setUpdatesEnabled(false); int Columns = PreviousSearchModel->columnCount(); int Rows = PreviousSearchModel->rowCount(); qDebug() << "Number of Rows: " << Rows; qDebug() << "Number of Columns: " << Columns; this->TestModel = new QStandardItemModel(Rows, Columns); for(int row = 0; row < Rows; ++row) { for(int column=0; column < Columns; ++column) { //QStandardItem *item = PreviousSearchModel->data(PreviousSearchModel->index(row,column)); //TestModel.setItem(row, column, item); //for fun output all contents of PreviousSearchModel to screen qDebug() << PreviousSearchModel->data(PreviousSearchModel->index(row, column)).type(); qDebug() << PreviousSearchModel->data(PreviousSearchModel->index(row, column)).toString(); //ui->PreviousSearchTableView->setModel(PreviouSearchModel); } } }
-
Final Part, 5
sqlconnect.h
//again trust me syntax is correct in actual file ifndef SQLCONNECT_H define SQLCONNECT_H include <QString> include <QtSql> class sqlconnect { public: QSqlDatabase db; QSqlQueryModel *QueryModel; int Test(QString Test) { qDebug() << "Did this class test print?"; return 0; } QSqlQueryModel* QueryDB(QString Query) { db = QSqlDatabase::addDatabase("QODBC"); db.setDatabaseName("someDB"); db.setUserName("SomeUser"); db.setPassword("12345"); //Create a new QSqlQueryModel using this->QueryModel = new QSqlQueryModel(); qDebug() << "Address of QueryModel: " << &QueryModel; if(db.open()) { //Execute the query and store data in QueryModel QueryModel->setQuery(Query); } else { qDebug() << "DB not connected"; } return QueryModel; } int closeDB() { db.close(); QSqlDatabase::removeDatabase("SomeDB"); return 0; } }; #endif
The program crashes if you click the pushbutton a second time and the code tries to dump the PreviousSearchModel to the screen. It fails at this line, qDebug() << PreviousSearchModel->data(PreviousSearchModel->index(row, column)).type(); found in the animalsearch.cpp
with exception code: 0xc0000005: read access violation at : 0x0in the animalsearch ui:
-
include sqlconnect.h"
[In Part 4] Can you just please remove that trailing
"
right now so that I can see the rest of my code without my eyes hurting, please? :) -
done:) I have to remove the # and some times the " and <> to get Askimet off my back.
-
@Core2 said in QSqlQueryModel to QStandardItemModel?:
to get Askimet off my back.
In these cases posting the code to https://pastebin.com/ and only sharing the link might help
As of the matter at hand:
from http://doc.qt.io/qt-5/qsqldatabase.html#addDatabaseWarning: If you add a connection with the same name as an existing connection, the new connection replaces the old one. If you call this function more than once without specifying connectionName, the default connection will be the one replaced.
Do not call
addDatabase
every time you use QueryDB use:// you should never have QSqlDatabase as a member of the class, read QSqlDatabase docs QSqlDatabase db = QSqlDatabase::database("MyDatabase", false); if (!db.isValid()) { db = QSqlDatabase::addDatabase("QODBC", "MyDatabase"); db.setDatabaseName("someDB"); db.setUserName("SomeUser"); db.setPassword("12345"); } if (!db.isOpen()){ if (db.open()) QSqlQueryModel* tempModel= new QSqlQueryModel(); tempModel->setQuery(Query); return tempModel; } qDebug() << "DB not connected";
P.S.
The view does not own the model so you are leaking it. callsetParent
on the returned model -
@Core2
I'm not used to looking through loads of other peoples' code to debug it, plus I use Python/PyQt not C++, so quite a bit would be different.Having said that, in the nicest way your code & approach is all over the place! :) I don't really understand what you're trying to do and how you're approaching achieving it. But I don't think it can be right.
I suspect your crash comes down to your
class sqlconnect
and how you use it. It creates and holds a connection to a database (QSqlDatabase
) and a correspondingQSqlQueryModel
. Its scope is limited to one invocation ofMainWindow::on_pushButton_clicked()
and itsAnimalSearch animalsearch
. If it's clicked a second time, and during that it tries to do something (like via a Table View) which refers to a model which was created "previously" using a "previous"sqlconnect
it will have gone out of scope. I suspect that will be the cause of the eror.I can see @VRonin has already posted. The most important thing is to start by redesigning your code so that you only do the
db = QSqlDatabase::addDatabase("QODBC");
once, and use that for all queries/models/views. Your wholeQueryDB
needs redesigning.this->SearchModel = new QSqlQueryModel(); SearchModel = CurrentSearch.QueryDB(SearchQuery);
This leaks a
QSqlQueryModel
. Itnew
s one, then overwrites the result with another one. You have this pattern all over the place. -