无法引用QLabel的像素图

Can't refesh pixmap of QLabel

本文关键字:像素 QLabel 引用      更新时间:2023-10-16

我已经被这个问题困了2天了。我使用Qt插件Visual Studio 2013上的Window 7-64 bit

我一直试图在QLabel s中显示一对图像。我需要定期操作像素数据,所以我将它们存储在QImage s中,每次我想刷新显示时,我设置QLabelQPixmap。问题是,只有当我以某种方式改变/移动窗口时,它似乎才会刷新。

如果我只是让QLabelQWidget的孩子,但从不设置布局,这个问题就会消失。如果我然后添加repaint()update(),问题又回来了。

(这是一个非常类似的帖子,我使用QGraphicsScene发布,但问题似乎比这更根本,所以我重新发布)

这是我的代码。首先是。h
#ifndef DISPLAYWIDGET_H
#define DISPLAYWIDGET_H
#include <QtWidgets/QWidget>
#include <QPixmap>
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QGraphicsPixmapItem>
#include <QPushButton>
#include <QHBoxLayout>
#include <QTimer>
#include <QLabel>
#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();
private:
    QLabel* bimageLabel;
    QLabel* dimageLabel;
    QImage* bImage;
    QImage* dImage;
    QTimer* frameGrab;
    QPushButton* debugButton;
    void CreateWidgets();
    void SetupGui();
    int w, h;
public slots:
    void GenerateNewData();
};
#endif // DISPLAYWIDGET_H

和。cpp.

#include "displaywidget.h"
DisplayWidget::DisplayWidget(int width, int height, QWidget *parent): QWidget(parent)
{
    //ui.setupUi(this);
    w = width;
    h = height;
    CreateWidgets();
    SetupGui();
    // seed the random number generator
    srand(RAND_SEED);
    GenerateNewData();
}
DisplayWidget::~DisplayWidget()
{
}
void DisplayWidget::CreateWidgets()
{
    bImage = new QImage(w, h, QImage::Format_ARGB32);
    dImage = new QImage(w, h, QImage::Format_ARGB32);
    bimageLabel = new QLabel(this);
    dimageLabel = new QLabel(this);
    debugButton = new QPushButton("DEBUG", this);
    bimageLabel->setStyleSheet("QLabel {background-color: black};");
    dimageLabel->setStyleSheet("QLabel {background-color: white};");
    frameGrab = new QTimer(this);
}
void DisplayWidget::SetupGui()
{
    QHBoxLayout * layout = new QHBoxLayout();
    setLayout(layout); // commenting this line out makes it refresh
    layout->addWidget(bimageLabel);
    layout->addWidget(dimageLabel);
    layout->addWidget(debugButton);
    connect(frameGrab, SIGNAL(timeout()),this, SLOT(GenerateNewData()));
    connect(debugButton, SIGNAL(clicked()), this, SLOT(GenerateNewData()));
    frameGrab->start(50);
}
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, 0, rand() % FULLSCALE, FULLSCALE);
    }
    bimageLabel->setPixmap(QPixmap::fromImage(*bImage).scaled(QSize(IM_PIXEL_WIDTH, IM_PIXEL_HEIGHT)));
    dimageLabel->setPixmap(QPixmap::fromImage(*dImage).scaled(QSize(IM_PIXEL_WIDTH, IM_PIXEL_HEIGHT)));
    //this->update(); // this breaks it again
}

我要疯了。我对Qt的经验非常有限,但我相信我有正确的方法。

请帮忙!

我已经在Ubuntu上测试了你的代码。不幸的是,我不能对windows发表评论。我稍微修改了代码(参见//@w:):

#include "displaywidget.h"
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();
}
DisplayWidget::~DisplayWidget()
{
}
void DisplayWidget::CreateWidgets()
{
    bImage = new QImage(w, h, QImage::Format_ARGB32);
    dImage = new QImage(w, h, QImage::Format_ARGB32);
    bimageLabel = new QLabel(this);
    bimageLabel->setScaledContents(true);
    dimageLabel = new QLabel(this);
    dimageLabel->setScaledContents(true);
    debugButton = new QPushButton("DEBUG", this);
    bimageLabel->setStyleSheet("QLabel {background-color: black};");
    dimageLabel->setStyleSheet("QLabel {background-color: grey};");
    frameGrab = new QTimer(this);
}
void DisplayWidget::SetupGui()
{
    //@w: Adding vertical layout as button below seems like better usage of space...
    QVBoxLayout * vlay = new QVBoxLayout();
    QHBoxLayout * hlay = new QHBoxLayout();
    hlay->addWidget(bimageLabel);
    hlay->addWidget(dimageLabel);
    vlay->addLayout(hlay);
    vlay->addWidget(debugButton);
    //@w: Removing size constraints on top layout allows me to resize window and see effect.
    vlay->setSizeConstraint(QLayout::SetNoConstraint);
    setLayout(vlay); // commenting this line out makes it refresh
    connect(frameGrab, SIGNAL(timeout()),this, SLOT(GenerateNewData()));
    //@w: I suppose we can chuck the button.... Currently it serves no purpose
    connect(debugButton, SIGNAL(clicked()), this, SLOT(GenerateNewData()));
    //@w: Timer slower initially, then increase to see where performance degrades.
    frameGrab->start(200);
}
void DisplayWidget::GenerateNewData()
{
    QRgb * bImageData = (QRgb *)bImage->scanLine(0);
    QRgb * dImageData = (QRgb *)dImage->scanLine(0);
    //@w: This code just varies the contents by having a b and d selector that
    //    alternates colour... Simple stuff...
    int bSelect = rand() % 3,
        dSelect = (bSelect==2) ? 0 : bSelect+1;
    for (int i = 0; i < w * h; i++)
    {
        //@w: 3 colours, only two being selected - can be improved, I suppose.
        QRgb rgb[3] =
        {
          (bSelect == 0) || (dSelect==0) ? qRgba(rand() % FULLSCALE, 0, 0, FULLSCALE) : 0,
          (bSelect == 1) || (dSelect==1) ? qRgba(0, rand() % FULLSCALE, 0, FULLSCALE) : 0,
          (bSelect == 2) || (dSelect==2) ? qRgba(0, 0, rand() % FULLSCALE, FULLSCALE) : 0,
        };
        bImageData[i] = rgb[bSelect];
        dImageData[i] = rgb[dSelect];
    }
    //@w: Removed scaling, as it depends on layout...
    bimageLabel->setPixmap(QPixmap::fromImage(*bImage));
    dimageLabel->setPixmap(QPixmap::fromImage(*dImage));
}

最初,标签从像素图中获取其大小。然后,标签遵循布局,布局遵循表单(主/父部件)的大小调整

QtForum为我解决了这个问题,天哪,这太尴尬了。

我忘了初始化循环计数器。固定的一切。