Загрузка файлов в drawBackground (QPainter * Painter, const QRectF &) - PullRequest
1 голос
/ 19 января 2012

в настоящее время я пытаюсь вставить * .obj-файлы в мою программу.Мой код основан на этом примере:

Ускорьте ваши виджеты с помощью OpenGL (измененная ссылка)

Единственное отличие в моем коде, это то, что у меня есть класс glwidget, в котором все чертежи определены.В классе OpenGLScene определяется только мой графический интерфейс.В функции drawBackground (QPainter * painter, const QRectF &) я вызываю функцию paintGL.

void OpenGLScene::drawBackground(QPainter *painter, const QRectF &)
{
    if (painter->paintEngine()->type() != QPaintEngine::OpenGL
    && painter->paintEngine()->type() != QPaintEngine::OpenGL2)
{
    qWarning("OpenGLScene: drawBackground needs a QGLWidget to be set as viewport on the graphics view");
    return;
}

painter->beginNativePainting();

glClearColor(m_backgroundColor.redF(), m_backgroundColor.greenF(), m_backgroundColor.blueF(), 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

if (m_model) {

    m_model->paintGL();
}

painter->endNativePainting();

}

Простое рисование и все работает отлично.У меня только проблемы, пока я не пытаюсь загрузить * .obj-Files.Я пробовал несколько вещей, которые не сработали.Теперь я получил решение определить все функции из класса модели (который вы можете найти в примере) в моем glWidget-классе, а затем вызвать функцию рендеринга в paintGL.После этого вызову paintGL в OpenGLScene.

Здесь вы можете увидеть мои заголовочные файлы: OpenGLScene.h и GLWidget.h:

class GLWidget : public QGLWidget
{
Q_OBJECT
public:
float           m_distance;
GLWidget(const QString &filePath);
GLWidget(QWidget *parent = 0);
~GLWidget();
QSize           minimumSizeHint() const;
QSize           sizeHint() const;
void            initializeGL();
void            paintGL();
void            resizeGL(int width, int height);
void render() const;
QString fileName() const { return m_fileName; }
int faces() const { return m_pointIndices.size() / 3; }
int edges() const { return m_edgeIndices.size() / 2; }
int points() const { return m_points.size(); }
QString m_fileName;
QVector<Point3d> m_points;
QVector<Point3d> m_normals;
QVector<int> m_edgeIndices;
QVector<int> m_pointIndices;
};


#ifndef QT_NO_CONCURRENT
#include <QFutureWatcher>
#endif

class GLWidget;

class OpenGLScene : public QGraphicsScene
{
Q_OBJECT

public:
OpenGLScene();
void drawBackground(QPainter *painter, const QRectF &rect);
QDialog *createDialog(const QString &windowTitle) const;

void setModel(GLWidget *model);

//Model       *m_model;
GLWidget    *m_model;
QColor      m_backgroundColor;
float       m_distance;
QLabel      *m_labels[4];
QWidget     *m_modelButton;
#ifndef QT_NO_CONCURRENT
QFutureWatcher<GLWidget *> m_modelLoader;
#endif
public slots:
void loadModel();
void loadModel(const QString &filePath);
void modelLoaded();
};

К сожалению, эта идея не работает, потому что я получаю эту ошибку:

«Нельзя использовать растровые изображения вне потока GUI»

Но я действительно не понимаю, что это должно означать.

1 Ответ

1 голос
/ 22 января 2012

Если вы переместили все элементы Model в GLWidget, тогда я предполагаю, что вы сейчас создаете свой экземпляр GLWidget в ::loadModel?Если так, то знайте, что это создается в новом потоке.Похоже, что он не перемещается автоматически в основной поток (GUI) после завершения потока загрузки.Что на самом деле происходит с QObject: открытый вопрос .

Если вы хотите полностью отключить многопоточность для упрощения вещей, то удалите строки

#ifndef QT_NO_CONCURRENT
#include <QFutureWatcher>
#endif

и

#ifndef QT_NO_CONCURRENT
QFutureWatcher<Model *> m_modelLoader;
#endif

в openglscene.h.В теле конструктора OpenGLScene удалите строки

#ifndef QT_NO_CONCURRENT
    connect(&m_modelLoader, SIGNAL(finished()), this, SLOT(modelLoaded()));
#endif

В OpenGLScene::loadModel(const QString &filePath) измените

#ifndef QT_NO_CONCURRENT
    m_modelLoader.setFuture(QtConcurrent::run(::loadModel, filePath));
#else
    setModel(::loadModel(filePath));
    modelLoaded();
#endif

на

    setModel(::loadModel(filePath));
    modelLoaded();

Наконец удалите

#ifndef QT_NO_CONCURRENT
    setModel(m_modelLoader.result());
#endif

из OpenGLScene::modelLoaded().

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...