如何创建 QT 项目文件(.pro)

从真正的零基础开始,详细教你如何创建 QT 项目文件。


第一步:打开 QT Creator

  1. 启动 QT Creator

    • 在开始菜单找到 "Qt Creator" 并点击打开

    • 或者桌面找到 Qt Creator 图标双击打开

  2. 初始界面

    • 打开后你会看到类似这样的界面:

      Welcome (欢迎页面)
      ├── Projects (项目)
      ├── Examples (示例)
      └── Tutorials (教程)


第二步:创建新项目

方法一:通过菜单创建(推荐)

  1. 点击菜单栏文件(File)新建文件或项目(New File or Project)或者按 Ctrl+N

  2. 选择项目类型:在弹出的对话框中,选择:

    Projects
    ├── Application (应用程序)
    │ └── Qt Widgets Application (Qt Widgets 应用程序)
    ├── Library (库)
    └── 其他...

    点击 "Choose" 按钮

3、项目位置设置

复制代码
位置(Location):
- 项目名称: ImageProcessor
- 创建路径: C:/Projects/  (点击"浏览"选择或手动输入)
- 不要有中文路径!

4、构建系统

  • 选择 qmake (默认)

  • 点击 "Next"

  1. 类信息

    • 类名:MainWindow (默认)

    • Base class:QMainWindow (默认)

    • 其他保持默认,点击 "Next"

  2. 翻译文件

    • 直接点击 "Next" (跳过)
  3. 构建套件

    • 选择 Desktop Qt MinGW (打勾)

    • 点击 "Next"

  4. 版本控制

    • 直接点击 "完成(Finish)"


方法二:手动创建文件夹和文件(如果上面方法不行)

  1. 创建项目文件夹

    • 打开文件管理器

    • 在 C 盘创建文件夹:C:\Projects\ImageProcessor

  2. 在 QT Creator 中创建文件

    • 在 QT Creator 中:文件新建文件或项目

    • 选择:Files and ClassesC++C++ Source File

    • 名称:main.cpp

    • 路径:选择你刚创建的 C:\Projects\ImageProcessor 文件夹

    • 点击完成

  3. 重复创建其他文件

    • 文件新建文件或项目

    • 选择:Files and ClassesC++C++ Header File

    • 名称:mainwindow.h

    • 路径:相同文件夹

    • 同样方法创建:mainwindow.cpp

  4. 创建 .pro 文件

    • 文件新建文件或项目

    • 选择:GeneralEmpty File

    • 名称:ImageProcessor.pro

    • 路径:相同文件夹


第三步:验证项目结构

创建完成后,你应该在 QT Creator 的左侧看到这样的项目结构:

复制代码
ImageProcessor (项目名称)
├── ImageProcessor.pro    # 这是 .pro 文件!
├── Headers (头文件)
│   └── mainwindow.h
├── Sources (源文件)
│   ├── main.cpp
│   └── mainwindow.cpp
└── Forms (界面文件)
    └── mainwindow.ui     # 这个会自动创建

重要 :如果你没有看到 .pro 文件,可能是因为:


第四步:如果还是看不到 .pro 文件

解决方法:

  1. 在 QT Creator 中打开现有项目

    • 文件打开文件或项目

    • 浏览到 C:\Projects\ImageProcessor 文件夹

    • 如果里面有 ImageProcessor.pro,选择它打开

    • 如果没有,继续下一步

  2. 手动创建 .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

  3. 在 QT Creator 中重新打开

    • 文件打开文件或项目

    • 选择刚才创建的 ImageProcessor.pro

    • 现在应该能看到完整的项目结构


第五步:检查项目是否创建成功

在 QT Creator 中,能看到:

  1. 左侧项目面板:显示所有文件

  2. .pro 文件:双击可以编辑

  3. 可以编译:点击左下角的锤子图标应该可以开始编译


    关于.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>


相关推荐
CodeAmaz6 小时前
通用 List 分批切割并循环查询数据库工具类
java·数据结构·工具类·分页
消失的旧时光-19436 小时前
Kotlinx.serialization 对多态对象(sealed class )支持更好用
java·服务器·前端
云帆小二6 小时前
从开发语言出发如何选择学习考试系统
开发语言·学习
光泽雨6 小时前
python学习基础
开发语言·数据库·python
leonardee7 小时前
Spring Security安全框架原理与实战
java·后端
q***5187 小时前
Spring Cloud gateway 路由规则
java
让学习成为一种生活方式7 小时前
Pfam 数据库详解--生信工具60
数据库
q***49867 小时前
数据库操作与数据管理——Rust 与 SQLite 的集成
数据库·rust·sqlite
百***06017 小时前
python爬虫——爬取全年天气数据并做可视化分析
开发语言·爬虫·python
jghhh017 小时前
基于幅度的和差测角程序
开发语言·matlab