从真正的零基础开始,详细教你如何创建 QT 项目文件。
第一步:打开 QT Creator
-
启动 QT Creator
-
在开始菜单找到 "Qt Creator" 并点击打开
-
或者桌面找到 Qt Creator 图标双击打开
-
-
初始界面
-
打开后你会看到类似这样的界面:
Welcome (欢迎页面)
├── Projects (项目)
├── Examples (示例)
└── Tutorials (教程)
-
第二步:创建新项目
方法一:通过菜单创建(推荐)
-
点击菜单栏 :
文件(File)→新建文件或项目(New File or Project)或者按Ctrl+N -
选择项目类型:在弹出的对话框中,选择:
Projects
├── Application (应用程序)
│ └── Qt Widgets Application (Qt Widgets 应用程序)
├── Library (库)
└── 其他...点击 "Choose" 按钮
3、项目位置设置:
位置(Location):
- 项目名称: ImageProcessor
- 创建路径: C:/Projects/ (点击"浏览"选择或手动输入)
- 不要有中文路径!
4、构建系统:
-
选择
qmake(默认) -
点击 "Next"
-
类信息:
-
类名:
MainWindow(默认) -
Base class:
QMainWindow(默认) -
其他保持默认,点击 "Next"
-
-
翻译文件:
- 直接点击 "Next" (跳过)
-
构建套件:
-
选择
Desktop Qt MinGW(打勾) -
点击 "Next"
-
-
版本控制:
- 直接点击 "完成(Finish)"

方法二:手动创建文件夹和文件(如果上面方法不行)
-
创建项目文件夹:
-
打开文件管理器
-
在 C 盘创建文件夹:
C:\Projects\ImageProcessor
-
-
在 QT Creator 中创建文件:
-
在 QT Creator 中:
文件→新建文件或项目 -
选择:
Files and Classes→C++→C++ Source File -
名称:
main.cpp -
路径:选择你刚创建的
C:\Projects\ImageProcessor文件夹 -
点击完成
-
-
重复创建其他文件:
-
文件→新建文件或项目 -
选择:
Files and Classes→C++→C++ Header File -
名称:
mainwindow.h -
路径:相同文件夹
-
同样方法创建:
mainwindow.cpp
-
-
创建 .pro 文件:
-
文件→新建文件或项目 -
选择:
General→Empty File -
名称:
ImageProcessor.pro -
路径:相同文件夹
-
第三步:验证项目结构
创建完成后,你应该在 QT Creator 的左侧看到这样的项目结构:
ImageProcessor (项目名称)
├── ImageProcessor.pro # 这是 .pro 文件!
├── Headers (头文件)
│ └── mainwindow.h
├── Sources (源文件)
│ ├── main.cpp
│ └── mainwindow.cpp
└── Forms (界面文件)
└── mainwindow.ui # 这个会自动创建
重要 :如果你没有看到 .pro 文件,可能是因为:
第四步:如果还是看不到 .pro 文件
解决方法:
-
在 QT Creator 中打开现有项目:
-
文件→打开文件或项目 -
浏览到
C:\Projects\ImageProcessor文件夹 -
如果里面有
ImageProcessor.pro,选择它打开 -
如果没有,继续下一步
-
-
手动创建 .pro 文件:
-
打开记事本或任何文本编辑器
-
复制粘贴以下内容:
-
保存为:
C:\Projects\ImageProcessor\ImageProcessor.pro -
注意:保存时选择"所有文件",文件名要包含
.pro扩展名pro
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
CONFIG += c++17
TARGET = ImageProcessor
TEMPLATE = app源文件
SOURCES +=
main.cpp
mainwindow.cpp头文件
HEADERS +=
mainwindow.h界面文件
FORMS +=
mainwindow.ui
-
-
-
在 QT Creator 中重新打开:
-
文件→打开文件或项目 -
选择刚才创建的
ImageProcessor.pro -
现在应该能看到完整的项目结构
-
第五步:检查项目是否创建成功
在 QT Creator 中,能看到:
-
左侧项目面板:显示所有文件
-
.pro 文件:双击可以编辑
-
可以编译:点击左下角的锤子图标应该可以开始编译
关于.ui文件,直接编辑文件
最简单的解决方案:
①找到文件位置:
-
在 QT Creator 左侧项目面板
-
右键点击
mainwindow.ui文件 -
选择 "在Explorer中显示"(Windows)
②用记事本打开:
-
在文件管理器中,右键点击
mainwindow.ui -
选择 "打开方式" → "记事本"
或者 "选择其他应用" → "记事本"
第六简单项目示例
第一步:编译 OpenCV 4.6 with MinGW
第二步:创建 QT 项目
项目名字为: ImageProcessor

①ImageProcessor.pro 的 QT 项目文件【输入代码内容】
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
CONFIG += c++17
# 设置 OpenCV 路径 - 根据你的实际路径修改
win32 {
INCLUDEPATH += D:/opencv-4.6.0/install/include
LIBS += -LD:/opencv-4.6.0/install/x64/mingw/lib \
-lopencv_core460 \
-lopencv_imgproc460 \
-lopencv_imgcodecs460 \
-lopencv_highgui460
}
SOURCES += \
main.cpp \
mainwindow.cpp
HEADERS += \
mainwindow.h
FORMS += \
mainwindow.ui
第三步:编写源代码
第一个文件:main.cpp【 #主程序文件】
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
第二个文件:mainwindow.h 【 #主窗口头文件】
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QImage>
#include <QPixmap>
#include <QFileDialog>
#include <QMessageBox>
#include <QLabel>
#include <QTimer>
// OpenCV 头文件
#include <opencv2/opencv.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
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_openImageButton_clicked();
void on_processImageButton_clicked();
void on_saveImageButton_clicked();
void on_grayscaleButton_clicked();
void on_edgeDetectionButton_clicked();
void on_blurButton_clicked();
private:
Ui::MainWindow *ui;
cv::Mat originalImage;
cv::Mat processedImage;
QLabel *statusLabel; // 状态栏标签
QImage cvMatToQImage(const cv::Mat &mat);
void updateImageDisplay();
void showStatusMessage(const QString &message, int timeout = 2000); // 显示状态信息
};
#endif // MAINWINDOW_H
第三个文件: mainwindow.cpp【 #主窗口实现文件】
#include "mainwindow.h"
#include "ui_mainwindow.h" // 自动生成的 UI 头文件
#include <QDebug>
// 构造函数
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent) // 调用父类构造函数
, ui(new Ui::MainWindow) // 创建 UI 对象
{
ui->setupUi(this); // 设置 UI
// 设置窗口标题
setWindowTitle("OpenCV 图像处理器 - MinGW 版本");
// 初始化状态栏
statusLabel = new QLabel(this);
statusLabel->setStyleSheet("QLabel { background-color : white; color : black; padding: 2px; }");
ui->statusbar->addWidget(statusLabel);
// 初始化按钮状态(开始时禁用)
ui->processImageButton->setEnabled(false); // 重置按钮
ui->saveImageButton->setEnabled(false); // 保存按钮
ui->grayscaleButton->setEnabled(false); // 灰度化按钮
ui->edgeDetectionButton->setEnabled(false); // 边缘检测按钮
ui->blurButton->setEnabled(false); // 模糊处理按钮
}
// 析构函数
MainWindow::~MainWindow()
{
delete ui;
delete statusLabel;
}
// 显示状态信息(2秒后自动消失)
void MainWindow::showStatusMessage(const QString &message, int timeout)
{
statusLabel->setText(message);
QTimer::singleShot(timeout, this, [this]() {
statusLabel->clear();
});
}
// 打开图片按钮点击事件
void MainWindow::on_openImageButton_clicked()
{
QString fileName = QFileDialog::getOpenFileName(this,
tr("Open Image"), "",
tr("Image Files (*.png *.jpg *.jpeg *.bmp *.tiff)"));
if (!fileName.isEmpty()) {
// 处理中文路径
QByteArray ba = fileName.toLocal8Bit();
const char* filePath = ba.constData();
// 使用OpenCV读取图像
originalImage = cv::imread(filePath, cv::IMREAD_COLOR);
if (originalImage.empty()) {
showStatusMessage("错误:无法打开图像文件!", 3000);
return;
}
// 关键修复:BGR 转 RGB
cv::cvtColor(originalImage, originalImage, cv::COLOR_BGR2RGB);
processedImage = originalImage.clone();
updateImageDisplay();
// 启用处理按钮
ui->processImageButton->setEnabled(true);
ui->grayscaleButton->setEnabled(true);
ui->edgeDetectionButton->setEnabled(true);
ui->blurButton->setEnabled(true);
showStatusMessage("成功:彩色图片加载成功!", 2000);
}
}
// 重置图像按钮点击事件
void MainWindow::on_processImageButton_clicked()
{
if (originalImage.empty()) {
showStatusMessage("错误:没有原始图像可重置!", 3000);
return;
}
try {
// 重置为原始图像
processedImage = originalImage.clone();
updateImageDisplay();
showStatusMessage("图像已重置为原始状态!", 2000);
} catch (const cv::Exception& e) {
showStatusMessage(QString("重置失败:%1").arg(e.what()), 3000);
}
}
// 保存图片按钮点击事件
void MainWindow::on_saveImageButton_clicked()
{
if (processedImage.empty()) {
showStatusMessage("错误:没有图像可保存!", 3000);
return;
}
QString fileName = QFileDialog::getSaveFileName(
this,
tr("保存图片"),
"",
tr("图片文件 (*.png *.jpg *.jpeg *.bmp)")
);
if (!fileName.isEmpty()) {
try {
// 转换回 BGR 格式保存
cv::Mat saveImage;
cv::cvtColor(processedImage, saveImage, cv::COLOR_RGB2BGR);
// 处理中文路径
QByteArray ba = fileName.toLocal8Bit();
const char* filePath = ba.constData();
if (cv::imwrite(filePath, saveImage)) {
showStatusMessage("图片保存成功!", 2000);
} else {
showStatusMessage("错误:无法保存图片!", 3000);
}
} catch (const cv::Exception& e) {
showStatusMessage(QString("保存失败:%1").arg(e.what()), 3000);
}
}
}
// 灰度化按钮点击事件
void MainWindow::on_grayscaleButton_clicked()
{
if (processedImage.empty()) {
showStatusMessage("错误:请先加载图片!", 3000);
return;
}
try {
cv::Mat grayImage;
// 转换为灰度图
cv::cvtColor(processedImage, grayImage, cv::COLOR_RGB2GRAY);
// 将单通道灰度图转换为3通道RGB图像用于显示
cv::cvtColor(grayImage, processedImage, cv::COLOR_GRAY2RGB);
updateImageDisplay();
ui->saveImageButton->setEnabled(true);
showStatusMessage("图像灰度化完成!", 2000);
} catch (const cv::Exception& e) {
showStatusMessage(QString("灰度化处理失败:%1").arg(e.what()), 3000);
}
}
// 边缘检测按钮点击事件
void MainWindow::on_edgeDetectionButton_clicked()
{
if (processedImage.empty()) {
showStatusMessage("错误:请先加载图片!", 3000);
return;
}
try {
cv::Mat gray, edges;
// 转换为灰度图进行处理
cv::cvtColor(processedImage, gray, cv::COLOR_RGB2GRAY);
cv::GaussianBlur(gray, gray, cv::Size(5, 5), 1.5, 1.5);
cv::Canny(gray, edges, 50, 150);
// 将边缘检测结果转换为彩色图像用于显示
cv::cvtColor(edges, processedImage, cv::COLOR_GRAY2RGB);
updateImageDisplay();
ui->saveImageButton->setEnabled(true);
showStatusMessage("边缘检测完成!", 2000);
} catch (const cv::Exception& e) {
showStatusMessage(QString("边缘检测失败:%1").arg(e.what()), 3000);
}
}
// 模糊处理按钮点击事件
void MainWindow::on_blurButton_clicked()
{
if (processedImage.empty()) {
showStatusMessage("错误:请先加载图片!", 3000);
return;
}
try {
// 对当前图像进行模糊处理
cv::GaussianBlur(processedImage, processedImage, cv::Size(15, 15), 0);
updateImageDisplay();
ui->saveImageButton->setEnabled(true);
showStatusMessage("图像模糊化完成!", 2000);
} catch (const cv::Exception& e) {
showStatusMessage(QString("模糊处理失败:%1").arg(e.what()), 3000);
}
}
// OpenCV Mat 转换为 QT Image
QImage MainWindow::cvMatToQImage(const cv::Mat &mat)
{
try {
if (mat.empty()) {
return QImage();
}
// 检查图像类型并相应转换
if (mat.type() == CV_8UC3) {
// 3通道 RGB 图像
return QImage(mat.data, mat.cols, mat.rows,
static_cast<int>(mat.step),
QImage::Format_RGB888).copy();
} else if (mat.type() == CV_8UC1) {
// 单通道灰度图像
return QImage(mat.data, mat.cols, mat.rows,
static_cast<int>(mat.step),
QImage::Format_Grayscale8).copy();
} else {
// 不支持的格式,尝试转换
cv::Mat converted;
mat.convertTo(converted, CV_8UC3);
return QImage(converted.data, converted.cols, converted.rows,
static_cast<int>(converted.step),
QImage::Format_RGB888).copy();
}
} catch (const cv::Exception& e) {
qDebug() << "图像转换错误:" << e.what();
return QImage();
}
}
// 更新图像显示
void MainWindow::updateImageDisplay()
{
// 检查是否有处理后的图像
if (!processedImage.empty()) {
// 确保图像是有效的
if (processedImage.cols > 0 && processedImage.rows > 0) {
QImage qimage = cvMatToQImage(processedImage);
if (!qimage.isNull()) {
QPixmap pixmap = QPixmap::fromImage(qimage);
// 缩放图像以适应标签大小,保持宽高比
pixmap = pixmap.scaled(
ui->imageLabel->size(),
Qt::KeepAspectRatio,
Qt::SmoothTransformation
);
ui->imageLabel->setPixmap(pixmap);
return;
}
}
}
// 如果显示失败,显示默认文本
ui->imageLabel->setText("图像显示错误或为空");
}
第四个文件:mainwindow.ui文件【#界面设计文件】
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>600</height>
</rect>
</property>
<property name="windowTitle">
<string>OpenCV 图像处理器</string>
</property>
<widget class="QWidget" name="centralwidget">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="imageLabel">
<property name="minimumSize">
<size>
<width>600</width>
<height>400</height>
</size>
</property>
<property name="frameShape">
<enum>QFrame::Box</enum>
</property>
<property name="text">
<string>请选择一张图片</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QPushButton" name="openImageButton">
<property name="text">
<string>打开图片</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="processImageButton">
<property name="text">
<string>重置图像</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="grayscaleButton">
<property name="text">
<string>灰度化</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="edgeDetectionButton">
<property name="text">
<string>边缘检测</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="blurButton">
<property name="text">
<string>模糊处理</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="saveImageButton">
<property name="text">
<string>保存图片</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<!-- 添加状态栏 -->
<widget class="QStatusBar" name="statusbar"/>
</widget>
<resources/>
<connections/>
</ui>