PDA

View Full Version : QGraphicsView doesn't update on QComboBox SIGNAL



vinnzcrafts
24th February 2014, 18:24
Hello, I'm having a little problem with a view that I have, I'm using the resizeEvent of the QMainWindow the view is in to call a function that redraws the view with a grid, so far so good, when I resize the window the view resizes along and the grid to. I also have a QComboBox that I use to choose the scale of the grid squares, the currentIndexChanged SIGNAL of the comboBox triggers a slot that calls the function that redraws the grid, but the view only updates after I resize the window again, it was suppose to update the view with the new grid scale as soon as the user changed the comboBox...?

This is a simplified version of the original that I did to make it easier to see the portion of the program which contains the fault, I tested it and the same behavior shows here...

main.h:


#include <QApplication>
#include "maincontrol.h"

int main(int argc,char *argv[])
{
QApplication a(argc,argv);
MainControl m;
m.show();
m.setted=1;
return a.exec();
}

maincontrol.h:


#ifndef MAINCONTROL_H
#define MAINCONTROL_H

#include <QMainWindow>
#include <QGraphicsView>
#include <QGraphicsScene>
#include <QComboBox>
#include <QPixmap>
#include <QImage>
#include <QResizeEvent>
#include <QLayout>
#include <QLabel>

class MainControl : public QMainWindow
{
Q_OBJECT
public:
explicit MainControl(QWidget *parent = 0);

QHBoxLayout *combo_layout;
QHBoxLayout *view_layout;
QVBoxLayout *main_layout;
QWidget *central_widget;

QGraphicsView *control_view;
QGraphicsScene *control_scene;
QPixmap *control_pixmap;
QComboBox *control_combobox;
QLabel *debug_label;
int SCALE;
int image_w;
int image_h;
int setted;
int set_pixel_value(int red,int green,int blue);
void process_canvas();
protected:
void resizeEvent(QResizeEvent *e);
signals:

public slots:
void update_scale(int s);

};

#endif // MAINCONTROL_H


maincontrol.cpp:


#include "maincontrol.h"

MainControl::MainControl(QWidget *parent) :
QMainWindow(parent)
{
//----------------------initiate properties
SCALE=10;
image_w=300;
image_h=300;
setted=0;
control_scene=new QGraphicsScene;
control_view=new QGraphicsView(control_scene);
control_view->setMinimumSize(image_w,image_h);
control_view->setResizeAnchor(QGraphicsView::NoAnchor);
control_view->setAlignment(Qt::AlignLeft|Qt::AlignTop);

control_pixmap=new QPixmap;
control_combobox=new QComboBox;

QString c_str;
int cc=1;
while(cc<=10)
{
c_str.setNum(cc);
control_combobox->addItem(c_str);
cc++;
}
control_combobox->setCurrentIndex((SCALE/2)-1);

combo_layout=new QHBoxLayout;
view_layout=new QHBoxLayout;
debug_label=new QLabel("");
main_layout=new QVBoxLayout;
central_widget=new QWidget;

//----------------------set layouts
combo_layout->addWidget(control_combobox);
view_layout->addWidget(control_view);

main_layout->addLayout(combo_layout);
main_layout->addLayout(view_layout);
main_layout->addWidget(debug_label);
central_widget->setLayout(main_layout);

this->setCentralWidget(central_widget);

//----------------------draw image once
process_canvas();
control_scene->addPixmap(*control_pixmap);
//----------------------connections
connect(control_combobox,SIGNAL(currentIndexChange d(int)),this,SLOT(update_scale(int)));
}
//--------------------------------------- PROCESS CANVAS -----------------------------------------------//
//makes the image AND UPDATES it to the view
//Problem:When resizeEvent calls this function it updates the view as it should according to
//the it's last command (control_view->update()) but when update_scale calls it it doesn't update
//until I resize it again
void MainControl::process_canvas()
{
QImage control_image(image_w,image_h,QImage::Format_RGB32 );
control_image.fill(set_pixel_value(0,0,0));
int cy=0;
int cx=0;
while(cy<control_image.height())
{
while(cx<control_image.width())
{
if(cx%(10*SCALE)==0 || cy%(10*SCALE)==0)
{
control_image.setPixel(cx,cy,set_pixel_value(150,1 50,150));
}
cx++;
}
cx=0;
cy++;
}
control_pixmap->convertFromImage(control_image.scaled(image_w,imag e_h));
control_view->update();
}
//--------------------------------------- RESIZE EVENT -----------------------------------------------//
//The size of the image was suppose to go along with the view
void MainControl::resizeEvent(QResizeEvent *e)
{
if(setted)
{
int new_w=e->size().width();
int old_w=e->oldSize().width();
int new_h=e->size().width();
int old_h=e->oldSize().width();

image_w+=new_w-old_w;
image_h+=new_h-old_h;
process_canvas();
}
}
//--------------------------------------- UPDATE SCALE -----------------------------------------------//
//It is called when the user changes the value of the comboBox
void MainControl::update_scale(int s)
{
SCALE=2*(s+1);
process_canvas();
}

anda_skoa
24th February 2014, 19:06
If you want to update the QGraphicsPixmapItem then you should keep a pointer to that and call setPixmap() with the new pixmap.

Cheers,
_

vinnzcrafts
24th February 2014, 23:00
It worked, thank you so very much anda_skoa :D
Am I the one to mark as SOLVED thread?

vinnzcrafts
5th March 2014, 09:48
Here is what I changed it after skoa's advice:

In maincontrol.h I declared a QGraphicsPixmapItem pointer to use with the QGraphicsScene:



QGraphicsPixmapItem *control_pixmap_item;

Then in the constructor I used:



control_pixmap_item->setPixmap(*control)
control_scene->addItem(control_pixmap_item);


Then on maincontrol.cpp I changed the update part in the process_canvas function:



void MainControl::process_canvas()
{
QImage control_image(image_w,image_h,QImage::Format_RGB32 );
control_image.fill(set_pixel_value(0,0,0));
int cy=0;
int cx=0;
while(cy<control_image.height())
{
while(cx<control_image.width())
{
if(cx%(10*SCALE)==0 || cy%(10*SCALE)==0)
{
control_image.setPixel(cx,cy,set_pixel_value(150,1 50,150));
}
cx++;
}
cx=0;
cy++;
}
control_pixmap->convertFromImage(control_image.scaled(image_w,imag e_h));
control_pixmap_item->setPixmap(*control_pixmap);
control_view->update();
}