Qt5与现代OpenGL学习(十二)在OpenGL Widge内,用button按钮画直线,不需要提升类

在这里插入图片描述
openglwidget.h

// openglwidget.h
#ifndef OPENGLWIDGET_H
#define OPENGLWIDGET_H

#include <QOpenGLWidget>
#include <QOpenGLFunctions_3_3_Core>
#include <QVector2D>
#include <QColor>

class OpenGLWidget : public QOpenGLWidget, protected QOpenGLFunctions_3_3_Core
{
    Q_OBJECT
public:
    explicit OpenGLWidget(QWidget *parent = nullptr);
    ~OpenGLWidget();

    void drawLine(const QVector2D &start, const QVector2D &end, const QColor &color = Qt::red);
    void clear();

protected:
    void initializeGL() override;
    void resizeGL(int w, int h) override;
    void paintGL() override;

private:
    GLuint VAO, VBO;
    QVector<QVector2D> vertices;
    QColor lineColor;
    bool hasLine;
};

#endif // OPENGLWIDGET_H

openglwidget.cpp

// openglwidget.cpp
#include "openglwidget.h"
#include <QOpenGLShaderProgram>

OpenGLWidget::OpenGLWidget(QWidget *parent)
    : QOpenGLWidget(parent), hasLine(false)
{
    QSurfaceFormat format;
    format.setVersion(3, 3);
    format.setProfile(QSurfaceFormat::CoreProfile);
    setFormat(format);
}

OpenGLWidget::~OpenGLWidget()
{
    makeCurrent();
    glDeleteVertexArrays(1, &VAO);
    glDeleteBuffers(1, &VBO);
    doneCurrent();
}

void OpenGLWidget::initializeGL()
{
    initializeOpenGLFunctions();
    glClearColor(0.2f, 0.2f, 0.2f, 1.0f);

    // 创建和编译着色器程序
    QOpenGLShaderProgram shaderProgram;
    shaderProgram.addShaderFromSourceCode(QOpenGLShader::Vertex,
        "#version 330 core\n"
        "layout (location = 0) in vec2 aPos;\n"
        "void main() {\n"
        "    gl_Position = vec4(aPos, 0.0, 1.0);\n"
        "}");

    shaderProgram.addShaderFromSourceCode(QOpenGLShader::Fragment,
        "#version 330 core\n"
        "out vec4 FragColor;\n"
        "uniform vec4 lineColor;\n"
        "void main() {\n"
        "    FragColor = lineColor;\n"
        "}");

    shaderProgram.link();

    // 设置顶点数据和缓冲
    glGenVertexArrays(1, &VAO);
    glGenBuffers(1, &VBO);

    glBindVertexArray(VAO);
    glBindBuffer(GL_ARRAY_BUFFER, VBO);

    glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), (void*)0);
    glEnableVertexAttribArray(0);

    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindVertexArray(0);

    // 启用抗锯齿
    glEnable(GL_LINE_SMOOTH);
    glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}

void OpenGLWidget::resizeGL(int w, int h)
{
    glViewport(0, 0, w, h);
}

void OpenGLWidget::paintGL()
{
    glClear(GL_COLOR_BUFFER_BIT);

    if (hasLine && vertices.size() >= 2)
    {
        QOpenGLShaderProgram shaderProgram;
        shaderProgram.addShaderFromSourceCode(QOpenGLShader::Vertex,
            "#version 330 core\n"
            "layout (location = 0) in vec2 aPos;\n"
            "void main() {\n"
            "    gl_Position = vec4(aPos, 0.0, 1.0);\n"
            "}");

        shaderProgram.addShaderFromSourceCode(QOpenGLShader::Fragment,
            "#version 330 core\n"
            "out vec4 FragColor;\n"
            "uniform vec4 lineColor;\n"
            "void main() {\n"
            "    FragColor = lineColor;\n"
            "}");

        shaderProgram.link();
        shaderProgram.bind();

        shaderProgram.setUniformValue("lineColor", lineColor);

        glBindBuffer(GL_ARRAY_BUFFER, VBO);
        glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(QVector2D), vertices.constData(), GL_STATIC_DRAW);
        glBindBuffer(GL_ARRAY_BUFFER, 0);

        glBindVertexArray(VAO);
        glLineWidth(2.0f);
        glDrawArrays(GL_LINES, 0, vertices.size());
        glBindVertexArray(0);
    }
}

void OpenGLWidget::drawLine(const QVector2D &start, const QVector2D &end, const QColor &color)
{
    makeCurrent();

    vertices.clear();
    vertices << start << end;
    lineColor = color;
    hasLine = true;

    update();
    doneCurrent();
}

void OpenGLWidget::clear()
{
    makeCurrent();
    vertices.clear();
    hasLine = false;
    update();
    doneCurrent();
}

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include "openglwidget.h"

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private slots:
    void on_pushButton_clicked();

private:
    Ui::MainWindow *ui;
    class OpenGLWidget *glWidget;
};
#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "openglwidget.h"
#include <QVBoxLayout>  // 必须包含这个头文件


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

    // 手动创建OpenGL Widget并添加到containerWidget中
        glWidget = new OpenGLWidget(ui->containerWidget);
        QVBoxLayout *layout = new QVBoxLayout(ui->containerWidget);
        layout->setContentsMargins(0, 0, 0, 0);
        layout->addWidget(glWidget);
        ui->containerWidget->setLayout(layout);
}

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


void MainWindow::on_pushButton_clicked()
{
    // 定义线的起点和终点(标准化设备坐标)
        QVector2D start(-0.8f, -0.5f);  // 左下方
        QVector2D end(0.8f, 0.5f);     // 右上方

        // 绘制蓝色直线
        glWidget->drawLine(start, end, QColor(0, 150, 255));
}

Qt Designer Widget是Qt设计师工具中的一个控件,可以用来创建用户界面。它提供了丰富的控件库和布局管理器,使界面设计更加方便快捷。使用Qt Designer设计界面时,可以通过设置样式表来改变控件的外观。但是,在Qt Designer中预览时样式正常,但程序运行时样式生效的问题,有两种解决方法,具体可以参考相关文章。 另外,Qt还提供了一个扩展的基础项,名为Graphics Widget,它在QGraphicsItem的基础上提供额外的功能。它似于QWidget,但更加灵活,可以被看作是一个大板。 总结起来,Qt Designer Widget是一个方便快捷的界面设计工具,可以使用样式表来改变控件外观。如果在程序运行时样式生效,可以参考相关文章中的解决方法。此外,Qt还提供了Graphics Widget这一扩展项,可以实现更灵活的界面设计。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [Qt QWidget 设置样式表生效的两种解决方案](https://download.csdn.net/download/xiezhongyuan07/87404417)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [Qt 设计师-Qt Designer基础控件介绍](https://blog.csdn.net/weixin_42964413/article/details/114387591)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

向日葵xyz

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值