• 7447阅读
  • 3回复

Qt4精彩实例分析中 实例36 有bug [复制链接]

上一主题 下一主题
离线kanyou222
 
只看楼主 倒序阅读 楼主  发表于: 2011-05-02
Qt精彩实例分析中,一个简单的画图工具 这个例子有一个bug,只能绘出一个点。为什么呢?
函数void DrawWidget::mouseMoveEvent(QMouseEvent *event)中少了 painter.end(); painter.end()的功能是调用distructor , 释放所有画图中用到的资源(Any resources used while painting are released. You don't normally need to call this since it is called by the destructor.),这样继续移动鼠标才会画出图来。




void DrawWidget::mouseMoveEvent(QMouseEvent * e)
{
    QPainter *painter = new QPainter(pix);   // 这里创建的对象 它不是在函数内创建的吗,出了这个函数它还存在啊?
                                                                  // 用new 创建的对象,出了这个函数它还会存在是吧? 但那个painter指针
                                                         // 应该不存在了吧, 那么再次进入这个函数时,new 会不会又创建一个新对象
                                                         //那这样怎么理解 上面解释 “它占用资源 ,要用end()来释放资源” 这句话?
    QPen pen;
    pen.setStyle((Qt::PenStyle)style);          
    pen.setWidth(weight);
    pen.setColor(color);
    painter->setPen(pen);
    
    painter->drawLine(startPos,e->pos());
    startPos = e->pos();
    update();
  painter->end();      //这里要加上这句才行
}


void DrawWidget::paintEvent(QPaintEvent *)
{
    QPainter painter(this);
    painter.drawPixmap(QPoint(0,0),*pix);
}




void DrawWidget::resizeEvent(QResizeEvent * event)
{
    if(height() > pix->height() || width() > pix->width())
    {
        QPixmap *newPix = new QPixmap(size());
        newPix->fill(Qt::white);
        QPainter p(newPix);
        p.drawPixmap(QPoint(0,0),*pix);
        pix = newPix;
                                 // 那为什么这里不加newPix ->end()
//这个和上面的不是一样吗,它也是用new 来创建对象的,每次改变窗体大小时,
// 都会调用这个函数,那不是重复创建这个对了吗,而每次创建这个QPixmap的对象,它都没有释放?
    }
    QWidget::resizeEvent(event);
}




void DrawWidget::clear()
{
    QPixmap *clearPix = new QPixmap(size());
    clearPix->fill(Qt::white);
    pix = clearPix;
    update();
}

[ 此帖被kanyou222在2011-05-02 14:20重新编辑 ]
离线dbzhang800

只看该作者 1楼 发表于: 2011-05-02
没看过这本书,不过看你了的描述,如果代码果真如此的话,建议这种书最好还是不要继续看了^_^

你发现了出问题的地方。但你的解决方法还是不太对。问题出在:通过 new 创建的东西,使用完毕后,它没有调用 delete进行删除。

1. painter 那一个,你应该调用 delete painter; 而不是简单的 end。
2. 至于 pix = clearPix; 这一个,赋值前应该先 delete 掉原来的。

题外: 其实这种情况下,根本就不用用 new ,直接分配到栈上就行了。

如果要用堆而不是栈,可以看看:
http://blog.csdn.net/dbzhang800/archive/2011/04/03/6300025.aspx
离线kanyou222
只看该作者 2楼 发表于: 2011-05-04
回 1楼(dbzhang800) 的帖子
谢谢你的回答,有点懂了
离线luofuchong
只看该作者 3楼 发表于: 2013-02-17
我是这么改的,供参考:
void DrawWidget::mouseMoveEvent(QMouseEvent * e)
{
    QPainter *painter = new QPainter(pix);
    QPen pen;
    pen.setStyle((Qt::PenStyle)style);
    pen.setWidth(weight);
    pen.setColor(color);
    painter->setPen(pen);

    painter->drawLine(startPos,e->pos());
    startPos = e->pos();
    update();
   delete painter;
}
void DrawWidget::resizeEvent(QResizeEvent * event)
{
    if(height() > pix->height() || width() > pix->width())
    {
        QPixmap *newPix = new QPixmap(size());
        newPix->fill(Qt::white);
        QPainter p(newPix);
        p.drawPixmap(QPoint(0,0),*pix);
       delete pix;
        pix = newPix;
    }
    QWidget::resizeEvent(event);
}
void DrawWidget::clear()
{
    delete pix;
    QPixmap *clearPix = new QPixmap(size());
    clearPix->fill(Qt::white);
    pix = clearPix;
    update();
}





快速回复
限100 字节
 
上一个 下一个