2

この質問は、誰かが独自のクラスでスレッドをオーバーロードしているときに何らかの形で回答されているようですが、QThread クラスを拡張せずに QTimer クラスを使用しようとするとどうなりますか。QTimer for QT を使用しようとしています。彼らの簡単な例

http://qt-project.org/doc/qt-4.7/qtimer.html

その例は次のとおりです。

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

しかし、これを試みると、エラーが発生し続けます。

QObject::startTimer: タイマーは、QThread で開始されたスレッドでのみ使用できます。

私は、Jamie King による YouTube のゲーム エンジン開発シリーズの一連のビデオに取り組んでいます。私は彼のビデオを最後まで追うつもりなので、現時点ではまったく異なるコーディング手法を抽象化することは好まれません。これは私がこれまでに持っているものです。

コードをできるだけシンプルに保つために、小さな簡単なサイド プロジェクトを作成しようとしました。ビルド エラーはありません。プログラムが開始された後にのみ発生します。

QTimerApp.cpp

#include <QtWidgets\qapplication.h>
#include <QtWidgets\qwidget.h>
#include "GLWin.h"

int main(int argc, char* argv[])
{
    QApplication application(argc, argv);
    GLWin MyGL;
    MyGL.show();

    return application.exec();

}

GLWin.h

#ifndef My_GL_Window
#define My_GL_Window
#include <QtOpenGL\qglwidget>
#include <QtCore\qtimer.h>

class GLWin : public QGLWidget
{




    Q_OBJECT            // preprocessor from QT - gives what we need for slots
        // Declaration* - should be in class. Declared in class, but not defined.
        // Needs to be defined in .cpp (manually)
        // Or allow QT to define for us. (preferred)
        // use moc.exe (found in $(ProjectDir)..\Middleware\Qt\bin\moc.exe against myGLWindow.h
        // C:\MyEngine\ProgramFiles\Middleware\Qt\bin\moc.exe myGLWindow.h > MyGLWindow_moc.cpp 
        // then include MyGLWindow_moc.cpp in project


    GLuint vertexBufferID;
    QTimer myTimer;

protected:
    void initializeGL();
    void paintGL();

    private slots:              //All classes that contain signals or slots must mention Q_OBJECT at the top of their declaration.
    // They must also derive (directly or indirectly) from QObject.

private:
    void updateWin();
};

#endif

GLWin.cpp

#include <gl\glew.h>
#include "GLWin.h"
#include <cassert>
#include <QTCore\QTimer.h>

void GLWin::initializeGL()
{

    GLenum errorCode = glewInit();
    assert(errorCode == 0);

    glGenBuffers(1, &vertexBufferID);
    glBindBuffer(GL_ARRAY_BUFFER, vertexBufferID);

    float verts[] =
    {
        +0.0f, +0.1f,
        -0.1f, -0.1f,
        +0.1f, -0.1f,
    };

    glBufferData(GL_ARRAY_BUFFER, sizeof(verts), verts, GL_STATIC_DRAW);



    QTimer* timer = new QTimer(0);
    connect(timer, SIGNAL(timeout()), this, SLOT(updateWin()));
    timer->start();

}

void GLWin::paintGL()
{
    glClear(GL_COLOR_BUFFER_BIT);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0);  
    glDrawArrays(GL_TRIANGLES, 0, 3);   
}

void GLWin::updateWin()
{
}

私が思いついた研究のほとんどは、クラスが QThread を拡張したときに run() 関数をオーバーロードすることに関係しています。私が知る限り、単純なタイマー ループが発生するために別のクラスを拡張したり作成したりする必要はありません。すでに QWidget を拡張しているので、私のオブジェクトはすでに QObject タイプです。

どんな支援も本当に感謝しています。ありがとうございました!

4

2 に答える 2

3

あなたのコードには多くの問題があります:

  • QtFoo\スタイルが含まれます。スラッシュを使用するのが一般的な方法であるため、スラッシュを使用することをお勧めします。

  • 実際には明示的に使用する必要はありませんQtFoo。また、ビルドシステムの信頼性が向上し、プロジェクトの移植性が向上するため、より優れています。

  • Q_DECL_FINAL最終クラスに最適化を使用しません。

  • Q_DECL_OVERRIDEオーバーライドされたメンバー メソッドには使用しません。

  • 実際にスロットをスロットとしてマークしません。

  • タイマーの親を設定しないため、メモリ リークが発生します。

  • cassertQt に独自のQ_ASSERTandがある場合に使用しQ_ASSERT_Xます。

  • qfoo.hスタイル インクルードを使用しますQFooが、一般的な使用パターンは です。

  • 新しいシグナルスロット構文を利用しません。

これは私にとっての作業バージョンです:

main.cpp

#include <glew.h>

#include <QApplication>
#include <QGLWidget>
#include <QTimer>

class GLWin Q_DECL_FINAL : public QGLWidget
{
    Q_OBJECT
    GLuint vertexBufferID;
    QTimer myTimer;

protected:
    void initializeGL() Q_DECL_OVERRIDE
    {
        GLenum errorCode = glewInit();
        Q_ASSERT(errorCode == 0);

        glGenBuffers(1, &vertexBufferID);
        glBindBuffer(GL_ARRAY_BUFFER, vertexBufferID);

        float verts[] =
        {
            0.0f, 0.1f,
            -0.1f, -0.1f,
            0.1f, -0.1f,
        };

        glBufferData(GL_ARRAY_BUFFER, sizeof(verts), verts, GL_STATIC_DRAW);

        QTimer* timer = new QTimer(this);
        connect(timer, &QTimer::timeout, this, &GLWin::updateWin);
        timer->start();
    }

    void paintGL() Q_DECL_OVERRIDE
    {
        glClear(GL_COLOR_BUFFER_BIT);
        glEnableVertexAttribArray(0);
        glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0);  
        glDrawArrays(GL_TRIANGLES, 0, 3);   
    }
private slots:
    void updateWin() {}
};

#include "main.moc"

int main(int argc, char **argv)
{
    QApplication application(argc, argv);
    GLWin MyGL;
    MyGL.show();
    return application.exec();
}

main.pro

TEMPLATE = app
TARGET = main
QT += widgets opengl
SOURCES += main.cpp
packagesExist(glew) {
    CONFIG += link_pkgconfig
    PKGCONFIG += glew
}

ビルドして実行

qmake && make && ./main
于 2014-12-29T06:56:26.747 に答える