C/C++ QT ,mainwindow界面存在两个按钮,一个画图形,一个清空所有图形,还有一个graphicsView窗口,graphicsView结合opengl,使用opengl在图像上层画上述形状,graphicsView底层要显示一张图像,需要保留graphicsView原有功能,请给出完整代码和详细的中文注释以及完整的步骤,头文件和源文件分开给。图形类型为空心矩形,矩形的每个顶点都由mainwindow界面指定,不需要界面输入,直接给出指定顶点,规避之前发生的错误,给我一份能用的代码
时间: 2025-07-22 20:28:24 浏览: 11
<think>我们使用Qt框架来实现这个需求。主要步骤包括:
1. 创建一个继承自QGraphicsView的类,使用OpenGL作为渲染引擎(设置视口为QOpenGLWidget)。
2. 在GraphicsView中显示一张底层图像(作为背景),然后在其上绘制空心矩形(作为前景)。
3. 创建主窗口MainWindow,包含两个按钮:一个用于绘制矩形,一个用于清空所有图形。
4. 保留GraphicsView的原有功能(如缩放、平移等)。
注意:为了在QGraphicsView中使用OpenGL,我们将设置其视口为QOpenGLWidget。同时,为了绘制图形,我们将使用QGraphicsScene来管理图形项。
具体实现:
- 我们将创建一个自定义的QGraphicsScene,用于显示背景图片和绘制矩形。
- 绘制矩形时,我们创建一个矩形图形项(QGraphicsRectItem)并添加到场景中,设置为空心(无填充色)。
- 清空图形时,移除所有除了背景图片以外的图形项。
由于要求底层显示一张图像,我们将这张图像作为场景的背景。但是注意,QGraphicsScene的背景绘制方式可能会因为缩放而模糊,因此我们采用另一种方式:在场景中添加一个图形项(QGraphicsPixmapItem)作为底层图像,这样我们可以控制它的位置和大小。
步骤:
1. 创建自定义GraphicsView类(可选,这里我们直接使用QGraphicsView,但在MainWindow中设置其视口为QOpenGLWidget)。
2. 创建MainWindow,并设置布局:两个按钮和一个GraphicsView。
3. 在GraphicsView中设置场景(QGraphicsScene),并添加一个图像项作为背景。
4. 实现绘制矩形:在场景中添加一个矩形图形项(设置画笔为实线,无画刷)。
5. 实现清空:删除场景中除背景图像项以外的所有图形项。
由于需要保留GraphicsView的原有功能(如鼠标滚轮缩放、平移等),我们不需要修改这些事件的默认处理。
代码结构:
我们分为头文件和源文件。
1. 头文件:mainwindow.h
2. 源文件:main.cpp, mainwindow.cpp
注意:为了避免之前出现的错误,我们将矩形的顶点直接指定(例如,在场景坐标系中,我们指定一个矩形的位置和大小)。
我们将使用一个成员变量来记录背景图像项,以便在清空时保留它。
具体代码实现如下:
首先,我们创建MainWindow类,在头文件中声明必要的成员和槽函数。
mainwindow.h:</think>以下是一个使用Qt和OpenGL实现的完整解决方案,包含详细的注释和分文件代码:
### 解决方案
#### 文件结构
1. `mainwindow.h` - 主窗口头文件
2. `mainwindow.cpp` - 主窗口实现
3. `openglgraphicsview.h` - OpenGL视图头文件
4. `openglgraphicsview.cpp` - OpenGL视图实现
5. `main.cpp` - 程序入口
---
### 1. mainwindow.h
```cpp
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QGraphicsView>
#include <QPushButton>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include "openglgraphicsview.h" // 自定义OpenGL视图
class MainWindow : public QMainWindow {
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
void drawRectangle(); // 绘制矩形
void clearScene(); // 清空图形
private:
void setupUI(); // 初始化UI
OpenGLGraphicsView *graphicsView; // OpenGL视图
QPushButton *btnDraw; // 绘制按钮
QPushButton *btnClear; // 清空按钮
};
#endif // MAINWINDOW_H
```
---
### 2. mainwindow.cpp
```cpp
#include "mainwindow.h"
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) {
setWindowTitle("OpenGL图形绘制");
resize(800, 600);
setupUI();
}
MainWindow::~MainWindow() {}
void MainWindow::setupUI() {
// 创建主布局
QWidget *centralWidget = new QWidget(this);
QVBoxLayout *mainLayout = new QVBoxLayout(centralWidget);
// 创建按钮区域
QHBoxLayout *buttonLayout = new QHBoxLayout();
btnDraw = new QPushButton("绘制矩形", this);
btnClear = new QPushButton("清空图形", this);
buttonLayout->addWidget(btnDraw);
buttonLayout->addWidget(btnClear);
// 创建OpenGL视图
graphicsView = new OpenGLGraphicsView(this);
graphicsView->setBackgroundImage(":/background.jpg"); // 设置底层图像
// 添加到主布局
mainLayout->addLayout(buttonLayout);
mainLayout->addWidget(graphicsView);
setCentralWidget(centralWidget);
// 连接信号槽
connect(btnDraw, &QPushButton::clicked, this, &MainWindow::drawRectangle);
connect(btnClear, &QPushButton::clicked, this, &MainWindow::clearScene);
}
void MainWindow::drawRectangle() {
// 定义矩形顶点坐标(规避之前错误)
QVector<QPointF> vertices = {
QPointF(100, 100), // 左上角
QPointF(300, 100), // 右上角
QPointF(300, 300), // 右下角
QPointF(100, 300) // 左下角
};
graphicsView->drawHollowRectangle(vertices);
}
void MainWindow::clearScene() {
graphicsView->clearAllShapes();
}
```
---
### 3. openglgraphicsview.h
```cpp
#ifndef OPENGLGRAPHICSVIEW_H
#define OPENGLGRAPHICSVIEW_H
#include <QGraphicsView>
#include <QOpenGLWidget>
#include <QGraphicsScene>
#include <QGraphicsPixmapItem>
#include <QVector>
#include <QPointF>
class OpenGLGraphicsView : public QGraphicsView {
Q_OBJECT
public:
explicit OpenGLGraphicsView(QWidget *parent = nullptr);
// 设置背景图像
void setBackgroundImage(const QString &imagePath);
// 绘制空心矩形
void drawHollowRectangle(const QVector<QPointF> &vertices);
// 清空所有图形
void clearAllShapes();
protected:
// 保留原有视图功能(缩放/平移)
void wheelEvent(QWheelEvent *event) override;
private:
QGraphicsScene *scene; // 场景对象
QGraphicsPixmapItem *background; // 背景图像项
};
#endif // OPENGLGRAPHICSVIEW_H
```
---
### 4. openglgraphicsview.cpp
```cpp
#include "openglgraphicsview.h"
#include <QOpenGLWidget>
#include <QGraphicsRectItem>
#include <QPen>
#include <QWheelEvent>
OpenGLGraphicsView::OpenGLGraphicsView(QWidget *parent)
: QGraphicsView(parent) {
// 设置OpenGL渲染
QOpenGLWidget *glWidget = new QOpenGLWidget(this);
setViewport(glWidget); // 使用OpenGL视口
// 创建场景
scene = new QGraphicsScene(this);
setScene(scene);
// 设置渲染优化
setRenderHint(QPainter::Antialiasing, true);
setRenderHint(QPainter::SmoothPixmapTransform, true);
setViewportUpdateMode(FullViewportUpdate);
}
void OpenGLGraphicsView::setBackgroundImage(const QString &imagePath) {
// 清除旧背景
if (background) {
scene->removeItem(background);
delete background;
}
// 加载并设置新背景
QPixmap pixmap(imagePath);
if (!pixmap.isNull()) {
background = scene->addPixmap(pixmap);
background->setZValue(-1); // 置于底层
setSceneRect(pixmap.rect()); // 设置场景大小
}
}
void OpenGLGraphicsView::drawHollowRectangle(const QVector<QPointF> &vertices) {
if (vertices.size() < 4) return;
// 创建空心矩形(无填充色)
QGraphicsPolygonItem *rect = new QGraphicsPolygonItem(
QPolygonF(vertices)
);
// 设置画笔样式
QPen pen(Qt::red, 3); // 红色边框,宽度3
pen.setStyle(Qt::DashLine); // 虚线样式
rect->setPen(pen);
rect->setBrush(Qt::NoBrush); // 无填充
// 添加到场景(位于背景之上)
rect->setZValue(1);
scene->addItem(rect);
}
void OpenGLGraphicsView::clearAllShapes() {
// 删除所有非背景项
QList<QGraphicsItem*> items = scene->items();
for (QGraphicsItem *item : items) {
if (item != background) {
scene->removeItem(item);
delete item;
}
}
}
void OpenGLGraphicsView::wheelEvent(QWheelEvent *event) {
// 保留缩放功能:Ctrl+滚轮缩放
if (event->modifiers() & Qt::ControlModifier) {
double scaleFactor = (event->angleDelta().y() > 0) ? 1.1 : 0.9;
scale(scaleFactor, scaleFactor);
} else {
QGraphicsView::wheelEvent(event); // 保持默认行为
}
}
```
---
### 5. main.cpp
```cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
// 设置OpenGL格式(可选)
QSurfaceFormat format;
format.setVersion(3, 3);
format.setProfile(QSurfaceFormat::CoreProfile);
QSurfaceFormat::setDefaultFormat(format);
MainWindow window;
window.show();
return app.exec();
}
```
---
### 关键功能说明
1. **OpenGL集成**:
- 通过`QOpenGLWidget`作为视口实现硬件加速渲染
- 保留原有视图功能(Ctrl+滚轮缩放)
2. **图像显示**:
- 使用`QGraphicsPixmapItem`显示底层图像
- 通过`setZValue(-1)`确保图像在底层
3. **图形绘制**:
- 空心矩形使用`QGraphicsPolygonItem`实现
- 设置`Qt::NoBrush`保证无填充
- 虚线边框通过`Qt::DashLine`实现
4. **坐标系统**:
- 矩形顶点直接指定为场景坐标
- 避免坐标转换错误(固定值示例)
5. **资源管理**:
- 使用资源文件加载背景图(需创建.qrc文件)
- 清空时保留背景图像
---
### 使用说明
1. 创建Qt Widgets Application项目
2. 添加上述文件到项目
3. 创建资源文件包含背景图像(例如`background.jpg`)
4. 在.pro文件中添加:`QT += opengl widgets`
5. 编译运行
> 注意:矩形顶点坐标已固定为`(100,100)`到`(300,300)`,如需动态修改可扩展为鼠标交互实现[^1][^2]。
阅读全文
相关推荐


















