前言:
我的想法是搭建一个和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);
}
}
持续更新中————————