1
votes

I'm learning Qt, and have come across a problem I can't figure out, so I'd like to ask the experts!

I am working on an application where I'd like to have a QImage object (using format QImage::Format_RGB888), and be able to manipulate individual pixels with the setPixel() method & save the images with QImageWriter... so far, so good. This all works.

My way of showing this Qimage is that the QMainWIndow contains a QGraphicsView object, and I created a QGraphicsScene, and set that scene on my MainWindow graphicsView.

The problem is that I'd like to be able to show this QImage on the UI "live", such that the user can see the pixels changing, as they are being manipulated. Currently, I have to re-generate a QGraphicsPixmapItem from the image, and re-addPixmap() to the scene, every time I want to see new changes.

Is there a way to view a QImage live, so that changes that are made are immediately seen? Am I using the wrong objects to hold and/or display my image?

I have a simple example attached (just the mainwindow.cpp part... the other files are just default stuff). This UI just has a button (to trigger the QImage changes), and place to display the QImage on the screen.

I've searched the internet, but haven't come across any posts that seem relevant. If anyone has any suggestions, I'd appreciate hearing them! thanks,

-Eric

QGraphicsScene *scene = NULL;
QGraphicsItem *line = NULL;
QImage *image = NULL;
QGraphicsPixmapItem *item = NULL;

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    scene = new QGraphicsScene();
    image = new QImage(60, 60, QImage::Format_RGB888 );

    image->fill(Qt::cyan);

    ui->retranslateUi(this);
    ui->graphicsView->setScene(scene);
    ui->graphicsView->show();

    line = (QGraphicsItem*) scene->addLine( QLine( 20, 40, 300, 100 ),
                    QPen(Qt::red, 6, Qt::DashLine, Qt::FlatCap));
    scene->setBackgroundBrush(QBrush(Qt::green, Qt::SolidPattern));
    scene->addEllipse(40, 80, 300, 240,
                        QPen(Qt::blue, 10, Qt::DashDotDotLine, Qt::RoundCap));

    item = new QGraphicsPixmapItem(QPixmap::fromImage(*image));
    scene->addPixmap(item->pixmap());

    // Connect the pushbutton to the buttonPressed method, below.
    connect(    ui->pushButton, SIGNAL(pressed()),
                this, SLOT( buttonPressed() ) );
}

// Slot connected to the button being pressed.
// Manipulate some pixels, and show the results.
void MainWindow::buttonPressed()
{
    printf("Now in buttonPressed...\n");
    int x, y;
    int offset = qrand();
    QRgb px;

    px = qRgb(20+offset, 10-offset, 30+offset);

    for (x=0; x< 60; x++)
        for(y=0; y< 60; y++)
        {
            image->setPixel(x, y, px );
        }
    // I'd like to NOT have to re-convert the image every time.
    item = new QGraphicsPixmapItem(QPixmap::fromImage(*image));
    scene->addPixmap(item->pixmap());
}
2

2 Answers

0
votes

You can just draw on a QLabel directly by creating the pixmap in place with Qpixmap::fromImage

Alternatively you can make your onw image display widget by deriving from QWidget and overloading the paint event

void DisplayWidget::paintEvent(QPaintEvent*)
{

  QPainter p(this);
  p.drawImage(m_image); // you can also specfy a src and dest rect to zoom
}   
0
votes

i think the better way will be to make Qgraphicsitem deriving from QGraphicsItem for your Image and add this item once in the constructor of Mainwindow.

scene->addItem(Myimageitem);

So in this way you dont need to do it after every iteration and whenever the update is called your image will be automatically updated.