当前位置: 首页 > news >正文

qt实践教学(编写一个代码生成工具)持续更新至完成———

前言:

我的想法是搭建一个和STM32cubemux类似的图形化代码生成工具,可以把我平时用到的代码整合一下全部放入这个软件中,做一个我自己专门的代码生成工具,我初步的想法是在下拉选框中拉取需要配置的功能,然后就弹出对应的脚位图,只需要点击芯片上的脚位就可以配置对应的端口的功能,大家有好的建议欢迎指正。本工具实时更新到完成为止,我会实时更新进度和制作中遇到的问题和想法。

1.界面编写

界面大概框架布局,

界面的搭建可以参考下面链接的教程

第一部分 学习Qt必备知识 · Qt 快速入门系列教程

  • 搭建好后,首先实现新建文件,保存文件,打开文件对应的功能。

选择新建动作,右击点击转到槽

选择triggered()//触发时机:当用户通过点击、快捷键等方式显式触发动作时(例如点击菜单项或工具栏按钮)

会在mainwindow.cpp自动生成一个槽函数

我们在该该函数里写上新建的代码

void MainWindow::on_action_N_triggered()
{
    // 弹出文件对话框,让用户选择保存路径和文件名
    QString fileName = QFileDialog::getSaveFileName(
        this,
        "保存文件",
        QDir::homePath(),  // 默认保存到用户主目录
        "文本文件 (*.c);;所有文件 (*)"
        );

    if (fileName.isEmpty()) {
        QMessageBox::warning(this, "警告", "未选择文件名!");
        return;
    }

    // 使用 QFile 创建文件
    QFile file(fileName);
    if (file.open(QIODevice::WriteOnly | QIODevice::Text)) {
        QTextStream stream(&file);
        stream << "这是一个新创建的文件\n";  // 写入初始内容
        file.close();

        QMessageBox::information(this, "成功", "文件已创建:" + fileName);
    } else {
        QMessageBox::critical(this, "错误", "无法创建文件:" + fileName);
    }

}

就实现了新建的功能

然后实现保存功能

点击保存动作右击转到槽

选择triggered()

在槽函数里写上保存的代码,现在保存的是TextEdit控件中的文本,之后再进行调整

void MainWindow::on_saveButton_clicked()
{
    // 弹出文件保存对话框
    QString fileName = QFileDialog::getSaveFileName(
        this,
        "保存文件",
        QDir::homePath(),
        "文本文件 (*.txt);;所有文件 (*)"
    );

    if (fileName.isEmpty()) {
        QMessageBox::warning(this, "警告", "未选择保存路径!");
        return;
    }

    // 打开文件并写入 QTextEdit 的内容
    QFile file(fileName);
    if (file.open(QIODevice::WriteOnly | QIODevice::Text)) {
        QTextStream stream(&file);
        stream << ui->textEdit->toPlainText();  // 获取 QTextEdit 的文本内容
        file.close();
        QMessageBox::information(this, "成功", "文件已保存!");
    } else {
        QMessageBox::critical(this, "错误", "无法保存文件!");
    }
}

我们先来设置主要的功能,就是点击配置选项的多选框,自动弹出芯片,并标出可选配置的脚位

下拉选项条转到槽填上以下代码

void MainWindow::on_comboBox_activated(int index)//芯片选择
{
    // 获取当前选项的图片路径标识
    QString imageName = ui->comboBox->itemData(index).toString();

    // 假设图片存放在可执行文件同级目录的 images 文件夹下
    QString imagePath = ":/myimages/MCU/" + imageName;

    // 加载图片
    QPixmap pixmap(imagePath);
    if (pixmap.isNull()) {
        qDebug() << "无法加载图片:" << imagePath;
        ui-> picture->setText("图片加载失败");
        return;
    }

    // 显示图片(自动缩放适应 QLabel)
    ui->picture->setPixmap(pixmap.scaled(ui->picture->size(), Qt::KeepAspectRatio));
}

然后初始化下拉框的值

 ui->comboBox->addItem("SC8P052", "SC8P052.png");
    ui->comboBox->addItem("SC8P054", "SC8P054.png");
    ui->comboBox->addItem("SC8P054_16A", "SC8P054_16A.png");
    ui->comboBox->addItem("SC8P062BD", "SC8P062BD.png");
    ui->comboBox->addItem("SC8P062BD_14A", "SC8P062BD_14A.png");
    ui->comboBox->addItem("SC8P8022D", "SC8P8022D.png");
    ui->comboBox->addItem("SC8P8122", "SC8P8122.png");
    ui->comboBox->addItem("MC30P6250", "MC30P6250.png");
    ui->comboBox->addItem("MC30P6280", "MC30P6280.png");
    ui->comboBox->addItem("P02", "P02.png");
    ui->comboBox->addItem("P04", "P04.png");
    ui->comboBox->addItem("SC8F073", "SC8F073.png");
    ui->comboBox->addItem("SC8F073_16A", "SC8F073_16A.png");

这是导入的图片文件

如何导入看这篇文章

Qt--导入整个目录的资源_现成的qt项目文件怎么导入进去-CSDN博客

我的设置完后,选择哪个芯片就会弹出对应的芯片脚位图

但是出来的图片有些模糊,可能是拉伸的比列不对,直接显示在界面上也有点占空间,我们把它变为浮窗的模式,下面是没有修改前的模式

 创建一个新的界面,用来显示浮窗

FloatImageDialog.h.h文件

#ifndef FLOATIMAGEDIALOG_H
#define FLOATIMAGEDIALOG_H

#include <QDialog>
#include <QLabel>
#include <QPixmap>

class FloatImageDialog : public QDialog
{
    Q_OBJECT

public:
    explicit FloatImageDialog(const QString &imagePath, QWidget *parent = nullptr);
    ~FloatImageDialog();
private:
    QLabel *imageLabel;  // 用于显示图片的标签
};

#endif // FLOATIMAGEDIALOG_H
FloatImageDialog.cpp文件
#include "FloatImageDialog.h"
#include <QVBoxLayout>
#include <QPushButton>
#include <QMouseEvent>  //
FloatImageDialog::FloatImageDialog(const QString &imagePath, QWidget *parent)
    : QDialog(parent)
{
    // 设置窗口属性:无边框、置顶、透明背景(可选)
    setWindowFlags(Qt::Tool | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint);
    setAttribute(Qt::WA_TranslucentBackground);  // 如果需要透明背景

    // 加载图片
    QPixmap pixmap(imagePath);
    if (pixmap.isNull()) {
        qDebug() << "无法加载图片:" << imagePath;
        return;
    }

    // 创建控件
    imageLabel = new QLabel(this);
    imageLabel->setPixmap(pixmap.scaled(400, 400, Qt::KeepAspectRatio, Qt::SmoothTransformation));

    // 可选:添加关闭按钮
    QPushButton *closeButton = new QPushButton("关闭", this);
    connect(closeButton, &QPushButton::clicked, this, &FloatImageDialog::close);

    // 布局
    QVBoxLayout *layout = new QVBoxLayout(this);
    layout->addWidget(imageLabel);
    layout->addWidget(closeButton);
}

FloatImageDialog::~FloatImageDialog() {}

void FloatImageDialog::mousePressEvent(QMouseEvent *event)
{
    if (event->button() == Qt::LeftButton) {
        dragPosition = event->globalPos() - frameGeometry().topLeft();
        event->accept();
    }
}

void FloatImageDialog::mouseMoveEvent(QMouseEvent *event)
{
    if (event->buttons() & Qt::LeftButton) {
        move(event->globalPos() - dragPosition);
        event->accept();
    }
}

主函数MainWindow.h中加入头文件

#include "FloatImageDialog.h"  // 包含自定义对话框头文件

转到用来隐藏显示MCU的槽函数

写入以下代码

   if (!floatDialog) {
        // 创建浮动窗口(传入图片资源路径)
        floatDialog = new FloatImageDialog(":/images/SC8P052.png", this);
        floatDialog->show();
    } else {
        // 关闭并释放浮动窗口
        floatDialog->close();
        delete floatDialog;
        floatDialog = nullptr;
    }

实现了芯片图片在另一个窗口显示并可以拖动

给它初始化固定在右侧,用以下代码时不要忘记头文件#include <QScreen>

void MainWindow::onToggleFloatWindow()
{
    if (!floatDialog) {
        // 创建浮动窗口
        floatDialog = new FloatImageDialog(":/images/SC8P052.png", this);

        // 获取主窗口的屏幕位置和尺寸
        QRect mainGeometry = this->geometry();

        // 计算浮动窗口的初始位置(主窗口右侧 + 10 像素)
        int x = mainGeometry.right() + 10;
        int y = mainGeometry.top();

        // 获取屏幕的可用区域(避免窗口超出屏幕)
        QScreen *screen = QGuiApplication::primaryScreen();
        QRect screenGeometry = screen->availableGeometry();

        // 如果浮动窗口超出屏幕右侧,调整到屏幕边缘
        int maxX = screenGeometry.right() - floatDialog->width();
        if (x > maxX) {
            x = maxX;
        }

        // 设置浮动窗口位置
        floatDialog->move(x, y);

        floatDialog->show();
    } else {
        // 关闭并释放浮动窗口
        floatDialog->close();
        delete floatDialog;
        floatDialog = nullptr;
    }
}

窗口跟随移动

// MainWindow.h
protected:
    void moveEvent(QMoveEvent *event) override;

// MainWindow.cpp
void MainWindow::moveEvent(QMoveEvent *event)
{
    QMainWindow::moveEvent(event);
    if (floatDialog) {
        // 主窗口移动时更新浮动窗口位置
        QRect mainGeometry = geometry();
        int x = mainGeometry.right() + 10;
        int y = mainGeometry.top();
        floatDialog->move(x, y);
    }
}

持续更新中————————

相关文章:

  • 力扣:1.两数之和(O(n)复杂度)
  • [Computer Vision]实验七:图像检索
  • 摄像头应用编程(四):ARM Linux LCD实时预览UVC摄像头画面
  • 摄像头应用编程(三):多平面视频采集
  • 009---基于Verilog HDL的单比特信号边沿检测
  • 【前端】在WebStorm中安装Node.js与nvm与npm的详细过程
  • 第15届 蓝桥杯 C++编程青少组中级省赛 202408 真题答案及解析
  • 从新加坡《Companion Guide on Securing AI Systems 》看可信AI全生命周期防护框架构建
  • SOUI基于Zint生成EAN码
  • QT-信号与槽
  • deepseek、腾讯元宝deepseek R1、百度deepseekR1关系
  • 【自学笔记】Spring基础知识点总览-持续更新
  • Java的异常体系中的Error
  • 如何在网页上显示3D CAD PMI
  • Grok 3能否打破大模型的魔咒?
  • 【四.RAG技术与应用】【1.RAG技术揭秘:大模型与检索增强生成】
  • Error Density-dependent Empirical Risk Minimization
  • 基于IMM算法的目标跟踪,四模型IMM|三维环境|4个模型分别是:CV、左转CT、右转CT、CA(基于EKF,订阅专栏后可获得完整源代码)
  • 计算机视觉之dlib人脸关键点绘制及微笑测试
  • VMware虚拟机IP配置
  • 宁波市纪委监委通报4起违反中央八项规定精神典型问题
  • 百年传承,再启新程,参天中国迎来2.0时代
  • 徐徕任上海浦东新区副区长,此前已任区委常委
  • 78家公募年度业绩比拼:23家营收净利双升,十强座次微调
  • 2025年度中国青年五四奖章暨新时代青年先锋奖评选揭晓
  • “光荣之城”2025上海红色文化季启动,红色主题市集亮相