【发布时间】:2015-06-08 21:18:00
【问题描述】:
我已经在这个问题上停留了 2 天。我在Window 7-64 bit 上为Visual Studio 2013 使用Qt 插件。
我一直在尝试在QLabels 中显示一对图像。我需要定期操作像素数据,所以我将它们存储在QImages 中,每次我想刷新显示时我设置QPixmap 的QLabel。问题是,如果我以某种方式更改/移动窗口,它似乎只会刷新。
如果我只是将QLabels 设为我的QWidget 的子级,但从不设置布局,这个问题就会消失。如果我再添加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 的经验非常有限,但我相信我的方法是正确的。
请帮忙!
【问题讨论】:
-
我怀疑这与您的布局和尺寸提示有关。详情参考此帖stackoverflow.com/questions/10758267/…
-
感谢您的回复。我认为我无法准确找出您认为可能存在的问题。当您移动/调整大小/单击小部件上的按钮时,通常会调用哪些函数?更新几何似乎并没有改变任何东西。
-
我没有给你答案,因为我最近没有使用Qt,但我怀疑再次调用setPixmap后布局的大小没有改变。您可以创建一个派生标签,在更新后返回正确的大小提示。您甚至可以将图像缓存在(派生的)标签中
-
也许我现在很愚蠢,但我希望在图像大小保持不变的情况下刷新图像像素。 sizehint 什么时候改变?
-
我已经在 Ubuntu 上测试了代码。我修改了样式以使用灰色和黑色,只是为了更好地查看标签。我已经删除了计时器,以免干扰您的调试按钮。布局按预期工作。它水平布置按钮和标签。是否调用更新没有区别(因为更改标签上的像素图会导致更新)。按下按钮时,图像会更新,大小会按比例缩放,因此按预期保持不变。不确定你期待什么行为......
标签: c++ qt refresh qpixmap qlabel