Blocked with QGraphicScene



  • Hello,

    i got a problem using QGrapicsScene, i want to display some picture with coordinates, but when i run the program nothing happend and it crashed..

    i put my code here so if someone can help me please.

    .h

    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H
    
    #include <QMainWindow>
    #include <QPixmap>
    #include <QPoint>
    #include <QSize>
    #include <iostream>
    #include <QMapIterator>
    #include <QMap>
    #include <QDebug>
    #include <QGraphicsItem>
    #include <QGraphicsScene>
    
    namespace Ui {
    	class MainWindow;
    }
    struct CostInfo
    {
    	QString ImageName;
    	int     Cost;
    };
    
    
    class MainWindow : public QMainWindow
    {
    	Q_OBJECT
    
    public:
    		QPixmap pixa;
    	explicit MainWindow(QWidget *parent = 0);
    
    
    
    	~MainWindow();
    
    
    
    
    
    private slots:
    	void on_push_clicked();
    	void on_push2_clicked();
    
    
    	void on_verticalSlider_sliderMoved(int position);
    
    	void on_verticalSlider_actionTriggered(int action);
    
    private:
    	Ui::MainWindow *ui;
    	QImage pixi;
    
    	float k;
    	int a;
    
    
    
    	int z=1;
    	int b;
    };
    
    #endif // MAINWINDOW_H
    
    

    .cpp

    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    #include <QPixmap>
    #include <QImage>
    #include <QFileDialog>
    #include <QColor>
    #include <QPoint>
    #include <QSize>
    #include <iostream>
    #include <QMapIterator>
    #include <QMap>
    #include <QDebug>
    #include <QGraphicsItem>
    #include <QGraphicsScene>
    using namespace std;
    
    // forwards
    QColor Couleurdominante(const QImage& image, const QPoint& topLeft, const QSize& rectSize);
    void Remplissage(QImage& image, const QPoint& topLeft, const QSize& rectSize, const QColor& colour);
    bool IsCloseColor( QColor c1, QColor c2 );
    void Remplacement (const QColor& colour, const QPoint& topLeft);
    QGraphicsScene scene;
    //-----------------------------------------------------
    
    QMap<QRgb, CostInfo > Costs = {
    	{ QColor(255 , 0 , 0 ).rgb(), { ":/img/fraise.png", 10 }},
    	{ QColor(0 , 255 , 0 ).rgb(), { ":/img/balleverte.png", 20 }},
    	{ QColor(0 , 0 , 255 ).rgb(), { ":/img/ballebleue.png", 20 }},
    	{ QColor(255 , 255 , 255 ).rgb(), { ":/img/balleblanche.png", 20 }},
    	{ QColor(255 , 128 , 0 ).rgb(), { ":/img/ballepeche.png", 20 }},
    	{ QColor(0 , 0 , 0 ).rgb(), { ":/img/noir.png", 20 }},
    	{ QColor(102 , 51 , 0 ).rgb(), { ":/img/marron.png", 20 }},
    	{ QColor(255 , 102 , 78 ).rgb(), { ":/img/rose.png", 20 }},
    	{ QColor(0 , 204 , 204 ).rgb(), { ":/img/turquoise.png", 20 }},
    	{ QColor(255 , 178 , 102 ).rgb(), { ":/img/beige.png", 20 }},
    	{ QColor(76 , 0 , 153 ).rgb(), { ":/img/violet.png", 20 }},
    	{ QColor(100 , 100 , 100 ).rgb(), { ":/img/gris.png", 20 }},
    };
    
    
    
    //-----------------------------------------------------
    MainWindow::MainWindow(QWidget* parent) :
    	QMainWindow(parent),
    	ui(new Ui::MainWindow) {
    	ui->setupUi(this);
    
    }
    //-----------------------------------------------------
    MainWindow::~MainWindow() {
    	delete ui;
    }
    //-----------------------------------------------------
    void MainWindow::on_push_clicked() {
    	QString fileName = QFileDialog::getOpenFileName(this,
    																									tr("Open Image"), "/", tr("Image Files (*.png *.jpg *.bmp)"));
    	QPixmap pix(fileName);
    	ui->label->setPixmap(pix);
    	ui->label->setFixedHeight(pix.height());
    	ui->label->setFixedWidth(pix.width());
    	const QSize s = pix.size();
    	pixi = QImage(pix.toImage());
    
    	ui->label_2->setText( "Size: " + QString::number(s.width()) + " " + QString::number(s.height()) );
    
    }
    //-----------------------------------------------------
    void MainWindow::on_push2_clicked() {
    
    	int z = 20 ;
    	for (int i = 0; i < pixi.width(); i += z) {
    		for (int j = 0; j < pixi.height(); j += z) {
    
    //			Remplissage(pixi, QPoint(i, j), QSize(z, z), Couleurdominante(pixi, QPoint(i, j), QSize(z, z)));
    			Remplacement(Couleurdominante(pixi, QPoint(i, j), QSize(z, z)), QPoint(i,j));
    
    
    		}
    	}
    	QGraphicsView view(&scene);
    	view.show();
    	pixa = QPixmap::fromImage(pixi);
    //	ui->label_3->setPixmap(pixa);
    //	ui->label_3->setFixedHeight(pixa.height());
    //	ui->label_3->setFixedWidth(pixa.width());
    
    
    }
    //-----------------------------------------------------
    //void Remplissage(QImage& image, const QPoint& topLeft, const QSize& rectangle, const QColor& colour) {
    
    //	int maxX = topLeft.x() + rectangle.width();
    //	int maxY = topLeft.y() + rectangle.height();
    
    //	for(int x = topLeft.x(); x < maxX; ++x) {
    //		for(int y = topLeft.y(); y < maxY; ++y) {
    //			image.setPixelColor(x, y, colour);
    
    
    
    //}}}
    
    //-----------------------------------------------------
    QColor Couleurdominante(const QImage& image, const QPoint& topLeft, const QSize& rectangle) {
    	int rouge = 0, vert = 0, bleue = 0;
    
    	int  X = topLeft.x() + rectangle.width();
    	int  Y = topLeft.y() + rectangle.height();
    
    	for (int y = topLeft.y(); y < Y; y++)  {
    		for (int x = topLeft.x(); x < X; x++)   {
    			QRgb pixel = image.pixel(x, y);
    
    			rouge += qRed(pixel);
    			vert += qGreen(pixel);
    			bleue += qBlue(pixel);
    		}
    	}
    
    	int n = rectangle.width() * rectangle.height();
    
    	Q_ASSERT(n);
    	if (n <= 0)
    		return Qt::black;
    
    	return QColor(rouge / n, vert / n, bleue / n);
    }
    //-----------------------------------------------------
    bool IsCloseColor( QColor c1, QColor c2 ) {
    	int diffRed   = abs(c1.red() - c2.red());
    	int diffGreen = abs(c1.green() - c2.green());
    	int diffBlue  = abs(c1.blue()  - c2.blue());
    
    	if (diffBlue + diffRed + diffGreen < 350) {
    		return true;
    
    	}	else {
    		return false;
    
    
    	}
    }
    //-----------------------------------------------------
    void MainWindow::on_verticalSlider_sliderMoved(int position) {
    }
    
    void Remplacement (const QColor& colour, const QPoint& topLeft){
    
    if (Costs.contains( colour.rgb() ))  {
    					CostInfo& ci = Costs[colour.rgb()];
    									//          int Cost = ci.Cost;
    				qDebug() << "check me--->" << ci.ImageName;
    				QPixmap pix( ci.ImageName );
    						if (pix.isNull()){
    							qDebug() << "nothing";
    						return;
    						};
    		QPixmap scaledPix = pix.scaled(   20, 20,
    																			 Qt::KeepAspectRatio,
    																			 Qt::SmoothTransformation
    																				 );
    		QGraphicsPixmapItem *item = new QGraphicsPixmapItem(scaledPix);
    			scene.addItem(item);
    			item->setPos(topLeft.x() , topLeft.y());
    
    }
    else {
    					foreach( QRgb key, Costs.keys() ) {
    					QColor BaseColor( key );
    					if (IsCloseColor(BaseColor, colour) == true){
    					if ( Costs.contains( BaseColor.rgb())){
    								qDebug () << "its OK with base color";
    											}else{
    											qDebug () << " base color had no match!!";
    								}
    
    		  CostInfo& ci = Costs[BaseColor.rgb()];
    			QPixmap pix( ci.ImageName );
    			qDebug() << "image i get from ci.ImageName : " << ci.ImageName;
    			QPixmap scaledPix = pix.scaled(   20, 20,
    																										 Qt::KeepAspectRatio,
    																										 Qt::SmoothTransformation
    																										 );
    					QGraphicsPixmapItem *item = new QGraphicsPixmapItem(scaledPix);
    					scene.addItem(item);
    			item->setPos(topLeft.x() , topLeft.y());
    	}
    	else {
    		qDebug() << "yep its no good";
    	}
    }
    
    }
    }
    
    
    


  • You create the QGraphicsView on the stack. It will be destroyed when leaving the function.
    It's unclear to me where you declare the variable "scene"



  • so i have to put the QGraphicsView in :

    MainWindow::~MainWindow() ?

    i read the i have to declare in general my scene



  • Easiest way is to declare both Scene and View as class member variables (QGraphicsScene* and QGraphicsView*), make a "new" on them in constructor, provide the main window as parent. Then you need not worry about desctruction.



  • So in my .h ?

    i do like :

    QGraphicsScene scene = new QGraphicsScene (this);
    QGraphicsViewview = new QGraphicsView (this);

    ?

    EDIT : And my program will work ?

    normally it should display picture ( 20 * 20 ) on the scene



  • sorry to up this,

    if someone could help me :/ i have to finish it for the 14/01 and i know it need few times to finish it, thanks for comprehension


  • Lifetime Qt Champion

    Hi,

    If you are in such a hurry, you should consider hiring someone to help you finish your project.

    This forum is a community driven, you can't ask the members to take your deadlines into consideration while they are helping you on their own time.

    That said, rather than absolutely trying to add everything at once to your class. Take the examples from Qt's documentation and learn how to add a pixmap properly to a scene with a view on it. Then you can add your image analysis logic.



  • I just asked for some help, i DIDNT said "help me u have no choise"
    And i learn from qt doc but as you can see i tried something and i have declaration problem


  • Moderators

    @Payx @Asperamanca already said what you should do: declare your scene and view as member variables and new them in your constructor. But not like this!

    QGraphicsScene scene = new QGraphicsScene (this);
    QGraphicsViewview = new QGraphicsView (this);
    

    instead do:

    scene = new QGraphicsScene (this);
    view = new QGraphicsView (this);
    


  • i declared
    QGraphicsScene scene;
    QGraphicsView view;
    in my .h
    and add this :

    void MainWindow::on_push2_clicked() {
    	scene = new QGraphicsScene (this);
    	view = new QGraphicsView (this);
    

    but i got all of this http://hpics.li/8905f8b



  • @Payx
    you have to declare scene and view as pointer.
    and for Remplacement , you have two choice

    1. pass the scene to it
    2. declare Remplacement as MainWindow's method

  • Lifetime Qt Champion

    QGraphicsScene scene; << Here you have an object
    QGraphicsView view; << Same
    
    void MainWindow::on_push2_clicked() {
    	scene = new QGraphicsScene (this); << trying to replace the object with a pointer to a newly create object.
    	view = new QGraphicsView (this); << same
    

    The error you are seeing here is because QObject based classes can't be copied or assigned.



  • ok so i did this :

    QGraphicsScene *scene;
    QGraphicsView *view;
    

    but it tell me that scene isnt declared in my remplacement's function which is in MainWindow pus2



  • @Flotisable said in Blocked with QGraphicScene:

    @Payx
    and for Remplacement , you have two choice

    1. pass the scene to it
    2. declare Remplacement as MainWindow's method

    I have said about it


  • Lifetime Qt Champion

    There's no need to replace anything, just create them in the constructor and be done with that part.

    When you want to modify the content of the scene you can for example clean it completely (there are other solution but it looks like the most simple in the current situation).



  • @SGaist sorry but, i don't understand well the "create in the constructor"


  • Moderators

    @Payx C++ constructor?

    class MainWindow : public QMainWindow
    {
    	Q_OBJECT
    public:
    	  QPixmap pixa;
    	  explicit MainWindow(QWidget *parent = 0);
    	  ~MainWindow();
    
    private slots:
    	void on_push_clicked();
    	void on_push2_clicked();
    	void on_verticalSlider_sliderMoved(int position);
    	void on_verticalSlider_actionTriggered(int action);
    
    private:
    	Ui::MainWindow *ui;
    	QImage pixi;
            QGraphicsScene *scene;
            QGraphicsView *view;
    	float k;
    	int a;
    	int z=1;
    	int b;
    };
    
    // In cpp file
    // This is the constructor
    MainWindow::MainWindow(QWidget *parent)
    {
    ...
        scene = new QGraphicsScene (this);
        view = new QGraphicsView (this);
    }


  • so it's exactly what i did, but have still the "scene isnt declared"



  • @Payx
    First I see some basic structural things. You do not need to #include in both your .h and .cpp. Although Qt uses smart includes, it is a waste of time. Just forward declare the pointers variables needed in your .h file. For example:

    class QGraphicsView;
    class QGraphicsScene;
    . . .
    QGraphicsScene* scene;
    QGraphicsView* view;

    In your .cpp file go ahead and include them.

    The second thing I saw and I haven't seen it addressed is your usage of the member 'scene'. Your code still indicates you are using it as an object and not a pointer. So, you can remove the use of '&' and use '->' instead of '.'

    You can get some weird errors when you mix.



  • i use -> here ?
    scene->addItem(item);



  • @Payx
    yes



  • same error


  • Lifetime Qt Champion

    Did you cleanup all your code ?
    Did you cleanup your includes ?



  • Not to sound harsh but you should probably learn the basics of c++, like what is a constructor :O


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.