0 / 0 / 0
Регистрация: 25.12.2014
Сообщений: 2
1

Крах программы, при изменении размера окна

24.05.2016, 23:48. Показов 552. Ответов 10
Метки нет (Все метки)

Здравствуйте.
Играюсь с QPaintEvent'ом. Рисую фрактал простенький и проблема заключается в том, что при изменении размера окна, либо, еще в моем случае, при вызове метода из меню, который выводит на экран простое сообщение about(), крашится программа. Пока не дошел до меню, то думал, что из-за изменения размеров крашится и делал поиск по этому, но в конечном итоге ни к чему не пришел. Есть предположение, что расчет и рисование само находится в одной рекурсивной функции, но как разделить это дело, не могу представить. В main.cpp лишь вызов окна.

paintwidget.h
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#ifndef PAINTWIDGET_H
#define PAINTWIDGET_H
 
#include <QWidget>
#include <QPainter>
#include <QMessageBox>
#include <QtMath>
 
class PaintWidget : public QWidget
{
    Q_OBJECT
public:
    explicit PaintWidget(QWidget *parent = 0);
    void paintEvent(QPaintEvent *);
    void rec(float x, float y, float angle, int level);
    QPainter *p = NULL;
    float A = 90;
    float AB = 40;
};
 
#endif // PAINTWIDGET_H
paintwidget.cpp
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
PaintWidget::PaintWidget(QWidget *parent) : QWidget(parent)
{
}
 
void PaintWidget::paintEvent(QPaintEvent *)
{
    if (p==NULL)
    {
        p = new QPainter(this);                     // Создаем контекст рисования
        p->setPen(QPen(Qt::black,1,Qt::SolidLine)); // Создаем перо для рисования
    }
    rec(this->width()/2,this->height(),A,0);
}
 
void PaintWidget::rec(float x, float y, float angle, int level)
{
    float angle1 = angle*M_PI/180;
    float x1 = x + AB * cos(angle1);
    float y1 = y - AB * sin(angle1);
    if((x1>=width()) || (y1>=height()) || (x1<=0) || (y1<=0) || (level>10))
        return;
    else
    {
        p->drawLine(x,y,x1,y1);
        rec(x1,y1,angle+15,level+1);
        rec(x1,y1,angle-15,level+1);
    }
}
mainwindow.h
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
 
#include <QMainWindow>
#include <QMenuBar>
#include <QMenu>
#include <QAction>
#include <QMessageBox>
#include <paintwidget.h>
 
class MainWindow : public QMainWindow
{
    Q_OBJECT
 
public:
    MainWindow(QWidget *parent = 0);
    ~MainWindow();
    PaintWidget *wgt;
public slots:
    void Aboutprog();
};
 
#endif // MAINWINDOW_H
mainwindow.cpp
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include "mainwindow.h"
 
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
   QMenuBar *menubar = new QMenuBar;
   QMenu *pmenu = new QMenu("&Help");
   QAction *About = new QAction(tr("&About"),this);
   connect(About, SIGNAL(triggered(bool)), this, SLOT(Aboutprog()));
   pmenu->addAction(About);
   menubar->addMenu(pmenu);
   this->setMenuBar(menubar);
   this->setWindowTitle("Main Window");
   wgt = new PaintWidget;
   setCentralWidget(wgt);
   this->resize(650,400);
}
 
MainWindow::~MainWindow()
{
}
 
void MainWindow::Aboutprog()
{
   QMessageBox::about(0, "About", "Fractal");
}
__________________
Помощь в написании контрольных, курсовых и дипломных работ, диссертаций здесь
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
24.05.2016, 23:48
Ответы с готовыми решениями:

Блокирование потока при изменении размера окна
Здравствуйте. Есть форма, в которой находится QLabel и QThread который который постоянно...

Qml изменение размера Canvas при изменении размера окна
Может есть какой нибудь способ, чтобы при изменении размера окна (в моем случае window) изменялся...

Перерисовка окна при изменении размера
Наверняка вопрос популярный, но найти пока не смогла. Киньте ссылкой, если есть. Начинаю только...

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

10
137 / 107 / 23
Регистрация: 06.10.2008
Сообщений: 451
25.05.2016, 08:48 2
Хмм, что то тут не так

void PaintWidget::rec(float x, float y, float angle, int level)
{
float angle1 = angle*M_PI/180;
float x1 = x + AB * cos(angle1);
float y1 = y - AB * sin(angle1);
if((x1>=width()) || (y1>=height()) || (x1<=0) || (y1<=0) || (level>10))
return;
else
{
p->drawLine(x,y,x1,y1);
rec(x1,y1,angle+15,level+1); //
rec(x1,y1,angle-15,level+1);
}
}

Добавлено через 10 минут
ООй!
Не то отправил
А если попробовать так
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#ifndef PAINTWIDGET_H
#define PAINTWIDGET_H
 
#include <QWidget>
#include <QPainter>
#include <QMessageBox>
#include <QtMath>
 
class PaintWidget : public QWidget
{
    Q_OBJECT
public:
    explicit PaintWidget(QWidget *parent = 0);
    void paintEvent(QPaintEvent *);
    void rec(float x, float y, float angle, int level);
    QPainter p;
    float A = 90;
    float AB = 40;
 
bool is_event;
};
 
#endif // PAINTWIDGET_H
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
PaintWidget::PaintWidget(QWidget *parent) : QWidget(parent)
{
 p.setPen(QPen(Qt::black,1,Qt::SolidLine)); // Создаем перо для рисования
is_event = true;
}
 
void PaintWidget::paintEvent(QPaintEvent *)
{
if (!is_event)
{
is_event = true;
return;
}
    rec(this->width()/2,this->height(),A,0);
}
 
void PaintWidget::rec(float x, float y, float angle, int level)
{
    float angle1 = angle*M_PI/180;
    float x1 = x + AB * cos(angle1);
    float y1 = y - AB * sin(angle1);
    if((x1>=width()) || (y1>=height()) || (x1<=0) || (y1<=0) || (level>10))
        return;
    else
    {
        p->drawLine(x,y,x1,y1);
is_event = false;
        rec(x1,y1,angle+15,level+1);
is_event = false;
        rec(x1,y1,angle-15,level+1);
    }
}
0
487 / 365 / 93
Регистрация: 10.03.2011
Сообщений: 1,513
Записей в блоге: 5
25.05.2016, 08:59 3
C
1
2
3
4
5
PaintWidget::rec(float x, float y, float angle, int level){
/* ... */
rec(x1,y1,angle+15,level+1);
}
}
У вас стек как, не резиновый?
0
137 / 107 / 23
Регистрация: 06.10.2008
Сообщений: 451
25.05.2016, 09:03 4
Цитата Сообщение от icpu Посмотреть сообщение
У вас стек как, не резиновый?
Там "нормально", после level > 10 - выход из цикла
Правда непонятно зачем.
0
487 / 365 / 93
Регистрация: 10.03.2011
Сообщений: 1,513
Записей в блоге: 5
25.05.2016, 09:39 5
Ну ладно, начнём с простого, замените рекуртку циклом, первым параметром about отправьте this. А там поговорим.
0
137 / 107 / 23
Регистрация: 06.10.2008
Сообщений: 451
25.05.2016, 09:49 6
Там похоже при вызове -
rec(x1,y1,angle+15,level+1);
Срабатывает
paintEvent
А он уже вызывает rec с параметром level = 0
0
487 / 365 / 93
Регистрация: 10.03.2011
Сообщений: 1,513
Записей в блоге: 5
25.05.2016, 10:02 7
mevn, избевьтесь от рекурсии. Уберите QPainter из членов класса. Да, придётся пересоздавать при каждой перерисовке. Нет, не дорого.
0
137 / 107 / 23
Регистрация: 06.10.2008
Сообщений: 451
25.05.2016, 10:19 8
Да не могу я избавиться от рекурсии, это не моя тема, да и не поможет это, просто из кода видно, что
1. при вызове -rec(x1,y1,angle+15,level+1); - /*вызывается 20 раз внутри себя*/
2. Срабатывает paintEvent вызывает rec с параметром level = 0 возврат к п 1. а там опять rec и тд.
Поэтому нужно сделать так чтобы при вызове rec - paintEvent не отрабатывал.
0
487 / 365 / 93
Регистрация: 10.03.2011
Сообщений: 1,513
Записей в блоге: 5
25.05.2016, 10:44 9
0) Можете.
2) Одна из задач QPainter - начинать и завершать циклы отрисовки, внутри которых не будет вызова paintEvent.
0
137 / 107 / 23
Регистрация: 06.10.2008
Сообщений: 451
25.05.2016, 10:56 10
0) Нет я не могу, я бы иначе все организовал (я против рекурсии), но , еще раз повторю, автор этой темы - kmeak;
2) paintEvent - This event handler can be reimplemented in a subclass to receive paint events passed in event. Происходит отрисовка линии, paintEvent и вызыватся
0
0 / 0 / 0
Регистрация: 25.12.2014
Сообщений: 2
25.05.2016, 16:18  [ТС] 11
Проблема решилась только за счет того, что каждый раз будет создаваться QPainter p в PaintEvent. Спасибо всем)
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
25.05.2016, 16:18
Помогаю со студенческими работами здесь

Изменение размера обьектов при изменении размера графического окна
Можно ли в pascalABC.net сделать следующее: чтобы приизменении размера графического окна изменялись...

Артефакт при изменении размера окна
Создал панель на основе класса CDockablePane, все бы ничего если бы при изменении его размеров оно...

Перерисовка объектов, при изменении размера окна
Всем доброго времени суток, такая проблема, надо, чтобы при изменении масштаба окна,...

Изменение Форм при изменении размера окна
Доброй ночи Подскажите пожалуйста как правильно реализовать изменение (положение) форм и элементов...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
11
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2022, CyberForum.ru