connect(定时器,SIGNAL(timeout()...)函数未被调用

时间:2016-02-06 23:56:50

标签: qt timer

对于一个类,我们获得了使用GLUT和OpenGL可视化烟雾的代码。我想在https://stackoverflow.com/a/17794523/651779之后将此转换为QT以及此处的示例:http://www.bogotobogo.com/Qt/Qt5_OpenGL_QGLWidget.php。它现在绘制小部件,但OpenGL部分不能按预期工作(见下图,应该是黑屏,当鼠标移过它时会改变)。编译代码不会给我任何警告或错误。

使用断点我可以看到它永远不会转到do_one_simulation_step(),因此事件队列可能永远不会为空,因此来自QObject::connect(timer,SIGNAL(timeout()),this,SLOT(do_one_simulation_step()));的槽不会被调用?我的代码放在下面。  enter image description here

myglwidget.h

#ifndef MYGLWIDGET_H
#define MYGLWIDGET_H

#include <QGLWidget>
#include <QTimer>
#include <rfftw.h>            

class MyGLWidget : public QGLWidget
{
    Q_OBJECT
public:
    explicit MyGLWidget(QWidget *parent = 0);
    ~MyGLWidget();
signals:

public slots:
    void do_one_simulation_step();

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);

public slots:

signals:

private:
    void visualize();
    QBasicTimer timer;
    int   winWidth, winHeight;      
    int   color_dir;           
    float vec_scale;            
    int   draw_smoke;          
    int   draw_vecs;            
    static const int COLOR_BLACKWHITE=0;   
    mapping: black-and-white, rainbow, banded
    static const int COLOR_RAINBOW=1;
    static const int COLOR_BANDS=2;
    int   scalar_col;           
    QPoint lastPos;
};

#endif // MYGLWIDGET_H

myglwidget.cpp

// myglwidget.cpp

#include <QtWidgets>
#include <QtOpenGL>
#include <GLUT/glut.h>         
#include "myglwidget.h"
#include "visualization.cpp"
#include <simulation.cpp>              

MyGLWidget::MyGLWidget(QWidget *parent)
    : QGLWidget(QGLFormat(QGL::SampleBuffers), parent)
{
    int   winWidth, winHeight;      
    int   color_dir = 0;            
    float vec_scale = 1000;         
    int   draw_smoke = 0;         
    int   draw_vecs = 1;           
    int   scalar_col = 0;          
    simulation.init_simulation(simulation.DIM);
    QTimer *timer = new QTimer;
    QObject::connect(timer,SIGNAL(timeout()),this,SLOT(do_one_simulation_step()));
}

MyGLWidget::~MyGLWidget()
{
}

QSize MyGLWidget::minimumSizeHint() const
{
    return QSize(50, 50);
}

QSize MyGLWidget::sizeHint() const
{
    return QSize(400, 400);
}

void MyGLWidget::initializeGL()
{
QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();
f->glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
}

void MyGLWidget::paintGL()
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    visualize();
    glFlush();
    swapBuffers();
}

//display: Handle window redrawing events. Simply delegates to draw().
void MyGLWidget::resizeGL(int width, int height)
{
    glViewport(0.0f, 0.0f, (GLfloat)width, (GLfloat)height);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluOrtho2D(0.0, (GLdouble)width, 0.0, (GLdouble)height);
    winWidth = width; winHeight = height;
}

void MyGLWidget::mousePressEvent(QMouseEvent *event)
{
    lastPos = event->pos();
}

void MyGLWidget::mouseMoveEvent(QMouseEvent *event)
{
    int mx = event->x() - lastPos.x();
    int my = event->y() - lastPos.y();

    int xi,yi,X,Y; double  dx, dy, len;
    static int lmx=0,lmy=0; 

    xi = (int)simulation.clamp((double)(simulation.DIM + 1) * ((double)mx / (double)winWidth));
    yi = (int)simulation.clamp((double)(simulation.DIM + 1) * ((double)(winHeight - my) / (double)winHeight));

    X = xi; Y = yi;

    if (X > (simulation.DIM - 1))  X = simulation.DIM - 1; if (Y > (simulation.DIM - 1))  Y = simulation.DIM - 1;
    if (X < 0) X = 0; if (Y < 0) Y = 0;

    // Add force at the cursor location
    my = winHeight - my;
    dx = mx - lmx; dy = my - lmy;
    len = sqrt(dx * dx + dy * dy);
    if (len != 0.0) {  dx *= 0.1 / len; dy *= 0.1 / len; }
    simulation.get_fx()[Y * simulation.DIM + X] += dx;
    simulation.get_fy()[Y * simulation.DIM + X] += dy;
    simulation.get_rho()[Y * simulation.DIM + X] = 10.0f;
    lmx = mx; lmy = my;
    lastPos = event->pos();
}

void MyGLWidget::visualize()
{

    int        i, j, idx, idx0, idx1, idx2, idx3; double px0,py0,px1,py1,px2,py2,px3,py3;
    fftw_real  wn = (fftw_real)winWidth / (fftw_real)(simulation.DIM + 1);   // Grid cell width
    fftw_real  hn = (fftw_real)winHeight / (fftw_real)(simulation.DIM + 1);  // Grid cell heigh

    if (draw_smoke)
    {
    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
    glBegin(GL_TRIANGLES);
    for (j = 0; j < simulation.DIM - 1; j++)            //draw smoke
    {
        for (i = 0; i < simulation.DIM - 1; i++)
        {
            px0  = wn + (fftw_real)i * wn;
            py0  = hn + (fftw_real)j * hn;
            idx0 = (j * simulation.DIM) + i;

            px1  = wn + (fftw_real)i * wn;
            py1  = hn + (fftw_real)(j + 1) * hn;
            idx1 = ((j + 1) * simulation.DIM) + i;

            px2  = wn + (fftw_real)(i + 1) * wn;
            py2  = hn + (fftw_real)(j + 1) * hn;
            idx2 = ((j + 1) * simulation.DIM) + (i + 1);

            px3  = wn + (fftw_real)(i + 1) * wn;
            py3  = hn + (fftw_real)j * hn;
            idx3 = (j * simulation.DIM) + (i + 1);

            set_colormap(simulation.get_rho()[idx0]);   glVertex2f(px0, py0);
            set_colormap(simulation.get_rho()[idx1]);   glVertex2f(px1, py1);
            set_colormap(simulation.get_rho()[idx2]);   glVertex2f(px2, py2);

            set_colormap(simulation.get_rho()[idx0]);   glVertex2f(px0, py0);
            set_colormap(simulation.get_rho()[idx2]);   glVertex2f(px2, py2);
            set_colormap(simulation.get_rho()[idx3]);   glVertex2f(px3, py3);
        }
    }
    glEnd();
    }

    if (draw_vecs)
    {
      glBegin(GL_LINES);
      for (i = 0; i < simulation.DIM; i++)
        for (j = 0; j < simulation.DIM; j++)
        {
          idx = (j * simulation.DIM) + i;
          direction_to_color(simulation.get_vx()[idx],simulation.get_vy()[idx],color_dir);
          glVertex2f(wn + (fftw_real)i * wn, hn + (fftw_real)j * hn);
          glVertex2f((wn + (fftw_real)i * wn) + vec_scale * simulation.get_vx()[idx], (hn + (fftw_real)j * hn) + vec_scale * simulation.get_vy()[idx]);
        }
      glEnd();
    }

}

void MyGLWidget::do_one_simulation_step()
{
    if (!simulation.get_frozen())
    {
        simulation.set_forces();
        simulation.solve(simulation.DIM, simulation.get_vx(), simulation.get_vy(), simulation.get_vx0(),
                         simulation.get_vy0(), simulation.get_visc(), simulation.get_dt());
        simulation.diffuse_matter(simulation.DIM, simulation.get_vx(), simulation.get_vy(),
                                 simulation.get_rho(), simulation.get_rho0(), simulation.get_dt());
        updateGL();
    }
}

window.h中

// window.h

#ifndef WINDOW_H
#define WINDOW_H

#include <QWidget>
#include <QSlider>

namespace Ui {
class Window;
}

class Window : public QWidget
{
    Q_OBJECT

public:
    explicit Window(QWidget *parent = 0);
    ~Window();

protected:
    void keyPressEvent(QKeyEvent *event);

private:
    Ui::Window *ui;
};

#endif // WINDOW_H

window.cpp

// window.cpp

#include <QtWidgets>
#include "window.h"
#include "ui_window.h"
#include "myglwidget.h"

Window::Window(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Window)
{
    ui->setupUi(this);
}

Window::~Window()
{
    delete ui;
}

void Window::keyPressEvent(QKeyEvent *e)
{
    if (e->key() == Qt::Key_Escape)
        close();
    else
        QWidget::keyPressEvent(e);
}

window.ui

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
  <class>Window</class>
  <widget class="QWidget" name="Window">
    <property name="geometry">
      <rect>
      <x>0</x>
      <y>0</y>
      <width>600</width>
      <height>638</height>
      </rect>
      </property>
      <property name="windowTitle">
        <string>Window</string>
        </property>
        <layout class="QVBoxLayout" name="verticalLayout">
          <item>
          <widget class="MyGLWidget" name="myGLWidget" native="true">
            <property name="minimumSize">
              <size>
              <width>500</width>
              <height>500</height>
              </size>
              </property>
              </widget>
              </item>
              </layout>
              </widget>
              <layoutdefault spacing="6" margin="11"/>
                <customwidgets>
                <customwidget>
                <class>MyGLWidget</class>
                <extends>QWidget</extends>
                <header>myglwidget.h</header>
                <container>1</container>
                <slots>
                <slot>setXRotation(int)</slot>
                <slot>setYRotation(int)</slot>
                <slot>setZRotation(int)</slot>
                </slots>
                </customwidget>
                </customwidgets>
                <resources/>
                <connections/>
                </ui>

1 个答案:

答案 0 :(得分:1)

  1. 您创建QTimer并将其存储在本地变量(不是类成员)中。
  2. 您无法启动您创建的计时器。