Russian Qt Forum
Ноябрь 26, 2024, 06:51 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2 3   Вниз
  Печать  
Автор Тема: Qt unhanded win32 exception  (Прочитано 15863 раз)
qwyllum
Гость
« : Май 15, 2013, 20:06 »

Доброго времени суток, уважаемые форумчане! С-но проблема: имеется класс, отвечающий за работу с БД, называемый DataBase. В нем есть переменная QSqlDatabase body. В классе диалога есть переменная  DataBase db. Долгое время не мог понять, почему при закрытии программы выдается ошибка о неизвестном исключении с предложением открыть проект в VS 2010. Ассемблер я понимаю плохо, поэтому копаться в отладке вряд ли получится. Я методично удалял из проги все лишнее, чтобы докопаться, какая строка вызвала исключение. И вот что накопал:
При создании диалога автоматически вызывается конструктор DataBase, т.к. диалог содержит переменную этого класса. В конструкторе есть строчка
Код:
  body = QSqlDatabase::addDatabase("QMYSQL","Connect2");
которая и вызывает это исключение. если убрать строку, то закрытие программы исключений не вызывает. я подумал, что скорее всего дело в том, что не закрыл соединение с БД, поэтому создал деструктор класса:
Код:
DataBase::~DataBase()
{
    body.close();
}
Однако это не помогло. Подскажите пожалуйста, в чем может быть еще ошибка?
Записан
Majestio
Гость
« Ответ #1 : Май 15, 2013, 20:41 »

Вот тут в третей позиции есть полезная инфа.
PS. Попробуй вынести инициализацию в метод или слот.
Записан
mta88
Гость
« Ответ #2 : Май 15, 2013, 20:54 »

метод addDatabase закрывает все предыдущие соединения с тем же драйвером и именем

это вполне может быть причиной исключения
при закрытии программа пытается что-то записать в закрытое соединение и выдает ошибку

возможными решениями будут
  • поменять имя "Connect2" на что нибудь другое
  • использовать одно соединение на всю программу


-------------------------------------------------

второй вариант:

из диалога наружу каким-то образом копируется объект data или указатель на него или объект, использующий его (QSqlQuery например)

при закрытии диалога этими объектами нельзя будет пользоваться (соединение закроется, указатель станет невалидным и т.д.)
Записан
qwyllum
Гость
« Ответ #3 : Май 15, 2013, 20:56 »

Вот тут в третей позиции есть полезная инфа.
PS. Попробуй вынести инициализацию в метод или слот.
Спасибо за ответ!
Для информации Вам: выдача результатов в поисковике на разных компьютерах может быть разной и зависит от предыдущих запросов. Поэтому я вряд ли смогу почерпнуть что-то полезное.

Я вынес в отдельный метод init() подключение к БД. Результат не изменился.
Записан
Majestio
Гость
« Ответ #4 : Май 15, 2013, 21:03 »

Конец дня, телепатические способности практически на нуле! Грустный Давайте ваши исходники, поразбираемся.
Записан
qwyllum
Гость
« Ответ #5 : Май 15, 2013, 21:04 »

метод addDatabase закрывает все предыдущие соединения с тем же драйвером и именем

это вполне может быть причиной исключения
при закрытии программа пытается что-то записать в закрытое соединение и выдает ошибку
Спасибо огромное за ответ! Да, я подумал в этом направлении, но у меня всего одно соединение в БД. Тем не менее я пробовал изменить имя соединения, а потом и вовсе убрал его(в методе addDataBase предусмотрено подключение по умолчанию)
второй вариант:
из диалога наружу каким-то образом копируется объект data или указатель на него или объект, использующий его (QSqlQuery например)

при закрытии диалога этими объектами нельзя будет пользоваться (соединение закроется, указатель станет невалидным и т.д.)
Такого не происходит. С-но, вот все, что происходит вне диалога:
Код:
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Dialog w;
    w.show();
    return a.exec();
}
кроме того, я закомментировал все, что только можно. Единственное, что происходит в диалоге  ui->setupUi(this);
В классе DataBase, который создается при создании диалога прописано:
Код:
   if (!QSqlDatabase::drivers().contains("QMYSQL"))
    {
        QMessageBox::critical(0, "Driver not foung", "This program needs the MySQL driver");
    }
    init();
в свою очередь, в init() прописана та злосчастная строчка. Причем, раньше такой ошибки не было, что вдвойне странно.
Записан
Majestio
Гость
« Ответ #6 : Май 15, 2013, 21:06 »

метод addDatabase закрывает все предыдущие соединения с тем же драйвером и именем
это вполне может быть причиной исключения
Не может. Соединение просто переоткрывается. Это видно в отладочных сообщениях. Если нужно два соединения - делаем так:
Код:
    DataBase = QSqlDatabase::addDatabase("QPSQL","First");
    TechBase = QSqlDatabase::addDatabase("QPSQL","Second");
Записан
qwyllum
Гость
« Ответ #7 : Май 15, 2013, 21:11 »

Конец дня, телепатические способности практически на нуле! Грустный Давайте ваши исходники, поразбираемся.
Код:
//database.h
#include <QObject>
#include <QtSql>
#include <QDebug>// библиотека для вывода системных сообщений
#include <QString>// библиотека для работы со строками
#include <QMessageBox>// библиотека для вывода сообщений MessageBox

class DataBase : public QObject
{
    Q_OBJECT
public:
    explicit DataBase(QObject *parent = 0);
     DataBase(QObject *parent, QString name);// конструктор класса. Передается имя БД, к которой нужно осуществить подключение
         ~DataBase();
     QSqlDatabase body;// переменная для работы с базой данных
     void init();
  
};

#endif // DATABASE_H


//database.cpp
#include "database.h"
#include <QStringList>

DataBase::DataBase(QObject *parent) :
    QObject(parent)
{
    // проверка на драйвер в системе:

    if (!QSqlDatabase::drivers().contains("QMYSQL"))
    {
        QMessageBox::critical(0, "Driver not foung", "This program needs the MySQL driver");
    }



    init();

}

void DataBase::init()
{
    body = QSqlDatabase::addDatabase("QMYSQL");

//    body.setHostName("localhost");
//    // имя базы
//    body.setDatabaseName("system");


//    body.setUserName("root");
//    body.setPassword("");
}



}


DataBase::~DataBase()
{
    body.close();
}


//dialog.h

#include "database.h"

namespace Ui {
class Dialog;
}

class Dialog : public QDialog
{
    Q_OBJECT


     DataBase db;


public:
    explicit Dialog(QWidget *parent = 0);

  
    ~Dialog();

private:
    Ui::Dialog *ui;
};

#endif // DIALOG_H


//dialog.cpp

#include "dialog.h"
#include "ui_dialog.h"
#include <QStringList>
#include <QList>



Dialog::Dialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::Dialog)
{
    ui->setupUi(this);

}

Dialog::~Dialog()
{

       delete ui;


}

main создает сам QT, так что его нет смысла выкладывать Улыбающийся
Записан
thechicho
Гость
« Ответ #8 : Май 15, 2013, 21:16 »

<QDebug>// библиотека для вывода системных сообщений

комменты жгут) это же просто класс Улыбающийся
Записан
Majestio
Гость
« Ответ #9 : Май 15, 2013, 21:18 »

попробуйте вызывать init() не напрямую, а вот так:

QTimer::singleShot(2000,this,SLOT(init()));

предварительно объявите его как public slots
Записан
qwyllum
Гость
« Ответ #10 : Май 15, 2013, 21:24 »

попробуйте вызывать init() не напрямую, а вот так:

QTimer::singleShot(2000,this,SLOT(init()));

предварительно объявите его как public slots
Спасибо за ответ! Я попробовал так, но безрезультатно. Также я создал слот close() и в деструкторе DataBase вызвал аналогичным образом его. Ошибка все равно выдается, но что странно - раньше он мне предлагал отловить исключение в Visual Studio, а теперь просто выдает окно ошибки. Ну хоть какие-то изменения :-)
Записан
thechicho
Гость
« Ответ #11 : Май 15, 2013, 21:28 »

я не силен в плюсах, но
class Dialog : public QDialog
{
    Q_OBJECT


     DataBase db;


public:

может стоить написать так
class Dialog : public QDialog
{
    Q_OBJECT
   
public:
    explicit Dialog(QWidget *parent = 0);
    ~Dialog();
    DataBase db;

//private:
    //DataBase db;
Записан
qwyllum
Гость
« Ответ #12 : Май 15, 2013, 21:33 »

UPD: решил поэксперементировать и в конструкторе написал так:
Код:
init();
     body.close();
Выдает исключение. Теперь так:
Код:
QTimer::singleShot(2000,this,SLOT(init()));
     body.close();;

Не выдает ошибок и все корректно. Отсюда вывод - получается при уничтожении экземпляра диалога как-то соединение некорректно закрывается?
Записан
Majestio
Гость
« Ответ #13 : Май 15, 2013, 21:40 »

Проверено электроникой!

Testo.pro
Код:
#-------------------------------------------------
#
# Project created by QtCreator 2013-05-12T08:01:55
#
#-------------------------------------------------
QT       += core gui sql
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = Testo
TEMPLATE = app
SOURCES += main.cpp\
        dialog.cpp
HEADERS  += dialog.h

main.cpp
Код:
#include "dialog.h"
#include <QApplication>

int main(int argc, char *argv[]) {
    QApplication a(argc, argv);
    Dialog w;
    w.show();
    return a.exec();
}

dialog.h
Код:
#ifndef DIALOG_H
#define DIALOG_H

#include <QtWidgets>
#include <QtSql>

class Dialog : public QDialog
{
    Q_OBJECT

public:
    QSqlDatabase DataBase;
    Dialog(QWidget *parent = 0);
    ~Dialog();
public slots:
    void SlotClick();
};

#endif // DIALOG_H

dialog.cpp
Код:
#include "dialog.h"

Dialog::Dialog(QWidget *parent)
    : QDialog(parent)
{
    QPushButton *B = new QPushButton("Click!");
    QHBoxLayout *L = new QHBoxLayout();
    L->addWidget(B);
    setLayout(L);
    connect(B,SIGNAL(clicked()),this,SLOT(SlotClick()));
}

Dialog::~Dialog()
{
   
}

void Dialog::SlotClick()
{
    DataBase = QSqlDatabase::addDatabase("QPSQL","First");
    DataBase.setHostName("192.168.1.47");
    DataBase.setDatabaseName("testo");
    DataBase.setUserName("pgsql");
    DataBase.setPassword("gfhjkm1");

    if (DataBase.open()) {
        QMessageBox::information(0,"Open","Ok");
        DataBase.close();
    } else {
        QMessageBox::information(0,"Open",tr("Error: ")+DataBase.lastError().text());
    }

}
Записан
qwyllum
Гость
« Ответ #14 : Май 15, 2013, 21:41 »

может стоить написать так
class Dialog : public QDialog
{
    Q_OBJECT
   
public:
    explicit Dialog(QWidget *parent = 0);
    ~Dialog();
    DataBase db;

//private:
    //DataBase db;
Спасибо за ответ! К сожалению, не помогло
Записан
Страниц: [1] 2 3   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.096 секунд. Запросов: 21.