QTDemo:串口调试工具

news2025/1/3 2:25:30

项目简介

本项目通过QT框架设计一款可以在Windows、Linux等平台的跨平台串口助手,串口功能能够满足基本的调试需求。

本项目采用的版本为:QT5.14 + visual studio 2022 进行开发。

项目源码:https://github.com/say-Hai/MyCOMDemo

项目页面:

image-20241220120411588

一、创建开发环境

打开vs新建工程,选择创建Qt Widgets Application项目,选择保存路径后,配置QT的SerialPort模块。

image-20241217214638298

二、配置ui界面

打开工程的ui文件,设置本项目的ui页面(可直接从本项目的ui文件中copy到自己的项目中;但是注意:需要暂时把comboBoxNo_2降级成普通QComboBox

image-20241218103406284

image-20241218102410011

三、编写串口扫描代码

通过QSerialPortInfo::availablePorts生成可用串口列表,(目前暂定在MyCOM.h的构造函数中编写串口列表函数)

MyCOM::MyCOM(QWidget* parent)
	: QMainWindow(parent)
{
	ui.setupUi(this);
	//创建串口列表
	QStringList comPort;
	foreach(const QSerialPortInfo & info, QSerialPortInfo::availablePorts())
	{
		comPort << info.portName();
	}
	ui.comboBoxNo_2->addItems(comPort);
}

image-20241218103454075

四、“打开串口”按钮设计

vs中无法使用Qt Creator的“转到槽”功能,因此需要开发者自己绑定槽函数;具体操作步骤为:https://www.cnblogs.com/ybqjymy/p/17999513

注:解决vs + qt 导致的乱码问题:出现中文的文件首行加上#pragma execution_character_set("utf-8")

当我们绑定好槽函数on_pushButtonOpen_clicked(),接下来就是实现串口打开逻辑:以下为具体代码

//Map定义代码查看源文件
void MyCOM::on_pushButtonOpen_clicked()
{
	QSerialPort::BaudRate CombaudRate;
	QSerialPort::DataBits ComdataBits;
	QSerialPort::StopBits ComstopBits;
	QSerialPort::Parity   ComParity;
	QString selectedBaudRate = ui.comboBoxComBaud_2->currentText();
	std::cout << selectedBaudRate.toStdString() << "\n";

	if (baudRateMap.contains(selectedBaudRate)) {
		CombaudRate = baudRateMap[selectedBaudRate];
	}
	else {
		// 如果用户选择了一个未知的波特率,可以设置默认值或提示错误
		CombaudRate = QSerialPort::Baud9600; // 默认值
		qWarning("Invalid baud rate selected. Defaulting to 9600.");
	}
//具体代码查看源文件
	// 根据用户选择设置数据位
	// 根据用户选择设置停止位
	// 根据用户选择设置校验方式
	
	//初始化串口
	MyCom.setBaudRate(CombaudRate);
	MyCom.setDataBits(ComdataBits);
	MyCom.setStopBits(ComstopBits);
	MyCom.setParity(ComParity);
	MyCom.setPortName(spTxt);
	//打开串口
	if (ui.pushButtonOpen_2->text() == "打开串口")
	{
		bool ComFlag;
		ComFlag = MyCom.open(QIODevice::ReadWrite);
		if (ComFlag == true)//串口打开成功
		{
			//串口下拉框设置为不可选
			ui.comboBoxCheck_2->setEnabled(false);
			//具体代码查看源文件
			//使能相应按钮等
			ui.pushButtonSend_2->setEnabled(true);
			//具体代码查看源文件
			ui.pushButtonOpen_2->setText(" 关闭串口 ");
		}
		else
		{
			QMessageBox::critical(this, "错误提示", "串口打开失败,该端口可能被占用或不存在!rnLinux系统可能为当前用户无串口访问权限!");
		}
	}
	else
	{
		MyCom.close();
		ui.pushButtonOpen_2->setText(" 打开串口 ");
		//具体代码查看源文件

		//使相应的按钮不可用
		ui.pushButtonSend_2->setEnabled(false);
		具体代码查看源文件
	}
}

五、串口数据发送与接收

通过信号槽机制,在发送区发送数据,通过&QIODevice::readyRead信号来通知接收区函数&MyCOM::MyComRevSlot打印串口发送的数据

代码逻辑:

  • 信号槽逻辑:当串口有数据可以读取时,自动响应MyComRevSlot函数。

    connect(&MyCom, &QIODevice::readyRead, this, &MyCOM::MyComRevSlot);
    
  • 发送区代码逻辑:通过第四步中的“转到槽”机制,在发送按钮上绑定槽函数on_pushButtonSend_clicked(),再槽函数中接收发送区字符并通过MyCom.write(comSendData)发送到串口。

    • 其中16进制发送需要将字符串格式化成16进制 QByteArray::fromHex(SendTemp.toUtf8()).data();
    //精简版,少了一些单选框的逻辑判断
    void MyCOM::on_pushButtonSend_clicked()
    {
    	QByteArray comSendData;
    	QString SendTemp;
    	int temp;
    
    	//读取发送窗口数据
    	SendTemp = ui.TextSend_2->toPlainText();
    
    	//判断发送格式,并格式化数据
    	if (ui.checkBoxSendHex_2->checkState() != false)//16进制发送
    	{
    		comSendData = QByteArray::fromHex(SendTemp.toUtf8()).data();//获取字符串
    	}
    	temp = MyCom.write(comSendData);
    }
    
  • 接收区代码逻辑:通过信号槽机制来调用MyComRevSlot函数,利用MyCom.readAll()读取串口的数据,最后显示到文本框内。

    //精简版
    void MyCOM::MyComRevSlot()
    {
    	QByteArray MyComRevBUff;//接收数据缓存
    	QString StrTemp, StrTimeDate, StrTemp1;
    
    	//读取串口接收到的数据,并格式化数据
    	MyComRevBUff = MyCom.readAll();
    	StrTemp = QString::fromLocal8Bit(MyComRevBUff);
    
    	curDateTime = QDateTime::currentDateTime();
    	StrTimeDate = curDateTime.toString("[yyyy-MM-dd hh:mm:ss.zzz]");
    
    	StrTemp = MyComRevBUff.toHex().toUpper();//转换为16进制数,并大写
    	for (int i = 0; i < StrTemp.length(); i += 2)//整理字符串,即添加空格
    	{
    		StrTemp1 += StrTemp.mid(i, 2);
    		StrTemp1 += " ";
    	}
    	//添加时间头
    	StrTemp1.prepend(StrTimeDate);
    	StrTemp1.append("\r\n");//后面添加换行
    	ui.TextRev_2->insertPlainText(StrTemp1);//显示数据
    	ui.TextRev_2->moveCursor(QTextCursor::End);//光标移动到文本末尾
    }
    

image-20241218164558507

六、周期循环发送指令

通过定时器,实现周期性指令发送功能

  • 创建定时器 QTimer* PriecSendTimer;

  • 在构造函数中注册定时器超时connect函数,调用on_pushButtonSend_clicked()

    	connect(PriecSendTimer, &QTimer::timeout, this, [=]() {on_pushButtonSend_clicked(); });
    
  • 通过信号槽机制,绑定选择框状态变化信号处理函数

    image-20241219135218164

  • 编写选择框变化处理函数

    void MyCOM::on_checkBoxPeriodicSend_stateChanged(int arg1)
    {
    	if (arg1 == false)
    	{
    		PriecSendTimer->stop();
    		ui.lineEditTime->setEnabled(true);
    	}
    	else
    	{
    		PriecSendTimer->start(ui.lineEditTime->text().toInt());
    		ui.lineEditTime->setEnabled(false);
    	}
    }
    

image-20241219134212145

七、接收流量统计及状态栏设计

通过设计状态栏来实时展示QLabel的相关数据

  • 自定义变量

    	//添加自定义变量
    	long ComSendSum, ComRevSum;//发送和接收流量统计变量
    	QLabel* qlbSendSum, * qlbRevSum;//发送接收流量label对象
    	QLabel* myLink, * MySource;
    
  • 变量绑定状态栏

    //创建底部状态栏及其相关部件
    QStatusBar* STABar = statusBar();
    
    qlbSendSum = new QLabel(this);
    qlbRevSum = new QLabel(this);
    myLink = new QLabel(this);
    MySource = new QLabel(this);
    myLink->setMinimumSize(90, 20);// 设置标签最小大小
    MySource->setMinimumSize(90, 20);
    qlbSendSum->setMinimumSize(100, 20);
    qlbRevSum->setMinimumSize(100, 20);
    ComSendSum = 0;
    ComRevSum = 0;
    
    setNumOnLabel(qlbSendSum, "Tx: ", ComSendSum);
    setNumOnLabel(qlbRevSum, "Rx: ", ComRevSum);
    
    STABar->addPermanentWidget(qlbSendSum);// 从右往左依次添加
    STABar->addPermanentWidget(qlbRevSum);
    STABar->addWidget(myLink);// 从左往右依次添加
    STABar->addWidget(MySource);
    
    myLink->setOpenExternalLinks(true);//状态栏显示官网、源码链接
    myLink->setText("<style> a {text-decoration: none} </style> <a href=\"http://8.134.156.7/\">--个人博客--");
    MySource->setOpenExternalLinks(true);
    MySource->setText("<style> a {text-decoration: none} </style> <a href=\"https://github.com/say-Hai/MyCOMDemo\">--源代码--");
    
  • 自定义函数来更改自定义变量

    void MyCOM::setNumOnLabel(QLabel* lbl, QString strS, long num)
    {
    	QString strN = QString("%1").arg(num);
    	QString str = strS + strN;
    	lbl->setText(str);
    }
    
  • 在发送/接收函数中调用自定义函数

    //发送
    temp = MyCom.write(comSendData);
    ComSendSum++;
    setNumOnLabel(qlbSendSum, "Tx: ", ComSendSum);
    
    //接收
    MyComRevBUff = MyCom.readAll();
    StrTemp = QString::fromLocal8Bit(MyComRevBUff);
    ComRevSum++;
    setNumOnLabel(qlbRevSum, "Rx: ", ComRevSum);
    

八、数据区清空功能

void MyCOM::on_pushButtonClearRev_clicked()
{
	ui.TextRev_2->clear();
	ComSendSum = 0;
	ComRevSum = 0;

	setNumOnLabel(qlbSendSum, "Tx: ", ComSendSum);
	setNumOnLabel(qlbRevSum, "Rx: ", ComRevSum);
}

void MyCOM::on_pushButtonClearSend_clicked()
{
	ui.TextSend_2->clear();
	ComSendSum = 0;
	ComRevSum = 0;

	setNumOnLabel(qlbSendSum, "Tx: ", ComSendSum);
	setNumOnLabel(qlbRevSum, "Rx: ", ComRevSum);
}

九、文件保存与读取功能

通过文件的读取快速实现对串口发送数据,通过写入文件的方式保存串口的输出。

  • 读取文件:通过QFile aFile(aFileName);QByteArray text = aFile.readAll();来获取文本数据,并写入到文本框中。

    //首先创建on_pushButtonRdFile_clicked信号槽机制打开文件夹选择文件路径
    void MyCOM::on_pushButtonRdFile_clicked()
    {
    	QString curPath = QDir::currentPath();
    	QString dlgTitle = "打开一个文件"; //对话框标题
    	QString filter = "文本文件(*.txt);;所有文件(*.*)"; //文件过滤器
    	QString aFileName = QFileDialog::getOpenFileName(this, dlgTitle, curPath, filter);
    	if (aFileName.isEmpty())
    		return;
    	openTextByIODevice(aFileName);
    }
    //通过openTextByIODevice来读取文件
    bool MyCOM::openTextByIODevice(const QString& aFileName)
    {
    	QFile aFile(aFileName);
    	if (!aFile.exists()) //文件不存在
    		return false;
    	if (!aFile.open(QIODevice::ReadOnly | QIODevice::Text))
    		return false;
    	QByteArray text = aFile.readAll();
    	QString strText = byteArrayToUnicode(text);//编码格式转换,防止GBK中文乱码
    	ui.TextSend_2->setPlainText(strText);
    	aFile.close();
    	return  true;
    }
    //其中防止编码格式问题,通过byteArrayToUnicode进行编码格式转换
    QString MyCOM::byteArrayToUnicode(const QByteArray& array)
    {
    	QTextCodec::ConverterState state;
    	// 先尝试使用utf-8的方式把QByteArray转换成QString
    	QString text = QTextCodec::codecForName("UTF-8")->toUnicode(array.constData(), array.size(), &state);
    	// 如果转换时无效字符数量大于0,说明编码格式不对
    	if (state.invalidChars > 0)
    	{
    		// 再尝试使用GBK的方式进行转换,一般就能转换正确(当然也可能是其它格式,但比较少见了)
    		text = QTextCodec::codecForName("GBK")->toUnicode(array);
    	}
    	return text;
    }
    
  • 写入文件:选择文件路径->调用aFile.write(strBytes, strBytes.length()); 写入文件

    void MyCOM::on_pushButtonSaveRev_clicked()
    {
    	QString curFile = QDir::currentPath();
    	QString dlgTitle = " 另存为一个文件 "; //对话框标题
    	QString filter = " 文本文件(*.txt);;所有文件(*.*);;h文件(*.h);;c++文件(*.cpp) "; //文件过滤器
    	QString aFileName = QFileDialog::getSaveFileName(this, dlgTitle, curFile, filter);
    	if (aFileName.isEmpty())
    		return;
    	saveTextByIODevice(aFileName);
    }
    bool MyCOM::saveTextByIODevice(const QString& aFileName) {
    	QFile aFile(aFileName);
    	if (!aFile.open(QIODevice::WriteOnly | QIODevice::Text))
    		return false;
    	QString str = ui.TextRev_2->toPlainText();//整个内容作为字符串
    	QByteArray  strBytes = str.toUtf8();//转换为字节数组
    	aFile.write(strBytes, strBytes.length());  //写入文件
    	aFile.close();
    
    	return true;
    }
    

十、多行发送功能

通过信号槽机制和定时器功能,实现对多行数据选择的循环发送

具体逻辑:根据选择框的状态确定定时器状态->通过定时器超时函数唤醒发送事件->在发送事件中确定此次需要发送的行数据->调用对应发送按钮函数

  • 通过选择框的状态变化来打开/关闭定时器发送

    void MyCOM::on_checkBoxMuti_stateChanged(int arg)
    {
    	if (!arg)
    	{
    		PriecSendTimer->stop();//关闭定时器
    		ui.lineEditTime->setEnabled(true);//使能对话框编辑
    	}
    	else
    	{
    		LastSend = 0;//从第一行开始发送
    		ui.checkBoxPeriodicSend->setChecked(false);
    		PriecSendTimer->start(ui.lineEditTime->text().toInt());
    		ui.lineEditTime->setEnabled(false);//关闭对话框编辑
    	}
    }
    
  • 重构定时器超时响应函数,适配多行重复发送功能

    connect(PriecSendTimer, &QTimer::timeout, this, [=]() {Pre_on_pushButtonSend_clicked(); });
    
    void MyCOM::Pre_on_pushButtonSend_clicked()
    {
    	if (ui.checkBoxPeriodicMutiSend_2->isChecked() == true)
    	{
    		while (LastSend < 10)
    		{
    			if (checkBoxes[LastSend]->isChecked())
    			{
                    //发送对应行的数据
    				on_pushButtonMuti_clicked(++LastSend);
    				break;
    			}
    			LastSend++;
    		}
    		if (LastSend == 10)
    		{
    			LastSend = 0;
    		}
    	}
    	else
    	{
            //普通发送
    		on_pushButtonSend_clicked();
    	}
    }
    
  • 通过行索引触发对应的点击事件

    void MyCOM::on_pushButtonMuti_clicked(int lineEditIndex)
    {
    	QString Strtemp;
    	switch (lineEditIndex) {
    	case 1:
    		Strtemp = ui.lineEditMuti1_2->text();
    		break;
    	case 2:
    		Strtemp = ui.lineEditMuti2_2->text();
    		break;
    	//...后面对应的操作
    	default:
    		return;  // 默认情况下不做任何操作
    	}
    	ui.TextSend_2->clear();
    	ui.TextSend_2->insertPlainText(Strtemp);
    	ui.TextSend_2->moveCursor(QTextCursor::End);
    	MyCOM::on_pushButtonSend_clicked();
    }
    

    十一:自动刷新串口下拉框

    实现方法:新建一个类继承QComboBox类,重写鼠标点击事件使其调用扫描端口函数

  • 新建mycombobox类,继承QComBox

    #include <QComboBox>
    #include <QMouseEvent>
    #include <QSerialPort>
    #include <QSerialPortInfo>
    
    class mycombobox : public QComboBox
    {
    	Q_OBJECT
    public:
    	explicit mycombobox(QWidget* parent = nullptr);
    
    	void mousePressEvent(QMouseEvent* event) override;
    signals:
    private:
    	void scanActivatePort();
    };
    
    
  • 重写扫描函数和鼠标点击函数

    mycombobox::mycombobox(QWidget* parent) : QComboBox(parent)
    {
    	scanActivatePort();
    }
    
    void mycombobox::mousePressEvent(QMouseEvent* event)
    {
    	if (event->button() == Qt::LeftButton)
    	{
    		scanActivatePort();
    		showPopup();
    	}
    }
    
    void mycombobox::scanActivatePort()
    {
    	clear();
    	//创建串口列表
    	QStringList comPort;
    	foreach(const QSerialPortInfo & info, QSerialPortInfo::availablePorts())
    	{
    		QString serialPortInfo = info.portName() + ": " + info.description();// 串口设备信息,芯片/驱动名称
    		comPort << serialPortInfo;
    	}
    	this->addItems(comPort);
    }
    
  • 最后将comboBoxNo_2组件提升为mycombobox

image-20241220115619125

到此整个软件设计完毕

END:信号槽绑定图

image-20241220120509952

参考文献:

[1] https://rymcu.com/portfolio/40

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2268320.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【K8S问题系列 | 21 】K8S中如果PV处于Bound状态,如何删除?【已解决】

在Kubernetes&#xff08;K8S&#xff09;的存储管理体系中&#xff0c;持久卷&#xff08;PersistentVolume&#xff0c;PV&#xff09;是一种重要的资源&#xff0c;它为Pod提供了持久化存储能力。当PV处于Bound状态时&#xff0c;意味着它已经与某个持久卷声明&#xff08;P…

【行业发展报告】2024大数据与智能化行业发展浅析

回首 2024&#xff0c;大数据智能化浪潮汹涌。海量数据宛如繁星&#xff0c;在智能算法的苍穹下汇聚、碰撞&#xff0c;释放出洞察市场与用户的强大能量&#xff0c;精准勾勒出商业新航线。我们精心雕琢技术架构&#xff0c;从数据存储的坚固基石到处理分析的高效引擎&#xff…

Mumu模拟器12开启ADB调试方法

在使用安卓模拟器进行开发或调试时&#xff0c;ADB&#xff08;Android Debug Bridge&#xff09;是一项不可或缺的工具。大多数模拟器默认开启了ADB调试功能&#xff0c;但在安装最新版的 Mumu模拟器12 时&#xff0c;可能会遇到 adb devices 无法识别设备的问题。 问题描述 …

金融租赁系统的创新发展与市场竞争力提升探讨

内容概要 随着经济的快速发展&#xff0c;金融租赁系统逐渐成为金融市场中不可或缺的一环。它不仅提供了灵活的资金解决方案&#xff0c;还促进了企业的资本结构优化与资源配置效率。因此&#xff0c;了解该系统的市场背景与发展现状至关重要。 在现今环境下&#xff0c;新兴…

SQL 实战:基于经纬度的距离计算与位置查询

在位置服务&#xff08;LBS&#xff09;系统中&#xff0c;基于地理位置查询和距离计算是核心功能之一。例如&#xff1a; 查找附近的商铺、加油站或医院。计算两点之间的实际直线距离。筛选出指定范围内的用户或设备位置。 MySQL 提供了多种方式实现地理位置查询&#xff0c…

DAY1牛客题库1-3算法题:C语言版本(思路仅供参考)

挑战一下7天刷完牛客题库的108个题&#xff0c;今天是第一天思密达~一直以来都特别懒的做题&#xff0c;还是得勤奋点我觉得~今天只做了3个~嘻嘻明天去玩回家多弄几个~ 1.输出字符串最后一个单词长度 【1】题目&#xff1a; #include"stdio.h" #include"string…

LeetCode 83 :删除排链表中的重复元素

题目&#xff1a; 地址&#xff1a;https://leetcode.cn/problems/remove-duplicates-from-sorted-list/ 方法一&#xff1a; 方法二&#xff1a; package com.zy.leetcode.LeetCode_04;/*** Author: zy* Date: 2024-12-25-15:19* Description: 删除排链表中的里复元素* …

微信流量主挑战:用户破16!新增文档转换(新纪元3)

朋友们&#xff0c;报告好消息&#xff01;我的小程序用户数量已经涨到16个了&#xff01;没错&#xff0c;真没拉朋友圈亲戚好友来撑场子&#xff0c;全靠实力&#xff08;和一点点运气&#xff09;吸引了16位陌生小伙伴光临&#xff01;这波进步&#xff0c;连我自己都感动了…

Java-38 深入浅出 Spring - AOP切面增强 核心概念 相关术语 Proxy配置

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; 大数据篇正在更新&#xff01;https://blog.csdn.net/w776341482/category_12713819.html 目前已经更新到了&#xff1a; MyBatis&#xff…

基于Docker+模拟器的Appium自动化测试(二)

模拟器的设置 打开“夜神模拟器”的系统设置&#xff0c;切换到“手机与网络”页&#xff0c;选中网络设置下的“开启网络连接”和“开启网络桥接模式”复选框&#xff0c;而后选择“静态IP”单选框&#xff0c;在IP地址中输入“192.168.0.105”&#xff0c;网关等内容不再赘述…

【从零开始入门unity游戏开发之——C#篇36】C#的out协变和in逆变如何解决泛型委托的类型转换问题

文章目录 一、知识回顾和问题分析1、回顾强制转换和as转换知识2、问题分析 二、为什么泛型委托不行&#xff1f;1、泛型类型的严格类型检查2、**as 和强制类型转换不能直接使用** 三、如何解决这个问题&#xff1f;1、**协变&#xff08;out&#xff09;**2、**逆变&#xff08…

深度学习使用Anaconda打开Jupyter Notebook编码

新手入门深度学习使用Anaconda打开Jupyter Notebook编码 1. 安装Anaconda 第一种是Anaconda官网下载安装包&#xff0c;但是很慢&#xff0c;不太建议 第二种使用国内清华大学镜像源下载 选择适合自己电脑的版本&#xff0c;支持windows&#xff0c;linux系统 下载完之后自行…

Linux套接字通信学习

Linux套接字通信 代码源码&#xff1a;https://github.com/say-Hai/TcpSocketLearn/tree/CThreadSocket 在网络通信的时候, 程序猿需要负责的应用层数据的处理(最上层)&#xff0c;而底层的数据封装与解封装&#xff08;如TCP/IP协议栈的功能&#xff09;通常由操作系统、网络协…

git clone 和 conda 换源

文章目录 git clone 通过 sshconda 创建虚拟环境通过 env.yml 文件conda 换源 git clone 通过 ssh git clone ssh://用户名IP地址:/仓库名字.gitconda 创建虚拟环境通过 env.yml 文件 conda env create -f environment.ymlconda 换源 Step 1 生成 .bashrc 文件在家目录下。…

机床数据采集网关在某机械制造企业的应用

随着工业4.0时代的到来&#xff0c;智能制造已成为制造业转型升级的重要方向。数控机床作为现代制造业的核心设备&#xff0c;其运行状态和加工参数的数据实时采集与分析对于提升生产效率、优化生产流程具有关键意义。 背景概述 某机械制造企业拥有多台数控机床&#xff0c;这…

c# RSA加解密工具,.netRSA加解密工具

软件介绍 名称: c# RSA加解密工具,.netRSA加解密工具依赖.net版本: .net 8.0工具类型: WinForm源码下载 c# RSA加解密工具,.netRSA加解密工具 依赖项 WinFormsRSA.csproj <Project

穷举vs暴搜vs深搜vs回溯vs剪枝_全排列_子集

46. 全排列 递归解决&#xff1a;一开始选一个数&#xff0c;递归进入下一层再选一个新的数&#xff0c;直到到最后一个数。反会上一层遍历其它数。 每次递归到叶子节点就找到了一种组合&#xff0c;思路有了具体怎么实现&#xff1f; 1.怎么记录每条路径&#xff1f; 定义一个…

【Trick】获取kaggle账号的token和api(用于数据集下载)

0&#xff1a;操作背景 由于未来的科研需要用到Unet&#xff0c;但是运行学长的史山代码无法跑通&#xff0c;自己写了一个Unet并load学长的数据集效果也很差&#xff0c;于是打算从最最基础的开始&#xff0c;上github调用一个Unet并成功在公有数据集上跑一遍实例。 Unet的g…

VS Code AI开发之Copilot配置和使用详解

随着AI开发工具的迅速发展&#xff0c;GitHub Copilot在Cursor、Winsuf、V0等一众工具的冲击下&#xff0c;推出了免费版本。接下来&#xff0c;我将为大家介绍GitHub Copilot的配置和使用方法。GitHub Copilot基于OpenAI Codex模型&#xff0c;旨在为软件开发者提供智能化的代…

论文解读 | NeurIPS'24 Lambda:学习匹配先验以处理无标记垂悬问题场景下的实体对齐任务...

点击蓝字 关注我们 AI TIME欢迎每一位AI爱好者的加入&#xff01; 点击 阅读原文 观看作者讲解回放&#xff01; 作者简介 尹航&#xff0c;上海交通大学博士生 内容简介 我们研究了带有无标记悬挂问题的实体对齐&#xff08;EA&#xff09;任务&#xff0c;即部分实体在另一个…