Russian Qt Forum

Qt => Вопросы новичков => Тема начата: billy4685 от Ноябрь 14, 2014, 00:42



Название: Как найти ошибку в коде, если ошибка выдается уже при запуске приложения?
Отправлено: billy4685 от Ноябрь 14, 2014, 00:42
Здравствуйте, господа форумчане. Часто бывает так, что в Qt Creator приложение собирается и
компилируется, но вот при запуске выбивает ошибку. Как в данном случаи понять где в коде ошибка,
и что за ошибка? Отладчиком можно в принципе найти ее, но он в данном случаи не выдаст
сообщение об ошибке. С помощью него пока мне удавалось просто узнать в какой строчке ошибка,
какие переменные не были созданы, ну и подобное. Может существует еще какой-нибудь обработчик
ошибок для подобных случаев? или может я не знаю всех возможных функций отладчика в Qt Creator?


Название: Re: Как найти ошибку в коде, если ошибка выдается уже при запуске приложения?
Отправлено: torwig от Ноябрь 14, 2014, 01:06
Вы правы, зачастую так и бывает, что компилируется приложение а ошибки уже потом появляются)
Расскажите, какие именно ошибки вы пытаетесь найти?
Разыменование нулевого указателя, выход за пределы массива, двойное удаление, неудачную попытку открытия файла или подключения по сети?
Выводите в qDebug() например сообщения, что пошло отклонение от ожидаемого поведения, есть еще Q_ASSERT(). Где-то есть тут обширная тема об исключениях. Некоторые объекты фреймворка Qt могут испускать сигналы об ошибке, операции могут возвращать false в случае неудачи.
Или вы нечто иное имеете в виду?


Название: Re: Как найти ошибку в коде, если ошибка выдается уже при запуске приложения?
Отправлено: Fregloin от Ноябрь 14, 2014, 09:19
К сожалению в сях не выводится подробное сообщение какв делфи, там выводится название функции и класс где ошибка в рантайме


Название: Re: Как найти ошибку в коде, если ошибка выдается уже при запуске приложения?
Отправлено: billy4685 от Ноябрь 14, 2014, 09:21
Да, я это и имел ввиду. Правда хотелось бы, чтобы при этом еще Qt Creator в таких случаях указывал что именно за ошибка. В моем же случае у меня выдается после запуска приложения вот такая ошибка.


Название: Re: Как найти ошибку в коде, если ошибка выдается уже при запуске приложения?
Отправлено: billy4685 от Ноябрь 14, 2014, 09:26
Спасибо всем за ответы)) жаль конечно, что как в делфи подробная информация не выводится.


Название: Re: Как найти ошибку в коде, если ошибка выдается уже при запуске приложения?
Отправлено: vulko от Ноябрь 14, 2014, 09:35
Ты хоть в дебаге запускаешь то?

Билд дебажный?

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


В дельфи такого, если правильно помню, нет. Хотя может и есть, последний раз с дельфи я работал в 99-м году.


Название: Re: Как найти ошибку в коде, если ошибка выдается уже при запуске приложения?
Отправлено: billy4685 от Ноябрь 14, 2014, 09:46
После пошаговой отладки, я нашел место ошибки. Я так понимаю ошибка из-за того, что я обращаюсь к QGridLayout, который был создан ранее для QGroupBox, когда добавляю кнопки в этот layout. У меня это делается в своем классе, который может создавать как виджеты типа QGroupBox, так и виджеты других нескольких типов. Походу когда я создал один экземпляр класса как QGroupBox(в данном случае создаю и layout и прицепляю его к этому виджету), и потом создал другой экземпляр класса для QPushButton (как массив кнопок), я пытаюсь добавить эти кнопки в этот layout, оно просто не видит этот layout, так как он относится к другому ранее созданному экземпляру класса (QGroupBox). Может из-за этого и приложение выдает ошибку при запуске. Отладчик как раз на месте добавления нового созданного виджета в layout и останавливает свою работу, бросая курсор в файл библиотеки qlayout.h перед строчкой  Q_DECLARE_PRIVATE(QLayout). Я прав?  


Название: Re: Как найти ошибку в коде, если ошибка выдается уже при запуске приложения?
Отправлено: vulko от Ноябрь 14, 2014, 10:28
После пошаговой отладки, я нашел место ошибки. Я так понимаю ошибка из-за того, что я обращаюсь к QGridLayout, который был создан ранее для QGroupBox, когда добавляю кнопки в этот layout. У меня это делается в своем классе, который может создавать как виджеты типа QGroupBox, так и виджеты других нескольких типов. Походу когда я создал один экземпляр класса как QGroupBox(в данном случае создаю и layout и прицепляю его к этому виджету), и потом создал другой экземпляр класса для QPushButton (как массив кнопок), я пытаюсь добавить эти кнопки в этот layout, оно просто не видит этот layout, так как он относится к другому ранее созданному экземпляру класса (QGroupBox). Может из-за этого и приложение выдает ошибку при запуске. Отладчик как раз на месте добавления нового созданного виджета в layout и останавливает свою работу, бросая курсор в файл библиотеки qlayout.h перед строчкой  Q_DECLARE_PRIVATE(QLayout). Я прав?  

возможно. сложно дать точный ответ когда не видишь кода.

что за ошибка то хоть? при обращении к qgridlayout ссылка нормальная?


Название: Re: Как найти ошибку в коде, если ошибка выдается уже при запуске приложения?
Отправлено: billy4685 от Ноябрь 14, 2014, 14:17
Вот пример кода:

mywidget.h
Код:
#ifndef MYWIDGET_H
#define MYWIDGET_H

#include <QtGui>
#include <QWidget>

#include "stdio.h"
#include "stdlib.h"

#define DIALOG  1
#define GROUP   2
#define BUTTON  3

class MyWidget
{
public:
    QWidget *wgt;
    QHBoxLayout *group_layout;
    Qt::Orientation group_orient;
    unsigned wgt_type, wgt_f;

    MyWidget(void *widget);
    MyWidget(MyWidget *parent, unsigned type);
    void create(void *parent, unsigned type, int x, int y, int w, int h);
    ~MyWidget();

    void setPosW(int x, int y);
    void setSizeW(int w, int h);
    void setStrW(const char *str);
    void showW(void);
};

#endif // MYWIDGET_H

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

MyWidget::MyWidget(void *widget)
{
   wgt_f = 1;

    wgt = (QWidget *)widget;

    if(wgt->metaObject()->className() == QString("QDialog"))
        wgt_type = DIALOG;
    else if(wgt->metaObject()->className() == QString("QToolButton"))
        wgt_type = BUTTON;
    else if(wgt->metaObject()->className() == QString("QGroupBox"))
        wgt_type = GROUP;
}

MyWidget::MyWidget(MyWidget *parent, unsigned wgt_type)
{
    wgt_f = 0;
    if(parent == NULL)
        create(NULL, wgt_type, 0, 0, 0, 0);
    else
        create(parent->wgt, wgt_type, 0, 0, 0, 0);
}

void MyWidget::create(void *parent, unsigned type, int x, int y, int w, int h)
{
    wgt_type = type;

    QPoint pos(x, y);
    QSize size(w, h);

    if(wgt_type == DIALOG)
        wgt = (QWidget *) new QDialog((QWidget *)parent);
    else if(wgt_type == BUTTON){
        wgt = (QWidget *) new QToolButton((QWidget *)parent);
        if(((QWidget *)parent)->metaObject()->className() == QString("QGroupBox"))
           group_layout->addWidget(wgt);
    }
    else if(wgt_type == GROUP)
    {
        wgt = (QWidget *) new QGroupBox((QWidget *)parent);

        group_layout = new QHBoxLayout;
        wgt->setLayout(group_layout);
    }
}

MyWidget::~MyWidget()
{
    if(wgt_f == 0)
        delete wgt;
    wgt = NULL;
}

void MyWidget::setPosW(int x, int y)
{
    QPoint pos(x, y);
    wgt->move(pos);
}

void MyWidget::setSizeW(int w, int h)
{
    wgt->setFixedSize(w, h);
}

void MyWidget::setStrW(const char *str)
{
    if(str == NULL)
    {
        return;
    }
    else{
        if(wgt_type == DIALOG)
            qobject_cast<QDialog *>(wgt)->setWindowTitle(str);
        else if(wgt_type == BUTTON)
            qobject_cast<QToolButton *>(wgt)->setText(str);
        else if(wgt_type == GROUP)
            qobject_cast<QGroupBox *>(wgt)->setTitle(str);
    }
}

void MyWidget::showW(void)
{
    wgt->show();
}

main.cpp
Код:
#include "mywidget.h"

int main(int argc, char *argv[]){
    QApplication app(argc, argv);

    qDebug() << "hello";

    MyWidget *base;
    base = new MyWidget(NULL, DIALOG);
    base->setPosW(40, 40);
    base->setSizeW(200, 200);
    base->setStrW("My class widget");
    base->showW();

    MyWidget *group;
    group = new MyWidget(base, GROUP);
    group->setSizeW(100, 100);
    group->setPosW(20, 20);
    group->setStrW("Group:");
    group->showW();

    MyWidget *button[3];
    for(int i=0; i<3; i++){
        button[i] = new MyWidget(group, BUTTON);
        button[i]->setSizeW(20, 20);
        button[i]->setStrW("Button");
        button[i]->showW();
    }

    return app.exec();
}

Работа программы останавливается на   group_layout->addWidget(wgt) в функции create(void *parent, unsigned type, int x, int y, int w, int h) в ветви else if(wgt_type == BUTTON){....}. Почему-то не хочет добавлять в layout кнопку? Как уже говорил ранее ошибка проявляется, только при запуске приложения. Может кто знает, как решить эту проблему?


Название: Re: Как найти ошибку в коде, если ошибка выдается уже при запуске приложения?
Отправлено: kambala от Ноябрь 14, 2014, 14:27
ну так для group_layout не выделена память, что непонятного? очевидно BUTTON попадается раньше GROUP.


Название: Re: Как найти ошибку в коде, если ошибка выдается уже при запуске приложения?
Отправлено: billy4685 от Ноябрь 14, 2014, 14:33
Ясно. Так может есть идеи, как можно layout в данном случаи правильно прикрепит к GroupBox, чтобы потом при создании с помощью класса  MyWidget кнопки на GroupBox, она автоматом добавлялась в layout? Ну типа того, как в некоторых других средах программирования, там ручками layout не нужно создавать, он уже имеется на GroupBox.


Название: Re: Как найти ошибку в коде, если ошибка выдается уже при запуске приложения?
Отправлено: billy4685 от Ноябрь 14, 2014, 14:41
Ах да еще, может кто-то знает как можно реализовать этот пример без приведения типов qobject_cast?


Название: Re: Как найти ошибку в коде, если ошибка выдается уже при запуске приложения?
Отправлено: vulko от Ноябрь 14, 2014, 14:54
Ясно. Так может есть идеи, как можно layout в данном случаи правильно прикрепит к GroupBox, чтобы потом при создании с помощью класса  MyWidget кнопки на GroupBox, она автоматом добавлялась в layout? Ну типа того, как в некоторых других средах программирования, там ручками layout не нужно создавать, он уже имеется на GroupBox.

не городить огород и сделать все ООПэшненько.
т.е. не надо пытаться объединить все виджеты в один, их же не просто так вынесли в разные классы.


Название: Re: Как найти ошибку в коде, если ошибка выдается уже при запуске приложения?
Отправлено: billy4685 от Ноябрь 14, 2014, 15:10
спасибо за советы, в дальнейшем учту)