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" -
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.
-
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.
-
@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
-
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.
-
@Flotisable said in Blocked with QGraphicScene:
@Payx
and forRemplacement
, you have two choice- pass the
scene
to it - declare
Remplacement
asMainWindow
's method
I have said about it
- pass the
-
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).
-
@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); }
-
@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.