Is there a way to view a QImage “live” on the UI?
-
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());
}@
-
I don't know if there is any generic solution for that, but in any case you can subclass QGraphicsPixmapItem and write your own code for ::repaint().
-
Hi Gene,
Thanks for taking a look at my question!
I'm still learning Qt, and not sure how to do this, but I'll explore this idea. Do you know of any implementations that do something similar?
-Eric -
give a try to
@
void QGraphicsPixmapItem::setPixmap ( const QPixmap & pixmap )
@ -
Hi Robot Herder, Thanks for this suggestion. It sounds like you're suggesting the same as Gene, right?
Or, is it something else? Can you give more context? thanks!
-Eric -
Hello.
AFAIK it's possible to set Z-order for objects at QGraphicsScene. My suggestion is to use something like layers: you draw your picture on the background, while user changes pixels on the foreground. When you need to save your picture you just get all pixels that were changed and write it into pixmap.