首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 移动开发 > QT开发 >

QPainter:begin: Widget painting can only begin as a result of a paintEvent,该怎么解决

2013-04-21 
QPainter::begin: Widget painting can only begin as a result of a paintEvent想把摄像头采集的数据放到

QPainter::begin: Widget painting can only begin as a result of a paintEvent
想把摄像头采集的数据放到QT上面显示!摄像头可以显示,但是总会出现这个错误,网上说要增加Qwidget的属性,但是不知道怎么加!!代码如下,希望大神指教一下

#include <QtGui>
#include "processImage.h"
#include "videodevice.h"
extern "C"
{
#include <stdio.h>
#include <stdlib.h>
}
ProcessImage::ProcessImage(QWidget *parent):QWidget(parent)
{
   //this->setAttribute(Qt::WA_PaintOutsidePaintEvent); 
   pp = (unsigned char *)malloc(320 * 240/*QWidget::width()*QWidget::height()*/* 3 * sizeof(char));
    painter = new QPainter(this); 
   frame = new QImage(pp,320,240,QImage::Format_RGB888);
   //frame = new QPixmap(640,240);
    label = new QLabel();
    vd = new VideoDevice(tr("/dev/video0"));

    connect(vd, SIGNAL(display_error(QString)), this,SLOT(display_error(QString)));
    rs = vd->open_device();
    if(-1==rs)
    {
        QMessageBox::warning(this,tr("error"),tr("open /dev/dsp error"),QMessageBox::Yes);
        vd->close_device();
    }

    rs = vd->init_device();
    if(-1==rs)
    {
        QMessageBox::warning(this,tr("error"),tr("init failed"),QMessageBox::Yes);
        vd->close_device();
    }

    rs = vd->start_capturing();
    if(-1==rs)
    {
        QMessageBox::warning(this,tr("error"),tr("start capture failed"),QMessageBox::Yes);
        vd->close_device();
    }

    if(-1==rs)
    {
        QMessageBox::warning(this,tr("error"),tr("get frame failed"),QMessageBox::Yes);
        vd->stop_capturing();
    }

    timer = new QTimer(this);
    connect(timer,SIGNAL(timeout()),this,SLOT(update()));
    timer->start(30);

    QHBoxLayout *hLayout = new QHBoxLayout();
    hLayout->addWidget(label);
    setLayout(hLayout);
    setWindowTitle(tr("Capture"));
}

ProcessImage::~ProcessImage()
{
    rs = vd->stop_capturing();
    rs = vd->uninit_device();
    rs = vd->close_device();
}

void ProcessImage::paintEvent(QPaintEvent *)
{
    rs = vd->get_frame((void **)&p,&len);
    convert_yuv_to_rgb_buffer(p,pp,320,240/*QWidget::width(),QWidget::height()*/);
     frame->loadFromData((uchar *)p,/*len*/320 * 240 * 3 * sizeof(char));

//    painter->begin(this);
//    painter->drawImage(0,0,*frame);
//    painter->end();


//    rs = vd->unget_frame();
   // frame->load("./img3.jpg");
   // label->setAttribute(Qt::WA_PaintOutsidePaintEvent); 
    label->setPixmap(QPixmap::fromImage(*frame,Qt::AutoColor));
   // label->show();
    rs = vd->unget_frame();
   // label->drawFrame();
}

void ProcessImage::display_error(QString err)
{
    QMessageBox::warning(this,tr("error"), err,QMessageBox::Yes);
}

/*yuv格式转换为rgb格式*/
int ProcessImage::convert_yuv_to_rgb_buffer(unsigned char *yuv, unsigned char *rgb, unsigned int width, unsigned int height)
{
 unsigned int in, out = 0;
 unsigned int pixel_16;
 unsigned char pixel_24[3];
 unsigned int pixel32;
 int y0, u, y1, v;
 for(in = 0; in < width * height * 2; in += 4) {
  pixel_16 =
   yuv[in + 3] << 24 |
   yuv[in + 2] << 16 |
   yuv[in + 1] <<  8 |
   yuv[in + 0];
  y0 = (pixel_16 & 0x000000ff);
  u  = (pixel_16 & 0x0000ff00) >>  8;
  y1 = (pixel_16 & 0x00ff0000) >> 16;
  v  = (pixel_16 & 0xff000000) >> 24;
  pixel32 = convert_yuv_to_rgb_pixel(y0, u, v);
  pixel_24[0] = (pixel32 & 0x000000ff);
  pixel_24[1] = (pixel32 & 0x0000ff00) >> 8;
  pixel_24[2] = (pixel32 & 0x00ff0000) >> 16;
  rgb[out++] = pixel_24[0];
  rgb[out++] = pixel_24[1];
  rgb[out++] = pixel_24[2];
  pixel32 = convert_yuv_to_rgb_pixel(y1, u, v);
  pixel_24[0] = (pixel32 & 0x000000ff);
  pixel_24[1] = (pixel32 & 0x0000ff00) >> 8;
  pixel_24[2] = (pixel32 & 0x00ff0000) >> 16;
  rgb[out++] = pixel_24[0];
  rgb[out++] = pixel_24[1];
  rgb[out++] = pixel_24[2];
 }
 return 0;
}

int ProcessImage::convert_yuv_to_rgb_pixel(int y, int u, int v)
{
 unsigned int pixel32 = 0;
 unsigned char *pixel = (unsigned char *)&pixel32;
 int r, g, b;
 r = y + (1.370705 * (v-128));
 g = y - (0.698001 * (v-128)) - (0.337633 * (u-128));
 b = y + (1.732446 * (u-128));
 if(r > 255) r = 255;
 if(g > 255) g = 255;
 if(b > 255) b = 255;
 if(r < 0) r = 0;
 if(g < 0) g = 0;
 if(b < 0) b = 0;
 pixel[0] = r * 220 / 256;
 pixel[1] = g * 220 / 256;


 pixel[2] = b * 220 / 256;
 return pixel32;
}
/*yu qt
[解决办法]
默认情况下要使用QPainter画图必须在在paintEvent()函数里,如果在其它地方的话,运行时会提示如下错误

QPainter::begin: Widget painting can only begin as a result of a paintEvent

要避免这个问题可以设置你要画图的那个widget的一个属性,加上类似这样的代码this->setAttribute(Qt::WA_PaintOutsidePaintEvent);就可以了。

painter = new QPainter(this); 你的这一句有什么用?去掉也可以吧
[解决办法]
setAttribute(Qt::WA_PaintOutsidePaintEvent)这个属性是有限制的,下面是帮助原文。
Makes it possible to use QPainter to paint on the widget outside paintEvent(). This flag is not supported on Windows, Mac OS X or Embedded Linux. We recommend that you use it only when porting Qt 3 code to Qt 4.

热点排行