c++ - Painter 在继承的 QOpenGLWidget 类上不活动

标签 c++ qt c++11 opengl

我想在 Qt 中非常有效地绘制基本的 2D 形状(正方形),因此我继承了 QOpenGLWidget 如下:
WatorOpenGLWidget.hpp

#include <QOpenGLWidget>
#include <QPainter>
#include "Environment.hpp"

#ifndef WATOROPENGLWIDGET_HPP
#define WATOROPENGLWIDGET_HPP


class WatorOpenGLWidget : public QOpenGLWidget
{
private:
    Environment* environment;
public:
    WatorOpenGLWidget(QWidget* widget, Environment* environment);
    void initializeGL() override;
    void paintGL() override;
    void resizeGL(int w, int h) override;
    void setEnvironment(Environment *e) {this->environment = e;};
};

#endif // WATOROPENGLWIDGET_HPP
WatorOpenGLWidget.cpp
#include "WatorOpenGLWidget.hpp"
#include <iostream>

WatorOpenGLWidget::WatorOpenGLWidget(QWidget* widget, Environment* e): QOpenGLWidget(widget), environment(e){
}
void WatorOpenGLWidget::initializeGL() {
    glClearColor(0, 0, 0, 1);
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_LIGHT0);
    glEnable(GL_LIGHTING);
    glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
    glEnable(GL_COLOR_MATERIAL);
}

void WatorOpenGLWidget::paintGL(){
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    QPainter painter(this);
    painter.setBrush(QBrush(Qt::blue));
    painter.drawRect(0, 0, 3 * environment->getWidth(), 3 * environment->getHeight());

    std::vector<Agent*> agents = environment->getAgents();
    for(uint32_t i = 0; i < agents.size(); i++){
        painter.setBrush(agents[i]->getColor());
        painter.drawRect(agents[i]->getX() * 3, agents[i]->getY() * 3, 3, 3);
    }
}

void WatorOpenGLWidget::resizeGL(int w, int h){
    glViewport(0, 0, w, h);
}
我创建了我的自定义小部件 WatorOpenGLWidget 从主窗口类:
#include "Mainwindow.hpp"
#include "ui_mainwindow.h"
#include "Environment.hpp"
#include "Fish.hpp"
#include "Shark.hpp"
#include <iostream>

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

    timer = new QTimer(this);
    connect(timer, SIGNAL(timeout()), this, SLOT(updateEnvironment()));
    timer->start(20);
    tick = 0;

    initializeEnvironment();
    opengl_widget = new WatorOpenGLWidget(nullptr, environment);
    opengl_widget->setFixedSize(3 * environment->getWidth(), 3 * environment->getHeight());
    ui->scrollAreaWidgetContents->layout()->addWidget(opengl_widget);
    updateGUI();
}

void MainWindow::initializeEnvironment(){
    this->environment = new Environment(100, 100, 0);

    std::vector<Agent*> agents;
    for(uint32_t i = 0; i < 5000; i++){
        agents.push_back(new Fish());
    }

    for(uint32_t i = 0; i < 1000; i++){
        agents.push_back(new Shark());
    }

    this->environment->placeAgents(agents);
}

void MainWindow::updateEnvironment(){
    initializeEnvironment();
    std::vector<Agent*> agents = environment->getAgents();
    for(uint32_t i = 0; i < agents.size(); i++){
        agents[i]->decide();
    }

    updateGUI();
}

void MainWindow::updateGUI(){
    opengl_widget->setEnvironment(environment);
    opengl_widget->paintGL();
    tick++;
    std::string tick_text = "tick " + std::to_string(tick);
    ui->tickLabel->setText(QString::fromStdString(tick_text));
}

MainWindow::~MainWindow()
{
    delete timer;
    delete environment;
    delete ui;
}
每次计时器触发时绘图都可以正常工作,但是在运行时会生成以下输出:
QPainter::begin: Paint device returned engine == 0, type: 1
QPainter::setBrush: Painter not active
QPainter::drawRects: Painter not active
QPainter::setBrush: Painter not active
QPainter::drawRects: Painter not active
QPainter::setBrush: Painter not active
QPainter::drawRects: Painter not active
我应该怎么做才能防止这种情况发生?使用 QPainter 对象是否比使用 OpenGL 原生函数更消耗 CPU?

最佳答案

你不应该调用 paintGL()直接调用update()将调用 paintEvent() 的方法方法,这又会调用 paintGL() .

void MainWindow::updateGUI(){
    opengl_widget->setEnvironment(environment);
    opengl_widget->update();
    tick++;
    ui->tickLabel->setText(QString("tick %1").arg(tick));
}

关于c++ - Painter 在继承的 QOpenGLWidget 类上不活动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64158603/

相关文章:

c++ - 如何使用 CLion 生成 dbg 文件以用于 VerySleepy

c++ - 可以在没有 boost 或 C++11 的情况下使用 Asio 吗?

c++11 - 使用 emplace 添加到 std::map 时如何避免临时副本?

c++ - 设备未打开错误 + QIODevice::write

c++ - 为 apache 编写基于 C++11 线程的模块

c++ - boost::write_graphviz - 如何水平生成图形

c++ - 如何在C++中将整数值转换为特定的ascii字符

c++ - 与第三方库的菱形继承(钻石问题)

c++ - Qt 正在获取对 YouTube api 的请求,不支持 utf8 字符

c++ - QThread::终止与杀死