代码之家  ›  专栏  ›  技术社区  ›  Ron Warholic

Qt中的GLWidget仅在mousemove上更新

  •  0
  • Ron Warholic  · 技术社区  · 17 年前

    我目前正在玩Qt,试图建立一个小粒子系统。在这里,我对GLWidget进行了子类化并对其进行了黑客攻击。一切都进行得很顺利,直到我做了一些未知的更改,现在小部件只在我移动鼠标时重新绘制(由于我触发了QTimer,它应该一直在这样做)。相关代码:

    class OpenGLWidget :  public QGLWidget  {
    
       Q_OBJECT
    
    public:
       OpenGLWidget(QWidget * parent = 0);
       ~OpenGLWidget();
    
    public slots:
       void toggleEmitter();
    
    protected:
       void initializeGL();
       void paintGL();
       void resizeGL(int width, int height);
       QSize minimumSizeHint() const;
       QSize sizeHint() const;
       void mousePressEvent(QMouseEvent *event);
       void mouseMoveEvent(QMouseEvent *event);
    
    protected slots:
       void timeOut();
    
    private:
    
       void testFunc(Particle & p, unsigned int t);
    
       QTime time;
       QTimer timer;
    
       Emitter emitter;
    

    来自.cpp的相关代码

    // in the constructor
    time.start();
    connect(&timer, SIGNAL(timeout()), this, SLOT(timeOut()));
    timer.start(0);
    
    void OpenGLWidget::initializeGL()  {
       GLuint tex = 0;
    
       qglClearColor(bgColor);
       glEnable(GL_DEPTH_TEST);   
       glClearDepth(1.0f);
        glDepthFunc(GL_LEQUAL);
       glShadeModel(GL_SMOOTH); 
    
       glDisable(GL_CULL_FACE);
       glEnable(GL_TEXTURE_2D); 
       glEnable( GL_BLEND );
       glBlendFunc( GL_SRC_ALPHA, GL_ONE); // _MINUS_SRC_ALPHA );
    
       glPointSize(3.0f);
    
       tex = bindTexture(QPixmap(QString("testparticle2.png")), GL_TEXTURE_2D);
       emitter = Emitter(Vector(0, 0, 0.0f), tex, 50, fastdelegate::FastDelegate2<Particle &, unsigned int>(this, &OpenGLWidget::testFunc));
    }
    
    void OpenGLWidget::paintGL()  {
       makeCurrent();
       glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    
       mainCam.SetView();
    
       glRotatef(xRot, 1, 0, 0);
       glRotatef(yRot, 0, 1, 0);
    
       emitter.Process(time.elapsed());
    
       totalTime += time.elapsed();
       time.restart();
    
    }
    
    void OpenGLWidget::resizeGL(int width, int height)  {
       contextWidth = width;
       contextHeight = height;
    
       glViewport(0, 0, width, height);
    
       glMatrixMode(GL_PROJECTION);
       glLoadIdentity();
       gluPerspective(55.0f, width / (float) height, 0.01f, 100.0f);
    
       glMatrixMode(GL_MODELVIEW);
       glLoadIdentity();
    
    }
    
    void OpenGLWidget::timeOut()  {
       updateGL();
    }
    
    void OpenGLWidget::mousePressEvent(QMouseEvent *event)  {
        lastX = event->pos().x();
        lastY = event->pos().y();
    }
    
    void OpenGLWidget::mouseMoveEvent(QMouseEvent *event)  {
        int dx = event->x() - lastX;
        int dy = event->y() - lastY;
    
        if (event->buttons() & Qt::LeftButton) {
            xRot += 3 * dy;
            yRot += 3 * dx;
        } else if (event->buttons() & Qt::RightButton) {
            xRot += 3 * dy;
            yRot += 3 * dx;
        }
    
        lastX = event->pos().x();
        lastY = event->pos().y();
    
    }
    
    3 回复  |  直到 13 年前
        1
  •  1
  •   gbjbaanb    17 年前

    考虑到updateGL()调用了glDraw(),而glDraw()调用了paintGL(),您可能认为计时器应该调用与mousemove事件相同的功能。

    你确定计时器真的在滴答作响吗?

    paintGL() .

    编辑:添加额外信息后:

    QTimer says

    超时0在所有 窗口系统事件中的事件

    因此,如果您希望它运行得尽可能快(尽管在Windows和大多数基于x386的系统上,10ms可能是最小值),那么请使用值1而不是0启动计时器。我认为这就是问题所在,它只有在有时间的时候才会滴答作响 完成 正在从队列中读取消息。

        2
  •  1
  •   Ariya Hidayat    17 年前

    processEvents() 在更新循环中,确保处理来自QTimer的挂起计时器事件。

        3
  •  1
  •   DaveShaw Thishin    14 年前