"Segmentation fault" po wczytaniu obrazka

0

Hej ;).

Po długim czasie zabrałem się za painta. Wszystko ok, tylko mam problem z wczytaniem obrazu do programu.

Podczas wczytania obrazu:

-obraz pojawia się, ale nie można po nim rysować.
-Zbyt duży obraz zamyka program.

Podczas wczytywania obrazu, ale po kliknięciu ,,anuluj":

-następuje jakby ,,wyczyszczenie utworzonych obiektów"

QPainter jakby nie istniał, QPixmap również.

Wklejam kod. Proszę o nie ocenianie konstrukcji tego programu. To na razie projekt.

MainWindow.h

 
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QPainter>
#include <QPaintEvent>
#include <QMessageBox>
#include <QMouseEvent>
#include <QLabel>
#include <QDesktopWidget>
#include <QMenu>
#include <QMenuBar>
#include <QFile>
#include <QFileDialog>
#include <QString>

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = 0);
    ~MainWindow();
   void paintEvent(QPaintEvent *e);
   void mousePressEvent(QMouseEvent *e);


    QPixmap *map ;
    QLabel *tabelka;
    QAction *quit;
    QPainter *pi;

private:

  int x,y,x1,y1;
  bool check;
  QString xdd;
  QFileDialog *dialog;
private slots:
  void save();
  void open();

};

#endif // MAINWINDOW_H

MainWindow.cpp

 
#include "mainwindow.h"

#define test QMessageBox::about(this,"test","test");


MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{


    check = true; // to draving.

    map = new QPixmap (this->width(),this->height()); //some size.
    tabelka = new QLabel;
    pi = new QPainter (map);

    map->fill(); //set white theme.

    QPen *pen = new QPen(Qt::black,2);
    pi->setPen(*pen);


    tabelka->setPixmap(*map);
    this->setCentralWidget(tabelka);


    QAction *openn = new QAction ("open",this);
    quit = new QAction ("&Quit",this);
    QAction *savee = new QAction ("Save", this);
    QMenu *file;
    file = menuBar()->addMenu("&File");
    file->addAction(quit);
    file->addAction(savee);
    file->addAction(openn);

    connect(quit,SIGNAL(triggered()),this, SLOT(close()));
    connect (savee,SIGNAL(triggered()),this,SLOT(save()));
    connect (openn,SIGNAL(triggered()),this,SLOT(open()));

       //25 - 38 simple, menu connection.

}

MainWindow::~MainWindow()
{

}

void MainWindow::paintEvent(QPaintEvent *e)
{


}

void MainWindow::mousePressEvent(QMouseEvent *e)
{
if(e->button()== Qt::LeftButton)
  {
   if(check)
   {

      x = e->x();
      y = e->y();
      check = false;


   }
    else if (!check)
   {

   x1 = e->x();
   y1 = e->y();
   check = true;

   pi->drawLine(x,y,x1,y1); // !!!!!!!!!!!!!!!!!!!!!!! Błąd jest tutaj, ale nie wiem co z tym zrobić. Dlaczego to ,,krzaczy".

   tabelka->setPixmap(*map);

   //simple, test draving.

   }


  }

}

void MainWindow::save() //saving. It is fine.
{
   dialog = new QFileDialog (this);

  xdd = dialog->getSaveFileName(this,"Save","/home/","Images(*.png)");

    QFile file(xdd);
    file.open(QIODevice::WriteOnly);
    map->save(&file,"png");

}
void MainWindow::open()
{
   dialog = new QFileDialog (this);
   xdd = dialog->getOpenFileName(this,"Open","/home/","Images(*.png)"); //working on linux

 map->load(xdd);
 tabelka->setPixmap(*map); //to show up.


}

Main.cpp

 
#include "mainwindow.h"
#include <QApplication>
#include <QLabel>
#include <QPainter>


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

Proszę o wytłumaczenie, co i jak.

Błąd to: Seg.entation fault.

Dzięki wielkie ;)

1
pi->drawLine(x,y,x1,y1); // !!!!!!!!!!!!!!!!!!!!!!! Błąd jest tutaj, ale nie wiem co z tym zrobić. Dlaczego to ,,krzaczy".

wyświetl sobie ile wynoszą te współrzędne i czy pi nie jest nullem.
czy wartości są sensowne?

0

Dobrze mam już rozwiązanie.

Otóż przy wywołaniu funkcji load z klasy QPixmap, Obiekt klasy QPainter tak jakby... ...rozłączył się z mapą.

 pi->begin(map);
 pi->drawLine(x,y,x1,y1);
 pi->end();

Wystarczyło dodać dwie linijki: begin i end.
Będę wdzięczny, jeśli ktoś mi wytłumaczy dokładnie, dlaczego tak się stało.

Dziękuję i pozdrawiam ;)

dodanie znacznika <code class="cpp"> - furious programming

1

QFileDialog::getSaveFileName i QFileDialog::getOpenFileName to funkcje statyczne, nie potrzebujesz tworzyć do nich nowego obiektu.

Powinieneś sprawdzać wynik ich działania, po wciśnięciu anuluj zwracany jest pusty string (""), który potem bezmyślnie przekazujesz dalej.

Przy okazji, popracuj nad wyciekami pamięci, wszystko zaalokowane za pomocą new bez podania rodzica w konstruktorze (lub ustawienia go później, ale tego nie robisz) to wyciek, np. Twój QPen * pi.

1

Uruchom w trybie debug (zielona strzałka z robalem) jak błąd wystąpi to program się zatrzyma i dostaniesz więcej informacji co jest źle.
Ja zgaduje, że próbujesz rysować poza granicami obrazka.
Najlepiej załącz zip-a z całym kodem by łatwo było go sprawdzić.

0

Cały problem polega na tym, że przekomponowujesz z zarządzaniem pamięcią i nadużywasz pól klasy.
Pozostawiając błędny design aplikacji, to powinno być zrobione tak jak w załączniku.

1 użytkowników online, w tym zalogowanych: 0, gości: 1