LINUX.ORG.RU

QGraphicsScene правильное помещение элементов и вылеты программы

 , , , ,


0

2

Нужно отобразить график. График будет динамическим и будет меняться в процессе деятельности программы, и взаимодействовать с пользователем( на графике должно быть можно рисовать). Выбрал для этого QGraphicsScene. Создал по кнопке такой метод

void MainWindow::paintXY()
{
    int n = X.size();
    double maxy = Y.at(0);
    double miny = Y.at(0);
    double maxX = X.at(0);
    double minX = X.at(0);
    for(int i = 0;i<n;i++){
        if(maxy<Y.at(i))maxy = Y.at(i);
        if(miny>Y.at(i))miny = Y.at(i);
        if(maxX<X.at(i))maxX = X.at(i);
        if(minX>X.at(i))minX = X.at(i);
    }

    double  dx = w/(maxX-minX);
    double dy = h/(maxy-miny);
    for(double i =miny;i<maxy;i+=(maxy-miny)/10){
     QGraphicsSimpleTextItem* text = new QGraphicsSimpleTextItem();
     text->setY(-dy*i);
     text->setText(QString("%1").arg(i));
     scene->addItem(text);
    }
    double di = ((maxX-minX)/10);
   for(double i =0;i<maxX;i=i+di){
     QGraphicsSimpleTextItem* text = new QGraphicsSimpleTextItem();
     text->setX(i*dx);
     text->setText(QString("%1").arg(i));
     scene->addItem(text);
    }
}

Собственно - подписи осей. Программа вылетает, когда захочет, обычно, пири каких-либо модификациях интерфейса - перетаскивание, разворачивание на весь экран... В чём тут проблема? Может нельзя записывать item созданный в методе с локальной ссылкой? Но вроде должно быть нормально, на сколько я понимаю - объект создаётся в куче, а ссылка на него кидается в items сцены, так почему программа вылетает?


В приведённом коде всё вроде ок. Ты бы дебаггером посмотрел бэктрейс для начала что ли. Кстати, у тебя деления на ноль не получается ли случайно?

unC0Rr ★★★★★ ()
    int n = X.size(); // здесь
    double maxy = Y.at(0);
    double miny = Y.at(0);
    double maxX = X.at(0);
    double minX = X.at(0);
    for(int i = 0;i<n;i++){
        if(maxy<Y.at(i))maxy = Y.at(i); // здесь
        if(miny>Y.at(i))miny = Y.at(i); // здесь
        if(maxX<X.at(i))maxX = X.at(i);
        if(minX>X.at(i))minX = X.at(i);
    }

Не знаю сильно ли связаны контейнеры X и Y, но они могут быть разной длины и возможно обращение к несуществующему элементу контейнера Y.

timon-ltv ()

плюсую unC0Rr. gdb тебе в помощь:

$ gdb имя_программы
(gdb) run
....
Делаешь так, чтобы программа вылетела
....
(gdb) bt
Дальше смотришь, в какой строчке падает => profit

solovey ★★ ()

Может нельзя записывать item созданный в методе с локальной ссылкой? Но вроде должно быть нормально, на сколько я понимаю - объект создаётся в куче, а ссылка на него кидается в items сцены, так почему программа вылетает?

Во-первых не ссылка, а указатель. Во-вторых, ты итемы со сцены как-то удаляешь? События какие-нибудь обрабатывешь?

no-such-file ★★★★★ ()
Ответ на: комментарий от solovey

Вот мой bt

(gdb) run
Starting program: /media/Files/Programming/Cpp/Projects/Solover/Gui/SoloverGui/SoloverGui 
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
[New Thread 0x7fffe7656700 (LWP 27985)]
[New Thread 0x7fffe6e55700 (LWP 27986)]
Args 
arg[ 0 ] = 1 
arg[ 1 ] = 1 
arg[ 2 ] = 0.2 
Data: 
|X |Y |Ych| 
-10 0.0907026 0.0907026 
-9 0.0261524 0.0261524 
-8 0.000426397 0.000426397 
-7 0.0145503 0.0145503 
-6 0.0679609 0.0679609 
-5 0.158529 0.158529 
-4 0.282644 0.282644 
-3 0.435358 0.435358 
-2 0.610582 0.610582 
-1 0.801331 0.801331 
0 1 1 
1 1.19867 1.19867 
2 1.38942 1.38942 
3 1.56464 1.56464 
4 1.71736 1.71736 
5 1.84147 1.84147 
6 1.93204 1.93204 
7 1.98545 1.98545 
8 1.99957 1.99957 
9 1.97385 1.97385 

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff60e9b1a in ?? () from /lib/x86_64-linux-gnu/libc.so.6
(gdb) bt
#0  0x00007ffff60e9b1a in ?? () from /lib/x86_64-linux-gnu/libc.so.6
#1  0x00007ffff60ebfb5 in malloc () from /lib/x86_64-linux-gnu/libc.so.6
#2  0x00007ffff407ae1c in XCreateGC ()
   from /usr/lib/x86_64-linux-gnu/libX11.so.6
#3  0x00007fffee5c9127 in ?? ()
   from /usr/lib/x86_64-linux-gnu/libgdk-x11-2.0.so.0
#4  0x00007fffee58c9ea in gdk_drawable_copy_to_image ()
   from /usr/lib/x86_64-linux-gnu/libgdk-x11-2.0.so.0
#5  0x00007fffee58c9ea in gdk_drawable_copy_to_image ()
   from /usr/lib/x86_64-linux-gnu/libgdk-x11-2.0.so.0
#6  0x00007fffee597f70 in gdk_pixbuf_get_from_drawable ()
   from /usr/lib/x86_64-linux-gnu/libgdk-x11-2.0.so.0
#7  0x00007ffff766c4a2 in ?? () from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
#8  0x00007ffff765c39e in QGtkStyle::drawComplexControl(QStyle::ComplexControl, QStyleOptionComplex const*, QPainter*, QWidget const*) const ()
   from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
#9  0x00007ffff773827b in QScrollBar::paintEvent(QPaintEvent*) ()
   from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
#10 0x00007ffff73280f6 in QWidget::event(QEvent*) ()
   from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
#11 0x00007ffff773817a in QScrollBar::event(QEvent*) ()
---Type <return> to continue, or q <return> to quit---
Мне он мало о чём говорит. ВОзникает стабильно при попытке ресайзить окно. Код, который я привёл выше я вызываю один единственный раз при нажатии кнопки, и больше его не трогаю, в нём никаких ошибок не возникает и второй раз он не выполняется, а когда я ресайзю окно - всё летит к чертям. Может вы мне посоветуете другой способ нарисовать график на QTGrapficsView, т.к. Я ещё толом не разобрался в его размерах, у сцены они отличаются от view.

vsrmis ()
Ответ на: комментарий от vsrmis

Вот мой bt

Он не полный. Там в конце черным по белому написано - нажмите «return», чтобы посмотреть дальше... Найди то место, где начинается ругань на твой код, а не на стандартные библиотеки. И уже в этом месте внимательно ищи ошибку.

Может вы мне посоветуете другой способ нарисовать график на QTGrapficsView

Вот здесь вряд ли чем-то помогу... У моих приложений на Qt другая специфика, поэтому в такие тонкости я не вдавался...

Да, и еще.. Если все рушится при изменении размеров, посмотри на resizeEvent. Может, его надо переопределить... Хотя это только догадки

solovey ★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.