Qt5:如何解决这个问题。自定义QWidget与自定义paintEvent()与QWidget move()函数

时间:2017-08-20 08:58:35

标签: c++ qt position qwidget paintevent

首先发布在这里,我也需要它来帮助别人。

我刚接触QT / c ++,但由于多年的业余爱好,我的进步相对较快。

我正在尝试通过制作游戏来学习它,所以,除了其他东西之外,我还制作了一个继承自QWidget的自定义精灵类。 作为一种常见的做法,我重新实现了paintEvent函数,使用一些技巧,qpixmap / qpainter,json文件,spritesheets,我自己编写的代码,以成功播放动画,如空闲/行走/攻击等姿势。

一切都很完美,直到我试图在QWidget中通过函数move(int x,int y)行走时移动它。

我认为问题在于,每次调用“move”函数时,它都会通过再次调用paintEvent函数,切换动画,生成多个问题等来更新/刷新/重新绘制QWidget。

我无法弄清楚如何移动它而不重新绘制或等待动画完成,或者我缺少什么。似乎没有其他方法可以移动QWidget。 我相信问题在于另一个被发射信号调用的事件函数,可能是moveEvent,但我重新实现它保持空,结果是相同的。

你知道吗?我应该以另一种方式重新制作它以避免这种麻烦吗?还是这么简单,因为我看不到与我相反的硬币?

如果需要,请求代码。 非常感谢Luna。

编辑1:

customsprite::customsprite(QWidget *parent, QString spriteName) : QWidget(parent)
{
// qpm is a QPixmap
qpm_idle.load(":/Assets/sprites/" + spriteName + ".png");
qpm_walk.load(":/Assets/sprites/" + spriteName + "_walk.png");
... 
// here goes a custom class to load json files for each sprite sheet
// the json contains x,y,h,w info to draw the animation
...
//some int,bools,qstrings
...
// fps is QTimer
fps.setInterval(33);
connect(&fps,SIGNAL(timeout()),this,SLOT(update()));
fps.start();
}


//the paintEvent:
void customsprite::paintEvent(QPaintEvent *){
//
QPainter qp(this);
QRect targetR(xMove,0,spriteW,spriteH);
QRect sourceR(jhV[status].getFrameX(jhV[status].namesV[spriteFg]),0,spriteW*sizeDivisor,spriteH*sizeDivisor);
// things abouts consulting jsonhelper info
switch (status){ // status is to know if should draw idle or walk animation
case 0:
    qp.drawPixmap(targetR,qpm_idle,sourceR);
    break;
case 1:
    xMove = xMove + 1;
    targetR = QRect(xMove,0,spriteW,spriteH);
    qp.drawPixmap(targetR,qpm_walk,sourceR);
    break;
default:
    break;
}


// all this works fine
if(!reversingAnimation && shouldAnimate){ // simple bool options
    spriteFg++; // an int counter refering to which frame should be drawed
    if(spriteFg == jhV[status].getSSSize()){ // this consults the json files by a custom jsonhelper, it works fine
        if(reversible){
            reversingAnimation = true;
            spriteFg = jhV[status].getSSSize() - 1;
        }else if(!reversible){
            spriteFg = 0;
            emitSignals();

            if(animateOnce == true){
                shouldAnimate = false;
            }
        }

    }
}
//here goes a similar the above code to to handle the animation playing in reverse, nothing important
}

然后在我的通用QMainWindow中,我添加了一个我的Customsprite类的实例,将其父级设置为QMainWindow,它出现,播放动画。 问题是当我尝试使用时:

//cs is customsprite
cs->move(cs->x()+1,cs->Y());

它会移动,但会多次中断动画。 我也尝试在paintEvent中添加一个“isWalking”bool过滤器,但它是一样的。

编辑2: 那里的“xMove”是一个用来成功平滑地移动动画的技巧,但它需要增加QWidget的宽度才能被看到。 不是一个好的解决方案。

0 个答案:

没有答案