QGraphicsView and some related problems
-
In my program i am getting image data from a device when i clicked a button. I hold image as cv::Mat(Opencv) object. After it i changed it to
qimage -> pixmap -> scene -> QGraphicsPixmapItem -> ui->graphicsview. And I have 2 sliders to changebrightness&contrastof image and 2 buttonsfitfor fit image to ui via scaling image,1:1to show image at original size and it should activate scrollbars if needed.I show image firstly as scaled after i read it. My codes:
/*HEADER*/ QGraphicsScene *scene = new QGraphicsScene; QImage qimg; QImage scaledQimg; QPixmap pixmap; cv::Mat img; cv::Mat imgProcessed; double brightness = 0; double contrast = 1; bool isImageScaled; QGraphicsPixmapItem *pix; /*SOURCE*/ //When image readed from device, signal emitted and that slot runs void MainWidget::ImageSlot(cv::Mat *image) { img = *image; isImageScaled = true; DrawImage(); } /*Other slots*/ void MainWidget::sliderBrightness_valueChanged(int value) { brightness = value; DrawImage(); } void MainWidget::sliderContrast_valueChanged(int value) { contrast = value; DrawImage(); } void MainWidget::buttonFIT_clicked() { isImageScaled = true; DrawImage(); } void MainWidget::button11_clicked() { isImageScaled = false; DrawImage(); } void MainWidget::DrawImage() { scene->clear(); if(!img.empty()){ img.convertTo(imgProcessed, -1, contrast, brightness); qimg = QImage(imgProcessed.data, imgProcessed.cols, imgProcessed.rows, imgProcessed.step, QImage::Format_Grayscale8); scaledQimg = qimg.scaled(ui->graphicsView->width() - 10, ui->graphicsView->height() - 10, Qt::KeepAspectRatio); if(isImageScaled) pixmap = QPixmap::fromImage(scaledQimg); else pixmap = QPixmap::fromImage(qimg); pix = scene->addPixmap(pixmap); ui->graphicsView->setScene(scene); } }Now I have multiple problems.
1-When i read another image from device, the old image ingraphicsviewstill stays there and new image overwrited to this, so sometimes i can see old image's part at left side of graphicsview. I addedscene->clear();to fix issue but nothing changed. How to solve this issue?
2-1:1button show image at original size and activate scrollbars, but after i clickFIT, scrollbars are still there. But I dont want any scrollbars in FIT mode because image is already scaled to available ui in this mode. How to do this?
3- Dealing with multiple qimage and isImageScaled variable are making program compilacted, are there any better approach for it? So it automatically activate scrollbars etc.
BONUS: Any advice for creating zoom in/out functionality to graphicsview? On touchscren with 2 fingers, on pc with mouse whell or maybe with buttons.I hope someone will read and give some solutions, thanks in advance.
-
In my program i am getting image data from a device when i clicked a button. I hold image as cv::Mat(Opencv) object. After it i changed it to
qimage -> pixmap -> scene -> QGraphicsPixmapItem -> ui->graphicsview. And I have 2 sliders to changebrightness&contrastof image and 2 buttonsfitfor fit image to ui via scaling image,1:1to show image at original size and it should activate scrollbars if needed.I show image firstly as scaled after i read it. My codes:
/*HEADER*/ QGraphicsScene *scene = new QGraphicsScene; QImage qimg; QImage scaledQimg; QPixmap pixmap; cv::Mat img; cv::Mat imgProcessed; double brightness = 0; double contrast = 1; bool isImageScaled; QGraphicsPixmapItem *pix; /*SOURCE*/ //When image readed from device, signal emitted and that slot runs void MainWidget::ImageSlot(cv::Mat *image) { img = *image; isImageScaled = true; DrawImage(); } /*Other slots*/ void MainWidget::sliderBrightness_valueChanged(int value) { brightness = value; DrawImage(); } void MainWidget::sliderContrast_valueChanged(int value) { contrast = value; DrawImage(); } void MainWidget::buttonFIT_clicked() { isImageScaled = true; DrawImage(); } void MainWidget::button11_clicked() { isImageScaled = false; DrawImage(); } void MainWidget::DrawImage() { scene->clear(); if(!img.empty()){ img.convertTo(imgProcessed, -1, contrast, brightness); qimg = QImage(imgProcessed.data, imgProcessed.cols, imgProcessed.rows, imgProcessed.step, QImage::Format_Grayscale8); scaledQimg = qimg.scaled(ui->graphicsView->width() - 10, ui->graphicsView->height() - 10, Qt::KeepAspectRatio); if(isImageScaled) pixmap = QPixmap::fromImage(scaledQimg); else pixmap = QPixmap::fromImage(qimg); pix = scene->addPixmap(pixmap); ui->graphicsView->setScene(scene); } }Now I have multiple problems.
1-When i read another image from device, the old image ingraphicsviewstill stays there and new image overwrited to this, so sometimes i can see old image's part at left side of graphicsview. I addedscene->clear();to fix issue but nothing changed. How to solve this issue?
2-1:1button show image at original size and activate scrollbars, but after i clickFIT, scrollbars are still there. But I dont want any scrollbars in FIT mode because image is already scaled to available ui in this mode. How to do this?
3- Dealing with multiple qimage and isImageScaled variable are making program compilacted, are there any better approach for it? So it automatically activate scrollbars etc.
BONUS: Any advice for creating zoom in/out functionality to graphicsview? On touchscren with 2 fingers, on pc with mouse whell or maybe with buttons.I hope someone will read and give some solutions, thanks in advance.
Hi,
There's no need to recreate the pixmap item every time, just set the image on the item when you want to change it.
-
Hi,
There's no need to recreate the pixmap item every time, just set the image on the item when you want to change it.
@SGaist You mean convert this
if(isImageScaled) pixmap = QPixmap::fromImage(scaledQimg); else pixmap = QPixmap::fromImage(qimg);to
if(isImageScaled) pixmap.convertFromImage(scaledQimg); else pixmap.convertFromImage(qimg);this, right?
And do you have any idea for my questions? -
@SGaist You mean convert this
if(isImageScaled) pixmap = QPixmap::fromImage(scaledQimg); else pixmap = QPixmap::fromImage(qimg);to
if(isImageScaled) pixmap.convertFromImage(scaledQimg); else pixmap.convertFromImage(qimg);this, right?
And do you have any idea for my questions?Not the QPixmap object, the QGraphicsPixmapItem object.
Which question ?
-
ı@SGaist said in QGraphicsView and some related problems:
Not the QPixmap object, the QGraphicsPixmapItem object
Im sorry, can you show it with code? I dont see where i am creating it every time.
I have 3 problems + one Bonus, any answer for any of them are welcome.
-
In my program i am getting image data from a device when i clicked a button. I hold image as cv::Mat(Opencv) object. After it i changed it to
qimage -> pixmap -> scene -> QGraphicsPixmapItem -> ui->graphicsview. And I have 2 sliders to changebrightness&contrastof image and 2 buttonsfitfor fit image to ui via scaling image,1:1to show image at original size and it should activate scrollbars if needed.I show image firstly as scaled after i read it. My codes:
/*HEADER*/ QGraphicsScene *scene = new QGraphicsScene; QImage qimg; QImage scaledQimg; QPixmap pixmap; cv::Mat img; cv::Mat imgProcessed; double brightness = 0; double contrast = 1; bool isImageScaled; QGraphicsPixmapItem *pix; /*SOURCE*/ //When image readed from device, signal emitted and that slot runs void MainWidget::ImageSlot(cv::Mat *image) { img = *image; isImageScaled = true; DrawImage(); } /*Other slots*/ void MainWidget::sliderBrightness_valueChanged(int value) { brightness = value; DrawImage(); } void MainWidget::sliderContrast_valueChanged(int value) { contrast = value; DrawImage(); } void MainWidget::buttonFIT_clicked() { isImageScaled = true; DrawImage(); } void MainWidget::button11_clicked() { isImageScaled = false; DrawImage(); } void MainWidget::DrawImage() { scene->clear(); if(!img.empty()){ img.convertTo(imgProcessed, -1, contrast, brightness); qimg = QImage(imgProcessed.data, imgProcessed.cols, imgProcessed.rows, imgProcessed.step, QImage::Format_Grayscale8); scaledQimg = qimg.scaled(ui->graphicsView->width() - 10, ui->graphicsView->height() - 10, Qt::KeepAspectRatio); if(isImageScaled) pixmap = QPixmap::fromImage(scaledQimg); else pixmap = QPixmap::fromImage(qimg); pix = scene->addPixmap(pixmap); ui->graphicsView->setScene(scene); } }Now I have multiple problems.
1-When i read another image from device, the old image ingraphicsviewstill stays there and new image overwrited to this, so sometimes i can see old image's part at left side of graphicsview. I addedscene->clear();to fix issue but nothing changed. How to solve this issue?
2-1:1button show image at original size and activate scrollbars, but after i clickFIT, scrollbars are still there. But I dont want any scrollbars in FIT mode because image is already scaled to available ui in this mode. How to do this?
3- Dealing with multiple qimage and isImageScaled variable are making program compilacted, are there any better approach for it? So it automatically activate scrollbars etc.
BONUS: Any advice for creating zoom in/out functionality to graphicsview? On touchscren with 2 fingers, on pc with mouse whell or maybe with buttons.I hope someone will read and give some solutions, thanks in advance.
@masa4 said in QGraphicsView and some related problems:
void MainWidget::DrawImage()
{
scene->clear();if(!img.empty()){ img.convertTo(imgProcessed, -1, contrast, brightness); qimg = QImage(imgProcessed.data, imgProcessed.cols, imgProcessed.rows, imgProcessed.step, QImage::Format_Grayscale8); scaledQimg = qimg.scaled(ui->graphicsView->width() - 10, ui->graphicsView->height() - 10, Qt::KeepAspectRatio); if(isImageScaled) pixmap = QPixmap::fromImage(scaledQimg); else pixmap = QPixmap::fromImage(qimg); pix = scene->addPixmap(pixmap); ui->graphicsView->setScene(scene); }}
There in the line where you call addPixmap. This create a new object every time.
This answers question 1
For question 2, retry when you stopped adding all these objects.
For question 3, do you mean you find complicated to manage two QImage objects ? Why are you creating two images and then selecting one of the two ? Move all the additional logic where it actually make sense then there's no need for multiple QImages. This will also avoid wasting CPU and RAM for nothing.
For the bonus question, check the Gesture Overview in Qt's documentation