对于软件的安装这里就不多介绍了。
本文章主要是根据本校图形学的实验知道来做。
创建一个简单的计算机图形学程序
第一步:创建项目及配置

这里创建的项目名和类名尽量和我的一样,避免后面直接复制我的代码时会出现一些名字上面的错误。QtWidgetsApplication1
【注意:这里创建的路径名里面不能出现中文】

其余选默认即可,到下面这里类名的创建尽量与我的一致。QtWidgetsApplication1

接下来的设置都选择默认即可。

遇到这里出现感叹号是因为还没有进行配置。

第二步:
接下来在Qt UI下填加菜单,菜单名为"app1", 生成下拉列表项test, 对应右侧的属性编辑器objectName属性值为actiontest, 更新并保存QtWidgetsApplication1.ui文件(UI文件,可编辑)

这里添加菜单,菜单名为"app1"。

生成下拉列表项test。

属性编辑器objectName属性值为actiontest,这里默认已经是了,不需要修改。

完成后修改Ctrl+shift+s保存文件。
第三步:代码编写。
实验要求及步骤如下:(先大致浏览一下即可)
在头文件QtWidgetsApplication1.h中添加槽函数
public slots:
void test();
在头文件QtWidgetsApplication1.h中添加QmessageBox头文件
#include<qmessagebox.h>
在QtWidgetsApplication1.cpp的构造函数QtWidgetsApplication1::QtWidgetsApplication1(QWidget *parent)
: QMainWindow(parent)中,ui.setupUi(this)函数之后添加:
connect(ui.actiontest, SIGNAL(triggered()), this, SLOT(test()));
在QtWidgetsApplication1.cpp完成测试函数test()
void QtWidgetsApplication1::test()
{
QMessageBox::information(NULL, "Title", "OK");
}
回到"编辑"板块,先对Qtwidgetsapplication1.h文件进行修改,修改要求如上。
这里可能一些同学不清楚怎么添加,可以将我下面的代码直接替换该文件的所有内容就行了。
#ifndef QTWIDGETSAPPLICATION1_H
#define QTWIDGETSAPPLICATION1_H
#include<qmessagebox.h>
#include <QMainWindow>
QT_BEGIN_NAMESPACE
namespace Ui { class QtWidgetsApplication1; }
QT_END_NAMESPACE
class QtWidgetsApplication1 : public QMainWindow
{
Q_OBJECT
public slots:
void test();
public:
QtWidgetsApplication1(QWidget *parent = nullptr);
~QtWidgetsApplication1();
private:
Ui::QtWidgetsApplication1 *ui;
};
#endif // QTWIDGETSAPPLICATION1_H
这里旁边的红线不是报错的意思,只是说明这里进行了修改没有保存的提示,所以我们
Ctrl+shift+s保存就没有该红线了。

接下来是对Qtwidgetsapplication1.cpp问价的编写,修改要求如上叙述过了。

这里也是防止一些同学不清楚怎么添加,可以将我下面的代码直接替换该文件的所有内容就行了。
#include "Qtwidgetsapplication1.h"
#include "ui_Qtwidgetsapplication1.h"
QtWidgetsApplication1::QtWidgetsApplication1(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::QtWidgetsApplication1)
{
ui->setupUi(this);
connect(ui->actiontest, SIGNAL(triggered()), this, SLOT(test()));
}
QtWidgetsApplication1::~QtWidgetsApplication1()
{
delete ui;
}
void QtWidgetsApplication1::test()
{
QMessageBox::information(NULL, "Title", "OK");
}
【注意对于这里自己动手添加的同学原要求里有一点小错,如下进行修改就行,这里可能是因为版本的问题】

接下来就可以 运行查看结果了。

查看实验结果:

【如果上述操作都正确但不能正常运行或者出现以下的错误就是因为你没有好好得读该文章,这些错误是因为项目的创建路径里出现了中文,注意这点后重新操作上述步骤】

或者

简单图形的绘制
实验要求如下:
第一步:添加绘图事件
头文件QtWidgetsApplication1.h中添加
#include <QPainter>
添加void paintEvent(QPaintEvent*);
public:
QtWidgetsApplication1(QWidget *parent = Q_NULLPTR);
void paintEvent(QPaintEvent*);
QtWidgetsApplication1.cpp文件中添加
void QtWidgetsApplication1::paintEvent(QPaintEvent*)
{
QPainter painter(this);
painter.setPen(QPen(Qt::blue, 4));
painter.drawLine(20, 20, 220, 220);
painter.drawLine(20, 220, 220, 20);
painter.drawEllipse(20, 20, 200, 200);
painter.drawRect(20, 20, 200, 200);
}
执行效果:
执行程序
这里主要就对那两个文件进行修改就行了。接下来我就简述的给出两个文件的代码就行,有兴趣的同学可以根据要求自己来添加代码:
对于Qtwidgetsapplication1.h,直接替换下述代码就行,并进行保存
#ifndef QTWIDGETSAPPLICATION1_H
#define QTWIDGETSAPPLICATION1_H
#include <QMainWindow>
#include <QMessageBox> // 已存在
#include <QPainter> // 已存在
#include <QPaintEvent> // 新增:paintEvent需要QPaintEvent类型
QT_BEGIN_NAMESPACE
namespace Ui { class QtWidgetsApplication1; }
QT_END_NAMESPACE
class QtWidgetsApplication1 : public QMainWindow
{
Q_OBJECT
public:
// 原构造函数已存在,避免重复声明
QtWidgetsApplication1(QWidget *parent = nullptr); // 保持nullptr或改用Q_NULLPTR
~QtWidgetsApplication1();
public slots:
void test();
protected:
// 正确的作用域:paintEvent应为protected
void paintEvent(QPaintEvent* event) override; // 添加override确保正确重写
private:
Ui::QtWidgetsApplication1 *ui;
};
#endif // QTWIDGETSAPPLICATION1_H
对于Qtwidgetsapplication1.cpp,直接替换下述代码就行,并进行保存
#include "Qtwidgetsapplication1.h"
#include "ui_Qtwidgetsapplication1.h"
QtWidgetsApplication1::QtWidgetsApplication1(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::QtWidgetsApplication1)
{
ui->setupUi(this);
connect(ui->actiontest, SIGNAL(triggered()), this, SLOT(test()));
}
QtWidgetsApplication1::~QtWidgetsApplication1()
{
delete ui;
}
void QtWidgetsApplication1::test()
{
QMessageBox::information(NULL, "Title", "OK");
}
// 新增绘图事件实现
void QtWidgetsApplication1::paintEvent(QPaintEvent *event)
{
Q_UNUSED(event); // 标记未使用参数避免警告
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing); // 抗锯齿
// 绘制蓝色图形
painter.setPen(QPen(Qt::blue, 4));
painter.drawLine(20, 20, 220, 220);
painter.drawLine(20, 220, 220, 20);
painter.drawEllipse(20, 20, 200, 200);
painter.drawRect(20, 20, 200, 200);
}
完成进行运行就能看到实验结果了,如下:

DDA方法直线的绘制:
实验要求如下:
在h文件中添加
public:
QtWidgetsApplication1(QWidget *parent = Q_NULLPTR);
void paintEvent(QPaintEvent*);
void DDA(QImage* image, int x1, int y1, int x2, int y2, QRgb value);
private:
Ui::QtWidgetsApplication1Class ui;
QPainter* paint;
在cpp文件中添加
void QtWidgetsApplication1::paintEvent(QPaintEvent*)
{
/*
QPainter painter(this);
painter.setPen(QPen(Qt::blue, 4));
painter.drawLine(20, 20, 220, 220);
painter.drawLine(20, 220, 220, 20);
painter.drawEllipse(20, 20, 200, 200);
painter.drawRect(20, 20, 200, 200);
*/
QImage image(800, 600, QImage::Format_RGB32);
paint = new QPainter;
paint->begin(this);
DDA(&image, 120, 120, 300, 150, qRgb(255, 0, 0));
paint->drawImage(0, 0, image);
paint->end();
}
void QtWidgetsApplication1::DDA(QImage* image, int x1, int y1, int x2, int y2, QRgb value)
{
int x;
float dx, dy, y, k;
dx = x2 - x1;
dy = y2 - y1;
k = dy / dx;
y = y1;
for (x = x1; x < x2; x++)
{
image->setPixel(x, int(y + 0.5), value);
y = y + k;
}
}
实现效果如下图:
这里也是主要就对那两个文件进行修改就行了。接下来我就简述的给出两个文件的代码就行,有兴趣的同学可以根据要求自己来添加代码:
对于Qtwidgetsapplication1.h,直接替换下述代码就行,并进行保存
#ifndef QTWIDGETSAPPLICATION1_H
#define QTWIDGETSAPPLICATION1_H
#include <QMainWindow>
#include <QMessageBox>
#include <QPainter>
#include <QPaintEvent>
#include <QImage> // 新增:DDA函数需要QImage类型
QT_BEGIN_NAMESPACE
namespace Ui {
class QtWidgetsApplication1; // UI类名应与实际生成的一致
}
QT_END_NAMESPACE
class QtWidgetsApplication1 : public QMainWindow
{
Q_OBJECT
public:
// 构造函数声明(保持唯一性)
QtWidgetsApplication1(QWidget *parent = nullptr); // 使用nullptr(C++11标准)
~QtWidgetsApplication1();
public slots:
void test();
protected:
// 绘图事件必须声明在protected区域
void paintEvent(QPaintEvent* event) override;
private:
// DDA算法函数声明(根据需求选择public/private)
void DDA(QImage* image, int x1, int y1, int x2, int y2, QRgb value);
private:
Ui::QtWidgetsApplication1 *ui; // 保持指针类型,与生成的UI类一致
// 注意:不建议将QPainter作为成员变量(见下方解释)
};
#endif // QTWIDGETSAPPLICATION1_H
对于Qtwidgetsapplication1.cpp,直接替换下述代码就行,并进行保存
#include "Qtwidgetsapplication1.h"
#include "ui_Qtwidgetsapplication1.h"
QtWidgetsApplication1::QtWidgetsApplication1(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::QtWidgetsApplication1)
{
ui->setupUi(this);
connect(ui->actiontest, SIGNAL(triggered()), this, SLOT(test()));
}
QtWidgetsApplication1::~QtWidgetsApplication1()
{
delete ui;
}
void QtWidgetsApplication1::test()
{
QMessageBox::information(NULL, "Title", "OK");
}
void QtWidgetsApplication1::paintEvent(QPaintEvent* event)
{
Q_UNUSED(event);
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing);
// 创建白色背景的QImage
QImage image(800, 600, QImage::Format_RGB32);
image.fill(Qt::white);
// 使用DDA绘制红色线段
DDA(&image, 120, 120, 300, 150, qRgb(255, 0, 0));
// 绘制到窗口左上角
painter.drawImage(0, 0, image);
}
void QtWidgetsApplication1::DDA(QImage* image, int x1, int y1, int x2, int y2, QRgb value)
{
int dx = x2 - x1;
int dy = y2 - y1;
int steps = abs(dx) > abs(dy) ? abs(dx) : abs(dy);
if (steps == 0) {
image->setPixel(x1, y1, value);
return;
}
float xIncrement = static_cast<float>(dx) / steps;
float yIncrement = static_cast<float>(dy) / steps;
float x = x1;
float y = y1;
for (int i = 0; i <= steps; ++i) {
// 检查坐标是否在图像范围内
if (x >= 0 && x < image->width() && y >= 0 && y < image->height()) {
image->setPixel(static_cast<int>(x + 0.5), static_cast<int>(y + 0.5), value);
}
x += xIncrement;
y += yIncrement;
}
}
完成进行运行就能看到实验结果了,如下:

历经数日的代码打磨、效果调试和文档整理,这篇QT实验手记终于得以和大家见面。作为一名技术分享者,你们的每一次「👍点赞」都是深夜Debug时的暖心咖啡,每一句「💬观点碰撞」都能让我在技术路上走得更稳更远。
如果在实践中发现文中存在表述偏差,或对某个技术细节有更优雅的实现思路,欢迎在评论区挥毫指点------你的真知灼见不仅会帮助我完善内容,更能为后来者点亮一盏明灯。让我们用开源精神共同构建更有价值的开发者社区,下篇技术见!