如何在更改QGraphicsPixmapItem之后更新QGraphicsView

时间:2015-06-05 16:54:19

标签: c++ qt qgraphicsview

我和Qt相当不错,但我看过很多帖子,人们无法按预期更新QGraphicsView。我正在尝试制作非常简单的小部件,它将显示两个数据数组,因为图像与某些alpha混合重叠。根据我收集的内容,最好的方法是创建一个QImage来保存图片数据,每次我想要更新叠加显示时,都会将QImage转换为QPixmap },然后使用它来更新QGraphicsPixmapItem的像素图(位于QGraphicsScene中的QGraphicsView

作为一个最小的工作示例,我将其设置为生成随机红色图像和随机绿色图像,并在它们之间进行随机混合。它是在计时器上设置的,用于生成新数据,理想情况下,更新视图。无论我有多少更新/重绘,我似乎都无法正确更新它。计时器似乎正在工作,并且随机数据生成似乎也有效,但是如果我在物理上改变窗口的大小,场景才会更新。

这是我的代码,只需几个块。首先DisplayWidget.h

#include <QtWidgets/QWidget>
#include "ui_displaywidget.h"
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QGraphicsPixmapItem>
#include <QPushButton>
#include "math.h"
#include <QVBoxLayout>
#include <qsize.h>
#include <qtimer.h>

#define FULLSCALE 255
#define IM_X_MIN -5.0
#define IM_X_MAX 5.0
#define IM_Z_MIN 0.0
#define IM_Z_MAX 15.0
#define IM_PIXEL_WIDTH 200
#define IM_PIXEL_HEIGHT IM_PIXEL_WIDTH * (IM_Z_MAX-IM_Z_MIN)/(IM_X_MAX - IM_X_MIN)
#define BORDER_WIDTH    10
#define RAND_SEED 7

class DisplayWidget : public QWidget
{
    Q_OBJECT

public:
    DisplayWidget(int width, int height, QWidget *parent = 0);
    ~DisplayWidget();

    void SetData(float * data, float minVal, float maxVal);
    void SetTransparency(float * alpha, float minVal, float maxVal);

private:
    //Ui::DisplayWidgetClass ui;
    QGraphicsView * view;
    QGraphicsScene * scene;
    QGraphicsPixmapItem * bModeItem;
    QGraphicsPixmapItem * dModeItem;
    QImage * bImage;
    QImage * dImage;
    QTimer * frameGrab;


    void CreateWidgets();
    void SetupGui();

    int w, h;

public slots:
    void GenerateNewData();
};

这是我的.cpp的相关部分。 GenerateNewData()是一个似乎不会产生场景更新的函数。这是我尝试过视图/场景/项目更新/重绘的地方。

DisplayWidget::DisplayWidget(int width, int height, QWidget *parent): QWidget(parent)
{
    w = width;
    h = height;

    CreateWidgets();
    SetupGui();

    // seed the random number generator
    srand(RAND_SEED);
    GenerateNewData();
}

void DisplayWidget::CreateWidgets()
{
    view = new QGraphicsView(this);
    scene = new QGraphicsScene(this);
    bModeItem = scene->addPixmap(QPixmap());
    dModeItem = scene->addPixmap(QPixmap());
    bImage = new QImage(w, h, QImage::Format_ARGB32);
    dImage = new QImage(w, h, QImage::Format_ARGB32);
    frameGrab = new QTimer(this);
}
void DisplayWidget::SetupGui()
{
    QVBoxLayout * layout = new QVBoxLayout(this);
    layout->addWidget(view);
    setLayout(layout);

    scene->setSceneRect(0, 0, IM_PIXEL_WIDTH, IM_PIXEL_HEIGHT);
    view->setGeometry(0, 0, IM_PIXEL_WIDTH + 2*BORDER_WIDTH, IM_PIXEL_HEIGHT + 2*BORDER_WIDTH);
    view->setScene(scene);
    bModeItem->setPixmap(QPixmap::fromImage(*bImage).scaled(QSize(IM_PIXEL_WIDTH, IM_PIXEL_HEIGHT)));
    dModeItem->setPixmap(QPixmap::fromImage(*dImage).scaled(QSize(IM_PIXEL_WIDTH, IM_PIXEL_HEIGHT)));
    connect(frameGrab, SIGNAL(timeout()),this, SLOT(GenerateNewData()));
    frameGrab->start(500);
}
void DisplayWidget::GenerateNewData()
{
    QRgb * bImageData = (QRgb *)bImage->scanLine(0);
    QRgb * dImageData = (QRgb *)dImage->scanLine(0);

    for (int i; i < w * h; i++)
    {
        bImageData[i] = qRgba(rand() % FULLSCALE, 0, 0, FULLSCALE);
        dImageData[i] = qRgba(0, 255,0, rand() % FULLSCALE);
    }

    bModeItem->setPixmap(QPixmap::fromImage(*bImage).scaled(QSize(IM_PIXEL_WIDTH, IM_PIXEL_HEIGHT)));
    dModeItem->setPixmap(QPixmap::fromImage(*dImage).scaled(QSize(IM_PIXEL_WIDTH, IM_PIXEL_HEIGHT)));
}

这是我的主要内容。

#include "displaywidget.h"
#include <QtWidgets/QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    DisplayWidget w(25,25);
    w.show();
    return a.exec();
}

我将不胜感激任何帮助!

0 个答案:

没有答案