Приложение падает при emit в пользовательском классе. |
Здравствуйте, гость ( Вход | Регистрация )
Приложение падает при emit в пользовательском классе. |
Arceny |
2.6.2008, 18:31
Сообщение
#1
|
Студент Группа: Участник Сообщений: 20 Регистрация: 15.4.2008 Из: Брянск Пользователь №: 149 Спасибо сказали: 0 раз(а) Репутация: 0 |
Есть приложение, есть свой собственный класс sql на основе QObject.
В конструкторе приложения инициализируется как db = new sql(this); При генерации сигнала из класса emit сигнал получаю ошибку сегментации. Этот сигнал пока ещё ни к чему не подключен.
Видно что валится при вызове из функции класса. Далее привожу весь код класса на всякий случай. Помогите, пожалуйста, найти ошибку.
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 |
4.6.2008, 1:51
Сообщение
#7
|
разработчик РЭА Группа: Сомодератор Сообщений: 9669 Регистрация: 9.1.2008 Из: Тюмень Пользователь №: 64 Спасибо сказали: 807 раз(а) Репутация: 94 |
да, но когда например соеденяшь слот и сигнал, и там что-то плохо, он автоматом выводи сам сообщение.
Можно еще попробовать перед emit его поставить, т.е. так qDebug() << emit readCategories(); если съест конечно. |
|
|
Текстовая версия | Сейчас: 14.1.2025, 2:08 |