QT开发中文网

Qt + OpenGL 实现鼠标左键实现框选效果,在 view 中 绘制鼠标框选的效果,在类的实现中要求继承QOpenGLWidget 和 QOpenGLFunctions_3_3_Core,将C++ 代码实现写入 WidgetPointView 中

在 WidgetPointView 类中添加如下代码:

class WidgetPointView : public QOpenGLWidget, protected QOpenGLFunctions_3_3_Core
{
    Q_OBJECT

public:
    explicit WidgetPointView(QWidget *parent = nullptr);

protected:
    void initializeGL() override;
    void resizeGL(int w, int h) override;
    void paintGL() override;
    void mousePressEvent(QMouseEvent *event) override;
    void mouseMoveEvent(QMouseEvent *event) override;

private:
    QVector<QVector2D> m_points; // 存储所有点的坐标
    QVector<QVector2D> m_selectedPoints; // 存储框选中的点的坐标
    bool m_selecting = false; // 是否正在进行框选操作
    QVector2D m_startPos; // 框选起点
    QVector2D m_endPos; // 框选终点
};

WidgetPointView::WidgetPointView(QWidget *parent)
    : QOpenGLWidget(parent)
{

}

void WidgetPointView::initializeGL()
{
    initializeOpenGLFunctions();
    glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
}

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

void WidgetPointView::paintGL()
{
    glClear(GL_COLOR_BUFFER_BIT);
    glPointSize(10.0f);
    glEnable(GL_POINT_SMOOTH);
    glBegin(GL_POINTS);
    glColor3f(1.0f, 0.0f, 0.0f);
    for (const auto &point : m_points) {
        glVertex2f(point.x(), point.y());
    }
    glEnd();

    if (m_selecting) {
        glDisable(GL_DEPTH_TEST);
        glPushMatrix();
        glLoadIdentity();
        glMatrixMode(GL_PROJECTION);
        glPushMatrix();
        glLoadIdentity();
        gluOrtho2D(0, width(), 0, height());

        glColor3f(0.0f, 0.0f, 1.0f);
        glLineWidth(1.0f);
        glBegin(GL_LINE_LOOP);

        glVertex2d(m_startPos.x(), m_startPos.y());
        glVertex2d(m_endPos.x(), m_startPos.y());
        glVertex2d(m_endPos.x(), m_endPos.y());
        glVertex2d(m_startPos.x(), m_endPos.y());

        glEnd();

        glPopMatrix();
        glMatrixMode(GL_MODELVIEW);
        glPopMatrix();
        glEnable(GL_DEPTH_TEST);
    }
}

void WidgetPointView::mousePressEvent(QMouseEvent *event)
{
    if (event->button() == Qt::LeftButton) {
        m_selecting = true;
        m_startPos = QVector2D(event->pos());
        m_endPos = QVector2D(event->pos());
    }
}

void WidgetPointView::mouseMoveEvent(QMouseEvent *event)
{
    if (m_selecting) {
        m_endPos = QVector2D(event->pos());
        update();
    }
}

在 paintGL() 方法中,首先绘制所有点,然后判断是否正在进行框选操作,如果是,就绘制框选的矩形。在 mousePressEvent() 中,如果是鼠标左键按下,就将 m_selecting 设为 true,并记录当前鼠标位置作为框选起点;在 mouseMoveEvent() 中,如果正在框选,就记录当前鼠标位置为框选终点,并调用 update() 方法使窗口重绘。需要注意的是,为了在 2D 坐标系中正确绘制矩形,需要先将当前的变换矩阵保存下来,然后设置投影矩阵为正交投影,绘制完矩形后再恢复变换矩阵和投影矩阵。

本站部分文章来源于网络,版权归原作者所有,如有侵权请联系站长删除。
转载请注明出处:https://qt.0voice.com/?id=1031

分享:
扫描分享到社交APP
上一篇
下一篇
发表列表
游客 游客
此处应有掌声~
评论列表

还没有评论,快来说点什么吧~

联系我们

在线咨询: 点击这里给我发消息

微信号:3007537140

上班时间: 10:30-22:30

关注我们
x

注册

已经有帐号?