当有人用自己的类重载一个线程时,似乎已经以某种形式回答了这个问题,但是如果只是尝试使用QTimer类而不扩展QThread类呢。我正在尝试使用QTimer进行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开头的线程。
我正在通过他的游戏引擎开发系列在YouTube上浏览Jamie King的视频集。我计划将他的视频放到发球台上,所以目前不需要任何抽象的完全不同的编码技术。这就是我到目前为止所拥有的。
我尝试制作一个小型的快速项目来保持代码尽可能简单。我没有任何构建错误 - 它们只在程序开始后才会出现
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类型了。
真正感谢任何帮助。谢谢!
答案 0 :(得分:3)
您的代码有很多问题:
QtFoo\
样式包括。你最好使用正斜杠,因为这是使用它的常用方法。
您实际上并不需要明确使用QtFoo
,它也更好,因为它使构建系统更可靠,项目更具可移植性。
您的最终课程不使用Q_DECL_FINAL
优化。
您不会将Q_DECL_OVERRIDE
用于重写的成员方法。
您实际上并未将广告位标记为广告位。
您没有为计时器设置父级,因此会泄漏内存。
当Qt拥有自己的cassert
和Q_ASSERT
时,您使用Q_ASSERT_X
。
您使用qfoo.h
样式包含,而QFoo
是常用用法模式。
您没有使用新的信号槽语法。
这是我的工作版本:
#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();
}
TEMPLATE = app
TARGET = main
QT += widgets opengl
SOURCES += main.cpp
packagesExist(glew) {
CONFIG += link_pkgconfig
PKGCONFIG += glew
}
qmake && make && ./main
答案 1 :(得分:-2)
哇。傻傻的,我终于找到答案了很长时间。
...在调试模式下,确保您链接的所有.lib和.dll都是调试器,而不是发行版.dll。
...即,我正在使用
Qt5OpenGL.dll和Qt5OpenGL.lib
而不是 Qt5OpenGLd.dll和Qt5OpenGLd.lib......我觉得自己很傻,但这永远不会再抓住我了。只是盲目地选择“哦嘿..我看到Qt5Open ......”足够好!只需确保检查所有文件,而不仅仅是那两个文件。
/捂脸!