crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

 
Ответить в данную темуНачать новую тему
> Приложение падает при emit в пользовательском классе.
Arceny
  опции профиля:
сообщение 2.6.2008, 18:31
Сообщение #1


Студент
*

Группа: Участник
Сообщений: 20
Регистрация: 15.4.2008
Из: Брянск
Пользователь №: 149

Спасибо сказали: 0 раз(а)




Репутация:   0  


Есть приложение, есть свой собственный класс sql на основе QObject.

В конструкторе приложения инициализируется как db = new sql(this);

При генерации сигнала из класса emit сигнал получаю ошибку сегментации. Этот сигнал пока ещё ни к чему не подключен.

where
#0  QMetaObject::activate (sender=0x0, m=0x806c208, local_signal_index=1, argv=0x0) at kernel/qobject.cpp:3076
#1  0x08069109 in sql::readCategories ()
#2  0x08066d9f in sql::deleteDisc ()
#3  0x0805f2d7 in myTree::deleteDisc ()
#4  0x08068c6d in myTree::qt_metacall ()
...

Видно что валится при вызове из функции класса.

Далее привожу весь код класса на всякий случай. Помогите, пожалуйста, найти ошибку.

#ifndef SQL_H
#define SQL_H

#include <QObject>
#include <QtSql>

struct configuration;

class sql : public QObject {
    Q_OBJECT
    public:
        sql(QObject *parent = 0);
        ~sql();
        bool isOpen();
        
    signals:
        void updateCategory(int catid);
        void readCategories();
    private:
        QSqlDatabase db;
        configuration * cnf;
        bool checkQuery(QSqlQuery q);
    public slots:
        bool initDatabase();
        bool openDatabase();
        bool closeDatabase();
        bool deleteDisc(int discid);
        bool deleteCategory(int catid);
        bool moveDisc(int discid, int oldid, int catid);
        bool moveAllDiscs(int oldid, int catid);
        bool addDisc(QString name, QString descr, int year, int catid);
        //bool addDisc();
};

#endif


CODE
#include <QMessageBox>

#include "sql.h"
#include "mainwindow.h"

/// Класс, в который вынесен основной функционал работы с БД

sql::sql(QObject *parent) : QObject(parent) {
cnf = &((mainWindow*)parent)->cnf;
}

sql::~sql() {

}

// проверяет запрос на безошибочность
bool sql::checkQuery(QSqlQuery q) {
if ( q.lastError().type() != QSqlError::NoError ) {
QMessageBox::critical(0,QCoreApplication::applicationName(),"SQL: "+q.lastQuery()+"\nError: "+q.lastError().text());
return false;
}
return true;
}

bool sql::initDatabase() {
qDebug() << "sql::initDatabase()";
if(cnf->dbType=="QSQLITE") {
QFile file(cnf->dbName);
file.remove();
}
if(openDatabase()) {
QSqlQuery query;
query.exec("CREATE TABLE category ("
"id INTEGER PRIMARY KEY,"
"name VARCHAR(64) NOT NULL,"
"nth INTEGER NOT NULL,"
"items INTEGER)");
if(!checkQuery(query)) return false;
query.exec("CREATE TABLE disc ("
"id INTEGER PRIMARY KEY,"
"name VARCHAR(128) NOT NULL,"
"descr TEXT,"
"year INTEGER,"
"catid INTEGER NOT NULL,"
"FOREIGN KEY (catid) REFERENCES category)");// ON UPDATE CASCADE)");
if(!checkQuery(query)) return false;
query.exec("CREATE TABLE files ("
"id INTEGER PRIMARY KEY," // просто id записи
"name VARCHAR(1024) NOT NULL," // имя файла/директории (не путь)
"parentid INTEGER NOT NULL," // id записи родителя (директории), для верхнего уровня 0
"type INTEGER NOT NULL," // тип: директория или файл (тип файла по необходимости)
"size INTEGER NOT NULL," // размер
"date VARCHAR(20)," // дата файла, не обязательно
"metadata INTEGER," // ссылка на метаданные если нужно.
"discid INTEGER NOT NULL," // ссылка на диск к которому принадлежат файлы
"FOREIGN KEY(discid) REFERENCES disc)");
if(!checkQuery(query)) return false;
return true;
} else
return false;
}

bool sql::openDatabase() {
qDebug() << "sql::openDatabase()";
closeDatabase();
db = QSqlDatabase::addDatabase(cnf->dbType);
db.setDatabaseName(cnf->dbName);
db.setHostName(cnf->server);
db.setUserName(cnf->username);
db.setPassword(cnf->password);
if(!db.open()) {
QMessageBox::warning(0, tr("Database error!"), db.lastError().text());
return false;
}
return true;
}

bool sql::closeDatabase() {
qDebug() << "sql::closeDatabase()";
if(db.isOpen()) {
QSqlQuery q1(db);
q1.exec("VACUUM files");
q1.exec("VACUUM disc");
q1.exec("VACUUM category");
db.close();
QSqlDatabase::removeDatabase(db.connectionName()); // correct
return true;
} else
return false;
}

bool sql::deleteDisc(int discid) {
qDebug() << "sql::deleteDisc(int discid)";

QSqlQuery q;
// извлекаем id категории
q.prepare("SELECT catid FROM disc WHERE id = ?");
q.addBindValue(discid); q.exec(); q.next();
int catid = q.value(0).toInt();

// удаляем диск
q.prepare("DELETE FROM disc WHERE id = ?");
q.addBindValue(discid); q.exec();

// удаляем файлы, принадлежащие диску
q.prepare("DELETE FROM files WHERE discid = ?");
q.addBindValue(discid); q.exec();

// извлекаем число дисков из категории
q.prepare("SELECT items FROM category WHERE id = ?");
q.addBindValue(catid); q.exec(); q.next();
int items = q.value(0).toInt();

// уменьшаем число дисков в категории на единичку
q.prepare("UPDATE category SET items = ? WHERE id = ?");
q.addBindValue(items-1); q.addBindValue(catid); q.exec();

emit readCategories();

return true;
}

bool sql::moveAllDiscs(int oldid, int catid) {
oldid=0; catid=0;
return true;
}

bool sql::moveDisc(int discid, int oldid, int catid) {
discid=0; oldid=0; catid=0;
return true;
}

bool sql::deleteCategory(int catid) {
qDebug() << "sql::deleteCategory(int catid)";
QSqlQuery q;

//удаляем диски
q.prepare("SELECT id from disc WHERE catid = ?");
q.addBindValue(catid); q.exec();
while(q.next()) {
deleteDisc(q.value(0).toInt());
}

// удаляем категорию
q.prepare("DELETE FROM category WHERE id=?");
q.addBindValue(catid);
q.exec();

return true;
}

bool sql::addDisc(QString name, QString descr, int year, int catid) {
return true;
}

bool sql::isOpen() {
return db.isOpen();
}
Причина редактирования: codebox, для длинных файлов
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
ViGOur
  опции профиля:
сообщение 3.6.2008, 8:31
Сообщение #2


Мастер
******

Группа: Модератор
Сообщений: 3296
Регистрация: 9.10.2007
Из: Москва
Пользователь №: 4

Спасибо сказали: 231 раз(а)




Репутация:   40  


Я думаю, что это как раз из-за того, что сигнал не подключен, попробуй подключить...
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 3.6.2008, 9:49
Сообщение #3


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


Arceny, ты консоль к приложению прикомпиль, в файле проекта, и в свой клас воткни qDebug(), перед посылкой сигнала, тогда Qt'я сама многое о сигналах раскажит, до ошибки сигментации.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Arceny
  опции профиля:
сообщение 3.6.2008, 13:06
Сообщение #4


Студент
*

Группа: Участник
Сообщений: 20
Регистрация: 15.4.2008
Из: Брянск
Пользователь №: 149

Спасибо сказали: 0 раз(а)




Репутация:   0  


Странно что этот же сигнал в другом методе класса не приводит к ошибке сегментации. Причину не могу найти уже второй день. В принцпе можно обойтись и без этого сигнала, но просто интересно.

Прикладываю весь проект, это программа для каталогизации дисков. СУБД пока только sqlite тестировалась, соответственно при инициализации БД выбирать её.

Сигнал генерируется в методе класса sql , вызываемого при удалении диска из какой-либо категории.

З.Ы. Qt4.4 , под винду собирать не пробовал.

http://slil.ru/25858903
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 3.6.2008, 19:15
Сообщение #5


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


ты всеже попробуй qDebug(), посмотри, что на консоль выведет.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Гость_Гость_Arceny_*_*
сообщение 4.6.2008, 1:47
Сообщение #6





Гости








    


Цитата(Litkevich Yuriy @ 3.6.2008, 19:15) *
ты всеже попробуй qDebug(), посмотри, что на консоль выведет.

Да пробовал. qDebug() ничего не выводит. Он на сколько я понимаю служит для вывода информации программистом в stderr по типу

qDebug() << "Error may be where";
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 4.6.2008, 1:51
Сообщение #7


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


да, но когда например соеденяшь слот и сигнал, и там что-то плохо, он автоматом выводи сам сообщение.
Можно еще попробовать перед emit его поставить, т.е. так
qDebug() << emit readCategories();
если съест конечно.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 1.12.2022, 15:30